Use =default for skeleton copy constructor
[ACE_TAO.git] / ACE / ace / XML_Utils / XML_Helper.tpp
blob3a234c1d5e6f3bcf3a4f3bd5ad085cf708455d7b
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"
12 #include <memory>
14 namespace XML
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),
32       e_handler_ (eh)
33   {
34     this->init_parser ();
35   }
37   template <typename Resolver, typename Error>
38   XML_Helper<Resolver, Error>::~XML_Helper ()
39   {
40     this->terminate_parser ();
41   }
43   template <typename Resolver, typename Error>
44   bool
45   XML_Helper<Resolver, Error>::is_initialized () const
46   {
47     return this->initialized_;
48   }
50   template <typename Resolver, typename Error>
51   void
52   XML_Helper<Resolver, Error>::init_parser ()
53   {
54     if (this->initialized_)
55       return;
57     // Initialize the Xerces run-time
58     try
59       {
60         if (!resolver_)
61           {
62             resolver_ = new Resolver ();
63             release_resolver_ = true;
64           }
66         if (!e_handler_)
67           {
68             e_handler_ = new Error ();
69             release_e_handler_ = true;
70           }
72         xercesc::XMLPlatformUtils::Initialize();
73       }
74     catch (const XMLException& e)
75       {
76         char* message = XMLString::transcode (e.getMessage());
77         std::unique_ptr<char[]> cleanup_message (message);
79         throw;
80       }
81     catch (...)
82       {
83         ACELIB_DEBUG ((LM_DEBUG, "(%P|%t) Some other exception, returning\n"));
84         return;
85       }
87     // Instantiate the DOM parser.
88     static const XMLCh gLS[] = { xercesc::chLatin_L,
89                                  xercesc::chLatin_S,
90                                  xercesc::chNull };
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;
97     return;
98   }
100   template <typename Resolver, typename Error>
101   XERCES_CPP_NAMESPACE::DOMDocument *
102   XML_Helper<Resolver, Error>::create_dom (const ACE_TCHAR *root,
103                                            const ACE_TCHAR *ns,
104                                            DOMDocumentType *doctype) const
105   {
106     if (!root || !ns)
107       return nullptr;
109     return this->impl_->createDocument (XStr (ns),
110                                         XStr (root),
111                                         doctype);
112   }
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
119   {
120     return this->impl_->createDocumentType (XStr (qn),
121                                             XStr (pid),
122                                             XStr (sid));
123   }
124   template <typename Resolver, typename Error>
125   XERCES_CPP_NAMESPACE::DOMDocument *
126   XML_Helper<Resolver, Error>::create_dom (const ACE_TCHAR *url) const
127   {
129     if (url == 0)
130       return 0;
132     try
133       {
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
150         // created.
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 ())
178           return 0;
180         return this->parser_->getDocument ();
181       }
182     catch (const DOMException& e)
183       {
184         const unsigned int maxChars = 2047;
185         XMLCh errText[maxChars + 1];
187         if (DOMImplementation::loadDOMExceptionMsg (e.code,
188                                                     errText,
189                                                     maxChars))
190           {
191             char* message = XMLString::transcode (errText);
192             std::unique_ptr<char[]> cleanup_message (message);
193           }
194         return 0;
196       }
197     catch (const XMLException& e)
198       {
199         char* message = XMLString::transcode (e.getMessage());
200         std::unique_ptr<char[]> cleanup_message (message);
201         throw 0;
202       }
203     catch (...)
204       {
205         ACELIB_DEBUG ((LM_DEBUG, "(%P|%t) Caught an unknown exception\n"));
206         throw;
207       }
209     return 0;
210   }
212   template <typename Resolver, typename Error>
213   void
214   XML_Helper<Resolver, Error>::terminate_parser ()
215   {
216     if (!this->initialized_)
217       return;
219     try
220       {
221         if (release_resolver_)
222           {
223             delete resolver_;
224             resolver_ = 0;
225           }
227         if (release_e_handler_)
228           {
229             delete e_handler_;
230             e_handler_ = 0;
231           }
233         this->parser_.reset (nullptr);
234         this->impl_ = nullptr;
235         xercesc::XMLPlatformUtils::Terminate();
236       }
237     catch (const XMLException& e)
238       {
239         char* message = XMLString::transcode (e.getMessage());
240         std::unique_ptr<char[]> cleanup_message (message);
241         throw;
242       }
244     this->initialized_ = false;
245     return;
246   }
248   template <typename Resolver, typename Error>
249   Resolver &
250   XML_Helper<Resolver, Error>::get_resolver ()
251   {
252     if (!this->resolver_)
253       throw std::exception ();
255     return *this->resolver_;
256   }
258   template <typename Resolver, typename Error>
259   Error &
260   XML_Helper<Resolver, Error>::get_error_handler ()
261   {
262     if (!this->e_handler_)
263       throw std::exception ();
265     return *this->e_handler_;
266   }
268   template <typename Resolver, typename Error>
269   bool
270   XML_Helper<Resolver, Error>::write_DOM (XERCES_CPP_NAMESPACE::DOMDocument *doc,
271                                           const ACE_TCHAR *file) const
272   {
273     try
274       {
275         bool retn;
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);
289         output->release ();
290         serializer->release ();
291         return retn;
292       }
293     catch (const xercesc::XMLException &e)
294       {
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"
302                     "Name: %C\n"
303                     "Message: %C\n"
304                     "SrcFile: %C\n"
305                     "SrcLine: %C\n",
306                     name,
307                     message,
308                     e.getSrcFile (),
309                     e.getSrcLine ()));
310         return false;
311       }
312   }