LCOV - code coverage report
Current view: top level - src/utils/xml - XMLSubSys.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 68 88 77.3 %
Date: 2024-05-05 15:31:14 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2002-2024 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             : 
      50             : 
      51             : // ===========================================================================
      52             : // method definitions
      53             : // ===========================================================================
      54             : void
      55       48429 : XMLSubSys::init() {
      56             :     try {
      57       48429 :         XMLPlatformUtils::Initialize();
      58       48429 :         myNextFreeReader = 0;
      59           0 :     } catch (const XERCES_CPP_NAMESPACE::XMLException& e) {
      60           0 :         throw ProcessError("Error during XML-initialization:\n " + StringUtils::transcode(e.getMessage()));
      61           0 :     }
      62       48429 : }
      63             : 
      64             : 
      65             : void
      66       43434 : XMLSubSys::setValidation(const std::string& validationScheme, const std::string& netValidationScheme, const std::string& routeValidationScheme) {
      67       86099 :     if (validationScheme != "never" && validationScheme != "auto" && validationScheme != "always" && validationScheme != "local") {
      68           0 :         throw ProcessError("Unknown xml validation scheme + '" + validationScheme + "'.");
      69             :     }
      70             :     myValidationScheme = validationScheme;
      71       44826 :     if (netValidationScheme != "never" && netValidationScheme != "auto" && netValidationScheme != "always" && netValidationScheme != "local") {
      72           0 :         throw ProcessError("Unknown network validation scheme + '" + netValidationScheme + "'.");
      73             :     }
      74             :     myNetValidationScheme = netValidationScheme;
      75       83716 :     if (routeValidationScheme != "never" && routeValidationScheme != "auto" && routeValidationScheme != "always" && routeValidationScheme != "local") {
      76           0 :         throw ProcessError("Unknown route validation scheme + '" + routeValidationScheme + "'.");
      77             :     }
      78             :     myRouteValidationScheme = routeValidationScheme;
      79       86852 :     if (myGrammarPool == nullptr &&
      80       29170 :             (myValidationScheme != "never" ||
      81       29170 :              myNetValidationScheme != "never" ||
      82             :              myRouteValidationScheme != "never")) {
      83       14248 :         myGrammarPool = new XERCES_CPP_NAMESPACE::XMLGrammarPoolImpl(XMLPlatformUtils::fgMemoryManager);
      84       14248 :         SAX2XMLReader* parser(XMLReaderFactory::createXMLReader(XMLPlatformUtils::fgMemoryManager, myGrammarPool));
      85             : #if _XERCES_VERSION >= 30100
      86       14248 :         parser->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesHandleMultipleImports, true);
      87             : #endif
      88       14248 :         const char* sumoPath = std::getenv("SUMO_HOME");
      89       42768 :         if (sumoPath == nullptr || !FileHelpers::isReadable(sumoPath + std::string("/data/xsd/net_file.xsd"))) {
      90             :             bool needWarning = true;
      91          96 :             if (validationScheme == "local") {
      92          64 :                 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          96 :             if (netValidationScheme == "local") {
      97           0 :                 if (needWarning) {
      98           0 :                     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          96 :             if (routeValidationScheme == "local") {
     104          32 :                 if (needWarning) {
     105           0 :                     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          96 :             if (needWarning) {
     111         128 :                 WRITE_WARNING(TL("Environment variable SUMO_HOME is not set properly, XML validation will fail or use slow website lookups."));
     112             :             }
     113          96 :             return;
     114             :         }
     115       42456 :         for (const char* const& filetype : {
     116             :                     "additional", "routes", "net"
     117       56608 :                 }) {
     118       84912 :             const std::string file = sumoPath + std::string("/data/xsd/") + filetype + "_file.xsd";
     119       42456 :             if (!parser->loadGrammar(file.c_str(), XERCES_CPP_NAMESPACE::Grammar::SchemaGrammarType, true)) {
     120           0 :                 WRITE_WARNINGF(TL("Cannot read local schema '%'."), file);
     121             :             }
     122             :         }
     123             :     }
     124             : }
     125             : 
     126             : 
     127             : void
     128       48903 : XMLSubSys::close() {
     129       91975 :     for (std::vector<SUMOSAXReader*>::iterator i = myReaders.begin(); i != myReaders.end(); ++i) {
     130       43072 :         delete *i;
     131             :     }
     132             :     myReaders.clear();
     133       48903 :     delete myGrammarPool;
     134       48903 :     myGrammarPool = nullptr;
     135       48903 :     XMLPlatformUtils::Terminate();
     136       48903 :     StringUtils::resetTranscoder();
     137       48903 : }
     138             : 
     139             : 
     140             : SUMOSAXReader*
     141       29503 : XMLSubSys::getSAXReader(SUMOSAXHandler& handler, const bool isNet, const bool isRoute) {
     142       29503 :     std::string validationScheme = isNet ? myNetValidationScheme : myValidationScheme;
     143       29503 :     if (isRoute) {
     144             :         validationScheme = myRouteValidationScheme;
     145             :     }
     146       59006 :     return new SUMOSAXReader(handler, validationScheme, myGrammarPool);
     147             : }
     148             : 
     149             : 
     150             : void
     151        7810 : XMLSubSys::setHandler(GenericSAXHandler& handler) {
     152        7810 :     myReaders[myNextFreeReader - 1]->setHandler(handler);
     153        7810 : }
     154             : 
     155             : 
     156             : bool
     157      105223 : XMLSubSys::runParser(GenericSAXHandler& handler, const std::string& file,
     158             :                      const bool isNet, const bool isRoute, const bool isExternal, const bool catchExceptions) {
     159      105223 :     MsgHandler::getErrorInstance()->clear();
     160      105223 :     std::string errorMsg = "";
     161             :     try {
     162      105223 :         std::string validationScheme = isNet ? myNetValidationScheme : myValidationScheme;
     163      105223 :         if (isRoute) {
     164             :             validationScheme = myRouteValidationScheme;
     165             :         }
     166      105267 :         if (isExternal && validationScheme == "local") {
     167           6 :             WRITE_MESSAGEF(TL("Disabling XML validation for external file '%'. Use 'auto' or 'always' to enable."), file);
     168             :             validationScheme = "never";
     169             :         }
     170      105223 :         if (myNextFreeReader == (int)myReaders.size()) {
     171       43081 :             myReaders.push_back(new SUMOSAXReader(handler, validationScheme, myGrammarPool));
     172             :         } else {
     173      125947 :             myReaders[myNextFreeReader]->setValidation(validationScheme);
     174       62142 :             myReaders[myNextFreeReader]->setHandler(handler);
     175             :         }
     176      105223 :         myNextFreeReader++;
     177      105223 :         std::string prevFile = handler.getFileName();
     178      105223 :         handler.setFileName(file);
     179      212109 :         myReaders[myNextFreeReader - 1]->parse(file);
     180      103560 :         handler.setFileName(prevFile);
     181      103560 :         myNextFreeReader--;
     182        1663 :     } catch (const ProcessError& e) {
     183        1663 :         if (catchExceptions) {
     184        3326 :             errorMsg = std::string(e.what()) != std::string("") ? e.what() : TL("Process Error");
     185             :         } else {
     186           0 :             throw;
     187             :         }
     188        1663 :     } catch (const std::runtime_error& re) {
     189           0 :         errorMsg = TLF("Runtime error: % while parsing '%'", re.what(), file);
     190           0 :     } catch (const std::exception& ex) {
     191           0 :         errorMsg = TLF("Error occurred: % while parsing '%'", ex.what(), file);
     192           0 :     } catch (const XERCES_CPP_NAMESPACE::SAXException& e) {
     193           0 :         errorMsg = TLF("SAX error occurred while parsing '%':\n %", file, StringUtils::transcode(e.getMessage()));
     194           0 :     } catch (...) {
     195           0 :         errorMsg = TLF("Unspecified error occurred while parsing '%'", file);
     196           0 :     }
     197      105223 :     if (errorMsg != "") {
     198        1663 :         if (catchExceptions) {
     199        4989 :             WRITE_ERROR(errorMsg);
     200             :         } else {
     201           0 :             throw ProcessError(errorMsg);
     202             :         }
     203             :     }
     204      106851 :     return !MsgHandler::getErrorInstance()->wasInformed();
     205             : }
     206             : 
     207             : 
     208             : /****************************************************************************/

Generated by: LCOV version 1.14