]> SALOME platform Git repositories - modules/shaper.git/blob - src/Config/Config_XMLReader.cpp
Salome HOME
2149feba08c113ed6850c7cef0c14c50c9bcabb1
[modules/shaper.git] / src / Config / Config_XMLReader.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 //
20
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>
26
27 #include <Events_Loop.h>
28 #include <Events_InfoMessage.h>
29 #include <libxml/parser.h>
30 #include <libxml/tree.h>
31
32 #include <fstream>
33 #include <sstream>
34
35 #ifdef WIN32
36 #pragma warning(disable : 4996) // for getenv
37 #endif
38
39 #ifdef _DEBUG
40 #include <iostream>
41 #endif
42
43 #ifdef WIN32
44     static const char FSEP = '\\';
45 #else
46     static const char FSEP = '/';
47 #endif
48
49 Config_XMLReader::Config_XMLReader(const std::string& theXmlFileName)
50     : myXmlDoc(NULL), myRootFileName(theXmlFileName)
51 {
52   myDocumentPath = findConfigFile(theXmlFileName);
53   if (myDocumentPath.empty()) {
54     Events_InfoMessage("Config_XMLReader", "Unable to open %1").arg(theXmlFileName).send();
55   }
56 }
57
58 Config_XMLReader::~Config_XMLReader()
59 {
60   xmlFreeDoc(myXmlDoc);
61 }
62
63 // LCOV_EXCL_START
64 std::string Config_XMLReader::resourcesConfigFile()
65 {
66   std::string aValue;
67   char* anEnv = getenv("SHAPER_ROOT_DIR");
68   if (anEnv) {
69     aValue = std::string(anEnv) +
70       FSEP + "share" + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper";
71   } else {
72     anEnv = getenv("OPENPARTS_ROOT_DIR");
73     if (anEnv) {
74       aValue = std::string(anEnv) + FSEP + "resources";
75     }
76   }
77   return aValue;
78 }
79
80 std::string Config_XMLReader::pluginConfigFile()
81 {
82   std::string aValue;
83   char* anEnv = getenv("SHAPER_ROOT_DIR");
84   if (anEnv) {
85     aValue = std::string(anEnv) +
86       FSEP + "share" + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper";
87   } else {
88     anEnv = getenv("OPENPARTS_ROOT_DIR");
89     if (anEnv) {
90       aValue = std::string(anEnv) + FSEP + "plugins";
91     }
92   }
93   return aValue;
94 }
95 // LCOV_EXCL_STOP
96
97 std::string Config_XMLReader::findConfigFile(const std::string theFileName, const int theFindIndex)
98 {
99   int aResultIndex = 0;
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");
104       if (!aProp)
105         continue;
106       aFileName = aProp->value();
107     } else {
108       std::ostringstream anEnvName;
109       if (aSolution == 1)
110         anEnvName<<"SHAPER_ROOT_DIR";
111       else if (aSolution == 2)
112         anEnvName<<"OPENPARTS_ROOT_DIR";
113       else
114         anEnvName<<"OPENPARTS_PLUGINS_DIR";
115
116       char* anEnv = getenv(anEnvName.str().c_str());
117       if (!anEnv)
118         continue;
119       if (aSolution > 2) { // there may be several paths separated by ";" symbol
120 // LCOV_EXCL_START
121         std::string anEnvPart = anEnv;
122         size_t aPosStart = 0, aPosEnd;
123         for(int aSubNum = 0; aSubNum < aSolution - 3; aSubNum++) {
124           aPosStart++;
125           aPosStart = anEnvPart.find(';', aPosStart);
126           if (aPosStart == std::string::npos)
127             break;
128         }
129         if (aPosStart == std::string::npos)
130           break;
131         if (aPosStart != 0)
132           aPosStart++;
133         aPosEnd = anEnvPart.find(';', aPosStart);
134         aFileName = anEnvPart.substr(aPosStart,
135           aPosEnd == std::string::npos ? aPosEnd : aPosEnd - aPosStart) + FSEP;
136 // LCOV_EXCL_STOP
137       } else {
138         aFileName = std::string(anEnv) + FSEP;
139       }
140       if (aSolution == 1)
141         aFileName += std::string("share") + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper";
142       else if (aSolution == 2)
143         aFileName += "plugins";
144     }
145
146     aFileName += FSEP + theFileName;
147     std::ifstream aTestFile(aFileName);
148     if (aTestFile) {
149       if (aResultIndex == theFindIndex)
150         return aFileName;
151       aResultIndex++;
152       if (aSolution == 1) // don't allow SHAPER and OpenParts paths treated simultaneously
153         aSolution++;
154     }
155   }
156   return ""; // no files found
157 }
158
159 void Config_XMLReader::readAll()
160 {
161   // to load external modules dependencies (like GEOM for Connector Feature)
162   Config_ModuleReader::loadScript("salome.shaper.initConfig", false);
163
164   for(int aSolution = 0; true; aSolution++) {
165     std::string aFoundFile = findConfigFile(myRootFileName, aSolution);
166     if (aFoundFile.empty()) {
167       break; // no more solutions
168     }
169
170     if (myXmlDoc != NULL) { // clear the previous XML document - now the new one will be opened
171       xmlFreeDoc(myXmlDoc);
172       myXmlDoc = NULL;
173     }
174     xmlNodePtr aRoot = findRoot(aFoundFile);
175     readRecursively(aRoot);
176   }
177 }
178
179 void Config_XMLReader::processNode(xmlNodePtr theNode)
180 {
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());
185 #ifdef _DEBUG
186     //std::cout << "Config_XMLReader::sourced node: " << aSourceFile << std::endl;
187 #endif
188   }
189 }
190
191 void Config_XMLReader::cleanup(xmlNodePtr)
192 {
193   // do nothing;
194 }
195
196 // LCOV_EXCL_START
197 bool Config_XMLReader::processChildren(xmlNodePtr aNode)
198 {
199   return true;
200 }
201 // LCOV_EXCL_STOP
202
203 xmlNodePtr Config_XMLReader::findRoot(const std::string theDocumentPath)
204 {
205   std::string aDocPath = theDocumentPath.empty() ? myDocumentPath : theDocumentPath;
206   if (myXmlDoc == NULL) {
207     myXmlDoc = xmlParseFile(aDocPath.c_str());
208   }
209   if (myXmlDoc == NULL) {
210 #ifdef _DEBUG
211     std::cout << "Config_XMLReader::import: " << "Document " << aDocPath
212     << " is not parsed successfully." << std::endl;
213 #endif
214     return NULL;
215   }
216   xmlNodePtr aRoot = xmlDocGetRootElement(myXmlDoc);
217 #ifdef _DEBUG
218   if(aRoot == NULL) {
219     std::cout << "Config_XMLReader::import: " << "Error: empty document";
220   }
221 #endif
222   return aRoot;
223 }
224
225 void Config_XMLReader::readRecursively(xmlNodePtr theParent)
226 {
227   if (!theParent)
228     return;
229   xmlNodePtr aNode = theParent->xmlChildrenNode;
230   for (; aNode; aNode = aNode->next) {
231     //Still no text processing in features...
232     if (!isElementNode(aNode)) {
233       continue;
234     }
235     processNode(aNode);
236     if (processChildren(aNode)) {
237       readRecursively(aNode);
238     }
239     cleanup(aNode);
240   }
241 }
242
243 // LCOV_EXCL_START
244 xmlNodePtr Config_XMLReader::node(void* theNode)
245 {
246   return static_cast<xmlNodePtr>(theNode);
247 }
248 // LCOV_EXCL_STOP
249
250 std::string Config_XMLReader::getNodeName(xmlNodePtr theNode)
251 {
252   std::string result = "";
253   char* aPropChars = (char*) theNode->name;
254   if (!aPropChars || aPropChars[0] == 0)
255     return result;
256   result = std::string(aPropChars);
257   return result;
258 }
259
260 void Config_XMLReader::storeAttribute(xmlNodePtr theNode, const char* theAttribute, bool doClean)
261 {
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;
266   }
267 }
268
269 // LCOV_EXCL_START
270 std::string Config_XMLReader::restoreAttribute(xmlNodePtr theNode, const char* theAttribute)
271 {
272   return restoreAttribute(getNodeName(theNode).c_str(), theAttribute);
273 }
274 // LCOV_EXCL_STOP
275
276 std::string Config_XMLReader::restoreAttribute(const char* theNodeName, const char* theAttribute)
277 {
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];
282   }
283   return result;
284 }
285
286 bool Config_XMLReader::cleanupAttribute(xmlNodePtr theNode, const char* theNodeAttribute)
287 {
288   return cleanupAttribute(getNodeName(theNode).c_str(), theNodeAttribute);
289 }
290
291 bool Config_XMLReader::cleanupAttribute(const char* theNodeName, const char* theNodeAttribute)
292 {
293   std::string aKey = std::string(theNodeName) + ":" + std::string(theNodeAttribute);
294   bool result = false;
295   std::map<std::string, std::string>::iterator anEntry = myCachedAttributes.find(aKey);
296   if( anEntry != myCachedAttributes.end()) {
297     myCachedAttributes.erase(anEntry);
298     result = true;
299   }
300   return result;
301 }
302
303 // LCOV_EXCL_START
304 const char* Config_XMLReader::encoding() const
305 {
306   return (const char*) myXmlDoc->encoding;
307 }
308 // LCOV_EXCL_STOP