Salome HOME
Add copyright header according to request of CEA from 06.06.2017
[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 email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
18 //
19
20 /*
21  * Config_XMLReader.cpp
22  *
23  *  Created on: Mar 14, 2014
24  *      Author: sbh
25  */
26
27 #include <Config_XMLReader.h>
28 #include <Config_Keywords.h>
29 #include <Config_Common.h>
30 #include <Config_PropManager.h>
31 #include <Config_ModuleReader.h>
32
33 #include <Events_Loop.h>
34 #include <Events_InfoMessage.h>
35 #include <libxml/parser.h>
36 #include <libxml/tree.h>
37
38 #include <fstream>
39
40 #ifdef WIN32
41 #pragma warning(disable : 4996) // for getenv
42 #endif
43
44 #ifdef _DEBUG
45 #include <iostream>
46 #endif
47
48 #ifdef WIN32
49     static const char FSEP = '\\';
50 #else
51     static const char FSEP = '/';
52 #endif
53
54 Config_XMLReader::Config_XMLReader(const std::string& theXmlFileName)
55     : myXmlDoc(NULL)
56 {
57   std::string prefix = "";
58   Config_Prop* aProp = Config_PropManager::findProp("Plugins", "default_path");
59   if (aProp)
60     prefix = aProp->value();
61   /*
62    * Get path to *.xml files (typically ./bin/../plugins/)
63
64    * the problem: application may be launched using python executable,
65    * to use environment variable (at least for the current moment)
66    */
67   if (prefix.empty())
68     prefix = pluginConfigFile();
69
70   myDocumentPath = prefix + FSEP + theXmlFileName;
71   std::ifstream aTestFile(myDocumentPath);
72   if (!aTestFile)
73     Events_InfoMessage("Config_XMLReader", "Unable to open %1").arg(myDocumentPath).send();
74   aTestFile.close();
75 }
76
77 Config_XMLReader::~Config_XMLReader()
78 {
79   xmlFreeDoc(myXmlDoc);
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("OPENPARTS_ROOT_DIR");
91     if (anEnv) {
92       aValue = std::string(anEnv) + FSEP + "plugins";
93     }
94   }
95   return aValue;
96 }
97
98 void Config_XMLReader::readAll()
99 {
100   // to load external modules dependencies (like GEOm for Connector Feature
101   Config_ModuleReader::loadScript("salome.shaper.initConfig", false);
102
103   xmlNodePtr aRoot = findRoot();
104   readRecursively(aRoot);
105 }
106
107 void Config_XMLReader::processNode(xmlNodePtr theNode)
108 {
109   if (isNode(theNode, NODE_SOURCE, NULL)) {
110     std::string aSourceFile = getProperty(theNode, SOURCE_FILE);
111     Config_XMLReader aSourceReader = Config_XMLReader(aSourceFile);
112     readRecursively(aSourceReader.findRoot());
113 #ifdef _DEBUG
114     //std::cout << "Config_XMLReader::sourced node: " << aSourceFile << std::endl;
115 #endif
116   }
117 }
118
119 void Config_XMLReader::cleanup(xmlNodePtr)
120 {
121   // do nothing;
122 }
123
124 bool Config_XMLReader::processChildren(xmlNodePtr aNode)
125 {
126   return true;
127 }
128
129 xmlNodePtr Config_XMLReader::findRoot()
130 {
131   if (myXmlDoc == NULL) {
132     myXmlDoc = xmlParseFile(myDocumentPath.c_str());
133   }
134   if (myXmlDoc == NULL) {
135 #ifdef _DEBUG
136     std::cout << "Config_XMLReader::import: " << "Document " << myDocumentPath
137     << " is not parsed successfully." << std::endl;
138 #endif
139     return NULL;
140   }
141   xmlNodePtr aRoot = xmlDocGetRootElement(myXmlDoc);
142 #ifdef _DEBUG
143   if(aRoot == NULL) {
144     std::cout << "Config_XMLReader::import: " << "Error: empty document";
145   }
146 #endif
147   return aRoot;
148 }
149
150 void Config_XMLReader::readRecursively(xmlNodePtr theParent)
151 {
152   if (!theParent)
153     return;
154   xmlNodePtr aNode = theParent->xmlChildrenNode;
155   for (; aNode; aNode = aNode->next) {
156     //Still no text processing in features...
157     if (!isElementNode(aNode)) {
158       continue;
159     }
160     processNode(aNode);
161     if (processChildren(aNode)) {
162       readRecursively(aNode);
163     }
164     cleanup(aNode);
165   }
166 }
167
168 xmlNodePtr Config_XMLReader::node(void* theNode)
169 {
170   return static_cast<xmlNodePtr>(theNode);
171 }
172
173 std::string Config_XMLReader::getNodeName(xmlNodePtr theNode)
174 {
175   std::string result = "";
176   char* aPropChars = (char*) theNode->name;
177   if (!aPropChars || aPropChars[0] == 0)
178     return result;
179   result = std::string(aPropChars);
180   return result;
181 }
182
183 void Config_XMLReader::storeAttribute(xmlNodePtr theNode, const char* theAttribute, bool doClean)
184 {
185   std::string aKey = getNodeName(theNode) + ":" + std::string(theAttribute);
186   std::string aValue = getProperty(theNode, theAttribute);
187   if (doClean || !aValue.empty()) {
188     myCachedAttributes[aKey] = aValue;
189   }
190 }
191
192 std::string Config_XMLReader::restoreAttribute(xmlNodePtr theNode, const char* theAttribute)
193 {
194   return restoreAttribute(getNodeName(theNode).c_str(), theAttribute);
195 }
196
197 std::string Config_XMLReader::restoreAttribute(const char* theNodeName, const char* theAttribute)
198 {
199   std::string aKey = std::string(theNodeName) + ":" + std::string(theAttribute);
200   std::string result = "";
201   if(myCachedAttributes.find(aKey) != myCachedAttributes.end()) {
202     result = myCachedAttributes[aKey];
203   }
204   return result;
205 }
206
207 bool Config_XMLReader::cleanupAttribute(xmlNodePtr theNode, const char* theNodeAttribute)
208 {
209   return cleanupAttribute(getNodeName(theNode).c_str(), theNodeAttribute);
210 }
211
212 bool Config_XMLReader::cleanupAttribute(const char* theNodeName, const char* theNodeAttribute)
213 {
214   std::string aKey = std::string(theNodeName) + ":" + std::string(theNodeAttribute);
215   bool result = false;
216   std::map<std::string, std::string>::iterator anEntry = myCachedAttributes.find(aKey);
217   if( anEntry != myCachedAttributes.end()) {
218     myCachedAttributes.erase(anEntry);
219     result = true;
220   }
221   return result;
222 }
223
224 const char* Config_XMLReader::encoding() const
225 {
226   return (const char*) myXmlDoc->encoding;
227 }