LCOV - code coverage report
Current view: top level - src/utils/xml - XMLSubSys.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 84.1 % 88 74
Test Date: 2024-12-21 15:45:41 Functions: 100.0 % 7 7

            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              : bool XMLSubSys::myNeedsValidationWarning = true;
      50              : 
      51              : 
      52              : // ===========================================================================
      53              : // method definitions
      54              : // ===========================================================================
      55              : void
      56        58451 : XMLSubSys::init() {
      57              :     try {
      58        58451 :         XMLPlatformUtils::Initialize();
      59        58451 :         myNextFreeReader = 0;
      60            0 :     } catch (const XERCES_CPP_NAMESPACE::XMLException& e) {
      61            0 :         throw ProcessError("Error during XML-initialization:\n " + StringUtils::transcode(e.getMessage()));
      62            0 :     }
      63        58451 : }
      64              : 
      65              : 
      66              : std::string
      67       167565 : XMLSubSys::warnLocalScheme(const std::string& newScheme, const bool haveSUMO_HOME) {
      68       167565 :     if (newScheme != "never" && newScheme != "auto" && newScheme != "always" && newScheme != "local") {
      69            0 :         throw ProcessError("Unknown xml validation scheme + '" + newScheme + "'.");
      70              :     }
      71       167565 :     if (!haveSUMO_HOME && newScheme == "local") {
      72           32 :         if (myNeedsValidationWarning) {
      73           16 :             WRITE_WARNING(TL("Environment variable SUMO_HOME is not set properly, disabling XML validation. Set 'auto' or 'always' for web lookups."));
      74           16 :             myNeedsValidationWarning = false;
      75              :         }
      76           32 :         return "never";
      77              :     }
      78              :     return newScheme;
      79              : }
      80              : 
      81              : 
      82              : void
      83        55855 : XMLSubSys::setValidation(const std::string& validationScheme, const std::string& netValidationScheme, const std::string& routeValidationScheme) {
      84        55855 :     const char* sumoPath = std::getenv("SUMO_HOME");
      85       167533 :     const bool haveSUMO_HOME = sumoPath != nullptr && FileHelpers::isReadable(sumoPath + std::string("/data/xsd/net_file.xsd"));
      86        55855 :     myValidationScheme = warnLocalScheme(validationScheme, haveSUMO_HOME);
      87        55855 :     myNetValidationScheme = warnLocalScheme(netValidationScheme, haveSUMO_HOME);
      88        55855 :     myRouteValidationScheme = warnLocalScheme(routeValidationScheme, haveSUMO_HOME);
      89        55855 :     if (myGrammarPool == nullptr &&
      90        35851 :             (myValidationScheme != "never" ||
      91        35851 :              myNetValidationScheme != "never" ||
      92              :              myRouteValidationScheme != "never")) {
      93        19992 :         if (!haveSUMO_HOME) {
      94           32 :             if (myNeedsValidationWarning) {
      95           32 :                 WRITE_WARNING(TL("Environment variable SUMO_HOME is not set properly, XML validation will fail or use slow website lookups."));
      96           32 :                 myNeedsValidationWarning = false;
      97              :             }
      98           32 :             return;
      99              :         }
     100        19960 :         myGrammarPool = new XERCES_CPP_NAMESPACE::XMLGrammarPoolImpl(XMLPlatformUtils::fgMemoryManager);
     101        19960 :         SAX2XMLReader* parser(XMLReaderFactory::createXMLReader(XMLPlatformUtils::fgMemoryManager, myGrammarPool));
     102              : #if _XERCES_VERSION >= 30100
     103        19960 :         parser->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesHandleMultipleImports, true);
     104              : #endif
     105        59880 :         for (const char* const& filetype : {
     106              :                     "additional", "routes", "net"
     107        79840 :                 }) {
     108        59880 :             const std::string file = sumoPath + std::string("/data/xsd/") + filetype + "_file.xsd";
     109        59880 :             if (!parser->loadGrammar(file.c_str(), XERCES_CPP_NAMESPACE::Grammar::SchemaGrammarType, true)) {
     110            0 :                 WRITE_WARNINGF(TL("Cannot read local schema '%'."), file);
     111              :             }
     112              :         }
     113        19960 :         delete parser;
     114              :     }
     115              : }
     116              : 
     117              : 
     118              : void
     119        58691 : XMLSubSys::close() {
     120       114110 :     for (std::vector<SUMOSAXReader*>::iterator i = myReaders.begin(); i != myReaders.end(); ++i) {
     121        55419 :         delete *i;
     122              :     }
     123              :     myReaders.clear();
     124        58691 :     delete myGrammarPool;
     125        58691 :     myGrammarPool = nullptr;
     126        58691 :     XMLPlatformUtils::Terminate();
     127        58691 :     StringUtils::resetTranscoder();
     128        58691 : }
     129              : 
     130              : 
     131              : SUMOSAXReader*
     132        45259 : XMLSubSys::getSAXReader(SUMOSAXHandler& handler, const bool isNet, const bool isRoute) {
     133        45259 :     std::string validationScheme = isNet ? myNetValidationScheme : myValidationScheme;
     134        45259 :     if (isRoute) {
     135              :         validationScheme = myRouteValidationScheme;
     136              :     }
     137        90518 :     return new SUMOSAXReader(handler, validationScheme, myGrammarPool);
     138              : }
     139              : 
     140              : 
     141              : void
     142         9328 : XMLSubSys::setHandler(GenericSAXHandler& handler) {
     143         9328 :     myReaders[myNextFreeReader - 1]->setHandler(handler);
     144         9328 : }
     145              : 
     146              : 
     147              : bool
     148       159972 : XMLSubSys::runParser(GenericSAXHandler& handler, const std::string& file,
     149              :                      const bool isNet, const bool isRoute, const bool isExternal, const bool catchExceptions) {
     150       159972 :     MsgHandler::getErrorInstance()->clear();
     151       159972 :     std::string errorMsg = "";
     152              :     try {
     153       159972 :         std::string validationScheme = isNet ? myNetValidationScheme : myValidationScheme;
     154       159972 :         if (isRoute) {
     155              :             validationScheme = myRouteValidationScheme;
     156              :         }
     157       159972 :         if (isExternal && validationScheme == "local") {
     158            3 :             WRITE_MESSAGEF(TL("Disabling XML validation for external file '%'. Use 'auto' or 'always' to enable."), file);
     159              :             validationScheme = "never";
     160              :         }
     161       159972 :         if (myNextFreeReader == (int)myReaders.size()) {
     162        55436 :             myReaders.push_back(new SUMOSAXReader(handler, validationScheme, myGrammarPool));
     163              :         } else {
     164       210006 :             myReaders[myNextFreeReader]->setValidation(validationScheme);
     165       104536 :             myReaders[myNextFreeReader]->setHandler(handler);
     166              :         }
     167       159972 :         myNextFreeReader++;
     168       159972 :         std::string prevFile = handler.getFileName();
     169       159972 :         handler.setFileName(file);
     170       320878 :         myReaders[myNextFreeReader - 1]->parse(file);
     171       159038 :         handler.setFileName(prevFile);
     172       159038 :         myNextFreeReader--;
     173          934 :     } catch (const ProcessError& e) {
     174          934 :         if (catchExceptions) {
     175         1866 :             errorMsg = std::string(e.what()) != std::string("") ? e.what() : TL("Process Error");
     176              :         } else {
     177            1 :             throw;
     178              :         }
     179          934 :     } catch (const std::runtime_error& re) {
     180            0 :         errorMsg = TLF("Runtime error: % while parsing '%'", re.what(), file);
     181            0 :     } catch (const std::exception& ex) {
     182            0 :         errorMsg = TLF("Error occurred: % while parsing '%'", ex.what(), file);
     183            0 :     } catch (const XERCES_CPP_NAMESPACE::SAXException& e) {
     184            0 :         errorMsg = TLF("SAX error occurred while parsing '%':\n %", file, StringUtils::transcode(e.getMessage()));
     185            0 :     } catch (...) {
     186            0 :         errorMsg = TLF("Unspecified error occurred while parsing '%'", file);
     187            0 :     }
     188       159971 :     if (errorMsg != "") {
     189          933 :         if (catchExceptions) {
     190         2800 :             WRITE_ERROR(errorMsg);
     191              :         } else {
     192            0 :             throw ProcessError(errorMsg);
     193              :         }
     194              :     }
     195       159971 :     return !MsgHandler::getErrorInstance()->wasInformed();
     196              : }
     197              : 
     198              : 
     199              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1