LCOV - code coverage report
Current view: top level - src/utils/handlers - CommonHandler.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 0.0 % 175 0
Test Date: 2025-11-13 15:38:19 Functions: 0.0 % 35 0

            Line data    Source code
       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              : /****************************************************************************/
      14              : /// @file    CommonHandler.cpp
      15              : /// @author  Pablo Alvarez Lopez
      16              : /// @date    Dec 2024
      17              : ///
      18              : // Collection of functions used in handlers
      19              : /****************************************************************************/
      20              : #include <config.h>
      21              : 
      22              : #include <utils/common/MsgHandler.h>
      23              : #include <utils/common/StringUtils.h>
      24              : #include <utils/xml/XMLSubSys.h>
      25              : 
      26              : #include "CommonHandler.h"
      27              : 
      28              : 
      29              : // ===========================================================================
      30              : // method definitions
      31              : // ===========================================================================
      32              : 
      33            0 : CommonHandler::CommonHandler(const std::string& filename) :
      34            0 :     myFilename(filename) {
      35            0 : }
      36              : 
      37              : 
      38            0 : CommonHandler::~CommonHandler() {}
      39              : 
      40              : 
      41              : void
      42            0 : CommonHandler::forceOverwriteElements() {
      43            0 :     myOverwriteElements = true;
      44            0 : }
      45              : 
      46              : 
      47              : void
      48            0 : CommonHandler::forceRemainElements() {
      49            0 :     myRemainElements = true;
      50            0 : }
      51              : 
      52              : 
      53              : void
      54            0 : CommonHandler::abortLoading() {
      55            0 :     myAbortLoading = true;
      56            0 : }
      57              : 
      58              : 
      59              : bool
      60            0 : CommonHandler::isErrorCreatingElement() const {
      61            0 :     return myErrorCreatingElement;
      62              : }
      63              : 
      64              : 
      65              : bool
      66            0 : CommonHandler::isForceOverwriteElements() const {
      67            0 :     return myOverwriteElements;
      68              : }
      69              : 
      70              : 
      71              : bool
      72            0 : CommonHandler::isForceRemainElements() const {
      73            0 :     return myRemainElements;
      74              : }
      75              : 
      76              : 
      77              : bool
      78            0 : CommonHandler::isAbortLoading() const {
      79            0 :     return myAbortLoading;
      80              : }
      81              : 
      82              : 
      83              : void
      84            0 : CommonHandler::parseParameters(const SUMOSAXAttributes& attrs) {
      85              :     // declare Ok Flag
      86            0 :     bool parsedOk = true;
      87              :     // get key
      88            0 :     const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, parsedOk);
      89              :     // get SumoBaseObject parent
      90            0 :     CommonXMLStructure::SumoBaseObject* SumoBaseObjectParent = myCommonXMLStructure.getCurrentSumoBaseObject()->getParentSumoBaseObject();
      91              :     // check parent
      92            0 :     if ((SumoBaseObjectParent == nullptr) || (SumoBaseObjectParent->getTag() == SUMO_TAG_ROOTFILE)) {
      93            0 :         writeError(TL("Parameters must be defined within an object"));
      94            0 :     } else if (SumoBaseObjectParent->getTag() == SUMO_TAG_PARAM) {
      95            0 :         writeError(TL("Parameters cannot be defined within another parameter."));
      96            0 :     } else if ((SumoBaseObjectParent->getTag() != SUMO_TAG_ERROR) && parsedOk) {
      97              :         // get tag str
      98            0 :         const std::string parentTagStr = toString(SumoBaseObjectParent->getTag());
      99              :         // circumventing empty string value
     100            0 :         const std::string value = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
     101              :         // show warnings if values are invalid
     102            0 :         if (key.empty()) {
     103            0 :             writeError(TLF("Error parsing key from % generic parameter. Key cannot be empty", parentTagStr));
     104            0 :         } else if (!SUMOXMLDefinitions::isValidParameterKey(key)) {
     105            0 :             writeError(TLF("Error parsing key from % generic parameter. Key contains invalid characters", parentTagStr));
     106              :         } else {
     107              :             // insert parameter in SumoBaseObjectParent
     108            0 :             SumoBaseObjectParent->addParameter(key, value);
     109              :         }
     110              :     }
     111            0 : }
     112              : 
     113              : 
     114              : CommonXMLStructure::SumoBaseObject*
     115            0 : CommonHandler::getEmbeddedRoute(const CommonXMLStructure::SumoBaseObject* sumoBaseObject) const {
     116              :     // locate route in childrens
     117            0 :     for (const auto& embeddedRoute : sumoBaseObject->getSumoBaseObjectChildren()) {
     118            0 :         if ((embeddedRoute->getTag() == SUMO_TAG_ROUTE) && (!embeddedRoute->hasStringAttribute(SUMO_ATTR_ID))) {
     119            0 :             return embeddedRoute;
     120              :         }
     121              :     }
     122              :     return nullptr;
     123              : }
     124              : 
     125              : 
     126              : void
     127            0 : CommonHandler::checkParsedParent(const SumoXMLTag currentTag, const std::vector<SumoXMLTag>& parentTags, bool& ok) {
     128            0 :     if (parentTags.size() > 0) {
     129              :         std::string tagsStr;
     130            0 :         for (auto it = parentTags.begin(); it != parentTags.end(); it++) {
     131            0 :             tagsStr.append(toString(*it));
     132            0 :             if ((it + 1) != parentTags.end()) {
     133            0 :                 if ((it + 2) != parentTags.end()) {
     134            0 :                     tagsStr.append(", ");
     135              :                 } else {
     136            0 :                     tagsStr.append(" or ");
     137              :                 }
     138              :             }
     139              :         }
     140              :         // obtain parent
     141            0 :         CommonXMLStructure::SumoBaseObject* const parent = myCommonXMLStructure.getCurrentSumoBaseObject()->getParentSumoBaseObject();
     142            0 :         if (parent == nullptr) {
     143            0 :             ok = writeError(TLF("'%' must be defined within the definition of a %.", toString(currentTag), tagsStr));
     144            0 :         } else if ((parent->getTag() != SUMO_TAG_ERROR) && std::find(parentTags.begin(), parentTags.end(), parent->getTag()) == parentTags.end()) {
     145            0 :             if (parent->hasStringAttribute(SUMO_ATTR_ID)) {
     146            0 :                 ok = writeError(TLF("'%' must be defined within the definition of a '%' (found % '%').", toString(currentTag), tagsStr,
     147              :                                     toString(parent->getTag()), parent->getStringAttribute(SUMO_ATTR_ID)));
     148              :             } else {
     149            0 :                 ok = writeError(TLF("'%' must be defined within the definition of a '%' (found %).", toString(currentTag), tagsStr,
     150              :                                     toString(parent->getTag())));
     151              :             }
     152              :         }
     153              :     }
     154            0 : }
     155              : 
     156              : 
     157              : bool
     158            0 : CommonHandler::checkListOfVehicleTypes(const SumoXMLTag tag, const std::string& id, const std::vector<std::string>& vTypeIDs) {
     159            0 :     for (const auto& vTypeID : vTypeIDs) {
     160            0 :         if (!SUMOXMLDefinitions::isValidTypeID(vTypeID)) {
     161            0 :             return writeError(TLF("Could not build % with ID '%' in netedit; '%' ist not a valid vType ID.", toString(tag), id, vTypeID));
     162              :         }
     163              :     }
     164              :     return true;
     165              : }
     166              : 
     167              : 
     168              : bool
     169            0 : CommonHandler::checkWithinDistribution(CommonXMLStructure::SumoBaseObject* obj) {
     170            0 :     if (obj->getParentSumoBaseObject() == nullptr) {
     171              :         return false;
     172            0 :     } else if (obj->getParentSumoBaseObject()->getTag() == SUMO_TAG_ROUTE_DISTRIBUTION) {
     173              :         return true;
     174            0 :     } else if (obj->getParentSumoBaseObject()->getTag() == SUMO_TAG_VTYPE_DISTRIBUTION) {
     175              :         return true;
     176              :     } else {
     177              :         return false;
     178              :     }
     179              : }
     180              : 
     181              : 
     182              : bool
     183            0 : CommonHandler::checkVehicleParents(CommonXMLStructure::SumoBaseObject* obj) {
     184            0 :     if (obj == nullptr) {
     185              :         return false;
     186            0 :     } else if (!obj->hasStringAttribute(SUMO_ATTR_ID)) {
     187              :         return false;
     188              :     } else {
     189            0 :         SumoXMLTag tag = obj->getTag();
     190            0 :         const std::string id = obj->getStringAttribute(SUMO_ATTR_ID);
     191            0 :         const bool hasRoute = obj->hasStringAttribute(SUMO_ATTR_ROUTE);
     192            0 :         const bool hasEmbeddedRoute = (getEmbeddedRoute(obj) != nullptr);
     193            0 :         const bool overEdges = obj->hasStringAttribute(SUMO_ATTR_FROM) && obj->hasStringAttribute(SUMO_ATTR_TO);
     194            0 :         const bool overJunctions = obj->hasStringAttribute(SUMO_ATTR_FROM_JUNCTION) && obj->hasStringAttribute(SUMO_ATTR_TO_JUNCTION);
     195            0 :         const bool overTAZs = obj->hasStringAttribute(SUMO_ATTR_FROM_TAZ) && obj->hasStringAttribute(SUMO_ATTR_TO_TAZ);
     196            0 :         if (hasRoute && hasEmbeddedRoute) {
     197            0 :             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));
     198              :         }
     199            0 :         if ((overEdges + overJunctions + overTAZs) > 1) {
     200            0 :             return writeError(TLF("Could not build % with ID '%' in netedit; Cannot have multiple from-to attributes.", toString(tag), id));
     201              :         }
     202            0 :         if ((hasRoute + hasEmbeddedRoute + overEdges + overJunctions + overTAZs) > 1) {
     203            0 :             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));
     204              :         }
     205            0 :         if ((hasRoute + hasEmbeddedRoute + overEdges + overJunctions + overTAZs) == 0) {
     206            0 :             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));
     207              :         }
     208              :         return true;
     209              :     }
     210              : }
     211              : 
     212              : 
     213              : bool
     214            0 : CommonHandler::checkPersonPlanParents(CommonXMLStructure::SumoBaseObject* obj) {
     215            0 :     const auto parent = obj->getParentSumoBaseObject();
     216            0 :     if (parent == nullptr) {
     217              :         return false;
     218            0 :     } else if (!parent->wasCreated()) {
     219              :         return false;
     220            0 :     } else if ((parent->getTag() == SUMO_TAG_PERSON) || (parent->getTag() == SUMO_TAG_PERSONFLOW)) {
     221            0 :         return true;
     222              :     } else {
     223              :         return false;
     224              :     }
     225              : }
     226              : 
     227              : 
     228              : bool
     229            0 : CommonHandler::checkContainerPlanParents(CommonXMLStructure::SumoBaseObject* obj) {
     230            0 :     const auto parent = obj->getParentSumoBaseObject();
     231            0 :     if (parent == nullptr) {
     232              :         return false;
     233            0 :     } else if (!parent->wasCreated()) {
     234              :         return false;
     235            0 :     } else if ((parent->getTag() == SUMO_TAG_CONTAINER) || (parent->getTag() == SUMO_TAG_CONTAINERFLOW)) {
     236            0 :         return true;
     237              :     } else {
     238              :         return false;
     239              :     }
     240              : }
     241              : 
     242              : 
     243              : bool
     244            0 : CommonHandler::checkStopParents(CommonXMLStructure::SumoBaseObject* obj) {
     245            0 :     const auto parent = obj->getParentSumoBaseObject();
     246            0 :     if (parent == nullptr) {
     247              :         return false;
     248            0 :     } else if (!parent->wasCreated()) {
     249              :         return false;
     250            0 :     } else if ((parent->getTag() == SUMO_TAG_ROUTE) || (parent->getTag() == SUMO_TAG_TRIP) ||
     251            0 :                (parent->getTag() == SUMO_TAG_VEHICLE) || (parent->getTag() == SUMO_TAG_FLOW) ||
     252            0 :                (parent->getTag() == SUMO_TAG_PERSON) || (parent->getTag() == SUMO_TAG_PERSONFLOW) ||
     253            0 :                (parent->getTag() == SUMO_TAG_CONTAINER) || (parent->getTag() == SUMO_TAG_CONTAINERFLOW)) {
     254            0 :         return true;
     255              :     } else {
     256              :         return false;
     257              :     }
     258              : }
     259              : 
     260              : 
     261              : bool
     262            0 : CommonHandler::checkNegative(const SumoXMLTag tag, const std::string& id, const SumoXMLAttr attribute, const int value, const bool canBeZero) {
     263            0 :     if (canBeZero) {
     264            0 :         if (value < 0) {
     265            0 :             return writeError(TLF("Could not build % with ID '%' in netedit; Attribute % cannot be negative.", toString(tag), id, toString(attribute)));
     266              :         } else {
     267              :             return true;
     268              :         }
     269              :     } else {
     270            0 :         if (value <= 0) {
     271            0 :             return writeError(TLF("Could not build % with ID '%' in netedit; Attribute % must be greather than zero.", toString(tag), id, toString(attribute)));
     272              :         } else {
     273              :             return true;
     274              :         }
     275              :     }
     276              : }
     277              : 
     278              : 
     279              : bool
     280            0 : CommonHandler::checkNegative(const SumoXMLTag tag, const std::string& id, const SumoXMLAttr attribute, const double value, const bool canBeZero) {
     281            0 :     if (canBeZero) {
     282            0 :         if (value < 0) {
     283            0 :             return writeError(TLF("Could not build % with ID '%' in netedit; Attribute % cannot be negative (%).", toString(tag), id, toString(attribute), toString(value)));
     284              :         } else {
     285              :             return true;
     286              :         }
     287              :     } else {
     288            0 :         if (value <= 0) {
     289            0 :             return writeError(TLF("Could not build % with ID '%' in netedit; Attribute % must be greather than zero (%).", toString(tag), id, toString(attribute), toString(value)));
     290              :         } else {
     291              :             return true;
     292              :         }
     293              :     }
     294              : }
     295              : 
     296              : 
     297              : bool
     298            0 : CommonHandler::checkNegative(const SumoXMLTag tag, const std::string& id, const SumoXMLAttr attribute, const SUMOTime value, const bool canBeZero) {
     299            0 :     if (canBeZero) {
     300            0 :         if (value < 0) {
     301            0 :             return writeError(TLF("Could not build % with ID '%' in netedit; Attribute % cannot be negative (%).", toString(tag), id, toString(attribute), time2string(value)));
     302              :         } else {
     303              :             return true;
     304              :         }
     305              :     } else {
     306            0 :         if (value <= 0) {
     307            0 :             return writeError(TLF("Could not build % with ID '%' in netedit; Attribute % must be greather than zero (%).", toString(tag), id, toString(attribute), time2string(value)));
     308              :         } else {
     309              :             return true;
     310              :         }
     311              :     }
     312              : }
     313              : 
     314              : 
     315              : bool
     316            0 : CommonHandler::checkFileName(const SumoXMLTag tag, const std::string& id, const SumoXMLAttr attribute, const std::string& value) {
     317            0 :     if (SUMOXMLDefinitions::isValidFilename(value)) {
     318              :         return true;
     319              :     } else {
     320            0 :         return writeError(TLF("Could not build % with ID '%' in netedit; % is invalid % ()", toString(tag), id, toString(attribute), value));
     321              :     }
     322              : }
     323              : 
     324              : 
     325              : bool
     326            0 : CommonHandler::checkValidAdditionalID(const SumoXMLTag tag, const std::string& value) {
     327            0 :     if (value.empty()) {
     328            0 :         return writeError(TLF("Could not build %; ID cannot be empty", toString(tag)));
     329            0 :     } else if (!SUMOXMLDefinitions::isValidVehicleID(value)) {
     330            0 :         return writeError(TLF("Could not build % with ID '%' in netedit; ID contains invalid characters.", toString(tag), value));
     331              :     } else {
     332              :         return true;
     333              :     }
     334              : }
     335              : 
     336              : 
     337              : bool
     338            0 : CommonHandler::checkValidDetectorID(const SumoXMLTag tag, const std::string& value) {
     339            0 :     if (value.empty()) {
     340            0 :         return writeError(TLF("Could not build %; ID cannot be empty", toString(tag)));
     341            0 :     } else if (!SUMOXMLDefinitions::isValidDetectorID(value)) {
     342            0 :         return writeError(TLF("Could not build % with ID '%' in netedit; detector ID contains invalid characters.", toString(tag), value));
     343              :     } else {
     344              :         return true;
     345              :     }
     346              : }
     347              : 
     348              : 
     349              : bool
     350            0 : CommonHandler::checkValidDemandElementID(const SumoXMLTag tag, const std::string& value) {
     351            0 :     if (value.empty()) {
     352            0 :         return writeError(TLF("Could not build %; ID cannot be empty", toString(tag)));
     353            0 :     } else if (!SUMOXMLDefinitions::isValidVehicleID(value)) {
     354            0 :         return writeError(TLF("Could not build % with ID '%' in netedit; ID contains invalid characters.", toString(tag), value));
     355              :     } else {
     356              :         return true;
     357              :     }
     358              : }
     359              : 
     360              : 
     361              : void
     362            0 : CommonHandler::writeWarningOverwriting(const SumoXMLTag tag, const std::string& id) {
     363            0 :     WRITE_WARNING(TLF("Overwriting % with ID '%'", toString(tag), id));
     364            0 : }
     365              : 
     366              : 
     367              : bool
     368            0 : CommonHandler::writeWarningDuplicated(const SumoXMLTag tag, const std::string& id, const SumoXMLTag checkedTag) {
     369            0 :     WRITE_WARNING(TLF("Could not build % with ID '%' in netedit; Found another % with the same ID.", toString(tag), id, toString(checkedTag)));
     370            0 :     return false;
     371              : }
     372              : 
     373              : 
     374              : bool
     375            0 : CommonHandler::writeError(const std::string& error) {
     376            0 :     WRITE_ERROR(error);
     377            0 :     myErrorCreatingElement = true;
     378            0 :     return false;
     379              : }
     380              : 
     381              : 
     382              : bool
     383            0 : CommonHandler::writeErrorInvalidPosition(const SumoXMLTag tag, const std::string& id) {
     384            0 :     return writeError(TLF("Could not build % with ID '%' in netedit; Invalid position over lane.", toString(tag), id));
     385              : }
     386              : 
     387              : 
     388              : bool
     389            0 : CommonHandler::writeErrorInvalidLanes(const SumoXMLTag tag, const std::string& id) {
     390            0 :     return writeError(TLF("Could not build % with ID '%' in netedit; List of lanes isn't valid.", toString(tag), id));
     391              : }
     392              : 
     393              : 
     394              : bool
     395            0 : CommonHandler::writeErrorInvalidParent(const SumoXMLTag tag, const std::string& id, const std::vector<SumoXMLTag> parentTags, const std::string& parentID) {
     396            0 :     if (parentTags.size() == 1) {
     397            0 :         return writeError(TLF("Could not build % with ID '%' in netedit; % parent with ID '%' doesn't exist.", toString(tag), id, toString(parentTags.front()), parentID));
     398              :     } else {
     399            0 :         return writeError(TLF("Could not build % with ID '%' in netedit; doesn't exist a % parent with ID '%'.", toString(tag), id, parseParentTags(parentTags), parentID));
     400              :     }
     401              : }
     402              : 
     403              : 
     404              : bool
     405            0 : CommonHandler::writeErrorInvalidParent(const SumoXMLTag tag, const std::vector<SumoXMLTag> parentTags, const std::string& parentID) {
     406            0 :     if (parentTags.size() == 1) {
     407            0 :         return writeError(TLF("Could not build % in netedit; % parent with ID '%' doesn't exist.", toString(tag), toString(parentTags.front()), parentID));
     408              :     } else {
     409            0 :         return writeError(TLF("Could not build % in netedit; doesn't exist a % parent with ID '%'.", toString(tag), parseParentTags(parentTags), parentID));
     410              :     }
     411              : }
     412              : 
     413              : 
     414              : bool
     415            0 : CommonHandler::writeErrorInvalidParent(const SumoXMLTag tag, const std::vector<SumoXMLTag> parentTags) {
     416            0 :     if (parentTags.size() == 1) {
     417            0 :         return writeError(TLF("Could not build % in netedit; % parent doesn't exist.", toString(tag), toString(parentTags.front())));
     418              :     } else {
     419            0 :         return writeError(TLF("Could not build % in netedit; doesn't exist a % parent.", toString(tag), parseParentTags(parentTags)));
     420              :     }
     421              : }
     422              : 
     423              : 
     424              : std::string
     425            0 : CommonHandler::parseParentTags(std::vector<SumoXMLTag> parentTags) const {
     426              :     std::string parentTagsStr;
     427              :     // Join all but the last with ", ", then add " or " + last
     428              :     std::string result;
     429            0 :     for (int i = 0; i < ((int)parentTags.size() - 1); i++) {
     430            0 :         if (i != 0) {
     431            0 :             result.append(", ");
     432              :         }
     433            0 :         result.append(toString(parentTags[i]));
     434              :     }
     435            0 :     result.append(TL(" or "));
     436            0 :     result.append(toString(parentTags.back()));
     437            0 :     return result;
     438              : }
     439              : 
     440              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1