Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #ifndef BOOTSTRP_XMLPARSE_HXX
30 : : #define BOOTSTRP_XMLPARSE_HXX
31 : :
32 : : #include "sal/config.h"
33 : :
34 : : #include <cstddef>
35 : : #include <vector>
36 : :
37 : : #include <signal.h>
38 : : #include <expat.h>
39 : : #include <rtl/ustring.hxx>
40 : : #include <rtl/ustrbuf.hxx>
41 : : #include "boost/unordered_map.hpp"
42 : : #include "export.hxx"
43 : :
44 : : class XMLParentNode;
45 : : class XMLElement;
46 : :
47 : :
48 : : using namespace ::rtl;
49 : : using namespace std;
50 : :
51 : : #define XML_NODE_TYPE_FILE 0x001
52 : : #define XML_NODE_TYPE_ELEMENT 0x002
53 : : #define XML_NODE_TYPE_DATA 0x003
54 : : #define XML_NODE_TYPE_COMMENT 0x004
55 : : #define XML_NODE_TYPE_DEFAULT 0x005
56 : :
57 : :
58 : : //-------------------------------------------------------------------------
59 : :
60 : : /** Holds data of Attributes
61 : : */
62 : 0 : class XMLAttribute
63 : : {
64 : : private:
65 : : rtl::OUString sName;
66 : : rtl::OUString sValue;
67 : :
68 : : public:
69 : : /// creates an attribute
70 : 0 : XMLAttribute(
71 : : const rtl::OUString &rName, // attributes name
72 : : const rtl::OUString &rValue // attributes data
73 : : )
74 : 0 : : sName( rName ), sValue( rValue ) {}
75 : :
76 : 0 : rtl::OUString GetName() const { return sName; }
77 : 0 : rtl::OUString GetValue() const { return sValue; }
78 : :
79 : 0 : void setValue(const rtl::OUString &rValue){sValue=rValue;}
80 : :
81 : : /// returns true if two attributes are equal and have the same value
82 : : sal_Bool IsEqual(
83 : : const XMLAttribute &rAttribute // the attribute which has to be equal
84 : : )
85 : : {
86 : : return (( rAttribute.sName == sName ) && ( rAttribute.sValue == sValue ));
87 : : }
88 : : };
89 : :
90 : : typedef std::vector< XMLAttribute* > XMLAttributeList;
91 : :
92 : : //-------------------------------------------------------------------------
93 : :
94 : : /** Virtual base to handle different kinds of XML nodes
95 : : */
96 : 0 : class XMLNode
97 : : {
98 : : protected:
99 : 0 : XMLNode() {}
100 : :
101 : : public:
102 : : virtual sal_uInt16 GetNodeType() = 0;
103 : 0 : virtual ~XMLNode() {}
104 : : };
105 : :
106 : : //-------------------------------------------------------------------------
107 : :
108 : : /** Virtual base to handle different kinds of child nodes
109 : : */
110 : : class XMLChildNode : public XMLNode
111 : : {
112 : : private:
113 : : XMLParentNode *pParent;
114 : :
115 : : protected:
116 : : XMLChildNode( XMLParentNode *pPar );
117 : : XMLChildNode():pParent( NULL ){};
118 : : XMLChildNode( const XMLChildNode& obj);
119 : : XMLChildNode& operator=(const XMLChildNode& obj);
120 : : public:
121 : : virtual sal_uInt16 GetNodeType() = 0;
122 : :
123 : : /// returns the parent of this node
124 : 0 : XMLParentNode *GetParent() { return pParent; }
125 : 0 : virtual ~XMLChildNode(){};
126 : : };
127 : :
128 : : typedef std::vector< XMLChildNode* > XMLChildNodeList;
129 : :
130 : : //-------------------------------------------------------------------------
131 : :
132 : : /** Virtual base to handle different kinds of parent nodes
133 : : */
134 : : class XMLData;
135 : :
136 : : class XMLParentNode : public XMLChildNode
137 : : {
138 : : private:
139 : : XMLChildNodeList* pChildList;
140 : : static int dbgcnt;
141 : :
142 : : protected:
143 : 0 : XMLParentNode( XMLParentNode *pPar )
144 : 0 : : XMLChildNode( pPar ), pChildList( NULL )
145 : : {
146 : 0 : }
147 : : XMLParentNode(): pChildList(NULL){
148 : : }
149 : : /// Copyconstructor
150 : : XMLParentNode( const XMLParentNode& );
151 : :
152 : : XMLParentNode& operator=(const XMLParentNode& obj);
153 : : virtual ~XMLParentNode();
154 : :
155 : :
156 : : public:
157 : : virtual sal_uInt16 GetNodeType() = 0;
158 : :
159 : : /// returns child list of this node
160 : 0 : XMLChildNodeList *GetChildList() { return pChildList; }
161 : :
162 : : /// adds a new child
163 : : void AddChild(
164 : : XMLChildNode *pChild /// the new child
165 : : );
166 : :
167 : : void RemoveAndDeleteAllChildren();
168 : : };
169 : :
170 : : //-------------------------------------------------------------------------
171 : :
172 : : /// Mapping numeric Language code <-> XML Element
173 : : typedef boost::unordered_map<rtl::OString, XMLElement*, rtl::OStringHash> LangHashMap;
174 : :
175 : : /// Mapping XML Element string identifier <-> Language Map
176 : : typedef boost::unordered_map<rtl::OString, LangHashMap*, rtl::OStringHash> XMLHashMap;
177 : :
178 : : /// Mapping iso alpha string code <-> iso numeric code
179 : : typedef boost::unordered_map<rtl::OString, int, rtl::OStringHash> HashMap;
180 : :
181 : : /// Mapping XML tag names <-> have localizable strings
182 : : typedef boost::unordered_map<rtl::OString, sal_Bool, rtl::OStringHash> TagMap;
183 : :
184 : : /** Holds information of a XML file, is root node of tree
185 : : */
186 : :
187 : :
188 : : class XMLFile : public XMLParentNode
189 : : {
190 : : public:
191 : : XMLFile(
192 : : const rtl::OUString &rFileName // the file name, empty if created from memory stream
193 : : );
194 : : XMLFile( const XMLFile& obj ) ;
195 : : ~XMLFile();
196 : :
197 : : void Print( XMLNode *pCur = NULL, sal_uInt16 nLevel = 0 );
198 : : virtual void SearchL10NElements( XMLParentNode *pCur, int pos = 0 );
199 : : void Extract( XMLFile *pCur = NULL );
200 : :
201 : 0 : XMLHashMap* GetStrings(){return XMLStrings;}
202 : : void Write( rtl::OString const &rFilename );
203 : : sal_Bool Write( ofstream &rStream , XMLNode *pCur = NULL );
204 : :
205 : : bool CheckExportStatus( XMLParentNode *pCur = NULL );// , int pos = 0 );
206 : :
207 : : XMLFile& operator=(const XMLFile& obj);
208 : :
209 : : virtual sal_uInt16 GetNodeType();
210 : :
211 : : /// returns file name
212 : 0 : rtl::OUString GetName() { return sFileName; }
213 : 0 : void SetName( const rtl::OUString &rFilename ) { sFileName = rFilename; }
214 : 0 : const std::vector<rtl::OString> getOrder(){ return order; }
215 : :
216 : : protected:
217 : : // writes a string as UTF8 with dos line ends to a given stream
218 : : void WriteString( ofstream &rStream, const rtl::OUString &sString );
219 : :
220 : : void InsertL10NElement( XMLElement* pElement);
221 : :
222 : : // DATA
223 : : rtl::OUString sFileName;
224 : :
225 : : const rtl::OString ID, OLDREF, XML_LANG;
226 : :
227 : : TagMap nodes_localize;
228 : : XMLHashMap* XMLStrings;
229 : :
230 : : std::vector <rtl::OString> order;
231 : : };
232 : :
233 : : /// An Utility class for XML
234 : : /// See RFC 3066 / #i8252# for ISO codes
235 : : class XMLUtil{
236 : :
237 : : public:
238 : : /// Quot the XML characters and replace \n \t
239 : : static void QuotHTML( rtl::OUString &rString );
240 : :
241 : : /// UnQuot the XML characters and restore \n \t
242 : : static void UnQuotHTML ( rtl::OUString &rString );
243 : : };
244 : :
245 : :
246 : :
247 : : //-------------------------------------------------------------------------
248 : :
249 : : /** Hold information of an element node
250 : : */
251 : : class XMLElement : public XMLParentNode
252 : : {
253 : : private:
254 : : rtl::OUString sElementName;
255 : : XMLAttributeList *pAttributes;
256 : : rtl::OString project,
257 : : filename,
258 : : id,
259 : : sOldRef,
260 : : resourceType,
261 : : languageId;
262 : : int nPos;
263 : :
264 : : protected:
265 : : void Print(XMLNode *pCur, OUStringBuffer& buffer , bool rootelement);
266 : : public:
267 : : /// create a element node
268 : : XMLElement(){}
269 : 0 : XMLElement(
270 : : const rtl::OUString &rName, // the element name
271 : : XMLParentNode *Parent // parent node of this element
272 : : ): XMLParentNode( Parent ),
273 : : sElementName( rName ),
274 : : pAttributes( NULL ),
275 : : project(""),
276 : : filename(""),
277 : : id(""),
278 : : sOldRef(""),
279 : : resourceType(""),
280 : : languageId(""),
281 : 0 : nPos(0)
282 : : {
283 : 0 : }
284 : : ~XMLElement();
285 : : XMLElement(const XMLElement&);
286 : :
287 : : XMLElement& operator=(const XMLElement& obj);
288 : : /// returns node type XML_NODE_ELEMENT
289 : : virtual sal_uInt16 GetNodeType();
290 : :
291 : : /// returns element name
292 : 0 : rtl::OUString GetName() { return sElementName; }
293 : :
294 : : /// returns list of attributes of this element
295 : 0 : XMLAttributeList *GetAttributeList() { return pAttributes; }
296 : :
297 : : /// adds a new attribute to this element, typically used by parser
298 : : void AddAttribute( const rtl::OUString &rAttribute, const rtl::OUString &rValue );
299 : :
300 : : void ChangeLanguageTag( const rtl::OUString &rValue );
301 : :
302 : : // Return a Unicode String representation of this object
303 : : OUString ToOUString();
304 : :
305 : : void SetProject ( rtl::OString const & prj ){ project = prj; }
306 : : void SetFileName ( rtl::OString const & fn ){ filename = fn; }
307 : 0 : void SetId ( rtl::OString const & theId ){ id = theId; }
308 : : void SetResourceType ( rtl::OString const & rt ){ resourceType = rt; }
309 : 0 : void SetLanguageId ( rtl::OString const & lid ){ languageId = lid; }
310 : 0 : void SetPos ( int nPos_in ){ nPos = nPos_in; }
311 : 0 : void SetOldRef ( rtl::OString const & sOldRef_in ){ sOldRef = sOldRef_in; }
312 : :
313 : 0 : virtual int GetPos() { return nPos; }
314 : : rtl::OString GetProject() { return project; }
315 : : rtl::OString GetFileName() { return filename; }
316 : : rtl::OString GetId() { return id; }
317 : 0 : rtl::OString GetOldref() { return sOldRef; }
318 : : rtl::OString GetResourceType(){ return resourceType; }
319 : : rtl::OString GetLanguageId() { return languageId; }
320 : :
321 : :
322 : : };
323 : : //-------------------------------------------------------------------------
324 : :
325 : :
326 : : /** Holds character data
327 : : */
328 : 0 : class XMLData : public XMLChildNode
329 : : {
330 : : private:
331 : : rtl::OUString sData;
332 : : bool isNewCreated;
333 : :
334 : : public:
335 : : /// create a data node
336 : 0 : XMLData(
337 : : const rtl::OUString &rData, // the initial data
338 : : XMLParentNode *Parent // the parent node of this data, typically a element node
339 : : )
340 : 0 : : XMLChildNode( Parent ), sData( rData ) , isNewCreated ( false ){}
341 : 0 : XMLData(
342 : : const rtl::OUString &rData, // the initial data
343 : : XMLParentNode *Parent, // the parent node of this data, typically a element node
344 : : bool newCreated
345 : : )
346 : 0 : : XMLChildNode( Parent ), sData( rData ) , isNewCreated ( newCreated ){}
347 : :
348 : : XMLData(const XMLData& obj);
349 : :
350 : : XMLData& operator=(const XMLData& obj);
351 : : virtual sal_uInt16 GetNodeType();
352 : :
353 : : /// returns the data
354 : 0 : rtl::OUString GetData() { return sData; }
355 : :
356 : : bool isNew() { return isNewCreated; }
357 : : /// adds new character data to the existing one
358 : : void AddData(
359 : : const rtl::OUString &rData // the new data
360 : : );
361 : :
362 : :
363 : :
364 : : };
365 : :
366 : : //-------------------------------------------------------------------------
367 : :
368 : : /** Holds comments
369 : : */
370 : 0 : class XMLComment : public XMLChildNode
371 : : {
372 : : private:
373 : : rtl::OUString sComment;
374 : :
375 : : public:
376 : : /// create a comment node
377 : 0 : XMLComment(
378 : : const rtl::OUString &rComment, // the comment
379 : : XMLParentNode *Parent // the parent node of this comemnt, typically a element node
380 : : )
381 : 0 : : XMLChildNode( Parent ), sComment( rComment ) {}
382 : :
383 : : virtual sal_uInt16 GetNodeType();
384 : :
385 : : XMLComment( const XMLComment& obj );
386 : :
387 : : XMLComment& operator=(const XMLComment& obj);
388 : :
389 : : /// returns the comment
390 : 0 : rtl::OUString GetComment() { return sComment; }
391 : : };
392 : :
393 : : //-------------------------------------------------------------------------
394 : :
395 : : /** Holds additional file content like those for which no handler exists
396 : : */
397 : 0 : class XMLDefault : public XMLChildNode
398 : : {
399 : : private:
400 : : rtl::OUString sDefault;
401 : :
402 : : public:
403 : : /// create a comment node
404 : 0 : XMLDefault(
405 : : const rtl::OUString &rDefault, // the comment
406 : : XMLParentNode *Parent // the parent node of this comemnt, typically a element node
407 : : )
408 : 0 : : XMLChildNode( Parent ), sDefault( rDefault ) {}
409 : :
410 : : XMLDefault(const XMLDefault& obj);
411 : :
412 : : XMLDefault& operator=(const XMLDefault& obj);
413 : :
414 : : /// returns node type XML_NODE_TYPE_COMMENT
415 : : virtual sal_uInt16 GetNodeType();
416 : :
417 : : /// returns the comment
418 : 0 : rtl::OUString GetDefault() { return sDefault; }
419 : : };
420 : :
421 : : //-------------------------------------------------------------------------
422 : :
423 : : /** struct for error information, used by class SimpleXMLParser
424 : : */
425 : 0 : struct XMLError {
426 : : XML_Error eCode; // the error code
427 : : std::size_t nLine; // error line number
428 : : std::size_t nColumn; // error column number
429 : : rtl::OUString sMessage; // readable error message
430 : : };
431 : :
432 : : //-------------------------------------------------------------------------
433 : :
434 : : /** validating xml parser, creates a document tree with xml nodes
435 : : */
436 : :
437 : :
438 : : class SimpleXMLParser
439 : : {
440 : : private:
441 : : XML_Parser aParser;
442 : : XMLError aErrorInformation;
443 : :
444 : : XMLFile *pXMLFile;
445 : : XMLParentNode *pCurNode;
446 : : XMLData *pCurData;
447 : :
448 : :
449 : : static void StartElementHandler( void *userData, const XML_Char *name, const XML_Char **atts );
450 : : static void EndElementHandler( void *userData, const XML_Char *name );
451 : : static void CharacterDataHandler( void *userData, const XML_Char *s, int len );
452 : : static void CommentHandler( void *userData, const XML_Char *data );
453 : : static void DefaultHandler( void *userData, const XML_Char *s, int len );
454 : :
455 : :
456 : : void StartElement( const XML_Char *name, const XML_Char **atts );
457 : : void EndElement( const XML_Char *name );
458 : : void CharacterData( const XML_Char *s, int len );
459 : : void Comment( const XML_Char *data );
460 : : void Default( const XML_Char *s, int len );
461 : :
462 : : public:
463 : : /// creates a new parser
464 : : SimpleXMLParser();
465 : : ~SimpleXMLParser();
466 : :
467 : : /// parse a file, returns NULL on criticall errors
468 : : XMLFile *Execute(
469 : : const rtl::OUString &rFileName, // the file name
470 : : XMLFile *pXMLFileIn // the XMLFile
471 : : );
472 : :
473 : : /// returns an error struct
474 : 0 : const XMLError &GetError() { return aErrorInformation; }
475 : : };
476 : :
477 : : #endif
478 : :
479 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|