OpenDDS  Snapshot(2023/04/28-20:55)
XML_String_Intf.cpp
Go to the documentation of this file.
1 #include "XML_String_Intf.h"
2 #include "xercesc/util/XercesDefs.hpp"
3 #include "xercesc/framework/MemBufInputSource.hpp"
4 #include "xercesc/parsers/XercesDOMParser.hpp"
5 #include "xercesc/sax/SAXParseException.hpp"
6 #include "xercesc/util/TransService.hpp"
7 #include "ace/XML_Utils/XML_Helper.h"
8 #include "ace/XML_Utils/XML_Schema_Resolver.h"
9 #include "ace/XML_Utils/XML_Error_Handler.h"
10 
11 
12 #include "dds/DCPS/debug.h"
13 
15 
16 namespace OpenDDS {
17 namespace DCPS {
18 
19  QOS_XML_String_Handler::QOS_XML_String_Handler(XML::XML_Error_Handler* error_handler) :
21  res_(new XML::XML_Schema_Resolver<XML::Environment_Resolver>()),
22  eh_(error_handler ? error_handler : new XML::XML_Error_Handler()),
23  parser_(0),
24  finalDoc_(0)
25  {
26  try
27  {
28  // Call Initialize if not already called
30 
31  ////////////////
32  // Create parser
33  parser_ = new XercesDOMParser();
34 
35  // Create a DomImplementation
36  XMLCh* xmlver = XMLString::transcode("XML 1.0");
37  DOMImplementation * domImpl = DOMImplementationRegistry::getDOMImplementation(xmlver);
38  XMLString::release(&xmlver);
39 
40  // Create a temporary document with a generic element
41  // it shall be replaced in future with final version
42  XMLCh* namespaceURI = XMLString::transcode("");
43  XMLCh* qualifiedName = XMLString::transcode("temp");
44  finalDoc_ = domImpl->createDocument(namespaceURI, qualifiedName,0);
45  XMLString::release(&namespaceURI);
46  XMLString::release(&qualifiedName);
47 
48  } catch (const XMLException& toCatch) {
49  char* message = XMLString::transcode(toCatch.getMessage());
51  ACE_TEXT ("QOS_XML_String_Handler::QOS_XML_String_Handler - ")
52  ACE_TEXT ("Error during XML initialization! :\n<%C>\n"),
53  message));
54  XMLString::release(&message);
55  }
56  }
57 
59  {
60  if (finalDoc_ != 0)
61  finalDoc_->release();
62  delete parser_;
63  delete res_;
64  delete eh_;
65 
66  XMLPlatformUtils::Terminate();
67  }
68 
71  {
73  try
74  {
75  // Create a InputSource to be used in parser with XML string
76  XMLCh * conv = XMLString::transcode(ACE_TEXT_ALWAYS_CHAR (membuf));
77  TranscodeToStr xmlTranscoded(conv,"utf-8");
78  XMLString::release(&conv);
79  MemBufInputSource xmlBuf(xmlTranscoded.str(), xmlTranscoded.length() ,"xml (in memory)");
80 
81  ///////////////////
82  // Configure Parser
83  //
84  // Perform Namespace processing.
85  parser_->setDoNamespaces (true);
86  // Discard comment nodes in the document
87  parser_->setCreateCommentNodes (false);
88  // Disable datatype normalization. The XML 1.0 attribute value
89  // normalization always occurs though.
90  // parser_->setFeature (XMLUni::fgDOMDatatypeNormalization, true);
91 
92  // Do not create EntityReference nodes in the DOM tree. No
93  // EntityReference nodes will be created, only the nodes
94  // corresponding to their fully expanded sustitution text will be
95  // created.
96  parser_->setCreateEntityReferenceNodes (false);
97  // Perform Validation
98  parser_->setValidationScheme (xercesc::AbstractDOMParser::Val_Always);
99  // Do not include ignorable whitespace in the DOM tree.
100  parser_->setIncludeIgnorableWhitespace (false);
101  // Enable the parser_'s schema support.
102  parser_->setDoSchema (true);
103  // Enable full schema constraint checking, including checking which
104  // may be time-consuming or memory intensive. Currently, particle
105  // unique attribution constraint checking and particle derivation
106  // restriction checking are controlled by this option.
107  parser_->setValidationSchemaFullChecking (true);
108  // The parser_ will treat validation error as fatal and will exit.
109  parser_->setValidationConstraintFatal (true);
110 
111  // Set resolver using auxiliary XML_Schema_Resolver
112  parser_->setEntityResolver(res_);
113 
114  // Set XML Error handler
115  parser_->setErrorHandler(eh_);
116 
117  // Parsing buffer
118  try {
119  parser_->parse(xmlBuf);
120  }
121  catch (const SAXParseException& toCatch) {
122  char* message = XMLString::transcode(toCatch.getMessage());
124  ACE_TEXT ("QOS_XML_String_Handler::init - ")
125  ACE_TEXT ("Exception message is: <%C>\n"),
126  message));
127  XMLString::release(&message);
128  return DDS::RETCODE_ERROR;
129  }
130  catch (const XMLException& toCatch) {
131  char* message = XMLString::transcode(toCatch.getMessage());
133  ACE_TEXT ("QOS_XML_String_Handler::init - ")
134  ACE_TEXT ("Exception message is: <%C>\n"),
135  message));
136  XMLString::release(&message);
137  return DDS::RETCODE_ERROR;
138  }
139  catch (const DOMException& toCatch) {
140  char* message = XMLString::transcode(toCatch.getMessage());
142  ACE_TEXT ("QOS_XML_String_Handler::init - ")
143  ACE_TEXT ("Exception message is: <%C>\n"),
144  message));
145  XMLString::release(&message);
146  return DDS::RETCODE_ERROR;
147  }
148  catch (...) {
150  ACE_TEXT ("QOS_XML_String_Handler::init - ")
151  ACE_TEXT ("Unexpected exception\n")
152  ));
153  return DDS::RETCODE_ERROR;
154  }
155 
156  DOMDocument * initialDoc = parser_->getDocument();
157  if (initialDoc == 0)
158  {
159  if (DCPS_debug_level > 1)
160  {
162  ACE_TEXT ("QOS_XML_String_Handler::init - ")
163  ACE_TEXT ("Failed to parse string\n")
164  ));
165  }
166  return DDS::RETCODE_ERROR;
167  }
168 
169  // Find "dds" node using the opendds namespace
170  XMLCh* ns = XMLString::transcode("http://www.omg.org/dds");
171  XMLCh* ddstag = XMLString::transcode("dds");
172 
173  DOMNodeList * ddsNodeList = initialDoc->getElementsByTagNameNS(ns, ddstag);
174  XMLString::release(&ns);
175  XMLString::release(&ddstag);
176 
177  // Check if it could find tag and namespace
178  if (ddsNodeList->getLength() == 0)
179  {
180  if (DCPS_debug_level > 1)
181  {
183  ACE_TEXT ("QOS_XML_String_Handler::init - ")
184  ACE_TEXT ("Could not find tag(dds) in namespace(http://www.omg.org/dds)\n")
185  ));
186  }
187  return DDS::RETCODE_ERROR;
188  }
189 
190  // Get the first node. It is expected to have only one
191  DOMNode * ddsNode = ddsNodeList->item(0);
192  if (DCPS_debug_level > 1)
193  {
194  char* message = XMLString::transcode(ddsNode->getNodeName());
196  ACE_TEXT ("QOS_XML_String_Handler::init - ")
197  ACE_TEXT ("Node name: <%C>\n"),
198  message));
199  XMLString::release(&message);
200  }
201 
202  DOMNode * clone = finalDoc_->importNode(ddsNode, true);
203 
204  // Check if import was successful
205  if (clone == 0)
206  {
207  if (DCPS_debug_level > 1)
208  {
210  ACE_TEXT ("QOS_XML_String_Handler::init - ")
211  ACE_TEXT ("Failed to get pointer of imported node\n")
212  ));
213  }
214  return DDS::RETCODE_ERROR;
215  }
216  // Replace root element by the cloned one. Thus the root element
217  // shall be "dds" as required by dds::reader::dds function
218  finalDoc_->replaceChild(clone,finalDoc_->getDocumentElement());
219 
220  ID_Map::TSS_ID_Map* TSS_ID_Map (ACE_Singleton<ID_Map::TSS_ID_Map, ACE_Null_Mutex>::instance());
221  (*TSS_ID_Map)->reset ();
222 
224 
225  }
226  catch (const CORBA::Exception &ex)
227  {
229  ACE_TEXT ("QOS_XML_String_Handler::init - ")
230  ACE_TEXT ("Caught CORBA exception whilst parsing XML\n"),
231  ex._info ().c_str ()));
232  retcode = DDS::RETCODE_ERROR;
233  }
234  catch (...)
235  {
237  ACE_TEXT ("QOS_XML_String_Handler::init - ")
238  ACE_TEXT ("Unexpected exception whilst parsing XML.\n")
239  ));
240  retcode = DDS::RETCODE_ERROR;
241  }
242  return retcode;
243  }
244 
245  void
247  const ACE_TCHAR *relpath)
248  {
249  res_->get_resolver().add_path(environment,relpath);
250  }
251 
252 }
253 }
254 
#define ACE_DEBUG(X)
#define ACE_ERROR(X)
const char * c_str(void) const
XERCES_CPP_NAMESPACE::DOMDocument * finalDoc_
DDS::ReturnCode_t init(const ACE_TCHAR *membuf)
#define ACE_TEXT_ALWAYS_CHAR(STRING)
::dds::qosProfile_seq dds(xercesc::DOMDocument const *d)
Definition: dds_qos.cpp:7398
LM_DEBUG
XERCES_CPP_NAMESPACE::XercesDOMParser * parser_
Parser.
char ACE_TCHAR
XML::XML_Schema_Resolver< XML::Environment_Resolver > * res_
Schema resolver.
virtual ACE_CString _info(void) const=0
void add_search_path(const ACE_TCHAR *environment, const ACE_TCHAR *relpath)
void Initialize(const CONFIGURATION_RESOURCE configuration_file, RETURN_CODE_TYPE &return_code)
Definition: FaceTSS.cpp:70
QOS_XML_String_Handler(XML::XML_Error_Handler *error_handler=0)
ACE_TEXT("TCP_Factory")
OpenDDS_Dcps_Export unsigned int DCPS_debug_level
Definition: debug.cpp:30
XML::XML_Error_Handler * eh_
Error handler.
::dds::qosProfile_seq profiles_
Definition: XML_Intf.h:116
const ReturnCode_t RETCODE_ERROR
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
const ReturnCode_t RETCODE_OK
LM_ERROR
The Internal API and Implementation of OpenDDS.
Definition: AddressCache.h:28