Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
XMLSubSys.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2002-2023 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>
31#include "SUMOSAXHandler.h"
32#include "SUMOSAXReader.h"
33#include "XMLSubSys.h"
34
35using XERCES_CPP_NAMESPACE::SAX2XMLReader;
36using XERCES_CPP_NAMESPACE::XMLPlatformUtils;
37using XERCES_CPP_NAMESPACE::XMLReaderFactory;
38
39
40// ===========================================================================
41// static member variables
42// ===========================================================================
43std::vector<SUMOSAXReader*> XMLSubSys::myReaders;
45std::string XMLSubSys::myValidationScheme = "local";
46std::string XMLSubSys::myNetValidationScheme = "local";
47std::string XMLSubSys::myRouteValidationScheme = "local";
48XERCES_CPP_NAMESPACE::XMLGrammarPool* XMLSubSys::myGrammarPool = nullptr;
49
50
51// ===========================================================================
52// method definitions
53// ===========================================================================
54void
56 try {
57 XMLPlatformUtils::Initialize();
59 } catch (const XERCES_CPP_NAMESPACE::XMLException& e) {
60 throw ProcessError("Error during XML-initialization:\n " + StringUtils::transcode(e.getMessage()));
61 }
62}
63
64
65void
66XMLSubSys::setValidation(const std::string& validationScheme, const std::string& netValidationScheme, const std::string& routeValidationScheme) {
67 if (validationScheme != "never" && validationScheme != "auto" && validationScheme != "always" && validationScheme != "local") {
68 throw ProcessError("Unknown xml validation scheme + '" + validationScheme + "'.");
69 }
70 myValidationScheme = validationScheme;
71 if (netValidationScheme != "never" && netValidationScheme != "auto" && netValidationScheme != "always" && netValidationScheme != "local") {
72 throw ProcessError("Unknown network validation scheme + '" + netValidationScheme + "'.");
73 }
74 myNetValidationScheme = netValidationScheme;
75 if (routeValidationScheme != "never" && routeValidationScheme != "auto" && routeValidationScheme != "always" && routeValidationScheme != "local") {
76 throw ProcessError("Unknown route validation scheme + '" + routeValidationScheme + "'.");
77 }
78 myRouteValidationScheme = routeValidationScheme;
79 if (myGrammarPool == nullptr &&
80 (myValidationScheme != "never" ||
81 myNetValidationScheme != "never" ||
82 myRouteValidationScheme != "never")) {
83 myGrammarPool = new XERCES_CPP_NAMESPACE::XMLGrammarPoolImpl(XMLPlatformUtils::fgMemoryManager);
84 SAX2XMLReader* parser(XMLReaderFactory::createXMLReader(XMLPlatformUtils::fgMemoryManager, myGrammarPool));
85#if _XERCES_VERSION >= 30100
86 parser->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesHandleMultipleImports, true);
87#endif
88 const char* sumoPath = std::getenv("SUMO_HOME");
89 if (sumoPath == nullptr || !FileHelpers::isReadable(sumoPath + std::string("/data/xsd/net_file.xsd"))) {
90 bool needWarning = true;
91 if (validationScheme == "local") {
92 WRITE_WARNING(TL("Environment variable SUMO_HOME is not set properly, disabling XML validation. Set 'auto' or 'always' for web lookups."));
93 needWarning = false;
94 myValidationScheme = "never";
95 }
96 if (netValidationScheme == "local") {
97 if (needWarning) {
98 WRITE_WARNING(TL("Environment variable SUMO_HOME is not set properly, disabling XML validation. Set 'auto' or 'always' for web lookups."));
99 needWarning = false;
100 }
101 myNetValidationScheme = "never";
102 }
103 if (routeValidationScheme == "local") {
104 if (needWarning) {
105 WRITE_WARNING(TL("Environment variable SUMO_HOME is not set properly, disabling XML validation. Set 'auto' or 'always' for web lookups."));
106 needWarning = false;
107 }
108 myRouteValidationScheme = "never";
109 }
110 if (needWarning) {
111 WRITE_WARNING(TL("Environment variable SUMO_HOME is not set properly, XML validation will fail or use slow website lookups."));
112 }
113 return;
114 }
115 for (const char* const& filetype : {
116 "additional", "routes", "net"
117 }) {
118 const std::string file = sumoPath + std::string("/data/xsd/") + filetype + "_file.xsd";
119 if (!parser->loadGrammar(file.c_str(), XERCES_CPP_NAMESPACE::Grammar::SchemaGrammarType, true)) {
120 WRITE_WARNINGF(TL("Cannot read local schema '%'."), file);
121 }
122 }
123 }
124}
125
126
127void
129 for (std::vector<SUMOSAXReader*>::iterator i = myReaders.begin(); i != myReaders.end(); ++i) {
130 delete *i;
131 }
132 myReaders.clear();
133 delete myGrammarPool;
134 myGrammarPool = nullptr;
135 XMLPlatformUtils::Terminate();
137}
138
139
141XMLSubSys::getSAXReader(SUMOSAXHandler& handler, const bool isNet, const bool isRoute) {
142 std::string validationScheme = isNet ? myNetValidationScheme : myValidationScheme;
143 if (isRoute) {
144 validationScheme = myRouteValidationScheme;
145 }
146 return new SUMOSAXReader(handler, validationScheme, myGrammarPool);
147}
148
149
150void
152 myReaders[myNextFreeReader - 1]->setHandler(handler);
153}
154
155
156bool
157XMLSubSys::runParser(GenericSAXHandler& handler, const std::string& file,
158 const bool isNet, const bool isRoute, const bool isExternal, const bool catchExceptions) {
160 std::string errorMsg = "";
161 try {
162 std::string validationScheme = isNet ? myNetValidationScheme : myValidationScheme;
163 if (isRoute) {
164 validationScheme = myRouteValidationScheme;
165 }
166 if (isExternal && validationScheme == "local") {
167 WRITE_MESSAGEF(TL("Disabling XML validation for external file '%'. Use 'auto' or 'always' to enable."), file);
168 validationScheme = "never";
169 }
170 if (myNextFreeReader == (int)myReaders.size()) {
171 myReaders.push_back(new SUMOSAXReader(handler, validationScheme, myGrammarPool));
172 } else {
173 myReaders[myNextFreeReader]->setValidation(validationScheme);
174 myReaders[myNextFreeReader]->setHandler(handler);
175 }
177 std::string prevFile = handler.getFileName();
178 handler.setFileName(file);
179 myReaders[myNextFreeReader - 1]->parse(file);
180 handler.setFileName(prevFile);
182 } catch (const ProcessError& e) {
183 if (catchExceptions) {
184 errorMsg = std::string(e.what()) != std::string("") ? e.what() : TL("Process Error");
185 } else {
186 throw;
187 }
188 } catch (const std::runtime_error& re) {
189 errorMsg = TLF("Runtime error: % while parsing '%'", re.what(), file);
190 } catch (const std::exception& ex) {
191 errorMsg = TLF("Error occurred: % while parsing '%'", ex.what(), file);
192 } catch (const XERCES_CPP_NAMESPACE::SAXException& e) {
193 errorMsg = TLF("SAX error occured while parsing '%':\n %", file, StringUtils::transcode(e.getMessage()));
194 } catch (...) {
195 errorMsg = TLF("Unspecified error occurred wile parsing '%'", file);
196 }
197 if (errorMsg != "") {
198 if (catchExceptions) {
199 WRITE_ERROR(errorMsg);
200 } else {
201 throw ProcessError(errorMsg);
202 }
203 }
205}
206
207
208/****************************************************************************/
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:271
#define WRITE_MESSAGEF(...)
Definition MsgHandler.h:273
#define WRITE_ERROR(msg)
Definition MsgHandler.h:279
#define WRITE_WARNING(msg)
Definition MsgHandler.h:270
#define TL(string)
Definition MsgHandler.h:287
#define TLF(string,...)
Definition MsgHandler.h:288
static bool isReadable(std::string path)
Checks whether the given file is readable.
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.
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
virtual void clear(bool resetInformed=true)
Clears information whether an error occurred previously and print aggregated message summary.
SAX-handler base for SUMO-files.
SAX-reader encapsulation containing binary reader.
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
static int myNextFreeReader
Information whether the reader is parsing.
Definition XMLSubSys.h:152
static std::vector< SUMOSAXReader * > myReaders
The XML Readers used for repeated parsing.
Definition XMLSubSys.h:149
static void setHandler(GenericSAXHandler &handler)
Sets the given handler for the default reader.
static std::string myValidationScheme
Information whether built reader/parser shall validate XML-documents against schemata.
Definition XMLSubSys.h:155
static void setValidation(const std::string &validationScheme, const std::string &netValidationScheme, const std::string &routeValidationScheme)
Enables or disables validation.
Definition XMLSubSys.cpp:66
static XERCES_CPP_NAMESPACE::XMLGrammarPool * myGrammarPool
Schema cache to be used for grammars which are not declared.
Definition XMLSubSys.h:164
static SUMOSAXReader * getSAXReader(SUMOSAXHandler &handler, const bool isNet=false, const bool isRoute=false)
Builds a reader and assigns the handler to it.
static void close()
Closes the xml-subsystem.
static void init()
Initialises the xml-subsystem.
Definition XMLSubSys.cpp:55
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false, const bool isRoute=false, const bool isExternal=false, const bool catchExceptions=true)
Runs the given handler on the given file; returns if everything's ok.
static std::string myRouteValidationScheme
Information whether built reader/parser shall validate SUMO routes against schemata.
Definition XMLSubSys.h:161
static std::string myNetValidationScheme
Information whether built reader/parser shall validate SUMO networks against schemata.
Definition XMLSubSys.h:158