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
34using XERCES_CPP_NAMESPACE::SAX2XMLReader;
35using XERCES_CPP_NAMESPACE::XMLPlatformUtils;
36using XERCES_CPP_NAMESPACE::XMLReaderFactory;
37
38
39// ===========================================================================
40// static member variables
41// ===========================================================================
42std::vector<SUMOSAXReader*> XMLSubSys::myReaders;
44std::string XMLSubSys::myValidationScheme = "local";
45std::string XMLSubSys::myNetValidationScheme = "local";
46std::string XMLSubSys::myRouteValidationScheme = "local";
47XERCES_CPP_NAMESPACE::XMLGrammarPool* XMLSubSys::myGrammarPool = nullptr;
48
49
50// ===========================================================================
51// method definitions
52// ===========================================================================
53void
55 try {
56 XMLPlatformUtils::Initialize();
58 } catch (const XERCES_CPP_NAMESPACE::XMLException& e) {
59 throw ProcessError("Error during XML-initialization:\n " + StringUtils::transcode(e.getMessage()));
60 }
61}
62
63
64void
65XMLSubSys::setValidation(const std::string& validationScheme, const std::string& netValidationScheme, const std::string& routeValidationScheme) {
66 if (validationScheme != "never" && validationScheme != "auto" && validationScheme != "always" && validationScheme != "local") {
67 throw ProcessError("Unknown xml validation scheme + '" + validationScheme + "'.");
68 }
69 myValidationScheme = validationScheme;
70 if (netValidationScheme != "never" && netValidationScheme != "auto" && netValidationScheme != "always" && netValidationScheme != "local") {
71 throw ProcessError("Unknown network validation scheme + '" + netValidationScheme + "'.");
72 }
73 myNetValidationScheme = netValidationScheme;
74 if (routeValidationScheme != "never" && routeValidationScheme != "auto" && routeValidationScheme != "always" && routeValidationScheme != "local") {
75 throw ProcessError("Unknown route validation scheme + '" + routeValidationScheme + "'.");
76 }
77 myRouteValidationScheme = routeValidationScheme;
78 if (myGrammarPool == nullptr &&
79 (myValidationScheme != "never" ||
80 myNetValidationScheme != "never" ||
81 myRouteValidationScheme != "never")) {
82 myGrammarPool = new XERCES_CPP_NAMESPACE::XMLGrammarPoolImpl(XMLPlatformUtils::fgMemoryManager);
83 SAX2XMLReader* parser(XMLReaderFactory::createXMLReader(XMLPlatformUtils::fgMemoryManager, myGrammarPool));
84#if _XERCES_VERSION >= 30100
85 parser->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesHandleMultipleImports, true);
86#endif
87 const char* sumoPath = std::getenv("SUMO_HOME");
88 if (sumoPath == nullptr) {
89 WRITE_WARNING(TL("Environment variable SUMO_HOME is not set, XML validation will fail or use slow website lookups."));
90 return;
91 }
92 if (StringUtils::startsWith(sumoPath, "http:") || StringUtils::startsWith(sumoPath, "https:") || StringUtils::startsWith(sumoPath, "ftp:")) {
93 throw ProcessError("SUMO_HOME looks like an URL, aborting to avoid inadvertent network access.");
94 }
95 for (const char* const& filetype : {
96 "additional", "routes", "net"
97 }) {
98 const std::string file = sumoPath + std::string("/data/xsd/") + filetype + "_file.xsd";
99 if (!parser->loadGrammar(file.c_str(), XERCES_CPP_NAMESPACE::Grammar::SchemaGrammarType, true)) {
100 WRITE_WARNING("Cannot read local schema '" + file + "'.");
101 }
102 }
103 }
104}
105
106
107void
109 for (std::vector<SUMOSAXReader*>::iterator i = myReaders.begin(); i != myReaders.end(); ++i) {
110 delete *i;
111 }
112 myReaders.clear();
113 delete myGrammarPool;
114 myGrammarPool = nullptr;
115 XMLPlatformUtils::Terminate();
117}
118
119
121XMLSubSys::getSAXReader(SUMOSAXHandler& handler, const bool isNet, const bool isRoute) {
122 std::string validationScheme = isNet ? myNetValidationScheme : myValidationScheme;
123 if (isRoute) {
124 validationScheme = myRouteValidationScheme;
125 }
126 return new SUMOSAXReader(handler, validationScheme, myGrammarPool);
127}
128
129
130void
132 myReaders[myNextFreeReader - 1]->setHandler(handler);
133}
134
135
136bool
137XMLSubSys::runParser(GenericSAXHandler& handler, const std::string& file,
138 const bool isNet, const bool isRoute) {
140 try {
141 std::string validationScheme = isNet ? myNetValidationScheme : myValidationScheme;
142 if (isRoute) {
143 validationScheme = myRouteValidationScheme;
144 }
145 if (myNextFreeReader == (int)myReaders.size()) {
146 myReaders.push_back(new SUMOSAXReader(handler, validationScheme, myGrammarPool));
147 } else {
148 myReaders[myNextFreeReader]->setValidation(validationScheme);
149 myReaders[myNextFreeReader]->setHandler(handler);
150 }
152 std::string prevFile = handler.getFileName();
153 handler.setFileName(file);
154 myReaders[myNextFreeReader - 1]->parse(file);
155 handler.setFileName(prevFile);
157 } catch (ProcessError& e) {
158 WRITE_ERROR(std::string(e.what()) != std::string("") ? std::string(e.what()) : std::string("Process Error"));
159 return false;
160 } catch (const std::runtime_error& re) {
161 WRITE_ERROR("Runtime error: " + std::string(re.what()) + " while parsing '" + file + "'");
162 return false;
163 } catch (const std::exception& ex) {
164 WRITE_ERROR("Error occurred: " + std::string(ex.what()) + " while parsing '" + file + "'");
165 return false;
166 } catch (...) {
167 WRITE_ERROR("Unspecified error occurred wile parsing '" + file + "'");
168 return false;
169 }
171}
172
173
174/****************************************************************************/
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:274
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:265
#define TL(string)
Definition: MsgHandler.h:282
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:321
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:79
virtual void clear(bool resetInformed=true)
Clears information whether an error occurred previously and print aggregated message summary.
Definition: MsgHandler.cpp:161
SAX-handler base for SUMO-files.
SAX-reader encapsulation containing binary reader.
Definition: SUMOSAXReader.h:53
static void resetTranscoder()
must be called when shutting down the xml subsystem
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
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:140
static int myNextFreeReader
Information whether the reader is parsing.
Definition: XMLSubSys.h:149
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:131
static std::string myValidationScheme
Information whether built reader/parser shall validate XML-documents against schemata.
Definition: XMLSubSys.h:152
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:121
static void close()
Closes the xml-subsystem.
Definition: XMLSubSys.cpp:108
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:137
static std::string myRouteValidationScheme
Information whether built reader/parser shall validate SUMO routes against schemata.
Definition: XMLSubSys.h:158
static std::string myNetValidationScheme
Information whether built reader/parser shall validate SUMO networks against schemata.
Definition: XMLSubSys.h:155