Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/xml/XMLSubSys.cpp
169678 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2002-2025 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
/****************************************************************************/
14
/// @file XMLSubSys.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Jakob Erdmann
17
/// @author Michael Behrisch
18
/// @date Mon, 1 Jul 2002
19
///
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>
28
#include <utils/common/FileHelpers.h>
29
#include <utils/common/MsgHandler.h>
30
#include <utils/common/StringUtils.h>
31
#include "SUMOSAXHandler.h"
32
#include "SUMOSAXReader.h"
33
#include "XMLSubSys.h"
34
35
using XERCES_CPP_NAMESPACE::SAX2XMLReader;
36
using XERCES_CPP_NAMESPACE::XMLPlatformUtils;
37
using XERCES_CPP_NAMESPACE::XMLReaderFactory;
38
39
40
// ===========================================================================
41
// static member variables
42
// ===========================================================================
43
std::vector<SUMOSAXReader*> XMLSubSys::myReaders;
44
int XMLSubSys::myNextFreeReader;
45
std::string XMLSubSys::myValidationScheme = "local";
46
std::string XMLSubSys::myNetValidationScheme = "local";
47
std::string XMLSubSys::myRouteValidationScheme = "local";
48
XERCES_CPP_NAMESPACE::XMLGrammarPool* XMLSubSys::myGrammarPool = nullptr;
49
bool XMLSubSys::myNeedsValidationWarning = true;
50
51
52
// ===========================================================================
53
// method definitions
54
// ===========================================================================
55
void
56
XMLSubSys::init() {
57
try {
58
XMLPlatformUtils::Initialize();
59
myNextFreeReader = 0;
60
} catch (const XERCES_CPP_NAMESPACE::XMLException& e) {
61
throw ProcessError("Error during XML-initialization:\n " + StringUtils::transcode(e.getMessage()));
62
}
63
}
64
65
66
std::string
67
XMLSubSys::warnLocalScheme(const std::string& newScheme, const bool haveSUMO_HOME) {
68
if (newScheme != "never" && newScheme != "auto" && newScheme != "always" && newScheme != "local") {
69
throw ProcessError("Unknown xml validation scheme + '" + newScheme + "'.");
70
}
71
if (!haveSUMO_HOME && newScheme == "local") {
72
if (myNeedsValidationWarning) {
73
WRITE_WARNING(TL("Environment variable SUMO_HOME is not set properly, disabling XML validation. Set 'auto' or 'always' for web lookups."));
74
myNeedsValidationWarning = false;
75
}
76
return "never";
77
}
78
return newScheme;
79
}
80
81
82
void
83
XMLSubSys::setValidation(const std::string& validationScheme, const std::string& netValidationScheme, const std::string& routeValidationScheme) {
84
const char* sumoPath = std::getenv("SUMO_HOME");
85
const bool haveSUMO_HOME = sumoPath != nullptr && FileHelpers::isReadable(sumoPath + std::string("/data/xsd/net_file.xsd"));
86
myValidationScheme = warnLocalScheme(validationScheme, haveSUMO_HOME);
87
myNetValidationScheme = warnLocalScheme(netValidationScheme, haveSUMO_HOME);
88
myRouteValidationScheme = warnLocalScheme(routeValidationScheme, haveSUMO_HOME);
89
if (myGrammarPool == nullptr &&
90
(myValidationScheme != "never" ||
91
myNetValidationScheme != "never" ||
92
myRouteValidationScheme != "never")) {
93
if (!haveSUMO_HOME) {
94
if (myNeedsValidationWarning) {
95
WRITE_WARNING(TL("Environment variable SUMO_HOME is not set properly, XML validation will fail or use slow website lookups."));
96
myNeedsValidationWarning = false;
97
}
98
return;
99
}
100
myGrammarPool = new XERCES_CPP_NAMESPACE::XMLGrammarPoolImpl(XMLPlatformUtils::fgMemoryManager);
101
SAX2XMLReader* parser(XMLReaderFactory::createXMLReader(XMLPlatformUtils::fgMemoryManager, myGrammarPool));
102
#if _XERCES_VERSION >= 30100
103
parser->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesHandleMultipleImports, true);
104
#endif
105
for (const char* const& filetype : {
106
"additional", "routes", "net"
107
}) {
108
const std::string file = sumoPath + std::string("/data/xsd/") + filetype + "_file.xsd";
109
if (!parser->loadGrammar(file.c_str(), XERCES_CPP_NAMESPACE::Grammar::SchemaGrammarType, true)) {
110
WRITE_WARNINGF(TL("Cannot read local schema '%'."), file);
111
}
112
}
113
delete parser;
114
}
115
}
116
117
118
void
119
XMLSubSys::close() {
120
for (std::vector<SUMOSAXReader*>::iterator i = myReaders.begin(); i != myReaders.end(); ++i) {
121
delete *i;
122
}
123
myReaders.clear();
124
delete myGrammarPool;
125
myGrammarPool = nullptr;
126
XMLPlatformUtils::Terminate();
127
StringUtils::resetTranscoder();
128
}
129
130
131
SUMOSAXReader*
132
XMLSubSys::getSAXReader(SUMOSAXHandler& handler, const bool isNet, const bool isRoute) {
133
std::string validationScheme = isNet ? myNetValidationScheme : myValidationScheme;
134
if (isRoute) {
135
validationScheme = myRouteValidationScheme;
136
}
137
return new SUMOSAXReader(handler, validationScheme, myGrammarPool);
138
}
139
140
141
void
142
XMLSubSys::setHandler(GenericSAXHandler& handler) {
143
myReaders[myNextFreeReader - 1]->setHandler(handler);
144
}
145
146
147
bool
148
XMLSubSys::runParser(GenericSAXHandler& handler, const std::string& file,
149
const bool isNet, const bool isRoute, const bool isExternal, const bool catchExceptions) {
150
MsgHandler::getErrorInstance()->clear();
151
std::string errorMsg = "";
152
try {
153
std::string validationScheme = isNet ? myNetValidationScheme : myValidationScheme;
154
if (isRoute) {
155
validationScheme = myRouteValidationScheme;
156
}
157
if (isExternal && validationScheme == "local") {
158
WRITE_MESSAGEF(TL("Disabling XML validation for external file '%'. Use 'auto' or 'always' to enable."), file);
159
validationScheme = "never";
160
}
161
if (myNextFreeReader == (int)myReaders.size()) {
162
myReaders.push_back(new SUMOSAXReader(handler, validationScheme, myGrammarPool));
163
} else {
164
myReaders[myNextFreeReader]->setValidation(validationScheme);
165
myReaders[myNextFreeReader]->setHandler(handler);
166
}
167
myNextFreeReader++;
168
std::string prevFile = handler.getFileName();
169
handler.setFileName(file);
170
myReaders[myNextFreeReader - 1]->parse(file);
171
handler.setFileName(prevFile);
172
myNextFreeReader--;
173
} catch (const ProcessError& e) {
174
if (catchExceptions) {
175
errorMsg = std::string(e.what()) != std::string("") ? e.what() : TL("Process Error");
176
} else {
177
throw;
178
}
179
} catch (const std::runtime_error& re) {
180
errorMsg = TLF("Runtime error: % while parsing '%'", re.what(), file);
181
} catch (const std::exception& ex) {
182
errorMsg = TLF("Error occurred: % while parsing '%'", ex.what(), file);
183
} catch (const XERCES_CPP_NAMESPACE::SAXException& e) {
184
errorMsg = TLF("SAX error occurred while parsing '%':\n %", file, StringUtils::transcode(e.getMessage()));
185
} catch (...) {
186
errorMsg = TLF("Unspecified error occurred while parsing '%'", file);
187
}
188
if (errorMsg != "") {
189
if (catchExceptions) {
190
WRITE_ERROR(errorMsg);
191
} else {
192
throw ProcessError(errorMsg);
193
}
194
}
195
return !MsgHandler::getErrorInstance()->wasInformed();
196
}
197
198
199
/****************************************************************************/
200
201