xref: /aoo42x/main/l10ntools/source/xmlparse.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_l10ntools.hxx"
30 #include <iterator> /* std::iterator*/
31 
32 #include <stdio.h>
33 #include <sal/alloca.h>
34 
35 #include "xmlparse.hxx"
36 #include <fstream>
37 #include <iostream>
38 #include <osl/mutex.hxx>
39 #include <osl/thread.hxx>
40 #ifdef __MINGW32__
41 #include <tools/prewin.h>
42 #include <tools/postwin.h>
43 #endif
44 using namespace std;
45 using namespace osl;
46 
47 //
48 // class XMLChildNode
49 //
50 
51 /*****************************************************************************/
52 XMLChildNode::XMLChildNode( XMLParentNode *pPar )
53 /*****************************************************************************/
54 				: pParent( pPar )
55 {
56 	if ( pParent )
57 		pParent->AddChild( this );
58 }
59 
60 
61 /*****************************************************************************/
62 XMLChildNode::XMLChildNode( const XMLChildNode& obj)
63 /*****************************************************************************/
64 :   XMLNode(obj),
65     pParent(obj.pParent){}
66 
67 /*****************************************************************************/
68 XMLChildNode& XMLChildNode::operator=(const XMLChildNode& obj){
69 /*****************************************************************************/
70 	if(this != &obj){
71         pParent=obj.pParent;
72     }
73     return *this;
74 }
75 //
76 // class XMLParentNode
77 //
78 
79 
80 /*****************************************************************************/
81 XMLParentNode::~XMLParentNode()
82 /*****************************************************************************/
83 {
84 	if( pChildList ){
85             RemoveAndDeleteAllChilds();
86             delete pChildList;
87 			pChildList = NULL;
88     }
89 	pChildList = NULL;
90 }
91 /*****************************************************************************/
92 XMLParentNode::XMLParentNode( const XMLParentNode& obj)
93 /*****************************************************************************/
94 : XMLChildNode( obj )
95 {
96 	if( obj.pChildList ){
97         pChildList=new XMLChildNodeList();
98         XMLChildNode* pNode = NULL;
99         for ( sal_uLong i = 0; i < obj.pChildList->Count(); i++ ){
100 			pNode = obj.pChildList->GetObject( i );
101             if( pNode != NULL){
102                 switch(pNode->GetNodeType()){
103                     case XML_NODE_TYPE_ELEMENT:
104                         AddChild( new XMLElement( *static_cast<XMLElement* >(pNode) ) ); break;
105                     case XML_NODE_TYPE_DATA:
106                         AddChild( new XMLData   ( *static_cast<XMLData* >   (pNode) ) ); break;
107                     case XML_NODE_TYPE_COMMENT:
108                         AddChild( new XMLComment( *static_cast<XMLComment* >(pNode) ) ); break;
109                     case XML_NODE_TYPE_DEFAULT:
110                         AddChild( new XMLDefault( *static_cast<XMLDefault* >(pNode) ) ); break;
111                     default:    fprintf(stdout,"XMLParentNode::XMLParentNode( const XMLParentNode& obj) strange obj");
112                 }
113             }
114         }
115     }else pChildList = NULL;
116 }
117 /*****************************************************************************/
118 XMLParentNode& XMLParentNode::operator=(const XMLParentNode& obj){
119 /*****************************************************************************/
120 	if(this!=&obj){
121         XMLChildNode::operator=(obj);
122         if( pChildList ){
123             RemoveAndDeleteAllChilds();
124             delete pChildList;
125 			pChildList = NULL;
126         }
127         if( obj.pChildList ){
128             pChildList=new XMLChildNodeList();
129             for ( sal_uLong i = 0; i < obj.pChildList->Count(); i++ )
130 			    AddChild( obj.pChildList->GetObject( i ) );
131         }else pChildList = NULL;
132 
133     }
134     return *this;
135 }
136 /*****************************************************************************/
137 void XMLParentNode::AddChild( XMLChildNode *pChild )
138 /*****************************************************************************/
139 {
140 	if ( !pChildList )
141 		pChildList = new XMLChildNodeList();
142 	pChildList->Insert( pChild, LIST_APPEND );
143 }
144 
145 /*****************************************************************************/
146 void XMLParentNode::AddChild( XMLChildNode *pChild , int pos )
147 /*****************************************************************************/
148 {
149 	if ( !pChildList )
150 		pChildList = new XMLChildNodeList();
151     pChildList->Insert( pChild, pos );
152 }
153 
154 /*****************************************************************************/
155 int XMLParentNode::GetPosition( ByteString id ){
156 /*****************************************************************************/
157     XMLElement* a;
158 
159     static const ByteString sEnusStr = ByteString(String::CreateFromAscii(ENGLISH_US_ISO).ToLowerAscii() , RTL_TEXTENCODING_ASCII_US ).ToLowerAscii();
160     static const ByteString sDeStr   = ByteString(String::CreateFromAscii(GERMAN_ISO2).ToLowerAscii()    , RTL_TEXTENCODING_ASCII_US ).ToLowerAscii();
161 
162     if ( pChildList ){
163         for ( sal_uLong i = 0; i < pChildList->Count(); i++ ) {
164 		    XMLChildNode *pChild = pChildList->GetObject( i );
165             if ( pChild->GetNodeType() == XML_NODE_TYPE_ELEMENT ){
166 			    a = static_cast<XMLElement* >(pChild);
167                 ByteString elemid( a->GetId() );
168                 elemid.ToLowerAscii();
169                 if (   elemid.Equals( id.ToLowerAscii() ) ){
170                     ByteString elemLID( a->GetLanguageId() );
171                     elemLID.ToLowerAscii();
172                     if( elemLID.Equals( sEnusStr) ) {
173                         return i;
174                     }
175                     else if( elemLID.Equals( sDeStr) ) {
176                         return i;
177                     }
178                 }
179             }
180         }
181     }
182     return -1;
183 }
184 
185 /*****************************************************************************/
186 int XMLParentNode::RemoveChild( XMLElement *pRefElement )
187 /*****************************************************************************/
188 {
189     XMLElement* a;
190     if ( pChildList ){
191         for ( sal_uLong i = 0; i < pChildList->Count(); i++ ) {
192 		    XMLChildNode *pChild = pChildList->GetObject( i );
193             if ( pChild->GetNodeType() == XML_NODE_TYPE_ELEMENT ){
194 			    a = static_cast<XMLElement* >(pChild);
195                 ByteString elemid( a->GetId() );
196                 elemid.ToLowerAscii();
197                 ByteString elemLID( a->GetLanguageId() );
198                 elemLID.ToLowerAscii();
199                 ByteString pRefLID( pRefElement->GetLanguageId() );
200                 pRefLID.ToLowerAscii();
201                 if ( elemid.Equals(pRefElement->GetId())
202                     && elemLID.Equals( pRefLID ) )
203 			    {
204                     if( pRefElement->ToOString().compareTo( a->ToOString() )==0 ){
205 						pChildList->Remove( i );
206                         delete a; // Test
207                         return i;
208                     }
209                 }
210             }
211 
212         }
213     }
214     return -1;
215 }
216 
217 /*****************************************************************************/
218 void XMLParentNode::RemoveAndDeleteAllChilds(){
219 /*****************************************************************************/
220 	if ( pChildList ) {
221 		for ( sal_uLong i = 0; i < pChildList->Count(); i++ )
222 			delete pChildList->GetObject( i );
223 		pChildList->Clear();
224 	}
225 }
226 
227 /*****************************************************************************/
228 XMLElement *XMLParentNode::GetChildElement( XMLElement *pRefElement )
229 /*****************************************************************************/
230 {
231 	for ( sal_uLong i = 0; i < pChildList->Count(); i++ ) {
232 		XMLChildNode *pChild = pChildList->GetObject( i );
233 		if ( pChild->GetNodeType() == XML_NODE_TYPE_ELEMENT )
234 			if ((( XMLElement * ) pChild )->GetName() ==
235 				pRefElement->GetName())
236 			{
237 				XMLAttributeList *pList = pRefElement->GetAttributeList();
238 				if ( !pList )
239 					return ( XMLElement * ) pChild;
240 
241 				sal_Bool bMatch = sal_False;
242 				for ( sal_uLong j = 0; j < pList->Count() && bMatch; j++ ) {
243 					XMLAttribute *pAttribute = pList->GetObject( j );
244 					XMLAttribute *pCandidate =
245 						(( XMLElement * ) pChild )->GetAttribute(
246 							*pAttribute );
247 					if ( !pCandidate || !pAttribute->IsEqual( *pCandidate ))
248 						bMatch = sal_False;
249 				}
250 				if ( bMatch )
251 					return ( XMLElement * ) pChild;
252 			}
253 	}
254 	return NULL;
255 }
256 
257 //
258 // class XMLFile
259 //
260 
261 /*****************************************************************************/
262 sal_uInt16 XMLFile::GetNodeType()
263 /*****************************************************************************/
264 {
265 	return XML_NODE_TYPE_FILE;
266 }
267 
268 /*****************************************************************************/
269 sal_Bool XMLFile::Write( ByteString &aFilename )
270 /*****************************************************************************/
271 {
272 
273     if ( aFilename.Len()) {
274 		// retry harder if there is a NFS problem,
275         for( int x = 1 ; x < 3 ; x++ ){	// this looks strange...yes!
276 			ofstream aFStream( aFilename.GetBuffer() , ios::out | ios::trunc );
277 
278             if( !aFStream )		// From time to time the stream can not be opened the first time on NFS volumes,
279 			{					// I wasn't able to track this down. I think this is an NFS issue .....
280                 //cerr << "ERROR: - helpex - Can't write to tempfile " << aFilename.GetBuffer() << " No#" << x << "\n";
281                 TimeValue aTime;
282                 aTime.Seconds = 3;
283                 aTime.Nanosec = 0;
284 
285                 osl::Thread::wait( aTime );
286             }
287             else
288             {
289                 // write out
290 				Write( aFStream );
291                 aFStream.close();
292 
293 				// check!
294 				DirEntry aTarget( aFilename );
295                 FileStat aFileStat( aTarget );
296 
297 				if( aFileStat.GetSize() < 1 )
298 				{
299                     //retry
300 					//cerr << "WARNING: - helpex - Can't create file " << aFilename.GetBuffer() << " No#" << x << "\n";
301                     aTarget.Kill();
302                 }
303 				else
304 				{
305                     //everything ok!
306 					return true;
307                 }
308             }
309 	    }
310 		cerr << "ERROR: - helpex - Can't create file " << aFilename.GetBuffer() << "\nPossible reason: Disk full ? Mounted NFS volume broken ? Wrong permissions ?\n";
311         exit( -1 );
312     }
313     cerr << "ERROR: - helpex - Empty file name\n";
314     exit( -1 );
315 }
316 
317 
318 
319 void XMLFile::WriteString( ofstream &rStream, const String &sString )
320 {
321 	ByteString sText( sString, RTL_TEXTENCODING_UTF8 );
322 	rStream << sText.GetBuffer();
323 }
324 
325 
326 sal_Bool XMLFile::Write( ofstream &rStream , XMLNode *pCur )
327 {
328     XMLUtil& xmlutil = XMLUtil::Instance();
329     (void) xmlutil;
330 
331     if ( !pCur )
332 		Write( rStream, this );
333 	else {
334 		switch( pCur->GetNodeType()) {
335 			case XML_NODE_TYPE_FILE: {
336 				if( GetChildList())
337 					for ( sal_uLong i = 0; i < GetChildList()->Count(); i++ )
338 						Write( rStream, GetChildList()->GetObject( i ));
339 			}
340 			break;
341 			case XML_NODE_TYPE_ELEMENT: {
342 				XMLElement *pElement = ( XMLElement * ) pCur;
343 				rStream  << "<";
344 				WriteString( rStream, pElement->GetName());
345 				if ( pElement->GetAttributeList())
346 					for ( sal_uLong j = 0; j < pElement->GetAttributeList()->Count(); j++ ) {
347 						rStream << " ";
348 						String sData(*pElement->GetAttributeList()->GetObject( j ));
349 						xmlutil.QuotHTML( sData );
350 						WriteString( rStream , sData );
351 						rStream << "=\"";
352 						sData=pElement->GetAttributeList()->GetObject( j )->GetValue();
353 						xmlutil.QuotHTML(  sData );
354 						WriteString( rStream , sData  );
355 						rStream << "\"";
356 					}
357 				if ( !pElement->GetChildList())
358 					rStream << "/>";
359 				else {
360 					rStream << ">";
361 					for ( sal_uLong k = 0; k < pElement->GetChildList()->Count(); k++ )
362 						Write( rStream, pElement->GetChildList()->GetObject( k ));
363 					rStream << "</";
364 					WriteString( rStream, pElement->GetName());
365 					rStream << ">";
366    				}
367 			}
368 			break;
369 			case XML_NODE_TYPE_DATA: {
370 				XMLData *pData = ( XMLData * ) pCur;
371 				String sData( pData->GetData());
372                 xmlutil.QuotHTML( sData );
373 				WriteString( rStream, sData );
374 			}
375 			break;
376 			case XML_NODE_TYPE_COMMENT: {
377 				XMLComment *pComment = ( XMLComment * ) pCur;
378 				rStream << "<!--";
379 				WriteString( rStream, pComment->GetComment());
380 				rStream << "-->";
381 			}
382 			break;
383 			case XML_NODE_TYPE_DEFAULT: {
384 				XMLDefault *pDefault = ( XMLDefault * ) pCur;
385 				WriteString( rStream, pDefault->GetDefault());
386 			}
387 			break;
388 		}
389 	}
390 	return sal_True;
391 }
392 
393 
394 void XMLFile::Print( XMLNode *pCur, sal_uInt16 nLevel )
395 {
396 
397 	if ( !pCur )
398 		Print( this );
399 	else {
400 		switch( pCur->GetNodeType()) {
401 			case XML_NODE_TYPE_FILE: {
402 				if( GetChildList())
403 					for ( sal_uLong i = 0; i < GetChildList()->Count(); i++ )
404 						Print( GetChildList()->GetObject( i ));
405 			}
406 			break;
407 			case XML_NODE_TYPE_ELEMENT: {
408 				XMLElement *pElement = ( XMLElement * ) pCur;
409 
410 				fprintf( stdout, "<%s", ByteString( pElement->GetName(), RTL_TEXTENCODING_UTF8 ).GetBuffer());
411 				if ( pElement->GetAttributeList())
412 					for ( sal_uLong j = 0; j < pElement->GetAttributeList()->Count(); j++ ){
413 						ByteString aAttrName( *pElement->GetAttributeList()->GetObject( j ), RTL_TEXTENCODING_UTF8 );
414                         if( !aAttrName.EqualsIgnoreCaseAscii( XML_LANG ) ) {
415                             fprintf( stdout, " %s=\"%s\"",
416                                 aAttrName.GetBuffer(),
417 							    ByteString( pElement->GetAttributeList()->GetObject( j )->GetValue(),
418 								    RTL_TEXTENCODING_UTF8 ).GetBuffer());
419                         }
420                     }
421 				if ( !pElement->GetChildList())
422 					fprintf( stdout, "/>" );
423 				else {
424 					fprintf( stdout, ">" );
425 					for ( sal_uLong k = 0; k < pElement->GetChildList()->Count(); k++ )
426 						Print( pElement->GetChildList()->GetObject( k ), nLevel + 1 );
427 					fprintf( stdout, "</%s>", ByteString( pElement->GetName(), RTL_TEXTENCODING_UTF8 ).GetBuffer());
428 				}
429 			}
430 			break;
431 			case XML_NODE_TYPE_DATA: {
432 				XMLData *pData = ( XMLData * ) pCur;
433 				String sData = pData->GetData();
434 				fprintf( stdout, "%s", ByteString( sData, RTL_TEXTENCODING_UTF8 ).GetBuffer());
435 			}
436 			break;
437 			case XML_NODE_TYPE_COMMENT: {
438 				XMLComment *pComment = ( XMLComment * ) pCur;
439 				fprintf( stdout, "<!--%s-->", ByteString( pComment->GetComment(), RTL_TEXTENCODING_UTF8 ).GetBuffer());
440 			}
441 			break;
442 			case XML_NODE_TYPE_DEFAULT: {
443 				XMLDefault *pDefault = ( XMLDefault * ) pCur;
444 				fprintf( stdout, "%s", ByteString( pDefault->GetDefault(), RTL_TEXTENCODING_UTF8 ).GetBuffer());
445 			}
446 			break;
447 		}
448 	}
449 }
450 XMLFile::~XMLFile()
451 {
452 	if( XMLStrings != NULL ){
453 		XMLHashMap::iterator pos = XMLStrings->begin();
454 		for( ; pos != XMLStrings->end() ; ++pos ){
455 			delete pos->second;				// Check and delete content also ?
456 		}
457 		delete XMLStrings;
458 		XMLStrings = NULL;
459 	}
460 }
461 /*****************************************************************************/
462 XMLFile::XMLFile( const String &rFileName ) // the file name, empty if created from memory stream
463 /*****************************************************************************/
464 				: XMLParentNode( NULL ),
465 				  sFileName    ( rFileName ),
466 				  ID           ( "id" ),
467                   OLDREF       ( "oldref" ),
468 				  XML_LANG     ( "xml-lang" ),
469 				  XMLStrings   ( NULL )
470 
471 {
472 //	nodes_localize.insert( TagMap::value_type(ByteString(String::CreateFromAscii("bookmark_value"),RTL_TEXTENCODING_ASCII_US) , sal_True) );
473 	nodes_localize.insert( TagMap::value_type(ByteString(String::CreateFromAscii("bookmark"),RTL_TEXTENCODING_ASCII_US) , sal_True) );
474     nodes_localize.insert( TagMap::value_type(ByteString(String::CreateFromAscii("variable"),RTL_TEXTENCODING_ASCII_US) , sal_True) );
475 	nodes_localize.insert( TagMap::value_type(ByteString(String::CreateFromAscii("paragraph"),RTL_TEXTENCODING_ASCII_US) , sal_True) );
476 	nodes_localize.insert( TagMap::value_type(ByteString(String::CreateFromAscii("alt"),RTL_TEXTENCODING_ASCII_US) , sal_True) );
477 	nodes_localize.insert( TagMap::value_type(ByteString(String::CreateFromAscii("caption"),RTL_TEXTENCODING_ASCII_US) , sal_True) );
478 	nodes_localize.insert( TagMap::value_type(ByteString(String::CreateFromAscii("title"),RTL_TEXTENCODING_ASCII_US) , sal_True) );
479 	nodes_localize.insert( TagMap::value_type(ByteString(String::CreateFromAscii("link"),RTL_TEXTENCODING_ASCII_US) , sal_True) );
480 }
481 /*****************************************************************************/
482 void XMLFile::Extract( XMLFile *pCur )
483 /*****************************************************************************/
484 {
485 	if( XMLStrings != NULL ) delete XMLStrings; // Elements ?
486 
487 	XMLStrings = new XMLHashMap();
488    	if ( !pCur )
489         SearchL10NElements( this );
490 	else {
491 		if( pCur->GetNodeType()==XML_NODE_TYPE_FILE) {
492             SearchL10NElements(pCur);
493 		}
494 	}
495 }
496 
497 /*****************************************************************************/
498 void XMLFile::View(){
499 /*****************************************************************************/
500 	XMLElement* cur;
501 	for(XMLHashMap::iterator pos=XMLStrings->begin(); pos!=XMLStrings->end();++pos){
502 		fprintf(stdout,"\nid=%s\n",(pos->first).GetBuffer());
503 		LangHashMap* elem=pos->second;
504 		for(LangHashMap::iterator pos2=elem->begin(); pos2!=elem->end();++pos2){
505 			fprintf( stdout,"\nlanguage=%s\n",(pos2->first).GetBuffer() );
506 			cur=pos2->second;
507 			fprintf(stdout,"\n%s\n",((XMLElement*)cur)->ToOString().getStr());
508 
509 		}
510 	}
511 }
512 
513 /*****************************************************************************/
514 void XMLFile::InsertL10NElement( XMLElement* pElement ){
515 /*****************************************************************************/
516 	ByteString tmpStr,id,oldref,language("");
517 	LangHashMap* elem;
518 
519     if( pElement->GetAttributeList() != NULL ){
520         for ( sal_uLong j = 0; j < pElement->GetAttributeList()->Count(); j++ ){
521 		    tmpStr=ByteString( *pElement->GetAttributeList()->GetObject( j ),RTL_TEXTENCODING_UTF8 );
522 		    if( tmpStr.CompareTo(ID)==COMPARE_EQUAL  ){	// Get the "id" Attribute
523 			    id = ByteString( pElement->GetAttributeList()->GetObject( j )->GetValue(),RTL_TEXTENCODING_UTF8 );
524 		    }
525 		    if( tmpStr.CompareTo( XML_LANG ) == COMPARE_EQUAL ){	// Get the "xml-lang" Attribute
526 			    language = ByteString( pElement->GetAttributeList()->GetObject( j )->GetValue(),RTL_TEXTENCODING_UTF8 );
527 		    }
528 
529 	    }
530     }else{
531         fprintf(stdout,"XMLFile::InsertL10NElement: No AttributeList found");
532         fprintf(stdout,"++++++++++++++++++++++++++++++++++++++++++++++++++");
533         Print( pElement , 0 );
534         fprintf(stdout,"++++++++++++++++++++++++++++++++++++++++++++++++++");
535     }
536 
537 	XMLHashMap::iterator pos = XMLStrings->find( id );
538 	if( pos == XMLStrings->end() ){				// No instanze , create new one
539         elem = new LangHashMap();
540         (*elem)[ language ]=pElement;
541 		XMLStrings->insert( XMLHashMap::value_type( id , elem ) );
542         order.push_back( id );
543 	}else{									// Already there
544         elem=pos->second;
545         if ( (*elem)[ language ] )
546         {
547             fprintf(stdout,"Error: Duplicated entry. ID = %s  LANG = %s in File %s\n", id.GetBuffer(), language.GetBuffer(), ByteString( sFullName,RTL_TEXTENCODING_ASCII_US ).GetBuffer() );
548             exit( -1 );
549         }
550         (*elem)[ language ]=pElement;
551 	}
552 }
553 /*****************************************************************************/
554 void XMLFile::showType(XMLParentNode* node){
555 /*****************************************************************************/
556 	switch (node->GetNodeType()){
557 		case XML_NODE_TYPE_ELEMENT: fprintf(stdout,"ELEMENT\n") ;break;
558 		case XML_NODE_TYPE_FILE:    fprintf(stdout,"FILE\n")    ;break;
559 		case XML_NODE_TYPE_COMMENT: fprintf(stdout,"COMMENT\n") ;break;
560 		case XML_NODE_TYPE_DATA:    fprintf(stdout,"DATA\n")    ;break;
561 		case XML_NODE_TYPE_DEFAULT: fprintf(stdout,"DEFAULT\n") ;break;
562 		default: break;
563 	}
564 }
565 XMLFile::XMLFile()
566 /*****************************************************************************/
567 				: XMLParentNode( NULL ),
568 				  ID           ( "id" ),
569                   OLDREF       ( "oldref" ),
570 				  XML_LANG     ( "xml-lang" ),
571 				  XMLStrings   ( NULL ){};
572 
573 
574 XMLFile::XMLFile( const XMLFile& obj )
575 /*****************************************************************************/
576 				: XMLParentNode( obj ),
577 				  sFileName    ( obj.sFileName ),
578 				  ID           ( "id" ),
579                   OLDREF       ( "oldref" ),
580 				  XML_LANG     ( "xml-lang" ),
581 				  XMLStrings   ( NULL )
582 {
583 	if( this!=&obj )
584 	{
585         nodes_localize  =obj.nodes_localize;
586         order           =obj.order;
587 
588 	}
589 }
590 /*****************************************************************************/
591 XMLFile& XMLFile::operator=(const XMLFile& obj){
592 /*****************************************************************************/
593     if( this!=&obj ){
594 
595         XMLParentNode::operator=(obj);
596 
597         nodes_localize  =obj.nodes_localize;
598         order           =obj.order;
599 
600 		if( XMLStrings )    delete XMLStrings;
601 
602 		if( obj.XMLStrings )
603         {
604             XMLStrings = new XMLHashMap();
605 	        for( XMLHashMap::iterator pos = obj.XMLStrings->begin() ; pos != obj.XMLStrings->end() ; ++pos )
606             {
607 		        LangHashMap* elem=pos->second;
608 		        LangHashMap* newelem = new LangHashMap();
609                 for(LangHashMap::iterator pos2=elem->begin(); pos2!=elem->end();++pos2){
610                     (*newelem)[ pos2->first ] = new XMLElement( *pos2->second );
611                     printf("*");
612 		        }
613                 (*XMLStrings)[ pos->first ] = newelem;
614             }
615         }
616     }
617     printf("done!\n");
618     return *this;
619 }
620 
621 
622 /*****************************************************************************/
623 void XMLFile::SearchL10NElements( XMLParentNode *pCur , int pos)
624 /*****************************************************************************/
625 {
626 	static const ByteString LOCALIZE("localize");
627 	static const ByteString THEID("id");
628 	bool bInsert	= true;
629 	if ( !pCur )
630 		SearchL10NElements( this  );
631 	else {
632 		switch( pCur->GetNodeType()) {
633 			case XML_NODE_TYPE_FILE: {
634                 XMLParentNode* pElement;
635                 if( GetChildList()){
636                     for ( sal_uLong i = 0; i < GetChildList()->Count(); i++ ){
637                         pElement = (XMLParentNode*) GetChildList()->GetObject( i );
638                         if( pElement->GetNodeType() ==  XML_NODE_TYPE_ELEMENT ) SearchL10NElements( pElement , i);
639                     }
640                 }
641             }
642 			break;
643 			case XML_NODE_TYPE_ELEMENT: {
644 				XMLElement *pElement = ( XMLElement * ) pCur;
645         		ByteString sName(pElement->GetName(),RTL_TEXTENCODING_ASCII_US);
646                 ByteString language,tmpStrVal,oldref;
647 				if ( pElement->GetAttributeList()){
648 					for ( sal_uLong j = 0 , cnt = pElement->GetAttributeList()->Count(); j < cnt && bInsert; j++ ){
649 						const ByteString tmpStr( *pElement->GetAttributeList()->GetObject( j ),RTL_TEXTENCODING_UTF8 );
650 						if( tmpStr.CompareTo(THEID)==COMPARE_EQUAL  ){	// Get the "id" Attribute
651 							tmpStrVal=ByteString( pElement->GetAttributeList()->GetObject( j )->GetValue(),RTL_TEXTENCODING_UTF8 );
652                             //printf("Checking id = %s\n",tmpStrVal.GetBuffer() );
653 						}
654 						if( tmpStr.CompareTo(LOCALIZE)==COMPARE_EQUAL  ){	// Get the "localize" Attribute
655 							bInsert=false;
656 						}
657 						if( tmpStr.CompareTo(XML_LANG)==COMPARE_EQUAL ){	// Get the "xml-lang" Attribute
658 							language=ByteString( pElement->GetAttributeList()->GetObject( j )->GetValue(),RTL_TEXTENCODING_UTF8 );
659 						}
660                         if( tmpStr.CompareTo(OLDREF)==COMPARE_EQUAL ){	// Get the "oldref" Attribute
661 		                    oldref=ByteString( pElement->GetAttributeList()->GetObject( j )->GetValue(),RTL_TEXTENCODING_UTF8 );
662 		                }
663 					}
664 					pElement->SetLanguageId ( language );
665 					pElement->SetId         ( tmpStrVal.GetBuffer() );
666                     pElement->SetOldRef     ( oldref  );
667                     pElement->SetPos( pos );
668 				}
669 
670 				if ( bInsert && ( nodes_localize.find( sName.ToLowerAscii() ) != nodes_localize.end() ) )
671 					InsertL10NElement(pElement);
672 				else if ( bInsert && pElement->GetChildList() ){
673 					for ( sal_uLong k = 0; k < pElement->GetChildList()->Count(); k++ )
674 						SearchL10NElements( (XMLParentNode*) pElement->GetChildList()->GetObject( k ) , k);
675 				}
676             }
677 			break;
678 			case XML_NODE_TYPE_DATA: {
679 			}
680 			break;
681 			case XML_NODE_TYPE_COMMENT: {
682 			}
683 			break;
684 			case XML_NODE_TYPE_DEFAULT: {
685 			}
686 			break;
687 		}
688 	}
689 }
690 
691 /*****************************************************************************/
692 bool XMLFile::CheckExportStatus( XMLParentNode *pCur )
693 /*****************************************************************************/
694 {
695     static bool bStatusExport = true;
696     const ByteString LOCALIZE("localize");
697     const ByteString STATUS("status");
698     const ByteString PUBLISH("PUBLISH");
699     const ByteString DEPRECATED("DEPRECATED");
700 
701     const ByteString TOPIC("topic");
702 	bool bInsert	= true;
703 	if ( !pCur )
704 		CheckExportStatus( this );
705 	else {
706         switch( pCur->GetNodeType()) {
707 			case XML_NODE_TYPE_FILE: {
708                 XMLParentNode* pElement;
709                 if( GetChildList()){
710                     for ( sal_uLong i = 0; i < GetChildList()->Count(); i++ ){
711                         pElement = (XMLParentNode*) GetChildList()->GetObject( i );
712                         if( pElement->GetNodeType() ==  XML_NODE_TYPE_ELEMENT ) CheckExportStatus( pElement );//, i);
713                     }
714                 }
715             }
716 			break;
717 			case XML_NODE_TYPE_ELEMENT: {
718 				XMLElement *pElement = ( XMLElement * ) pCur;
719         		ByteString sName(pElement->GetName(),RTL_TEXTENCODING_ASCII_US);
720                 if( sName.EqualsIgnoreCaseAscii( TOPIC ) ){
721 				    if ( pElement->GetAttributeList()){
722 					    for ( sal_uLong j = 0 , cnt = pElement->GetAttributeList()->Count(); j < cnt && bInsert; j++ ){
723 						    const ByteString tmpStr( *pElement->GetAttributeList()->GetObject( j ),RTL_TEXTENCODING_UTF8 );
724                             if( tmpStr.EqualsIgnoreCaseAscii( STATUS ) ){
725 							    ByteString tmpStrVal=ByteString( pElement->GetAttributeList()->GetObject( j )->GetValue(),RTL_TEXTENCODING_UTF8 );
726                                 if( !tmpStrVal.EqualsIgnoreCaseAscii( PUBLISH )  &&
727                                     !tmpStrVal.EqualsIgnoreCaseAscii( DEPRECATED )){
728                                     bStatusExport = false;
729                                 }
730 						    }
731 
732                         }
733                     }
734                 }
735 				else if ( pElement->GetChildList() ){
736 					for ( sal_uLong k = 0; k < pElement->GetChildList()->Count(); k++ )
737 						CheckExportStatus( (XMLParentNode*) pElement->GetChildList()->GetObject( k ) );//, k);
738 				}
739             }
740 			break;
741 		}
742 	}
743     return bStatusExport;
744 }
745 
746 /*****************************************************************************/
747 sal_uInt16 XMLElement::GetNodeType()
748 /*****************************************************************************/
749 {
750 	return XML_NODE_TYPE_ELEMENT;
751 }
752 
753 /*****************************************************************************/
754 XMLElement::XMLElement(const XMLElement& obj)
755 /*****************************************************************************/
756 	:
757                 XMLParentNode   ( obj ),
758 				sElementName    ( obj.sElementName ),
759 				pAttributes     ( NULL ),
760 				project         ( obj.project ),
761 				filename        ( obj.filename ),
762 				id              ( obj.id ),
763 				sOldRef         ( obj.sOldRef ),
764 				resourceType    ( obj.resourceType ),
765 				languageId      ( obj.languageId ),
766                 nPos            ( obj.nPos )
767 
768 {
769     if ( obj.pAttributes ){
770         pAttributes = new XMLAttributeList();
771         for ( sal_uLong i = 0; i < obj.pAttributes->Count(); i++ )
772 			AddAttribute( *obj.pAttributes->GetObject( i ) , obj.pAttributes->GetObject( i )->GetValue() );
773     }
774 }
775 
776 /*****************************************************************************/
777 XMLElement& XMLElement::operator=(const XMLElement& obj){
778 /*****************************************************************************/
779     if( this!=&obj ){
780         XMLParentNode::operator=(obj);
781         sElementName    =obj.sElementName;
782 		project         =obj.project;
783 		filename        =obj.filename;
784 		id              =obj.id;
785 		sOldRef         =obj.sOldRef;
786 		resourceType    =obj.resourceType;
787 		languageId      =obj.languageId;
788         nPos            =obj.nPos;
789 
790         if ( pAttributes ){
791             for ( sal_uLong i = 0; i < pAttributes->Count(); i++ )
792 			    delete pAttributes->GetObject( i );
793 	        delete pAttributes;
794 	    }
795         if ( obj.pAttributes ){
796             pAttributes         =new XMLAttributeList();
797             for ( sal_uLong i = 0; i < obj.pAttributes->Count(); i++ )
798 			    AddAttribute( *obj.pAttributes->GetObject( i ) , obj.pAttributes->GetObject( i )->GetValue() );
799         }
800     }
801     return *this;
802 }
803 
804 /*****************************************************************************/
805 void XMLElement::AddAttribute( const String &rAttribute, const String &rValue )
806 /*****************************************************************************/
807 {
808 	if ( !pAttributes )
809 		pAttributes = new XMLAttributeList();
810 	pAttributes->Insert( new XMLAttribute( rAttribute, rValue ), LIST_APPEND );
811 }
812 
813 /*****************************************************************************/
814 void XMLElement::ChangeLanguageTag( const String &rValue ){
815 /*****************************************************************************/
816     static const String rName = String::CreateFromAscii("xml-lang");
817     SetLanguageId( ByteString(rValue,RTL_TEXTENCODING_UTF8) );
818     if ( pAttributes ){
819         for ( sal_uLong i = 0; i < pAttributes->Count(); i++ ){
820             if ( *pAttributes->GetObject( i ) == rName ){
821                 pAttributes->GetObject( i )->setValue(rValue);
822             }
823         }
824     }
825     XMLChildNode* pNode  = NULL;
826     XMLElement*   pElem  = NULL;
827     XMLChildNodeList* pCList = GetChildList();
828 
829     if( pCList != NULL ){
830         for ( sal_uLong i = 0; i < pCList->Count(); i++ ){
831 			pNode = pCList->GetObject( i );
832             if( pNode != NULL && pNode->GetNodeType() == XML_NODE_TYPE_ELEMENT ){
833                 pElem = static_cast< XMLElement* >(pNode);
834                 pElem->ChangeLanguageTag( rValue );
835                 pElem->SetLanguageId( ByteString(rValue,RTL_TEXTENCODING_UTF8) );
836                 pElem  = NULL;
837                 pNode  = NULL;
838             }
839         }
840         pCList = NULL;
841     }
842 }
843 /*****************************************************************************/
844 XMLAttribute *XMLElement::GetAttribute( const String &rName	)
845 /*****************************************************************************/
846 {
847 	if ( pAttributes )
848 		for ( sal_uLong i = 0; i < pAttributes->Count(); i++ )
849 			if ( *pAttributes->GetObject( i ) == rName )
850 				return pAttributes->GetObject( i );
851 
852 	return NULL;
853 }
854 
855 /*****************************************************************************/
856 XMLElement::~XMLElement()
857 /*****************************************************************************/
858 {
859 	if ( pAttributes ) {
860 		for ( sal_uLong i = 0; i < pAttributes->Count(); i++ )
861 			delete pAttributes->GetObject( i );
862 
863 		delete pAttributes;
864 		pAttributes = NULL;
865 	}
866 }
867 /*****************************************************************************/
868 bool	XMLElement::Equals(OUString refStr){
869 /*****************************************************************************/
870 	return  refStr.equals( ToOUString() );
871 }
872 
873 /*****************************************************************************/
874 OString XMLElement::ToOString(){
875 /*****************************************************************************/
876     OUString ouEmpty;
877 
878 	OUStringBuffer* buffer = new OUStringBuffer();
879 	Print( this, *buffer , true );
880 
881 	OString result( (sal_Unicode* )buffer->getStr(), buffer->getLength() , RTL_TEXTENCODING_UTF8 );
882 	delete buffer;
883 	return result;
884 }
885 /*****************************************************************************/
886 OUString XMLElement::ToOUString(){
887 /*****************************************************************************/
888 	OUStringBuffer* buffer = new OUStringBuffer();
889 	Print(this,*buffer,true);
890 	OUString result=buffer->makeStringAndClear();
891 	String xy(result.getStr());
892     result=OUString(xy);
893 	delete buffer;
894 	return result;
895 }
896 /*****************************************************************************/
897 void XMLElement::Print(XMLNode *pCur, OUStringBuffer& buffer , bool rootelement ){
898 /*****************************************************************************/
899     //YD FIXME somewhere COMMENT is defined as 4!
900     static const String _COMMENT = String::CreateFromAscii("comment");
901     static const OUString XML_LANG ( OUString::createFromAscii("xml-lang") );
902 
903     if(pCur!=NULL){
904         if(rootelement){
905             XMLElement *pElement = ( XMLElement * ) pCur;
906             if ( pElement->GetAttributeList()){
907                 if ( pElement->GetChildList()){
908                     XMLChildNode* tmp=NULL;
909                     for ( sal_uLong k = 0; k < pElement->GetChildList()->Count(); k++ ){
910 				        tmp=pElement->GetChildList()->GetObject( k );
911                         Print( tmp, buffer , false);
912                     }
913 				}
914 			}
915         }
916         else{
917 
918         switch( pCur->GetNodeType()) {
919 			case XML_NODE_TYPE_ELEMENT: {
920 				XMLElement *pElement = ( XMLElement * ) pCur;
921 
922                 if(  !pElement->GetName().EqualsIgnoreCaseAscii( _COMMENT ) ){
923                     buffer.append( OUString::createFromAscii("\\<") );
924 				    buffer.append( pElement->GetName() );
925 				    if ( pElement->GetAttributeList()){
926 					    for ( sal_uLong j = 0; j < pElement->GetAttributeList()->Count(); j++ ){
927 
928                             OUString aAttrName( *pElement->GetAttributeList()->GetObject( j ) );
929                             if( !aAttrName.equalsIgnoreAsciiCase( XML_LANG ) ) {
930                                 buffer.append( OUString::createFromAscii(" ") );
931                                 buffer.append( aAttrName );
932                                 buffer.append( OUString::createFromAscii("=") );
933 						        buffer.append( OUString::createFromAscii("\\\"") );
934 					            buffer.append( pElement->GetAttributeList()->GetObject( j )->GetValue() );
935 						        buffer.append( OUString::createFromAscii("\\\"") );
936                             }
937 					    }
938                     }
939 				    if ( !pElement->GetChildList())
940 					    buffer.append( OUString::createFromAscii("/\\>") );
941 				    else {
942 					    buffer.append( OUString::createFromAscii("\\>") );
943                         XMLChildNode* tmp=NULL;
944                         for ( sal_uLong k = 0; k < pElement->GetChildList()->Count(); k++ ){
945 						    tmp=pElement->GetChildList()->GetObject( k );
946                             Print( tmp, buffer , false);
947                         }
948 					    buffer.append( OUString::createFromAscii("\\</") );
949 				        buffer.append( pElement->GetName() );
950                         buffer.append( OUString::createFromAscii("\\>") );
951 	                }
952                 }
953 			}
954 			break;
955 			case XML_NODE_TYPE_DATA: {
956 				XMLData *pData = ( XMLData * ) pCur;
957 				String sData = pData->GetData();
958                 buffer.append( sData );
959 			}
960 			break;
961 			case XML_NODE_TYPE_COMMENT: {
962 				XMLComment *pComment = ( XMLComment * ) pCur;
963 				buffer.append( OUString::createFromAscii("<!--") );
964 			    buffer.append( pComment->GetComment() );
965 			    buffer.append( OUString::createFromAscii("-->") );
966 			}
967 			break;
968 			case XML_NODE_TYPE_DEFAULT: {
969 				XMLDefault *pDefault = ( XMLDefault * ) pCur;
970 				buffer.append( pDefault->GetDefault() );
971 			}
972 			break;
973 		}
974         }
975     }else {
976         fprintf(stdout,"\n#+------Error: NULL Pointer in XMLELement::Print------+#\n");
977         return;
978     }
979 }
980 
981 
982 //
983 // class XMLData
984 //
985 /*****************************************************************************/
986 XMLData::XMLData(const XMLData& obj)
987 /*****************************************************************************/
988 	: XMLChildNode( obj ),
989       sData( obj.sData ) ,
990       isNewCreated ( obj.isNewCreated ){}
991 
992 /*****************************************************************************/
993 XMLData& XMLData::operator=(const XMLData& obj){
994 /*****************************************************************************/
995 	if( this!=&obj ){
996         XMLChildNode::operator=( obj );
997         sData           = obj.sData;
998         isNewCreated    = obj.isNewCreated;
999     }
1000     return *this;
1001 }
1002 /*****************************************************************************/
1003 void XMLData::AddData( const String &rData) {
1004 /*****************************************************************************/
1005 	sData += rData;
1006 }
1007 
1008 /*****************************************************************************/
1009 sal_uInt16 XMLData::GetNodeType()
1010 /*****************************************************************************/
1011 {
1012 	return XML_NODE_TYPE_DATA;
1013 }
1014 
1015 //
1016 // class XMLComment
1017 //
1018 
1019 /*****************************************************************************/
1020 sal_uInt16 XMLComment::GetNodeType()
1021 /*****************************************************************************/
1022 {
1023 	return XML_NODE_TYPE_COMMENT;
1024 }
1025 /*****************************************************************************/
1026 XMLComment::XMLComment(const XMLComment& obj)
1027 /*****************************************************************************/
1028 	: XMLChildNode( obj ),
1029       sComment( obj.sComment ){}
1030 
1031 /*****************************************************************************/
1032 XMLComment& XMLComment::operator=(const XMLComment& obj){
1033 /*****************************************************************************/
1034 	if( this!=&obj ){
1035         XMLChildNode::operator=( obj );
1036         sComment        = obj.sComment;
1037     }
1038     return *this;
1039 }
1040 
1041 //
1042 // class XMLDefault
1043 //
1044 
1045 /*****************************************************************************/
1046 sal_uInt16 XMLDefault::GetNodeType()
1047 /*****************************************************************************/
1048 {
1049 	return XML_NODE_TYPE_DEFAULT;
1050 }
1051 /*****************************************************************************/
1052 XMLDefault::XMLDefault(const XMLDefault& obj)
1053 /*****************************************************************************/
1054 	: XMLChildNode( obj ),
1055       sDefault( obj.sDefault){}
1056 
1057 /*****************************************************************************/
1058 XMLDefault& XMLDefault::operator=(const XMLDefault& obj){
1059 /*****************************************************************************/
1060 	if( this!=&obj ){
1061         XMLChildNode::operator=( obj );
1062         sDefault        = obj.sDefault;
1063     }
1064     return *this;
1065 }
1066 
1067 
1068 //
1069 // class SimpleXMLParser
1070 //
1071 
1072 #define XML_CHAR_TO_OUSTRING(x) OStringToOUString(OString(x), RTL_TEXTENCODING_UTF8)
1073 #define XML_CHAR_N_TO_OUSTRING(x,n) OStringToOUString(OString(x,n), RTL_TEXTENCODING_UTF8 )
1074 
1075 
1076 /*****************************************************************************/
1077 SimpleXMLParser::SimpleXMLParser()
1078 /*****************************************************************************/
1079 				: pXMLFile( NULL )
1080 {
1081     aParser = XML_ParserCreate( NULL );
1082 	XML_SetUserData( aParser, this );
1083 	XML_SetElementHandler( aParser, (XML_StartElementHandler) StartElementHandler, (XML_EndElementHandler) EndElementHandler );
1084 	XML_SetCharacterDataHandler( aParser, (XML_CharacterDataHandler) CharacterDataHandler );
1085 	XML_SetCommentHandler( aParser, (XML_CommentHandler) CommentHandler );
1086 	XML_SetDefaultHandler( aParser, (XML_DefaultHandler) DefaultHandler );
1087 }
1088 
1089 /*****************************************************************************/
1090 SimpleXMLParser::~SimpleXMLParser()
1091 /*****************************************************************************/
1092 {
1093 	XML_ParserFree( aParser );
1094 }
1095 
1096 /*****************************************************************************/
1097 void SimpleXMLParser::StartElementHandler(
1098 	void *userData, const XML_Char *name, const XML_Char **atts )
1099 /*****************************************************************************/
1100 {
1101 	(( SimpleXMLParser * ) userData )->StartElement( name, atts );
1102 }
1103 
1104 
1105 /*****************************************************************************/
1106 void SimpleXMLParser::EndElementHandler(
1107 	void *userData, const XML_Char *name )
1108 /*****************************************************************************/
1109 {
1110 	(( SimpleXMLParser * ) userData )->EndElement( name );
1111 }
1112 
1113 /*****************************************************************************/
1114 void SimpleXMLParser::CharacterDataHandler(
1115 	void *userData, const XML_Char *s, int len )
1116 /*****************************************************************************/
1117 {
1118 	(( SimpleXMLParser * ) userData )->CharacterData( s, len );
1119 }
1120 
1121 /*****************************************************************************/
1122 void SimpleXMLParser::CommentHandler(
1123 	void *userData, const XML_Char *data )
1124 /*****************************************************************************/
1125 {
1126 	(( SimpleXMLParser * ) userData )->Comment( data );
1127 }
1128 
1129 /*****************************************************************************/
1130 void SimpleXMLParser::DefaultHandler(
1131 	void *userData, const XML_Char *s, int len )
1132 /*****************************************************************************/
1133 {
1134 	(( SimpleXMLParser * ) userData )->Default( s, len );
1135 }
1136 
1137 /*****************************************************************************/
1138 void SimpleXMLParser::StartElement(
1139 	const XML_Char *name, const XML_Char **atts )
1140 /*****************************************************************************/
1141 {
1142 	String sElementName = String( XML_CHAR_TO_OUSTRING( name ));
1143 	XMLElement *pElement = new XMLElement( sElementName, ( XMLParentNode * ) pCurNode );
1144 	pCurNode = pElement;
1145 	pCurData = NULL;
1146 
1147 	int i = 0;
1148 	while( atts[i] ) {
1149 		pElement->AddAttribute(
1150 			String( XML_CHAR_TO_OUSTRING( atts[ i ] )),
1151 			String( XML_CHAR_TO_OUSTRING( atts[ i + 1 ] )));
1152 		i += 2;
1153 	}
1154 }
1155 
1156 /*****************************************************************************/
1157 void SimpleXMLParser::EndElement( const XML_Char *name )
1158 /*****************************************************************************/
1159 {
1160 	// This variable is not used at all, but the the sax C interface can't be changed
1161     // To prevent warnings this dummy assignment is used
1162     // +++
1163     (void) name;
1164 
1165     pCurNode = pCurNode->GetParent();
1166 	pCurData = NULL;
1167 }
1168 
1169 /*****************************************************************************/
1170 void SimpleXMLParser::CharacterData(
1171 	const XML_Char *s, int len )
1172 /*****************************************************************************/
1173 {
1174 	if ( !pCurData ){
1175 		String x=String( XML_CHAR_N_TO_OUSTRING( s, len ));
1176 		XMLUtil::UnQuotHTML(x);
1177 		pCurData = new XMLData( x , pCurNode );
1178 	}else{
1179 		String x=String( XML_CHAR_N_TO_OUSTRING( s, len ));
1180 		XMLUtil::UnQuotHTML(x);
1181 		pCurData->AddData( x );
1182 
1183 	}
1184 }
1185 
1186 /*****************************************************************************/
1187 void SimpleXMLParser::Comment(
1188 	const XML_Char *data )
1189 /*****************************************************************************/
1190 {
1191 	pCurData = NULL;
1192 		new XMLComment( String( XML_CHAR_TO_OUSTRING( data )), pCurNode );
1193 }
1194 
1195 /*****************************************************************************/
1196 void SimpleXMLParser::Default(
1197 	const XML_Char *s, int len )
1198 /*****************************************************************************/
1199 {
1200 	pCurData = NULL;
1201 	new XMLDefault(
1202 		String( XML_CHAR_N_TO_OUSTRING( s, len )), pCurNode );
1203 }
1204 
1205 /*****************************************************************************/
1206 XMLFile *SimpleXMLParser::Execute( const String &rFullFileName , const String &rFileName, XMLFile* pXMLFileIn )
1207 /*****************************************************************************/
1208 {
1209 //	printf("DBG: SimpleXMLParser::Execute( %s )", ByteString( rFileName , RTL_TEXTENCODING_ASCII_US ).GetBuffer() );
1210     aErrorInformation.eCode = XML_ERROR_NONE;
1211 	aErrorInformation.nLine = 0;
1212 	aErrorInformation.nColumn = 0;
1213 	aErrorInformation.sMessage = String::CreateFromAscii( "ERROR: Unable to open file " );
1214 	aErrorInformation.sMessage += rFileName;
1215 
1216 	SvFileStream aStream( rFileName, STREAM_STD_READ );
1217 
1218 	if ( !aStream.IsOpen())
1219 		return NULL;
1220 
1221 	SvMemoryStream aMemStream;
1222 	aStream >> aMemStream;
1223 	aMemStream.Seek( 0 );
1224 
1225 	aStream.Close();
1226 
1227     pXMLFile = pXMLFileIn;
1228     pXMLFile->SetName( rFileName );
1229     pXMLFile->SetFullName( rFullFileName );
1230 
1231 	return Execute( &aMemStream );
1232 }
1233 
1234 /*****************************************************************************/
1235 XMLFile *SimpleXMLParser::Execute( SvMemoryStream *pStream )
1236 /*****************************************************************************/
1237 {
1238 	if ( !pXMLFile )
1239 		pXMLFile = new XMLFile( String());
1240 
1241 	pCurNode = pXMLFile;
1242 	pCurData = NULL;
1243 
1244 	sal_uLong nPos = pStream->Tell();
1245 	pStream->Seek( STREAM_SEEK_TO_END );
1246 
1247 	aErrorInformation.eCode = XML_ERROR_NONE;
1248 	aErrorInformation.nLine = 0;
1249 	aErrorInformation.nColumn = 0;
1250 	if ( pXMLFile->GetName().Len()) {
1251 		aErrorInformation.sMessage = String::CreateFromAscii( "File " );
1252 		aErrorInformation.sMessage += pXMLFile->GetName();
1253 		aErrorInformation.sMessage += String::CreateFromAscii( " parsed succesfully" );
1254 	}
1255 	else
1256 		aErrorInformation.sMessage = String::CreateFromAscii( "XML-File parsed successfully" );
1257 
1258 	if ( !XML_Parse(
1259 		aParser, ( char * ) pStream->GetData() + nPos, pStream->Tell() - nPos, sal_True ))
1260 	{
1261 		aErrorInformation.eCode = XML_GetErrorCode( aParser );
1262 		aErrorInformation.nLine = XML_GetErrorLineNumber( aParser );
1263 		aErrorInformation.nColumn = XML_GetErrorColumnNumber( aParser );
1264 
1265 		aErrorInformation.sMessage = String::CreateFromAscii( "ERROR: " );
1266 		if ( pXMLFile->GetName().Len())
1267 			aErrorInformation.sMessage += pXMLFile->GetName();
1268 		else
1269 			aErrorInformation.sMessage += String::CreateFromAscii( "XML-File" );
1270 		aErrorInformation.sMessage += String::CreateFromAscii( " (" );
1271 		aErrorInformation.sMessage += String::CreateFromInt64( aErrorInformation.nLine );
1272 		aErrorInformation.sMessage += String::CreateFromAscii( "," );
1273 		aErrorInformation.sMessage += String::CreateFromInt64( aErrorInformation.nColumn );
1274 		aErrorInformation.sMessage += String::CreateFromAscii( "): " );
1275 
1276 		switch( aErrorInformation.eCode ) {
1277   			case XML_ERROR_NO_MEMORY: aErrorInformation.sMessage += String::CreateFromAscii( "No memory" ); break;
1278   			case XML_ERROR_SYNTAX: aErrorInformation.sMessage += String::CreateFromAscii( "Syntax" ); break;
1279   			case XML_ERROR_NO_ELEMENTS: aErrorInformation.sMessage += String::CreateFromAscii( "No elements" ); break;
1280   			case XML_ERROR_INVALID_TOKEN: aErrorInformation.sMessage += String::CreateFromAscii( "Invalid token" ); break;
1281   			case XML_ERROR_UNCLOSED_TOKEN: aErrorInformation.sMessage += String::CreateFromAscii( "Unclosed token" ); break;
1282   			case XML_ERROR_PARTIAL_CHAR: aErrorInformation.sMessage += String::CreateFromAscii( "Partial char" ); break;
1283   			case XML_ERROR_TAG_MISMATCH: aErrorInformation.sMessage += String::CreateFromAscii( "Tag mismatch" ); break;
1284   			case XML_ERROR_DUPLICATE_ATTRIBUTE: aErrorInformation.sMessage += String::CreateFromAscii( "Dublicat attribute" ); break;
1285   			case XML_ERROR_JUNK_AFTER_DOC_ELEMENT: aErrorInformation.sMessage += String::CreateFromAscii( "Junk after doc element" ); break;
1286   			case XML_ERROR_PARAM_ENTITY_REF: aErrorInformation.sMessage += String::CreateFromAscii( "Param entity ref" ); break;
1287   			case XML_ERROR_UNDEFINED_ENTITY: aErrorInformation.sMessage += String::CreateFromAscii( "Undefined entity" ); break;
1288   			case XML_ERROR_RECURSIVE_ENTITY_REF: aErrorInformation.sMessage += String::CreateFromAscii( "Recursive entity ref" ); break;
1289   			case XML_ERROR_ASYNC_ENTITY: aErrorInformation.sMessage += String::CreateFromAscii( "Async_entity" ); break;
1290   			case XML_ERROR_BAD_CHAR_REF: aErrorInformation.sMessage += String::CreateFromAscii( "Bad char ref" ); break;
1291   			case XML_ERROR_BINARY_ENTITY_REF: aErrorInformation.sMessage += String::CreateFromAscii( "Binary entity" ); break;
1292   			case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF: aErrorInformation.sMessage += String::CreateFromAscii( "Attribute external entity ref" ); break;
1293   			case XML_ERROR_MISPLACED_XML_PI: aErrorInformation.sMessage += String::CreateFromAscii( "Misplaced xml pi" ); break;
1294   			case XML_ERROR_UNKNOWN_ENCODING: aErrorInformation.sMessage += String::CreateFromAscii( "Unknown encoding" ); break;
1295   			case XML_ERROR_INCORRECT_ENCODING: aErrorInformation.sMessage += String::CreateFromAscii( "Incorrect encoding" ); break;
1296   			case XML_ERROR_UNCLOSED_CDATA_SECTION: aErrorInformation.sMessage += String::CreateFromAscii( "Unclosed cdata section" ); break;
1297   			case XML_ERROR_EXTERNAL_ENTITY_HANDLING: aErrorInformation.sMessage += String::CreateFromAscii( "External entity handling" ); break;
1298   			case XML_ERROR_NOT_STANDALONE: aErrorInformation.sMessage += String::CreateFromAscii( "Not standalone" ); break;
1299             case XML_ERROR_NONE: break;
1300             default:
1301                 break;
1302 
1303 		}
1304 		delete pXMLFile;
1305 		pXMLFile = NULL;
1306 	}
1307 	pStream->Seek( nPos );
1308 
1309 	return pXMLFile;
1310 }
1311 
1312 /*****************************************************************************/
1313 void XMLUtil::QuotHTML( String &rString )
1314 /*****************************************************************************/
1315 {
1316 	OUStringBuffer sReturn;
1317 	static const String LT(String::CreateFromAscii("<"));
1318 	static const String QLT(String::CreateFromAscii("&lt;"));
1319 	static const String GT(String::CreateFromAscii(">"));
1320 	static const String QGT(String::CreateFromAscii("&gt;"));
1321 	static const String QUOT(String::CreateFromAscii("\\"));
1322 	static const String QQUOT(String::CreateFromAscii("&quot;"));
1323 	static const String APOS(String::CreateFromAscii("\""));
1324 	static const String QAPOS(String::CreateFromAscii("&apos;"));
1325 	static const String AMP(String::CreateFromAscii("&"));
1326 	static const String QAMP(String::CreateFromAscii("&amp;"));
1327 	static const String SLASH(String::CreateFromAscii("\\"));
1328 
1329 	for ( sal_uInt16 i = 0; i < rString.Len(); i++) {
1330 		if ( i < rString.Len()) {
1331 			switch ( rString.GetChar( i )) {
1332 				case '\\': if( i+1 <= rString.Len() ){
1333 							switch( rString.GetChar( i+1 ) ){
1334                              case '<':  sReturn.append( LT );i++;break;
1335                              case '>':  sReturn.append( GT );i++;break;
1336                              case '\\': sReturn.append( QUOT );i++;break;
1337                              case '\"': sReturn.append( APOS );i++;break;
1338                              //case '\'': sReturn += "\'";i++;break;
1339                              //case '&' : sRetrun += "&";i++;break;
1340                              default:   sReturn.append( SLASH );break;
1341 
1342                            }
1343                           }
1344                         break;
1345 
1346                 case '<':
1347                     sReturn.append( QLT );
1348 					break;
1349 
1350 				case '>':
1351                     sReturn.append( QGT );
1352 					break;
1353 
1354 				case '\"':
1355                     sReturn.append( QQUOT );
1356 					break;
1357 
1358 /*				case '\'':
1359                     sReturn += "&apos;";
1360 					break;
1361 */
1362 				case '&':
1363 					if (
1364 						  ( ( i + 4 ) < rString.Len()) &&
1365 						  ( String( rString.Copy( i, 5 ) ).Equals( QAMP ) )
1366 					   )
1367 						sReturn.append( rString.GetChar( i ) );
1368 					else
1369 						sReturn.append( QAMP );
1370 				break;
1371 
1372 				default:
1373 					sReturn.append( rString.GetChar( i ) );
1374 				break;
1375 			}
1376 		}
1377 	}
1378 	rString = String( sReturn.makeStringAndClear() );
1379 }
1380 
1381 void XMLUtil::UnQuotHTML( String &rString ){
1382     UnQuotData( rString );
1383 }
1384 
1385 void XMLUtil::UnQuotData( String &rString_in ){
1386 	ByteString sReturn;
1387     ByteString sString( rString_in , RTL_TEXTENCODING_UTF8 );
1388 	while ( sString.Len()) {
1389 	    if ( sString.Copy( 0, 1 ) == "\\" ) {
1390 			sReturn += "\\\\";
1391 			sString.Erase( 0, 1 );
1392 		}
1393 		else if ( sString.Copy( 0, 5 ) == "&amp;" ) {
1394 			sReturn += "&";
1395 			sString.Erase( 0, 5 );
1396 		}
1397 		else if ( sString.Copy( 0, 4 ) == "&lt;" ) {
1398 			sReturn += "<";
1399 			sString.Erase( 0, 4 );
1400 		}
1401 		else if ( sString.Copy( 0, 4 ) == "&gt;" ) {
1402 			sReturn += ">";
1403 			sString.Erase( 0, 4 );
1404 		}
1405 		else if ( sString.Copy( 0, 6 ) == "&quot;" ) {
1406 			sReturn += "\"";
1407 			sString.Erase( 0, 6 );
1408 		}
1409 		else if ( sString.Copy( 0, 6 ) == "&apos;" ) {
1410 			sReturn += "\'";
1411 			sString.Erase( 0, 6 );
1412 		}
1413 		else {
1414 			sReturn += sString.GetChar( 0 );
1415 			sString.Erase( 0, 1 );
1416 		}
1417 	}
1418     rString_in = String(sReturn , RTL_TEXTENCODING_UTF8 );
1419 
1420 
1421 }
1422 
1423 XMLUtil::XMLUtil(){
1424 }
1425 
1426 
1427 /*****************************************************************************/
1428 void XMLUtil::dump(){
1429 /*****************************************************************************/
1430 	int cnt=1;
1431     printf("size=%lu\n",static_cast<unsigned long>(lMap.size()));
1432     for(HashMap::iterator pos = lMap.begin(); pos != lMap.end() ; ++pos){
1433         fprintf(stdout,"key=%s , value=%d , no=%d\n",pos->first.GetBuffer(),pos->second,cnt++);
1434     }
1435 }
1436 /*****************************************************************************/
1437 XMLUtil&  XMLUtil::Instance(){
1438 /*****************************************************************************/
1439 	static XMLUtil instance;
1440 	return instance;
1441 }
1442 /*****************************************************************************/
1443 XMLUtil::~XMLUtil(){}
1444 /*****************************************************************************/
1445 /*****************************************************************************/
1446 ByteString XMLUtil::GetIsoLangByIndex( sal_uInt16 nIndex )
1447 /*****************************************************************************/
1448 {
1449 	if(nIndex > 0 && MAX_LANGUAGES >= nIndex )
1450 		return isoArray[nIndex];
1451 	return "";
1452 }
1453 
1454