X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FConfig%2FConfig_XMLReader.cpp;h=f7af50c8f21e7a9ead3ecf0652948525c84bbe84;hb=7603884deb939196de914470e2f4273efcb7317a;hp=fd625fc3f0f070d23d6072449107440923127b77;hpb=c38397a5dd4d35001147a9dfbf649771c6f22229;p=modules%2Fshaper.git diff --git a/src/Config/Config_XMLReader.cpp b/src/Config/Config_XMLReader.cpp index fd625fc3f..f7af50c8f 100644 --- a/src/Config/Config_XMLReader.cpp +++ b/src/Config/Config_XMLReader.cpp @@ -1,175 +1,296 @@ -/* - * Config_XMLReader.cpp - * - * Created on: Mar 14, 2014 - * Author: sbh - */ +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// #include +#include +#include +#include +#include -#include -#include -#include +#include +#include +#include +#include + +#include +#include #ifdef WIN32 -//For GetModuleFileNameW -#include +#pragma warning(disable : 4996) // for getenv #endif #ifdef _DEBUG #include #endif - -Config_XMLReader::Config_XMLReader(const std::string& theXmlFileName) -{ - std::string prefix; - //Get path to *.xml files (typically ./bin/../plugins/) #ifdef WIN32 - HMODULE hModule = GetModuleHandleW(NULL); - WCHAR wchar_path[MAX_PATH]; - GetModuleFileNameW(hModule, wchar_path, MAX_PATH); - char char_path[MAX_PATH]; - char DefChar = ' '; - WideCharToMultiByte(CP_ACP, 0, wchar_path, -1, char_path, MAX_PATH, &DefChar, NULL); - prefix = std::string(char_path); - //chop "bin\XGUI.exe" - unsigned found = prefix.rfind("bin"); - if(found != std::string::npos) - prefix.replace(found, prefix.length(), "plugins\\"); + static const char FSEP = '\\'; #else - //TODO(sbh): Find full path to binary on linux - prefix = "../plugins/"; + static const char FSEP = '/'; #endif - m_DocumentPath = prefix + theXmlFileName; +Config_XMLReader::Config_XMLReader(const std::string& theXmlFileName) + : myXmlDoc(NULL), myRootFileName(theXmlFileName) +{ + myDocumentPath = findConfigFile(theXmlFileName); + if (myDocumentPath.empty()) { + Events_InfoMessage("Config_XMLReader", "Unable to open %1").arg(theXmlFileName).send(); + } } - Config_XMLReader::~Config_XMLReader() { + xmlFreeDoc(myXmlDoc); +} + +std::string Config_XMLReader::resourcesConfigFile() +{ + std::string aValue; + char* anEnv = getenv("SHAPER_ROOT_DIR"); + if (anEnv) { + aValue = std::string(anEnv) + + FSEP + "share" + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper"; + } else { + anEnv = getenv("OPENPARTS_ROOT_DIR"); + if (anEnv) { + aValue = std::string(anEnv) + FSEP + "resources"; + } + } + return aValue; +} + +std::string Config_XMLReader::pluginConfigFile() +{ + std::string aValue; + char* anEnv = getenv("SHAPER_ROOT_DIR"); + if (anEnv) { + aValue = std::string(anEnv) + + FSEP + "share" + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper"; + } else { + anEnv = getenv("OPENPARTS_ROOT_DIR"); + if (anEnv) { + aValue = std::string(anEnv) + FSEP + "plugins"; + } + } + return aValue; +} + +std::string Config_XMLReader::findConfigFile(const std::string theFileName, const int theFindIndex) +{ + int aResultIndex = 0; + for(int aSolution = 0; aSolution < 12; aSolution++) { + std::string aFileName; + if (aSolution == 0) { + Config_Prop* aProp = Config_PropManager::findProp("Plugins", "default_path"); + if (!aProp) + continue; + aFileName = aProp->value(); + } else { + std::ostringstream anEnvName; + if (aSolution == 1) + anEnvName<<"SHAPER_ROOT_DIR"; + else if (aSolution == 2) + anEnvName<<"OPENPARTS_ROOT_DIR"; + else + anEnvName<<"OPENPARTS_PLUGINS_DIR"; + + char* anEnv = getenv(anEnvName.str().c_str()); + if (!anEnv) + continue; + if (aSolution > 2) { // there may be several paths separated by ";" symbol + std::string anEnvPart = anEnv; + size_t aPosStart = 0, aPosEnd; + for(int aSubNum = 0; aSubNum < aSolution - 3; aSubNum++) { + aPosStart++; + aPosStart = anEnvPart.find(';', aPosStart); + if (aPosStart == std::string::npos) + break; + } + if (aPosStart == std::string::npos) + break; + if (aPosStart != 0) + aPosStart++; + aPosEnd = anEnvPart.find(';', aPosStart); + aFileName = anEnvPart.substr(aPosStart, + aPosEnd == std::string::npos ? aPosEnd : aPosEnd - aPosStart) + FSEP; + } else { + aFileName = std::string(anEnv) + FSEP; + } + if (aSolution == 1) + aFileName += std::string("share") + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper"; + else if (aSolution == 2) + aFileName += "plugins"; + } + + aFileName += FSEP + theFileName; + std::ifstream aTestFile(aFileName); + if (aTestFile) { + if (aResultIndex == theFindIndex) + return aFileName; + aResultIndex++; + if (aSolution == 1) // don't allow SHAPER and OpenParts paths treated simultaneously + aSolution++; + } + } + return ""; // no files found } -/* - * Read all nodes (recursively if processChildren() is true - * for a node). For each read node the processNode will be - * called. - */ void Config_XMLReader::readAll() { - xmlNodePtr aRoot = findRoot(); - readRecursively(aRoot); + // to load external modules dependencies (like GEOM for Connector Feature) + Config_ModuleReader::loadScript("salome.shaper.initConfig", false); + + for(int aSolution = 0; true; aSolution++) { + std::string aFoundFile = findConfigFile(myRootFileName, aSolution); + if (aFoundFile.empty()) { + break; // no more solutions + } + + if (myXmlDoc != NULL) { // clear the previous XML document - now the new one will be opened + xmlFreeDoc(myXmlDoc); + myXmlDoc = NULL; + } + xmlNodePtr aRoot = findRoot(aFoundFile); + readRecursively(aRoot); + } +} + +void Config_XMLReader::processNode(xmlNodePtr theNode) +{ + if (isNode(theNode, NODE_SOURCE, NULL)) { + std::string aSourceFile = getProperty(theNode, SOURCE_FILE); + Config_XMLReader aSourceReader = Config_XMLReader(aSourceFile); + readRecursively(aSourceReader.findRoot()); +#ifdef _DEBUG + //std::cout << "Config_XMLReader::sourced node: " << aSourceFile << std::endl; +#endif + } } -/* - * Allows to customize reader's behavior for a node. Virtual. - * The default implementation does nothing. (In debug mode prints - * some info) - */ -void Config_XMLReader::processNode(xmlNodePtr aNode) +void Config_XMLReader::cleanup(xmlNodePtr) { - #ifdef _DEBUG - std::cout << "Config_XMLReader::processNode: " - << aNode->name << " content: " - << aNode->content << std::endl; - #endif + // do nothing; } -/* - * Defines which nodes should be processed recursively. Virtual. - * The default implementation to read all nodes. - */ bool Config_XMLReader::processChildren(xmlNodePtr aNode) { return true; } -xmlNodePtr Config_XMLReader::findRoot() +xmlNodePtr Config_XMLReader::findRoot(const std::string theDocumentPath) { - xmlDocPtr aDoc; - aDoc = xmlParseFile(m_DocumentPath.c_str()); - if(aDoc == NULL) { - #ifdef _DEBUG - std::cout << "Config_XMLReader::import: " << "Document " << m_DocumentPath - << " is not parsed successfully." << std::endl; - #endif + std::string aDocPath = theDocumentPath.empty() ? myDocumentPath : theDocumentPath; + if (myXmlDoc == NULL) { + myXmlDoc = xmlParseFile(aDocPath.c_str()); + } + if (myXmlDoc == NULL) { +#ifdef _DEBUG + std::cout << "Config_XMLReader::import: " << "Document " << aDocPath + << " is not parsed successfully." << std::endl; +#endif return NULL; } - xmlNodePtr aRoot = xmlDocGetRootElement(aDoc); - #ifdef _DEBUG + xmlNodePtr aRoot = xmlDocGetRootElement(myXmlDoc); +#ifdef _DEBUG if(aRoot == NULL) { std::cout << "Config_XMLReader::import: " << "Error: empty document"; } - #endif +#endif return aRoot; } -/* - * Calls processNode() for each child (for some - recursively) - * of the given node. - * \sa ReadAll() - */ void Config_XMLReader::readRecursively(xmlNodePtr theParent) { - static Event_ID aFeatureEvent = Event_Loop::EventByName("Feature"); - - if(!theParent) + if (!theParent) return; xmlNodePtr aNode = theParent->xmlChildrenNode; - for(; aNode; aNode = aNode->next) { + for (; aNode; aNode = aNode->next) { + //Still no text processing in features... + if (!isElementNode(aNode)) { + continue; + } processNode(aNode); - if(processChildren(aNode)) { + if (processChildren(aNode)) { readRecursively(aNode); - Config_FeatureMessage aMessage(aFeatureEvent, this); } + cleanup(aNode); } } -/* - * void* -> xmlNodePtr - */ xmlNodePtr Config_XMLReader::node(void* theNode) { return static_cast(theNode); } -/* - * Returns named property for a given node as std::string. - */ -std::string Config_XMLReader::getProperty(xmlNodePtr theNode, const char* name) +std::string Config_XMLReader::getNodeName(xmlNodePtr theNode) { std::string result = ""; - char* aPropChars = (char*) xmlGetProp(theNode, BAD_CAST name); - if(!aPropChars || aPropChars[0] == 0) + char* aPropChars = (char*) theNode->name; + if (!aPropChars || aPropChars[0] == 0) return result; result = std::string(aPropChars); return result; } -/* - * Returns true if theNode is XML node with a given name. - */ -bool Config_XMLReader::isNode(xmlNodePtr theNode, const char* theNodeName, ...) +void Config_XMLReader::storeAttribute(xmlNodePtr theNode, const char* theAttribute, bool doClean) +{ + std::string aKey = getNodeName(theNode) + ":" + std::string(theAttribute); + std::string aValue = getProperty(theNode, theAttribute); + if (doClean || !aValue.empty()) { + myCachedAttributes[aKey] = aValue; + } +} + +std::string Config_XMLReader::restoreAttribute(xmlNodePtr theNode, const char* theAttribute) +{ + return restoreAttribute(getNodeName(theNode).c_str(), theAttribute); +} + +std::string Config_XMLReader::restoreAttribute(const char* theNodeName, const char* theAttribute) +{ + std::string aKey = std::string(theNodeName) + ":" + std::string(theAttribute); + std::string result = ""; + if(myCachedAttributes.find(aKey) != myCachedAttributes.end()) { + result = myCachedAttributes[aKey]; + } + return result; +} + +bool Config_XMLReader::cleanupAttribute(xmlNodePtr theNode, const char* theNodeAttribute) +{ + return cleanupAttribute(getNodeName(theNode).c_str(), theNodeAttribute); +} + +bool Config_XMLReader::cleanupAttribute(const char* theNodeName, const char* theNodeAttribute) { + std::string aKey = std::string(theNodeName) + ":" + std::string(theNodeAttribute); bool result = false; - const xmlChar* aName = theNode->name; - if(!aName || theNode->type != XML_ELEMENT_NODE) - return false; - - if(!xmlStrcmp(aName, (const xmlChar *) theNodeName)) - return true; - - va_list args; // define argument list variable - va_start (args, theNodeName); // init list; point to last defined argument - while(true) { - char *anArg = va_arg (args, char *); // get next argument - if(anArg == NULL) - break; - if(!xmlStrcmp(aName, (const xmlChar *) anArg)) { - va_end (args); // cleanup the system stack - return true; - } + std::map::iterator anEntry = myCachedAttributes.find(aKey); + if( anEntry != myCachedAttributes.end()) { + myCachedAttributes.erase(anEntry); + result = true; } - va_end (args); // cleanup the system stack - return false; + return result; } + +const char* Config_XMLReader::encoding() const +{ + return (const char*) myXmlDoc->encoding; +} \ No newline at end of file