All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Writer.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file Writer.cpp
22 
23  \brief A class that models a XML writer object built on top of Xerces-C++.
24 */
25 
26 // TerraLib
27 #include "../common/Exception.h"
28 #include "../common/StringUtils.h"
29 #include "../common/Translator.h"
30 #include "StrToXMLCh.h"
31 #include "XMLChToStr.h"
32 #include "Writer.h"
33 
34 // Boost
35 #include <boost/lexical_cast.hpp>
36 
37 // Xerces-C++
38 #include <xercesc/dom/DOMDocument.hpp>
39 #include <xercesc/dom/DOMDocumentType.hpp>
40 #include <xercesc/dom/DOMElement.hpp>
41 #include <xercesc/dom/DOMException.hpp>
42 #include <xercesc/dom/DOMImplementation.hpp>
43 #include <xercesc/dom/DOMImplementationRegistry.hpp>
44 #include <xercesc/dom/DOMText.hpp>
45 
46 #include <xercesc/util/PlatformUtils.hpp>
47 #include <xercesc/util/OutOfMemoryException.hpp>
48 #include <xercesc/dom/DOM.hpp>
49 #include <xercesc/framework/StdOutFormatTarget.hpp>
50 #include <xercesc/framework/LocalFileFormatTarget.hpp>
51 #include <xercesc/framework/MemBufFormatTarget.hpp>
52 
54  : m_impl(0),
55  m_doc(0),
56  m_indice(0),
57  m_topIndice(0)
58 {
59  // TODO
60 }
61 
63 {
64  if(m_doc)
65  {
66  m_doc->release();
67  }
68 }
69 
70 void te::xerces::Writer::writeStartDocument(const std::string& encoding, const std::string& standalone)
71 {
72  m_standalone = te::common::Convert2UCase(standalone) == "NO" ? false : true;
73  m_encoding = encoding;
74 }
75 
77 {
78  // primeiro a declaracao dos objetos Xerces
79 #if XERCES_VERSION_MAJOR == 2
80  xercesc::DOMWriter* theSerializer = ( (xercesc::DOMImplementationLS*)m_impl)->createDOMWriter();
81  int* theOutput = 0; // for compat
82 #else // Xerces3
83  xercesc::DOMLSSerializer* theSerializer = ((xercesc::DOMImplementationLS*)m_impl)->createLSSerializer();
84  xercesc::DOMLSOutput* theOutput = 0;
85 #endif
86 
87  xercesc::XMLFormatTarget* myFormTarget = 0;
88 
89  try
90  {
91  // Se nao tem filename, eh stdout
92  if( m_uri.empty() )
93  myFormTarget = new xercesc::StdOutFormatTarget();
94  else
95  myFormTarget = new xercesc::LocalFileFormatTarget( m_uri.c_str() );
96 
97 #if XERCES_VERSION_MAJOR == 2
98  theSerializer->writeNode( myFormTarget, *doc_ );
99 #else // Xerces3
100  theOutput = ( (xercesc::DOMImplementationLS*)m_impl)->createLSOutput();
101  theOutput->setByteStream(myFormTarget);
102  theSerializer->write(m_doc, theOutput );
103 #endif
104 
105  delete theOutput;
106  delete theSerializer;
107  delete myFormTarget;
108  }
109  catch( const xercesc::OutOfMemoryException& )
110  {
111  delete theOutput;
112  delete theSerializer;
113  delete myFormTarget;
114 
115  throw te::common::Exception(TE_TR("Out of memory"));
116  }
117  catch( const xercesc::DOMException& e )
118  {
119  delete theOutput;
120  delete theSerializer;
121  delete myFormTarget;
122 
123  std::string err = XMLChToStr(e.getMessage()).getStr();
124 
125  throw te::common::Exception(TE_TR("Exception message is: ") + err);
126  }
127  catch(...)
128  {
129  delete theSerializer;
130  delete myFormTarget;
131 
132  throw te::common::Exception(TE_TR("An error occurred while outputing the xml document."));
133  }
134 }
135 
136 void te::xerces::Writer::writeStartElement(const std::string& qName)
137 {
138  try
139  {
140  if(!m_doc)
141  {
142  m_impl = xercesc::DOMImplementationRegistry::getDOMImplementation(StrToXMLCh("Core").getXMLCh());
143 
144  if(m_impl)
145  {
146  try
147  {
148  if(m_rootNamespaceUri.empty())
149  m_doc = m_impl->createDocument(0, StrToXMLCh(qName).getXMLCh(), 0);
150  else
151  m_doc = m_impl->createDocument(StrToXMLCh(m_rootNamespaceUri).getXMLCh(), StrToXMLCh(qName).getXMLCh(), 0);
152 
153  m_doc->setXmlStandalone(m_standalone);
154 
155  m_elementSet.push_back(m_doc->getDocumentElement());
156 
157  m_topIndice = 0;
158 
159  m_topElementSet.push_back(0);
160  }
161  catch(xercesc::DOMException& e)
162  {
163  std::string err = XMLChToStr(e.getMessage()).getStr();
164  }
165  }
166  else
167  throw te::common::Exception(TE_TR("DOM implementation fails"));
168  }
169  else
170  {
171  m_elementSet.push_back(m_doc->createElement(StrToXMLCh(qName).getXMLCh()));
172  m_elementSet[m_topIndice]->appendChild(m_elementSet[++m_indice] );
173 
174  // ajusta o topElement do Elemento atual
175  m_topElementSet.push_back(m_topIndice);
176 
177  // ele vira pai
178  m_topIndice = m_indice;
179  }
180  }
181  catch( const xercesc::OutOfMemoryException& )
182  {
183  throw te::common::Exception(TE_TR("Out of memory"));
184  }
185  catch( const xercesc::DOMException& e )
186  {
187  std::string err = XMLChToStr(e.getMessage()).getStr();
188  throw te::common::Exception(TE_TR("Exception message is: ") + err );
189  }
190  catch(...)
191  {
192  throw te::common::Exception(TE_TR("An error occurred adding a element"));
193  }
194 }
195 
196 void te::xerces::Writer::writeElement(const std::string& qName, const std::string& value)
197 {
198  try
199  {
200  m_elementSet.push_back(m_doc->createElement(StrToXMLCh(qName).getXMLCh()));
201  m_elementSet[m_topIndice]->appendChild(m_elementSet[++m_indice]);
202 
203  // ajusta o topElement do Elemento atual
204  m_topElementSet.push_back(m_topIndice);
205 
206  // Colocando dados no elemento, se houver
207  if(!value.empty())
208  addText(value);
209  }
210  catch(const xercesc::DOMException& e)
211  {
212  throw te::common::Exception(TE_TR("Exception message is: ") + XMLChToStr(e.getMessage()).getStr());
213  }
214  catch(...)
215  {
216  throw te::common::Exception(TE_TR("An error occurred adding the element: ") + ( qName.empty() ? std::string( "[empty]" ) : qName ));
217  }
218 }
219 
220 void te::xerces::Writer::writeElement(const std::string& qName, const double& value)
221 {
222  writeElement(qName, boost::lexical_cast<std::string>(value));
223 }
224 
225 void te::xerces::Writer::writeElement(const std::string& qName, boost::int32_t value)
226 {
227  writeElement(qName, boost::lexical_cast<std::string>(value));
228 }
229 
230 void te::xerces::Writer::writeElement(const std::string& qName, boost::uint32_t value)
231 {
232  writeElement(qName, boost::lexical_cast<std::string>(value));
233 }
234 
235 void te::xerces::Writer::writeElement(const std::string& qName, boost::int64_t value)
236 {
237  writeElement(qName, boost::lexical_cast<std::string>(value));
238 }
239 
240 void te::xerces::Writer::writeElement(const std::string& qName, boost::uint64_t value)
241 {
242  writeElement(qName, boost::lexical_cast<std::string>(value));
243 }
244 
245 void te::xerces::Writer::writeAttribute(const std::string& attName, const std::string& value)
246 {
247  try
248  {
249  m_elementSet[m_topIndice]->setAttribute(StrToXMLCh(attName).getXMLCh(), StrToXMLCh(value).getXMLCh());
250  }
251  catch(const xercesc::DOMException& e)
252  {
253  throw te::common::Exception(TE_TR("Exception message is: ") + XMLChToStr(e.getMessage()).getStr());
254  }
255  catch(...)
256  {
257  throw te::common::Exception(TE_TR("An error occurred adding the attribute: ") + ( attName.empty() ? std::string( "[empty]" ) : attName ));
258  }
259 }
260 
261 void te::xerces::Writer::writeAttribute(const std::string& attName, const double& value)
262 {
263  writeAttribute(attName, boost::lexical_cast<std::string>(value));
264 }
265 
266 void te::xerces::Writer::writeAttribute(const std::string& attName, boost::int32_t value)
267 {
268  writeAttribute(attName, boost::lexical_cast<std::string>(value));
269 }
270 
271 void te::xerces::Writer::writeAttribute(const std::string& attName, boost::uint32_t value)
272 {
273  writeAttribute(attName, boost::lexical_cast<std::string>(value));
274 }
275 
276 void te::xerces::Writer::writeAttribute(const std::string& attName, boost::int64_t value)
277 {
278  writeAttribute(attName, boost::lexical_cast<std::string>(value));
279 }
280 
281 void te::xerces::Writer::writeAttribute(const std::string& attName, boost::uint64_t value)
282 {
283  writeAttribute(attName, boost::lexical_cast<std::string>(value));
284 }
285 
286 void te::xerces::Writer::writeValue(const std::string& value)
287 {
288  addText(value);
289 }
290 
291 void te::xerces::Writer::writeValue(const double& value)
292 {
293  addText(boost::lexical_cast<std::string>(value));
294 }
295 
296 void te::xerces::Writer::writeValue(boost::int32_t value)
297 {
298  addText(boost::lexical_cast<std::string>(value));
299 }
300 
301 void te::xerces::Writer::writeValue(boost::uint32_t value)
302 {
303  addText(boost::lexical_cast<std::string>(value));
304 }
305 
306 void te::xerces::Writer::writeValue(boost::int64_t value)
307 {
308  addText(boost::lexical_cast<std::string>(value));
309 }
310 
311 void te::xerces::Writer::writeValue(boost::uint64_t value)
312 {
313  addText(boost::lexical_cast<std::string>(value));
314 }
315 
316 void te::xerces::Writer::writeEndElement(const std::string& qName)
317 {
318  m_topIndice = m_topElementSet.at( m_topIndice );
319 }
320 
321 void te::xerces::Writer::addText(const std::string& qValue)
322 {
323  try
324  {
325  xercesc::DOMText* domText = m_doc->createTextNode(StrToXMLCh(qValue).getXMLCh());
326  m_elementSet[m_indice]->appendChild(domText);
327  }
328  catch(const xercesc::DOMException& e)
329  {
330  throw te::common::Exception(TE_TR("Exception message is: ") + XMLChToStr(e.getMessage()).getStr());
331  }
332  catch(...)
333  {
334  throw te::common::Exception(TE_TR("An error occurred adding the value to the element"));
335  }
336 }
A class for converting a standard string to a Xerces string (XMLCh).
Definition: StrToXMLCh.h:47
void writeStartElement(const std::string &qName)
Definition: Writer.cpp:136
A class for converting a standard string to a Xerces string (XMLCh).
void addText(const std::string &qValue)
Adds a XML value to the last inserted element.
Definition: Writer.cpp:321
void writeStartDocument(const std::string &encoding, const std::string &standalone)
Definition: Writer.cpp:70
std::string Convert2UCase(const std::string &value)
It converts a string to upper case.
Definition: StringUtils.h:163
void writeToFile()
Definition: Writer.cpp:76
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:347
void writeElement(const std::string &qName, const std::string &value)
Definition: Writer.cpp:196
A class for converting a Xerces string (XMLCh) to a standard string.
Definition: XMLChToStr.h:50
A class for converting a Xerces string (XMLCh) to a standard string.
~Writer()
Destructor.
Definition: Writer.cpp:62
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
Definition: Exception.h:58
Writer()
Default constructor.
Definition: Writer.cpp:53
void writeEndElement(const std::string &qName)
Definition: Writer.cpp:316
void writeValue(const std::string &value)
Definition: Writer.cpp:286
void writeAttribute(const std::string &attName, const std::string &value)
Definition: Writer.cpp:245