Eclipse SUMO - Simulation of Urban MObility
XMLSubSys.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2002-2022 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
20 // Utility methods for initialising, closing and using the XML-subsystem
21 /****************************************************************************/
22 #include <config.h>
23 
24 #include <cstdint>
25 #include <xercesc/util/PlatformUtils.hpp>
26 #include <xercesc/sax2/XMLReaderFactory.hpp>
27 #include <xercesc/framework/XMLGrammarPoolImpl.hpp>
30 #include "SUMOSAXHandler.h"
31 #include "SUMOSAXReader.h"
32 #include "XMLSubSys.h"
33 
34 using XERCES_CPP_NAMESPACE::SAX2XMLReader;
35 using XERCES_CPP_NAMESPACE::XMLPlatformUtils;
36 using XERCES_CPP_NAMESPACE::XMLReaderFactory;
37 
38 
39 // ===========================================================================
40 // static member variables
41 // ===========================================================================
42 std::vector<SUMOSAXReader*> XMLSubSys::myReaders;
44 SAX2XMLReader::ValSchemes XMLSubSys::myValidationScheme = SAX2XMLReader::Val_Auto;
45 SAX2XMLReader::ValSchemes XMLSubSys::myNetValidationScheme = SAX2XMLReader::Val_Auto;
46 SAX2XMLReader::ValSchemes XMLSubSys::myRouteValidationScheme = SAX2XMLReader::Val_Auto;
47 XERCES_CPP_NAMESPACE::XMLGrammarPool* XMLSubSys::myGrammarPool = nullptr;
48 
49 
50 // ===========================================================================
51 // method definitions
52 // ===========================================================================
53 void
55  try {
56  XMLPlatformUtils::Initialize();
57  myNextFreeReader = 0;
58  } catch (const XERCES_CPP_NAMESPACE::XMLException& e) {
59  throw ProcessError("Error during XML-initialization:\n " + StringUtils::transcode(e.getMessage()));
60  }
61 }
62 
63 
64 void
65 XMLSubSys::setValidation(const std::string& validationScheme, const std::string& netValidationScheme, const std::string& routeValidationScheme) {
66  if (validationScheme == "never") {
67  myValidationScheme = SAX2XMLReader::Val_Never;
68  } else if (validationScheme == "auto") {
69  myValidationScheme = SAX2XMLReader::Val_Auto;
70  } else if (validationScheme == "always") {
71  myValidationScheme = SAX2XMLReader::Val_Always;
72  } else {
73  throw ProcessError("Unknown xml validation scheme + '" + validationScheme + "'.");
74  }
75  if (netValidationScheme == "never") {
76  myNetValidationScheme = SAX2XMLReader::Val_Never;
77  } else if (netValidationScheme == "auto") {
78  myNetValidationScheme = SAX2XMLReader::Val_Auto;
79  } else if (netValidationScheme == "always") {
80  myNetValidationScheme = SAX2XMLReader::Val_Always;
81  } else {
82  throw ProcessError("Unknown network validation scheme + '" + netValidationScheme + "'.");
83  }
84  if (routeValidationScheme == "never") {
85  myRouteValidationScheme = SAX2XMLReader::Val_Never;
86  } else if (routeValidationScheme == "auto") {
87  myRouteValidationScheme = SAX2XMLReader::Val_Auto;
88  } else if (routeValidationScheme == "always") {
89  myRouteValidationScheme = SAX2XMLReader::Val_Always;
90  } else {
91  throw ProcessError("Unknown route validation scheme + '" + routeValidationScheme + "'.");
92  }
93  if (myGrammarPool == nullptr &&
94  (myValidationScheme != SAX2XMLReader::Val_Never ||
95  myNetValidationScheme != SAX2XMLReader::Val_Never ||
96  myRouteValidationScheme != SAX2XMLReader::Val_Never)) {
97  myGrammarPool = new XERCES_CPP_NAMESPACE::XMLGrammarPoolImpl(XMLPlatformUtils::fgMemoryManager);
98  SAX2XMLReader* parser(XMLReaderFactory::createXMLReader(XMLPlatformUtils::fgMemoryManager, myGrammarPool));
99 #if _XERCES_VERSION >= 30100
100  parser->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesHandleMultipleImports, true);
101 #endif
102  const char* sumoPath = std::getenv("SUMO_HOME");
103  if (sumoPath == nullptr) {
104  WRITE_WARNING("Environment variable SUMO_HOME is not set, schema resolution will use slow website lookups.");
105  return;
106  }
107  for (const std::string& filetype : {
108  "additional", "routes", "net"
109  }) {
110  const std::string file = sumoPath + std::string("/data/xsd/") + filetype + "_file.xsd";
111  if (!parser->loadGrammar(file.c_str(), XERCES_CPP_NAMESPACE::Grammar::SchemaGrammarType, true)) {
112  WRITE_WARNING("Cannot read local schema '" + file + "', will try website lookup.");
113  }
114  }
115  }
116 }
117 
118 
119 void
121  for (std::vector<SUMOSAXReader*>::iterator i = myReaders.begin(); i != myReaders.end(); ++i) {
122  delete *i;
123  }
124  myReaders.clear();
125  delete myGrammarPool;
126  myGrammarPool = nullptr;
127  XMLPlatformUtils::Terminate();
129 }
130 
131 
133 XMLSubSys::getSAXReader(SUMOSAXHandler& handler, const bool isNet, const bool isRoute) {
134  SAX2XMLReader::ValSchemes validationScheme = isNet ? myNetValidationScheme : myValidationScheme;
135  if (isRoute) {
136  validationScheme = myRouteValidationScheme;
137  }
138  return new SUMOSAXReader(handler, validationScheme, myGrammarPool);
139 }
140 
141 
142 void
144  myReaders[myNextFreeReader - 1]->setHandler(handler);
145 }
146 
147 
148 bool
149 XMLSubSys::runParser(GenericSAXHandler& handler, const std::string& file,
150  const bool isNet, const bool isRoute) {
152  try {
153  SAX2XMLReader::ValSchemes validationScheme = isNet ? myNetValidationScheme : myValidationScheme;
154  if (isRoute) {
155  validationScheme = myRouteValidationScheme;
156  }
157  if (myNextFreeReader == (int)myReaders.size()) {
158  myReaders.push_back(new SUMOSAXReader(handler, validationScheme, myGrammarPool));
159  } else {
160  myReaders[myNextFreeReader]->setValidation(validationScheme);
161  myReaders[myNextFreeReader]->setHandler(handler);
162  }
164  std::string prevFile = handler.getFileName();
165  handler.setFileName(file);
166  myReaders[myNextFreeReader - 1]->parse(file);
167  handler.setFileName(prevFile);
169  } catch (ProcessError& e) {
170  WRITE_ERROR(std::string(e.what()) != std::string("") ? std::string(e.what()) : std::string("Process Error"));
171  return false;
172  } catch (const std::runtime_error& re) {
173  WRITE_ERROR("Runtime error: " + std::string(re.what()) + " while parsing '" + file + "'");
174  return false;
175  } catch (const std::exception& ex) {
176  WRITE_ERROR("Error occurred: " + std::string(ex.what()) + " while parsing '" + file + "'");
177  return false;
178  } catch (...) {
179  WRITE_ERROR("Unspecified error occurred wile parsing '" + file + "'");
180  return false;
181  }
183 }
184 
185 
186 /****************************************************************************/
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:288
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:280
A handler which converts occuring elements and attributes into enums.
void setFileName(const std::string &name)
Sets the current file name.
const std::string & getFileName() const
returns the current file name
bool wasInformed() const
Returns the information whether any messages were added.
Definition: MsgHandler.cpp:294
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:80
virtual void clear(bool resetInformed=true)
Clears information whether an error occurred previously and print aggregated message summary.
Definition: MsgHandler.cpp:162
SAX-handler base for SUMO-files.
SAX-reader encapsulation containing binary reader.
Definition: SUMOSAXReader.h:52
static void resetTranscoder()
must be called when shutting down the xml subsystem
static std::string transcode(const XMLCh *const data)
converts a 0-terminated XMLCh* array (usually UTF-16, stemming from Xerces) into std::string in UTF-8
Definition: StringUtils.h:137
static int myNextFreeReader
Information whether the reader is parsing.
Definition: XMLSubSys.h:149
static XERCES_CPP_NAMESPACE::SAX2XMLReader::ValSchemes myRouteValidationScheme
Information whether built reader/parser shall validate SUMO routes against schemata.
Definition: XMLSubSys.h:158
static XERCES_CPP_NAMESPACE::SAX2XMLReader::ValSchemes myNetValidationScheme
Information whether built reader/parser shall validate SUMO networks against schemata.
Definition: XMLSubSys.h:155
static std::vector< SUMOSAXReader * > myReaders
The XML Readers used for repeated parsing.
Definition: XMLSubSys.h:146
static void setHandler(GenericSAXHandler &handler)
Sets the given handler for the default reader.
Definition: XMLSubSys.cpp:143
static void setValidation(const std::string &validationScheme, const std::string &netValidationScheme, const std::string &routeValidationScheme)
Enables or disables validation.
Definition: XMLSubSys.cpp:65
static XERCES_CPP_NAMESPACE::XMLGrammarPool * myGrammarPool
Schema cache to be used for grammars which are not declared.
Definition: XMLSubSys.h:161
static SUMOSAXReader * getSAXReader(SUMOSAXHandler &handler, const bool isNet=false, const bool isRoute=false)
Builds a reader and assigns the handler to it.
Definition: XMLSubSys.cpp:133
static void close()
Closes the xml-subsystem.
Definition: XMLSubSys.cpp:120
static XERCES_CPP_NAMESPACE::SAX2XMLReader::ValSchemes myValidationScheme
Information whether built reader/parser shall validate XML-documents against schemata.
Definition: XMLSubSys.h:152
static void init()
Initialises the xml-subsystem.
Definition: XMLSubSys.cpp:54
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false, const bool isRoute=false)
Runs the given handler on the given file; returns if everything's ok.
Definition: XMLSubSys.cpp:149