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