1 #include "XML_Helper.h"
2 #include "ace/Log_Msg.h"
3 #include "ace/Log_Category.h"
4 #include "xercesc/util/XMLUniDefs.hpp"
5 #include "xercesc/dom/DOM.hpp"
6 #include "XML_Error_Handler.h"
7 #include "XML_Schema_Resolver.h"
8 #include "xercesc/framework/LocalFileFormatTarget.hpp"
9 #include "xercesc/dom/DOM.hpp"
10 #include "XercesString.h"
11 #include "xercesc/dom/DOMLSSerializer.hpp"
16 using xercesc::XMLException;
17 using xercesc::XMLString;
18 using xercesc::DOMImplementation;
19 using xercesc::DOMImplementationRegistry;
20 // using xercesc::DOMBuilder;
21 using xercesc::DOMImplementationLS;
22 using xercesc::XMLUni;
23 using xercesc::DOMDocument;
24 using xercesc::DOMException;
25 using xercesc::DOMDocumentType;
26 using xercesc::XercesDOMParser;
28 // TODO this is stub implementation
29 template <typename Resolver, typename Error>
30 XML_Helper<Resolver, Error>::XML_Helper (Resolver *resolver, Error *eh)
31 : resolver_ (resolver),
37 template <typename Resolver, typename Error>
38 XML_Helper<Resolver, Error>::~XML_Helper ()
40 this->terminate_parser ();
43 template <typename Resolver, typename Error>
45 XML_Helper<Resolver, Error>::is_initialized () const
47 return this->initialized_;
50 template <typename Resolver, typename Error>
52 XML_Helper<Resolver, Error>::init_parser ()
54 if (this->initialized_)
57 // Initialize the Xerces run-time
62 resolver_ = new Resolver ();
63 release_resolver_ = true;
68 e_handler_ = new Error ();
69 release_e_handler_ = true;
72 xercesc::XMLPlatformUtils::Initialize();
74 catch (const XMLException& e)
76 char* message = XMLString::transcode (e.getMessage());
77 std::unique_ptr<char[]> cleanup_message (message);
83 ACELIB_DEBUG ((LM_DEBUG, "(%P|%t) Some other exception, returning\n"));
87 // Instantiate the DOM parser.
88 static const XMLCh gLS[] = { xercesc::chLatin_L,
92 // Get an implementation of the Load-Store (LS) interface
93 // and cache it for later use
94 impl_ = DOMImplementationRegistry::getDOMImplementation(gLS);
96 this->initialized_ = true;
100 template <typename Resolver, typename Error>
101 XERCES_CPP_NAMESPACE::DOMDocument *
102 XML_Helper<Resolver, Error>::create_dom (const ACE_TCHAR *root,
104 DOMDocumentType *doctype) const
109 return this->impl_->createDocument (XStr (ns),
114 template <typename Resolver, typename Error>
115 XERCES_CPP_NAMESPACE::DOMDocumentType *
116 XML_Helper<Resolver, Error>::create_doctype (const ACE_TCHAR *qn,
117 const ACE_TCHAR *pid,
118 const ACE_TCHAR *sid) const
120 return this->impl_->createDocumentType (XStr (qn),
124 template <typename Resolver, typename Error>
125 XERCES_CPP_NAMESPACE::DOMDocument *
126 XML_Helper<Resolver, Error>::create_dom (const ACE_TCHAR *url) const
134 if (this->parser_.get () == 0)
135 this->parser_.reset ((new xercesc::XercesDOMParser ()));
137 // Perform Namespace processing.
138 this->parser_->setDoNamespaces (true);
140 // Discard comment nodes in the document
141 this->parser_->setCreateCommentNodes (false);
143 // Disable datatype normalization. The XML 1.0 attribute value
144 // normalization always occurs though.
145 // this->parser_->setFeature (XMLUni::fgDOMDatatypeNormalization, true);
147 // Do not create EntityReference nodes in the DOM tree. No
148 // EntityReference nodes will be created, only the nodes
149 // corresponding to their fully expanded sustitution text will be
151 this->parser_->setCreateEntityReferenceNodes (false);
153 // Perform Validation
154 this->parser_->setValidationScheme (xercesc::AbstractDOMParser::Val_Always);
156 // Do not include ignorable whitespace in the DOM tree.
157 this->parser_->setIncludeIgnorableWhitespace (false);
159 // Enable the parser's schema support.
160 this->parser_->setDoSchema (true);
162 // Enable full schema constraint checking, including checking which
163 // may be time-consuming or memory intensive. Currently, particle
164 // unique attribution constraint checking and particle derivation
165 // restriction checking are controlled by this option.
166 this->parser_->setValidationSchemaFullChecking (true);
168 // The parser will treat validation error as fatal and will exit.
169 this->parser_->setValidationConstraintFatal (true);
171 this->parser_->setErrorHandler (e_handler_);
173 this->parser_->setEntityResolver (resolver_);
175 this->parser_->parse (ACE_TEXT_ALWAYS_CHAR (url));
177 if (e_handler_ && e_handler_->getErrors ())
180 return this->parser_->getDocument ();
182 catch (const DOMException& e)
184 const unsigned int maxChars = 2047;
185 XMLCh errText[maxChars + 1];
187 if (DOMImplementation::loadDOMExceptionMsg (e.code,
191 char* message = XMLString::transcode (errText);
192 std::unique_ptr<char[]> cleanup_message (message);
197 catch (const XMLException& e)
199 char* message = XMLString::transcode (e.getMessage());
200 std::unique_ptr<char[]> cleanup_message (message);
205 ACELIB_DEBUG ((LM_DEBUG, "(%P|%t) Caught an unknown exception\n"));
212 template <typename Resolver, typename Error>
214 XML_Helper<Resolver, Error>::terminate_parser ()
216 if (!this->initialized_)
221 if (release_resolver_)
227 if (release_e_handler_)
233 this->parser_.reset (nullptr);
234 this->impl_ = nullptr;
235 xercesc::XMLPlatformUtils::Terminate();
237 catch (const XMLException& e)
239 char* message = XMLString::transcode (e.getMessage());
240 std::unique_ptr<char[]> cleanup_message (message);
244 this->initialized_ = false;
248 template <typename Resolver, typename Error>
250 XML_Helper<Resolver, Error>::get_resolver ()
252 if (!this->resolver_)
253 throw std::exception ();
255 return *this->resolver_;
258 template <typename Resolver, typename Error>
260 XML_Helper<Resolver, Error>::get_error_handler ()
262 if (!this->e_handler_)
263 throw std::exception ();
265 return *this->e_handler_;
268 template <typename Resolver, typename Error>
270 XML_Helper<Resolver, Error>::write_DOM (XERCES_CPP_NAMESPACE::DOMDocument *doc,
271 const ACE_TCHAR *file) const
276 XERCES_CPP_NAMESPACE::DOMLSSerializer *serializer (impl_->createLSSerializer ());
277 XERCES_CPP_NAMESPACE::DOMConfiguration *ser_config (serializer->getDomConfig ());
278 XERCES_CPP_NAMESPACE::DOMLSOutput *output (impl_->createLSOutput ());
280 if (ser_config->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true))
281 ser_config->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true);
283 XMLFormatTarget *format_target = new XERCES_CPP_NAMESPACE::LocalFileFormatTarget (ACE_TEXT_ALWAYS_CHAR (file));
285 output->setByteStream (format_target);
287 retn = serializer->write (doc, output);
290 serializer->release ();
293 catch (const xercesc::XMLException &e)
295 char* message = XMLString::transcode (e.getMessage());
296 std::unique_ptr<char[]> cleanup_message (message);
298 char* name = XMLString::transcode (e.getType());
299 std::unique_ptr<char[]> cleanup_name (name);
301 ACELIB_ERROR ((LM_ERROR, "Caught exception while serializing DOM to file.\n"