Eclipse SUMO - Simulation of Urban MObility
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
CommonHandler.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-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/****************************************************************************/
18// Collection of functions used in handlers
19/****************************************************************************/
20#include <config.h>
21
24#include <utils/xml/XMLSubSys.h>
25
26#include "CommonHandler.h"
27
28
29// ===========================================================================
30// method definitions
31// ===========================================================================
32
33CommonHandler::CommonHandler(const std::string& filename) :
34 myFilename(filename) {
35}
36
37
39
40
41bool
45
46
47void
49 // declare Ok Flag
50 bool parsedOk = true;
51 // get key
52 const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, parsedOk);
53 // get SumoBaseObject parent
55 // check parent
56 if ((SumoBaseObjectParent == nullptr) || (SumoBaseObjectParent->getTag() == SUMO_TAG_ROOTFILE)) {
57 writeError(TL("Parameters must be defined within an object"));
58 } else if (SumoBaseObjectParent->getTag() == SUMO_TAG_PARAM) {
59 writeError(TL("Parameters cannot be defined within another parameter."));
60 } else if ((SumoBaseObjectParent->getTag() != SUMO_TAG_ERROR) && parsedOk) {
61 // get tag str
62 const std::string parentTagStr = toString(SumoBaseObjectParent->getTag());
63 // circumventing empty string value
64 const std::string value = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
65 // show warnings if values are invalid
66 if (key.empty()) {
67 writeError(TLF("Error parsing key from % generic parameter. Key cannot be empty", parentTagStr));
69 writeError(TLF("Error parsing key from % generic parameter. Key contains invalid characters", parentTagStr));
70 } else {
71 // insert parameter in SumoBaseObjectParent
72 SumoBaseObjectParent->addParameter(key, value);
73 }
74 }
75}
76
77
80 // locate route in childrens
81 for (const auto& embeddedRoute : sumoBaseObject->getSumoBaseObjectChildren()) {
82 if ((embeddedRoute->getTag() == SUMO_TAG_ROUTE) && (!embeddedRoute->hasStringAttribute(SUMO_ATTR_ID))) {
83 return embeddedRoute;
84 }
85 }
86 return nullptr;
87}
88
89
90void
91CommonHandler::checkParsedParent(const SumoXMLTag currentTag, const std::vector<SumoXMLTag>& parentTags, bool& ok) {
92 if (parentTags.size() > 0) {
93 std::string tagsStr;
94 for (auto it = parentTags.begin(); it != parentTags.end(); it++) {
95 tagsStr.append(toString(*it));
96 if ((it + 1) != parentTags.end()) {
97 if ((it + 2) != parentTags.end()) {
98 tagsStr.append(", ");
99 } else {
100 tagsStr.append(" or ");
101 }
102 }
103 }
104 // obtain parent
106 if (parent == nullptr) {
107 ok = writeError(TLF("'%' must be defined within the definition of a %.", toString(currentTag), tagsStr));
108 } else if ((parent->getTag() != SUMO_TAG_ERROR) && std::find(parentTags.begin(), parentTags.end(), parent->getTag()) == parentTags.end()) {
109 if (parent->hasStringAttribute(SUMO_ATTR_ID)) {
110 ok = writeError(TLF("'%' must be defined within the definition of a '%' (found % '%').", toString(currentTag), tagsStr,
111 toString(parent->getTag()), parent->getStringAttribute(SUMO_ATTR_ID)));
112 } else {
113 ok = writeError(TLF("'%' must be defined within the definition of a '%' (found %).", toString(currentTag), tagsStr,
114 toString(parent->getTag())));
115 }
116 }
117 }
118}
119
120
121bool
122CommonHandler::checkListOfVehicleTypes(const SumoXMLTag tag, const std::string& id, const std::vector<std::string>& vTypeIDs) {
123 for (const auto& vTypeID : vTypeIDs) {
124 if (!SUMOXMLDefinitions::isValidTypeID(vTypeID)) {
125 return writeError(TLF("Could not build % with ID '%' in netedit; '%' ist not a valid vType ID.", toString(tag), id, vTypeID));
126 }
127 }
128 return true;
129}
130
131
132bool
134 if (obj->getParentSumoBaseObject() == nullptr) {
135 return false;
137 return true;
139 return true;
140 } else {
141 return false;
142 }
143}
144
145
146bool
148 if (obj == nullptr) {
149 return false;
150 } else if (!obj->hasStringAttribute(SUMO_ATTR_ID)) {
151 return false;
152 } else {
153 SumoXMLTag tag = obj->getTag();
154 const std::string id = obj->getStringAttribute(SUMO_ATTR_ID);
155 const bool hasRoute = obj->hasStringAttribute(SUMO_ATTR_ROUTE);
156 const bool hasEmbeddedRoute = (getEmbeddedRoute(obj) != nullptr);
157 const bool overEdges = obj->hasStringAttribute(SUMO_ATTR_FROM) && obj->hasStringAttribute(SUMO_ATTR_TO);
160 if (hasRoute && hasEmbeddedRoute) {
161 return writeError(TLF("Could not build % with ID '%' in netedit; Cannot have an external route and an embedded route in the same definition.", toString(tag), id));
162 }
163 if ((overEdges + overJunctions + overTAZs) > 1) {
164 return writeError(TLF("Could not build % with ID '%' in netedit; Cannot have multiple from-to attributes.", toString(tag), id));
165 }
166 if ((hasRoute + hasEmbeddedRoute + overEdges + overJunctions + overTAZs) > 1) {
167 return writeError(TLF("Could not build % with ID '%' in netedit; Cannot have from-to attributes and route attributes in the same definition.", toString(tag), id));
168 }
169 if ((hasRoute + hasEmbeddedRoute + overEdges + overJunctions + overTAZs) == 0) {
170 return writeError(TLF("Could not build % with ID '%' in netedit; Requires either a route or an embedded route or a from-to attribute (Edges, junctions or TAZs).", toString(tag), id));
171 }
172 return true;
173 }
174}
175
176
177bool
179 const auto parent = obj->getParentSumoBaseObject();
180 if (parent == nullptr) {
181 return false;
182 } else if (!parent->wasCreated()) {
183 return false;
184 } else if ((parent->getTag() == SUMO_TAG_PERSON) || (parent->getTag() == SUMO_TAG_PERSONFLOW)) {
185 return true;
186 } else {
187 return false;
188 }
189}
190
191
192bool
194 const auto parent = obj->getParentSumoBaseObject();
195 if (parent == nullptr) {
196 return false;
197 } else if (!parent->wasCreated()) {
198 return false;
199 } else if ((parent->getTag() == SUMO_TAG_CONTAINER) || (parent->getTag() == SUMO_TAG_CONTAINERFLOW)) {
200 return true;
201 } else {
202 return false;
203 }
204}
205
206
207bool
209 const auto parent = obj->getParentSumoBaseObject();
210 if (parent == nullptr) {
211 return false;
212 } else if (!parent->wasCreated()) {
213 return false;
214 } else if ((parent->getTag() == SUMO_TAG_ROUTE) || (parent->getTag() == SUMO_TAG_TRIP) ||
215 (parent->getTag() == SUMO_TAG_VEHICLE) || (parent->getTag() == SUMO_TAG_FLOW) ||
216 (parent->getTag() == SUMO_TAG_PERSON) || (parent->getTag() == SUMO_TAG_PERSONFLOW) ||
217 (parent->getTag() == SUMO_TAG_CONTAINER) || (parent->getTag() == SUMO_TAG_CONTAINERFLOW)) {
218 return true;
219 } else {
220 return false;
221 }
222}
223
224
225bool
226CommonHandler::checkNegative(const SumoXMLTag tag, const std::string& id, const SumoXMLAttr attribute, const int value, const bool canBeZero) {
227 if (canBeZero) {
228 if (value < 0) {
229 return writeError(TLF("Could not build % with ID '%' in netedit; Attribute % cannot be negative.", toString(tag), id, toString(attribute)));
230 } else {
231 return true;
232 }
233 } else {
234 if (value <= 0) {
235 return writeError(TLF("Could not build % with ID '%' in netedit; Attribute % must be greather than zero.", toString(tag), id, toString(attribute)));
236 } else {
237 return true;
238 }
239 }
240}
241
242
243bool
244CommonHandler::checkNegative(const SumoXMLTag tag, const std::string& id, const SumoXMLAttr attribute, const double value, const bool canBeZero) {
245 if (canBeZero) {
246 if (value < 0) {
247 return writeError(TLF("Could not build % with ID '%' in netedit; Attribute % cannot be negative (%).", toString(tag), id, toString(attribute), toString(value)));
248 } else {
249 return true;
250 }
251 } else {
252 if (value <= 0) {
253 return writeError(TLF("Could not build % with ID '%' in netedit; Attribute % must be greather than zero (%).", toString(tag), id, toString(attribute), toString(value)));
254 } else {
255 return true;
256 }
257 }
258}
259
260
261bool
262CommonHandler::checkNegative(const SumoXMLTag tag, const std::string& id, const SumoXMLAttr attribute, const SUMOTime value, const bool canBeZero) {
263 if (canBeZero) {
264 if (value < 0) {
265 return writeError(TLF("Could not build % with ID '%' in netedit; Attribute % cannot be negative (%).", toString(tag), id, toString(attribute), time2string(value)));
266 } else {
267 return true;
268 }
269 } else {
270 if (value <= 0) {
271 return writeError(TLF("Could not build % with ID '%' in netedit; Attribute % must be greather than zero (%).", toString(tag), id, toString(attribute), time2string(value)));
272 } else {
273 return true;
274 }
275 }
276}
277
278
279bool
280CommonHandler::checkFileName(const SumoXMLTag tag, const std::string& id, const SumoXMLAttr attribute, const std::string& value) {
282 return true;
283 } else {
284 return writeError(TLF("Could not build % with ID '%' in netedit; % is invalid % ()", toString(tag), id, toString(attribute), value));
285 }
286}
287
288
289bool
290CommonHandler::checkValidAdditionalID(const SumoXMLTag tag, const std::string& value) {
291 if (value.empty()) {
292 return writeError(TLF("Could not build %; ID cannot be empty", toString(tag)));
293 } else if (!SUMOXMLDefinitions::isValidVehicleID(value)) {
294 return writeError(TLF("Could not build % with ID '%' in netedit; ID contains invalid characters.", toString(tag), value));
295 } else {
296 return true;
297 }
298}
299
300
301bool
302CommonHandler::checkValidDetectorID(const SumoXMLTag tag, const std::string& value) {
303 if (value.empty()) {
304 return writeError(TLF("Could not build %; ID cannot be empty", toString(tag)));
305 } else if (!SUMOXMLDefinitions::isValidDetectorID(value)) {
306 return writeError(TLF("Could not build % with ID '%' in netedit; detector ID contains invalid characters.", toString(tag), value));
307 } else {
308 return true;
309 }
310}
311
312
313bool
314CommonHandler::checkValidDemandElementID(const SumoXMLTag tag, const std::string& value) {
315 if (value.empty()) {
316 return writeError(TLF("Could not build %; ID cannot be empty", toString(tag)));
317 } else if (!SUMOXMLDefinitions::isValidVehicleID(value)) {
318 return writeError(TLF("Could not build % with ID '%' in netedit; ID contains invalid characters.", toString(tag), value));
319 } else {
320 return true;
321 }
322}
323
324
325void
326CommonHandler::writeWarningOverwritting(const SumoXMLTag tag, const std::string& id) {
327 WRITE_WARNING(TLF("Overwritting % with ID '%'", toString(tag), id));
328}
329
330
331bool
332CommonHandler::writeWarningDuplicated(const SumoXMLTag tag, const std::string& id, const SumoXMLTag checkedTag) {
333 return writeError(TLF("Could not build % with ID '%' in netedit; Found another % with the same ID.", toString(tag), id, toString(checkedTag)));
334}
335
336
337bool
338CommonHandler::writeError(const std::string& error) {
339 WRITE_ERROR(error);
341 return false;
342}
343
344
345bool
346CommonHandler::writeErrorInvalidPosition(const SumoXMLTag tag, const std::string& id) {
347 return writeError(TLF("Could not build % with ID '%' in netedit; Invalid position over lane.", toString(tag), id));
348}
349
350
351bool
352CommonHandler::writeErrorEmptyEdges(const SumoXMLTag tag, const std::string& id) {
353 return writeError(TLF("Could not build % with ID '%' in netedit; List of edges cannot be empty.", toString(tag), id));
354}
355
356
357bool
358CommonHandler::writeErrorInvalidLanes(const SumoXMLTag tag, const std::string& id) {
359 return writeError(TLF("Could not build % with ID '%' in netedit; List of lanes isn't valid.", toString(tag), id));
360}
361
362
363bool
364CommonHandler::writeErrorInvalidParent(const SumoXMLTag tag, const std::string& id, const SumoXMLTag parentTag, const std::string& parentID) {
365 return writeError(TLF("Could not build % with ID '%' in netedit; % parent with ID '%' doesn't exist.", toString(tag), id, toString(parentTag), parentID));
366}
367
368
369bool
370CommonHandler::writeErrorInvalidParent(const SumoXMLTag tag, const SumoXMLTag parentTag, const std::string& parentID) {
371 return writeError(TLF("Could not build % in netedit; % parent with ID '%' doesn't exist.", toString(tag), toString(parentTag), parentID));
372}
373
374
375bool
377 return writeError(TLF("Could not build % in netedit; % parent doesn't exist.", toString(tag), toString(parentTag)));
378}
379
380/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define WRITE_ERROR(msg)
Definition MsgHandler.h:296
#define WRITE_WARNING(msg)
Definition MsgHandler.h:287
#define TL(string)
Definition MsgHandler.h:305
#define TLF(string,...)
Definition MsgHandler.h:307
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition SUMOTime.cpp:91
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_CONTAINERFLOW
@ SUMO_TAG_ROOTFILE
root file
@ SUMO_TAG_VEHICLE
description of a vehicle
@ SUMO_TAG_ROUTE_DISTRIBUTION
distribution of a route
@ SUMO_TAG_FLOW
a flow definition using from and to edges or a route
@ SUMO_TAG_CONTAINER
@ SUMO_TAG_ROUTE
description of a route
@ SUMO_TAG_VTYPE_DISTRIBUTION
distribution of a vehicle type
@ SUMO_TAG_PARAM
parameter associated to a certain key
@ SUMO_TAG_ERROR
tag used for indicate that there is an error (usually loading elements in handlers)
@ SUMO_TAG_PERSON
@ SUMO_TAG_PERSONFLOW
@ SUMO_TAG_TRIP
a single trip definition (used by router)
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_FROM_JUNCTION
@ SUMO_ATTR_VALUE
@ SUMO_ATTR_TO_JUNCTION
@ SUMO_ATTR_TO_TAZ
@ SUMO_ATTR_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_FROM_TAZ
@ SUMO_ATTR_ROUTE
@ SUMO_ATTR_ID
@ SUMO_ATTR_KEY
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
bool checkStopParents(CommonXMLStructure::SumoBaseObject *obj)
check stop parents
CommonXMLStructure::SumoBaseObject * getEmbeddedRoute(const CommonXMLStructure::SumoBaseObject *sumoBaseObject) const
get embedded route from children
virtual ~CommonHandler()
Destructor.
void checkParsedParent(const SumoXMLTag currentTag, const std::vector< SumoXMLTag > &parentTags, bool &ok)
check parsed parents
bool checkContainerPlanParents(CommonXMLStructure::SumoBaseObject *obj)
check container plan parents
bool writeError(const std::string &error)
write error and enable error creating element
bool myErrorCreatingElement
flag for mark if a element wasn't created
CommonHandler()=delete
invalidate default onstructor
bool checkValidDetectorID(const SumoXMLTag tag, const std::string &value)
check if the given detector ID is valid
bool writeErrorInvalidParent(const SumoXMLTag tag, const std::string &id, const SumoXMLTag parentTag, const std::string &parentID)
write error "invalid parent element" giving ids of current and parent element
bool checkListOfVehicleTypes(const SumoXMLTag tag, const std::string &id, const std::vector< std::string > &vTypeIDs)
check list of IDs
void parseParameters(const SUMOSAXAttributes &attrs)
parse generic parameters
bool writeWarningDuplicated(const SumoXMLTag tag, const std::string &id, const SumoXMLTag checkedTag)
write warning duplicated element
void writeWarningOverwritting(const SumoXMLTag tag, const std::string &id)
write warning overwritting element
bool writeErrorEmptyEdges(const SumoXMLTag tag, const std::string &id)
write error "empty edges"
bool checkWithinDistribution(CommonXMLStructure::SumoBaseObject *obj)
check if the given object is within a distribution (VType or routes)
bool checkValidAdditionalID(const SumoXMLTag tag, const std::string &value)
check if the given additional ID is valid
bool checkFileName(const SumoXMLTag tag, const std::string &id, const SumoXMLAttr attribute, const std::string &value)
check if the given filename is valid
bool writeErrorInvalidPosition(const SumoXMLTag tag, const std::string &id)
write error "invalid position"
CommonXMLStructure myCommonXMLStructure
common XML Structure
bool writeErrorInvalidLanes(const SumoXMLTag tag, const std::string &id)
write error "invalid list of lanes"
bool checkVehicleParents(CommonXMLStructure::SumoBaseObject *obj)
check vehicle parents
bool checkNegative(const SumoXMLTag tag, const std::string &id, const SumoXMLAttr attribute, const int value, const bool canBeZero)
check if the given int value is NOT negative
bool checkValidDemandElementID(const SumoXMLTag tag, const std::string &value)
check if the given demand elmement ID is valid
bool isErrorCreatingElement() const
get flag for mark if a element wasn't created
bool checkPersonPlanParents(CommonXMLStructure::SumoBaseObject *obj)
check person plan parents
bool hasStringAttribute(const SumoXMLAttr attr) const
has function
SumoBaseObject * getParentSumoBaseObject() const
get pointer to mySumoBaseObjectParent SumoBaseObject (if is null, then is the root)
SumoXMLTag getTag() const
get XML myTag
const std::string & getStringAttribute(const SumoXMLAttr attr) const
get string attribute
const std::vector< SumoBaseObject * > & getSumoBaseObjectChildren() const
get SumoBaseObject children
CommonXMLStructure::SumoBaseObject * getCurrentSumoBaseObject() const
get current editedSumoBaseObject
Encapsulated SAX-Attributes.
virtual std::string getString(int id, bool *isPresent=nullptr) const =0
Returns the string-value of the named (by its enum-value) attribute.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
static bool isValidTypeID(const std::string &value)
whether the given string is a valid id for an edge or vehicle type
static bool isValidVehicleID(const std::string &value)
whether the given string is a valid id for a vehicle or flow
static bool isValidFilename(const std::string &value)
whether the given string is a valid attribute for a filename (for example, a name)
static bool isValidDetectorID(const std::string &value)
whether the given string is a valid id for an detector
static bool isValidParameterKey(const std::string &value)
whether the given string is a valid key for a parameter