//$Id$ #include "XML_Helper.h" #include "ace/Auto_Ptr.h" #include "ace/Log_Msg.h" //#include "ciao/Logger/Log_Macros.h" #include "xercesc/util/XMLUniDefs.hpp" #include "xercesc/dom/DOM.hpp" #include "XML_Error_Handler.h" #include "XML_Schema_Resolver.h" #include "xercesc/framework/LocalFileFormatTarget.hpp" #include "xercesc/dom/DOM.hpp" #include "XercesString.h" #if XERCES_VERSION_MAJOR == 3 #include "xercesc/dom/DOMLSSerializer.hpp" #endif namespace CIAO { namespace XML { using xercesc::XMLException; using xercesc::XMLString; using xercesc::DOMImplementation; using xercesc::DOMImplementationRegistry; // using xercesc::DOMBuilder; using xercesc::DOMImplementationLS; using xercesc::XMLUni; using xercesc::DOMDocument; using xercesc::DOMException; using xercesc::DOMDocumentType; using xercesc::XercesDOMParser; /* template XML_Helper::XML_Helper (void) : initialized_ (false) { this->init_parser (); } */ // TODO this is stub implementation template XML_Helper::XML_Helper (Resolver &resolver, Error &eh) : initialized_ (false), resolver_ (resolver), e_handler_ (eh) { this->init_parser (); } template XML_Helper::~XML_Helper (void) { this->terminate_parser (); } template bool XML_Helper::is_initialized (void) const { return this->initialized_ == true; } template void XML_Helper::init_parser (void) { if (this->initialized_) return; // CIAO_DEBUG ((LM_TRACE, CLINFO //"XML_Helper<>::is_initialized - Initializing the Xerces runtime \n")); // Initialize the Xerces run-time try { xercesc::XMLPlatformUtils::Initialize(); } catch (const XMLException& e) { char* message = XMLString::transcode (e.getMessage()); ACE_Auto_Basic_Array_Ptr cleanup_message (message); throw; } catch (...) { ACE_DEBUG ((LM_DEBUG, "(%P|%t) Some other exception," " returning\n")); return; } // Instantiate the DOM parser. static const XMLCh gLS[] = { xercesc::chLatin_L, xercesc::chLatin_S, xercesc::chNull }; // Get an implementation of the Load-Store (LS) interface // and cache it for later use impl_ = DOMImplementationRegistry::getDOMImplementation(gLS); this->initialized_ = true; return; } template XERCES_CPP_NAMESPACE::DOMDocument * XML_Helper::create_dom (const ACE_TCHAR *root, const ACE_TCHAR *ns, DOMDocumentType *doctype) const { if (root == 0 || ns == 0) return 0; return this->impl_->createDocument (XStr (ns), XStr (root), doctype); } template XERCES_CPP_NAMESPACE::DOMDocumentType * XML_Helper::create_doctype (const ACE_TCHAR *qn, const ACE_TCHAR *pid, const ACE_TCHAR *sid) const { return this->impl_->createDocumentType (XStr (qn), XStr (pid), XStr (sid)); } template XERCES_CPP_NAMESPACE::DOMDocument * XML_Helper::create_dom (const ACE_TCHAR *url) const { if (url == 0) return 0; try { if (this->parser_.get () == 0) this->parser_.reset ((new xercesc::XercesDOMParser ())); // Perform Namespace processing. this->parser_->setDoNamespaces (true); // Discard comment nodes in the document this->parser_->setCreateCommentNodes (false); // Disable datatype normalization. The XML 1.0 attribute value // normalization always occurs though. // this->parser_->setFeature (XMLUni::fgDOMDatatypeNormalization, true); // Do not create EntityReference nodes in the DOM tree. No // EntityReference nodes will be created, only the nodes // corresponding to their fully expanded sustitution text will be // created. this->parser_->setCreateEntityReferenceNodes (false); // Perform Validation this->parser_->setValidationScheme (xercesc::AbstractDOMParser::Val_Always); // Do not include ignorable whitespace in the DOM tree. this->parser_->setIncludeIgnorableWhitespace (false); // Enable the parser's schema support. this->parser_->setDoSchema (true); // Enable full schema constraint checking, including checking which // may be time-consuming or memory intensive. Currently, particle // unique attribution constraint checking and particle derivation // restriction checking are controlled by this option. this->parser_->setValidationSchemaFullChecking (true); // The parser will treat validation error as fatal and will exit. this->parser_->setValidationConstraintFatal (true); this->parser_->setErrorHandler (&e_handler_); this->parser_->setEntityResolver (&resolver_); this->parser_->parse (ACE_TEXT_ALWAYS_CHAR (url)); if (e_handler_.getErrors ()) return 0; return this->parser_->getDocument (); } catch (const DOMException& e) { const unsigned int maxChars = 2047; XMLCh errText[maxChars + 1]; if (DOMImplementation::loadDOMExceptionMsg (e.code, errText, maxChars)) { char* message = XMLString::transcode (errText); ACE_Auto_Basic_Array_Ptr cleanup_message (message); } return 0; } catch (const XMLException& e) { char* message = XMLString::transcode (e.getMessage()); ACE_Auto_Basic_Array_Ptr cleanup_message (message); throw 0; } catch (...) { ACE_DEBUG ((LM_DEBUG, "(%P|%t) Caught an unknown exception \n")); throw; } return 0; } template void XML_Helper::terminate_parser (void) { try { xercesc::XMLPlatformUtils::Terminate(); } catch (const XMLException& e) { char* message = XMLString::transcode (e.getMessage()); ACE_Auto_Basic_Array_Ptr cleanup_message (message); throw; } this->initialized_ = false; return; } template bool XML_Helper::write_DOM (XERCES_CPP_NAMESPACE::DOMDocument *doc, const ACE_TCHAR *file) const { try { bool retn; #if XERCES_VERSION_MAJOR == 3 XERCES_CPP_NAMESPACE::DOMLSSerializer *serializer (impl_->createLSSerializer ()); XERCES_CPP_NAMESPACE::DOMConfiguration *ser_config (serializer->getDomConfig ()); XERCES_CPP_NAMESPACE::DOMLSOutput *output (impl_->createLSOutput ()); if (ser_config->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true)) ser_config->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true); XMLFormatTarget *format_target = new XERCES_CPP_NAMESPACE::LocalFileFormatTarget (ACE_TEXT_ALWAYS_CHAR (file)); output->setByteStream (format_target); retn = serializer->write (doc, output); output->release (); serializer->release (); return retn; #else std::auto_ptr writer (impl_->createDOMWriter()); if (writer->canSetFeature (XMLUni::fgDOMWRTFormatPrettyPrint, true)) writer->setFeature (XMLUni::fgDOMWRTFormatPrettyPrint, true); std::auto_ptr ft (new xercesc::LocalFileFormatTarget(file)); retn = writer->writeNode(ft.get (), *doc); return retn; #endif } catch (const xercesc::XMLException &e) { char* message = XMLString::transcode (e.getMessage()); ACE_Auto_Basic_Array_Ptr cleanup_message (message); char* name = XMLString::transcode (e.getType()); ACE_Auto_Basic_Array_Ptr cleanup_name (name); ACE_ERROR ((LM_ERROR, "Caught exception while serializing DOM to file.\n" "Name: %s\n" "Message: %s\n" "SrcFile: %s\n" "SrcLine: %d\n", name, message, e.getSrcFile (), e.getSrcLine ())); return false; } } } }