Salome HOME
Merge branch 'master' of salome:modules/shaper
[modules/shaper.git] / src / Config / Config_XMLReader.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 /*
4  * Config_XMLReader.cpp
5  *
6  *  Created on: Mar 14, 2014
7  *      Author: sbh
8  */
9
10 #include <Config_XMLReader.h>
11 #include <Config_Keywords.h>
12 #include <Config_Common.h>
13 #include <Config_PropManager.h>
14
15 #include <Events_Loop.h>
16 #include <Events_Error.h>
17 #include <libxml/parser.h>
18 #include <libxml/tree.h>
19
20 #include <fstream>
21
22 #ifdef WIN32
23 #pragma warning(disable : 4996) // for getenv
24 #endif
25
26 #ifdef _DEBUG
27 #include <iostream>
28 #endif
29
30 #ifdef WIN32
31     static const char FSEP = '\\';
32 #else
33     static const char FSEP = '/';
34 #endif
35
36 Config_XMLReader::Config_XMLReader(const std::string& theXmlFileName)
37     : myXmlDoc(NULL)
38 {
39   std::string prefix = ""; 
40   Config_Prop* aProp = Config_PropManager::findProp("Plugins", "default_path");
41   if (aProp)
42     prefix = aProp->value();
43   /*
44    * Get path to *.xml files (typically ./bin/../plugins/)
45
46    * the problem: application may be launched using python executable,
47    * to use environment variable (at least for the current moment)
48    */
49   if (prefix.empty())
50     prefix = pluginConfigFile();
51
52   myDocumentPath = prefix + FSEP + theXmlFileName;
53   std::ifstream aTestFile(myDocumentPath);
54   if (!aTestFile) Events_Error::send("Unable to open " + myDocumentPath);
55   aTestFile.close();
56 }
57
58 Config_XMLReader::~Config_XMLReader()
59 {
60   xmlFreeDoc(myXmlDoc);
61 }
62
63 std::string Config_XMLReader::pluginConfigFile()
64 {
65   std::string aValue;
66   char* anEnv = getenv("SHAPER_ROOT_DIR");
67   if (anEnv) {
68     aValue = std::string(anEnv) +
69       FSEP + "share" + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper";
70   } else {
71     anEnv = getenv("OPENPARTS_ROOT_DIR");
72     if (anEnv) {
73       aValue = std::string(anEnv) + FSEP + "plugins";
74     }
75   }
76   return aValue;
77 }
78
79 void Config_XMLReader::readAll()
80 {
81   xmlNodePtr aRoot = findRoot();
82   readRecursively(aRoot);
83 }
84
85 void Config_XMLReader::processNode(xmlNodePtr theNode)
86 {
87   if (isNode(theNode, NODE_SOURCE, NULL)) {
88     std::string aSourceFile = getProperty(theNode, SOURCE_FILE);
89     Config_XMLReader aSourceReader = Config_XMLReader(aSourceFile);
90     readRecursively(aSourceReader.findRoot());
91 #ifdef _DEBUG
92     //std::cout << "Config_XMLReader::sourced node: " << aSourceFile << std::endl;
93 #endif
94   }
95 }
96
97 void Config_XMLReader::cleanup(xmlNodePtr)
98 {
99   // do nothing;
100 }
101
102 bool Config_XMLReader::processChildren(xmlNodePtr aNode)
103 {
104   return true;
105 }
106
107 xmlNodePtr Config_XMLReader::findRoot()
108 {
109   if (myXmlDoc == NULL) {
110     myXmlDoc = xmlParseFile(myDocumentPath.c_str());
111   }
112   if (myXmlDoc == NULL) {
113 #ifdef _DEBUG
114     std::cout << "Config_XMLReader::import: " << "Document " << myDocumentPath
115     << " is not parsed successfully." << std::endl;
116 #endif
117     return NULL;
118   }
119   xmlNodePtr aRoot = xmlDocGetRootElement(myXmlDoc);
120 #ifdef _DEBUG
121   if(aRoot == NULL) {
122     std::cout << "Config_XMLReader::import: " << "Error: empty document";
123   }
124 #endif
125   return aRoot;
126 }
127
128 void Config_XMLReader::readRecursively(xmlNodePtr theParent)
129 {
130   if (!theParent)
131     return;
132   xmlNodePtr aNode = theParent->xmlChildrenNode;
133   for (; aNode; aNode = aNode->next) {
134     //Still no text processing in features...
135     if (!isElementNode(aNode)) {
136       continue;
137     }
138     processNode(aNode);
139     if (processChildren(aNode)) {
140       readRecursively(aNode);
141     }
142     cleanup(aNode);
143   }
144 }
145
146 xmlNodePtr Config_XMLReader::node(void* theNode)
147 {
148   return static_cast<xmlNodePtr>(theNode);
149 }
150
151 std::string Config_XMLReader::getNodeName(xmlNodePtr theNode)
152 {
153   std::string result = "";
154   char* aPropChars = (char*) theNode->name;
155   if (!aPropChars || aPropChars[0] == 0)
156     return result;
157   result = std::string(aPropChars);
158   return result;
159 }
160
161 void Config_XMLReader::storeAttribute(xmlNodePtr theNode, const char* theAttribute, bool doClean)
162 {
163   std::string aKey = getNodeName(theNode) + ":" + std::string(theAttribute);
164   std::string aValue = getProperty(theNode, theAttribute);
165   if (doClean || !aValue.empty()) {
166     myCachedAttributes[aKey] = aValue;
167   }
168 }
169
170 std::string Config_XMLReader::restoreAttribute(xmlNodePtr theNode, const char* theAttribute)
171 {
172   return restoreAttribute(getNodeName(theNode).c_str(), theAttribute);
173 }
174
175 std::string Config_XMLReader::restoreAttribute(const char* theNodeName, const char* theAttribute)
176 {
177   std::string aKey = std::string(theNodeName) + ":" + std::string(theAttribute);
178   std::string result = "";
179   if(myCachedAttributes.find(aKey) != myCachedAttributes.end()) {
180     result = myCachedAttributes[aKey];
181   }
182   return result;
183 }
184
185 bool Config_XMLReader::cleanupAttribute(xmlNodePtr theNode, const char* theNodeAttribute)
186 {
187   return cleanupAttribute(getNodeName(theNode).c_str(), theNodeAttribute);
188 }
189
190 bool Config_XMLReader::cleanupAttribute(const char* theNodeName, const char* theNodeAttribute)
191 {
192   std::string aKey = std::string(theNodeName) + ":" + std::string(theNodeAttribute);
193   bool result = false;
194   std::map<std::string, std::string>::iterator anEntry = myCachedAttributes.find(aKey);
195   if( anEntry != myCachedAttributes.end()) {
196     myCachedAttributes.erase(anEntry);
197     result = true;
198   }
199   return result;
200 }