1 /****************************************************************************
2 * VCGLib                                                            o o     *
3 * Visual and Computer Graphics Library                            o     o   *
4 *                                                                _   O  _   *
5 * Copyright(C) 2004-2008                                           \/)\/    *
6 * Visual Computing Lab                                            /\/|      *
7 * ISTI - Italian National Research Council                           |      *
8 *                                                                    \      *
9 * All rights reserved.                                                      *
10 *                                                                           *
11 * This program is free software; you can redistribute it and/or modify      *
12 * it under the terms of the GNU General Public License as published by      *
13 * the Free Software Foundation; either version 2 of the License, or         *
14 * (at your option) any later version.                                       *
15 *                                                                           *
16 * This program 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 General Public License (http://www.gnu.org/licenses/gpl.txt)          *
20 * for more details.                                                         *
21 *                                                                           *
22 ****************************************************************************/
23 #ifndef _XML_DOCUMENT_MANAGING_H
24 #define _XML_DOCUMENT_MANAGING_H
25 
26 #include <vector>
27 #include <set>
28 #include <QDomDocument>
29 #include<QFile>
30 #include<QVector>
31 #include <QXmlStreamWriter>
32 #include <QString>
33 
34 class XMLTag
35 {
36 public:
37 	typedef std::pair<QString,QString> TagAttribute;
38 	typedef QVector<TagAttribute> TagAttributes;
39 	QString _tagname;
40 	TagAttributes _attributes;
41 
42 	XMLTag(const QString& tagname = QString(),const TagAttributes& attr = TagAttributes())
_tagname(tagname)43 		:_tagname(tagname),_attributes(attr)
44 	{
45 	}
46 
~XMLTag()47 	virtual ~XMLTag()
48 	{
49 	}
50 };
51 
52 class XMLLeafTag : public XMLTag
53 {
54 public:
55 		QVector<QString> _text;
56 
57 		XMLLeafTag(const QString& tagname = QString(),const QVector<QString>& text = QVector<QString>())
XMLTag(tagname)58 			:XMLTag(tagname),_text(text)
59 		{
60 		}
61 
~XMLLeafTag()62 		virtual ~XMLLeafTag()
63 		{
64 		}
65 };
66 
67 class XMLDocumentWriter;
68 
69 class XMLVisitor;
70 
71 class XMLNode
72 {
73 public:
74 	XMLNode(XMLTag* tag);
75 	virtual ~XMLNode();
76 
77 	virtual void applyProcedure(XMLVisitor& v) = 0;
78 
79 	XMLTag* _tag;
80 };
81 
82 class XMLInteriorNode : public XMLNode
83 {
84 public:
85 	XMLInteriorNode(XMLTag* tag);
86 
87 	XMLNode* son(int ii);
88 
89 	QVector< XMLNode* > sons();
90 
91 	void applyProcedure(XMLVisitor& v);
92 
93 	~XMLInteriorNode();
94 
95 	QVector< XMLNode* > _sons;
96 };
97 
98 class XMLLeafNode : public XMLNode
99 {
100 public:
101 	XMLLeafNode(XMLLeafTag* leaftag);
102 
103 	void applyProcedure(XMLVisitor& v);
104 	virtual ~XMLLeafNode();
105 };
106 
107 class XMLDocument
108 {
109 public:
XMLDocument(XMLInteriorNode * root)110 	XMLDocument(XMLInteriorNode* root)
111 		:_root(root)
112 	{
113 	}
114 
~XMLDocument()115 	~XMLDocument()
116 	{
117 		delete (_root);
118 	}
119 
120 	XMLInteriorNode* _root;
121 };
122 
123 
124 class XMLVisitor
125 {
126 public:
127 	virtual void operator()(XMLLeafNode& leaf) = 0;
128 	virtual void operator()(XMLInteriorNode& intnode) = 0;
129 };
130 
131 
132 class XMLDocumentWriter : public XMLVisitor
133 {
134 private:
135 	QXmlStreamWriter _stream;
136 	QFile _file;
137 	bool _error;
138 
writeText(XMLLeafNode & node)139 	void writeText(XMLLeafNode& node)
140 	{
141 		XMLLeafTag* leaftag = static_cast<XMLLeafTag*>(node._tag);
142 		for(QVector<QString>::iterator it = leaftag->_text.begin();it != leaftag->_text.end();++it)
143 		{
144 			QString tmp = "";
145 			if (it != leaftag->_text.begin())
146 				tmp = QString(" ");
147 			_stream.writeCharacters(tmp + *it);
148 		}
149 	}
150 
writeAttributes(XMLNode & node)151 	void writeAttributes(XMLNode& node)
152 	{
153 		QXmlStreamAttributes attr;
154 		for(XMLTag::TagAttributes::iterator it = node._tag->_attributes.begin();it != node._tag->_attributes.end();++it)
155 			attr.append(it->first,it->second);
156 		_stream.writeAttributes(attr);
157 	}
158 
recursiveStep(XMLInteriorNode & intnode)159 	void recursiveStep(XMLInteriorNode& intnode)
160 	{
161 		QVector< XMLNode* > sons = intnode.sons();
162 		for(QVector< XMLNode* >::iterator its = sons.begin();its != sons.end();++its)
163 			(*its)->applyProcedure(*this);
164 	}
165 
166 public:
167 
operator()168 	void operator()(XMLLeafNode& node)
169 	{
170 		_stream.writeStartElement(node._tag->_tagname);
171 		writeAttributes(node);
172 		writeText(node);
173 		_stream.writeEndElement();
174 	}
175 
operator()176 	void operator()(XMLInteriorNode& intnode)
177 	{
178 		_stream.writeStartElement(intnode._tag->_tagname);
179 		writeAttributes(intnode);
180 		recursiveStep(intnode);
181 		_stream.writeEndElement();
182 	}
183 
operator()184 	void operator()(XMLDocument& doc)
185 	{
186 		_stream.writeStartDocument();
187 		operator()(*(doc._root));
188 		_stream.writeEndDocument();
189 	}
190 
write(XMLDocument & doc)191 	void write(XMLDocument& doc)
192 	{
193 		(*this)(doc);
194 	}
195 
isReliable()196 	bool isReliable() const
197 	{
198 		return !_error;
199 	}
200 
201 	XMLDocumentWriter(const char* filename,const bool autoformatting = true)
_stream()202 		:_stream(),_file(filename),_error(false)
203 	{
204 		if (!_file.open(QIODevice::WriteOnly | QIODevice::Text))
205 			_error = true;
206 		_stream.setDevice(&_file);
207 		_stream.setAutoFormatting(autoformatting);
208 	}
209 
~XMLDocumentWriter()210   virtual ~XMLDocumentWriter()
211 	{
212 		_file.close();
213 	}
214 };
215 
216 #endif
217