1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include <Config_XMLReader.h>
22 #include <Config_Keywords.h>
23 #include <Config_Common.h>
24 #include <Config_PropManager.h>
25 #include <Config_ModuleReader.h>
27 #include <Events_Loop.h>
28 #include <Events_InfoMessage.h>
29 #include <libxml/parser.h>
30 #include <libxml/tree.h>
36 #pragma warning(disable : 4996) // for getenv
44 static const char FSEP = '\\';
46 static const char FSEP = '/';
49 Config_XMLReader::Config_XMLReader(const std::string& theXmlFileName)
50 : myXmlDoc(NULL), myRootFileName(theXmlFileName)
52 myDocumentPath = findConfigFile(theXmlFileName);
53 if (myDocumentPath.empty()) {
54 Events_InfoMessage("Config_XMLReader", "Unable to open %1").arg(theXmlFileName).send();
58 Config_XMLReader::~Config_XMLReader()
64 std::string Config_XMLReader::resourcesConfigFile()
67 char* anEnv = getenv("SHAPER_ROOT_DIR");
69 aValue = std::string(anEnv) +
70 FSEP + "share" + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper";
72 anEnv = getenv("OPENPARTS_ROOT_DIR");
74 aValue = std::string(anEnv) + FSEP + "resources";
80 std::string Config_XMLReader::pluginConfigFile()
83 char* anEnv = getenv("SHAPER_ROOT_DIR");
85 aValue = std::string(anEnv) +
86 FSEP + "share" + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper";
88 anEnv = getenv("OPENPARTS_ROOT_DIR");
90 aValue = std::string(anEnv) + FSEP + "plugins";
97 std::string Config_XMLReader::findConfigFile(const std::string theFileName, const int theFindIndex)
100 for(int aSolution = 0; aSolution < 12; aSolution++) {
101 std::string aFileName;
102 if (aSolution == 0) {
103 Config_Prop* aProp = Config_PropManager::findProp("Plugins", "default_path");
106 aFileName = aProp->value();
108 std::ostringstream anEnvName;
110 anEnvName<<"SHAPER_ROOT_DIR";
111 else if (aSolution == 2)
112 anEnvName<<"OPENPARTS_ROOT_DIR";
114 anEnvName<<"OPENPARTS_PLUGINS_DIR";
116 char* anEnv = getenv(anEnvName.str().c_str());
119 if (aSolution > 2) { // there may be several paths separated by ";" symbol
121 std::string anEnvPart = anEnv;
122 size_t aPosStart = 0, aPosEnd;
123 for(int aSubNum = 0; aSubNum < aSolution - 3; aSubNum++) {
125 aPosStart = anEnvPart.find(';', aPosStart);
126 if (aPosStart == std::string::npos)
129 if (aPosStart == std::string::npos)
133 aPosEnd = anEnvPart.find(';', aPosStart);
134 aFileName = anEnvPart.substr(aPosStart,
135 aPosEnd == std::string::npos ? aPosEnd : aPosEnd - aPosStart) + FSEP;
138 aFileName = std::string(anEnv) + FSEP;
141 aFileName += std::string("share") + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper";
142 else if (aSolution == 2)
143 aFileName += "plugins";
146 aFileName += FSEP + theFileName;
147 std::ifstream aTestFile(aFileName);
149 if (aResultIndex == theFindIndex)
152 if (aSolution == 1) // don't allow SHAPER and OpenParts paths treated simultaneously
156 return ""; // no files found
159 void Config_XMLReader::readAll()
161 // to load external modules dependencies (like GEOM for Connector Feature)
162 Config_ModuleReader::loadScript("salome.shaper.initConfig", false);
164 for(int aSolution = 0; true; aSolution++) {
165 std::string aFoundFile = findConfigFile(myRootFileName, aSolution);
166 if (aFoundFile.empty()) {
167 break; // no more solutions
170 if (myXmlDoc != NULL) { // clear the previous XML document - now the new one will be opened
171 xmlFreeDoc(myXmlDoc);
174 xmlNodePtr aRoot = findRoot(aFoundFile);
175 readRecursively(aRoot);
179 void Config_XMLReader::processNode(xmlNodePtr theNode)
181 if (isNode(theNode, NODE_SOURCE, NULL)) {
182 std::string aSourceFile = getProperty(theNode, SOURCE_FILE);
183 Config_XMLReader aSourceReader = Config_XMLReader(aSourceFile);
184 readRecursively(aSourceReader.findRoot());
186 //std::cout << "Config_XMLReader::sourced node: " << aSourceFile << std::endl;
191 void Config_XMLReader::cleanup(xmlNodePtr)
197 bool Config_XMLReader::processChildren(xmlNodePtr aNode)
203 xmlNodePtr Config_XMLReader::findRoot(const std::string theDocumentPath)
205 std::string aDocPath = theDocumentPath.empty() ? myDocumentPath : theDocumentPath;
206 if (myXmlDoc == NULL) {
207 myXmlDoc = xmlParseFile(aDocPath.c_str());
209 if (myXmlDoc == NULL) {
211 std::cout << "Config_XMLReader::import: " << "Document " << aDocPath
212 << " is not parsed successfully." << std::endl;
216 xmlNodePtr aRoot = xmlDocGetRootElement(myXmlDoc);
219 std::cout << "Config_XMLReader::import: " << "Error: empty document";
225 void Config_XMLReader::readRecursively(xmlNodePtr theParent)
229 xmlNodePtr aNode = theParent->xmlChildrenNode;
230 for (; aNode; aNode = aNode->next) {
231 //Still no text processing in features...
232 if (!isElementNode(aNode)) {
236 if (processChildren(aNode)) {
237 readRecursively(aNode);
244 xmlNodePtr Config_XMLReader::node(void* theNode)
246 return static_cast<xmlNodePtr>(theNode);
250 std::string Config_XMLReader::getNodeName(xmlNodePtr theNode)
252 std::string result = "";
253 char* aPropChars = (char*) theNode->name;
254 if (!aPropChars || aPropChars[0] == 0)
256 result = std::string(aPropChars);
260 void Config_XMLReader::storeAttribute(xmlNodePtr theNode, const char* theAttribute, bool doClean)
262 std::string aKey = getNodeName(theNode) + ":" + std::string(theAttribute);
263 std::string aValue = getProperty(theNode, theAttribute);
264 if (doClean || !aValue.empty()) {
265 myCachedAttributes[aKey] = aValue;
270 std::string Config_XMLReader::restoreAttribute(xmlNodePtr theNode, const char* theAttribute)
272 return restoreAttribute(getNodeName(theNode).c_str(), theAttribute);
276 std::string Config_XMLReader::restoreAttribute(const char* theNodeName, const char* theAttribute)
278 std::string aKey = std::string(theNodeName) + ":" + std::string(theAttribute);
279 std::string result = "";
280 if(myCachedAttributes.find(aKey) != myCachedAttributes.end()) {
281 result = myCachedAttributes[aKey];
286 bool Config_XMLReader::cleanupAttribute(xmlNodePtr theNode, const char* theNodeAttribute)
288 return cleanupAttribute(getNodeName(theNode).c_str(), theNodeAttribute);
291 bool Config_XMLReader::cleanupAttribute(const char* theNodeName, const char* theNodeAttribute)
293 std::string aKey = std::string(theNodeName) + ":" + std::string(theNodeAttribute);
295 std::map<std::string, std::string>::iterator anEntry = myCachedAttributes.find(aKey);
296 if( anEntry != myCachedAttributes.end()) {
297 myCachedAttributes.erase(anEntry);
304 const char* Config_XMLReader::encoding() const
306 return (const char*) myXmlDoc->encoding;