Salome HOME
Issue #1860: fix end lines with spaces
[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_InfoMessage.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)
55     Events_InfoMessage("Config_XMLReader", "Unable to open %1").arg(myDocumentPath).send();
56   aTestFile.close();
57 }
58
59 Config_XMLReader::~Config_XMLReader()
60 {
61   xmlFreeDoc(myXmlDoc);
62 }
63
64 std::string Config_XMLReader::pluginConfigFile()
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 + "plugins";
75     }
76   }
77   return aValue;
78 }
79
80 void Config_XMLReader::readAll()
81 {
82   xmlNodePtr aRoot = findRoot();
83   readRecursively(aRoot);
84 }
85
86 void Config_XMLReader::processNode(xmlNodePtr theNode)
87 {
88   if (isNode(theNode, NODE_SOURCE, NULL)) {
89     std::string aSourceFile = getProperty(theNode, SOURCE_FILE);
90     Config_XMLReader aSourceReader = Config_XMLReader(aSourceFile);
91     readRecursively(aSourceReader.findRoot());
92 #ifdef _DEBUG
93     //std::cout << "Config_XMLReader::sourced node: " << aSourceFile << std::endl;
94 #endif
95   }
96 }
97
98 void Config_XMLReader::cleanup(xmlNodePtr)
99 {
100   // do nothing;
101 }
102
103 bool Config_XMLReader::processChildren(xmlNodePtr aNode)
104 {
105   return true;
106 }
107
108 xmlNodePtr Config_XMLReader::findRoot()
109 {
110   if (myXmlDoc == NULL) {
111     myXmlDoc = xmlParseFile(myDocumentPath.c_str());
112   }
113   if (myXmlDoc == NULL) {
114 #ifdef _DEBUG
115     std::cout << "Config_XMLReader::import: " << "Document " << myDocumentPath
116     << " is not parsed successfully." << std::endl;
117 #endif
118     return NULL;
119   }
120   xmlNodePtr aRoot = xmlDocGetRootElement(myXmlDoc);
121 #ifdef _DEBUG
122   if(aRoot == NULL) {
123     std::cout << "Config_XMLReader::import: " << "Error: empty document";
124   }
125 #endif
126   return aRoot;
127 }
128
129 void Config_XMLReader::readRecursively(xmlNodePtr theParent)
130 {
131   if (!theParent)
132     return;
133   xmlNodePtr aNode = theParent->xmlChildrenNode;
134   for (; aNode; aNode = aNode->next) {
135     //Still no text processing in features...
136     if (!isElementNode(aNode)) {
137       continue;
138     }
139     processNode(aNode);
140     if (processChildren(aNode)) {
141       readRecursively(aNode);
142     }
143     cleanup(aNode);
144   }
145 }
146
147 xmlNodePtr Config_XMLReader::node(void* theNode)
148 {
149   return static_cast<xmlNodePtr>(theNode);
150 }
151
152 std::string Config_XMLReader::getNodeName(xmlNodePtr theNode)
153 {
154   std::string result = "";
155   char* aPropChars = (char*) theNode->name;
156   if (!aPropChars || aPropChars[0] == 0)
157     return result;
158   result = std::string(aPropChars);
159   return result;
160 }
161
162 void Config_XMLReader::storeAttribute(xmlNodePtr theNode, const char* theAttribute, bool doClean)
163 {
164   std::string aKey = getNodeName(theNode) + ":" + std::string(theAttribute);
165   std::string aValue = getProperty(theNode, theAttribute);
166   if (doClean || !aValue.empty()) {
167     myCachedAttributes[aKey] = aValue;
168   }
169 }
170
171 std::string Config_XMLReader::restoreAttribute(xmlNodePtr theNode, const char* theAttribute)
172 {
173   return restoreAttribute(getNodeName(theNode).c_str(), theAttribute);
174 }
175
176 std::string Config_XMLReader::restoreAttribute(const char* theNodeName, const char* theAttribute)
177 {
178   std::string aKey = std::string(theNodeName) + ":" + std::string(theAttribute);
179   std::string result = "";
180   if(myCachedAttributes.find(aKey) != myCachedAttributes.end()) {
181     result = myCachedAttributes[aKey];
182   }
183   return result;
184 }
185
186 bool Config_XMLReader::cleanupAttribute(xmlNodePtr theNode, const char* theNodeAttribute)
187 {
188   return cleanupAttribute(getNodeName(theNode).c_str(), theNodeAttribute);
189 }
190
191 bool Config_XMLReader::cleanupAttribute(const char* theNodeName, const char* theNodeAttribute)
192 {
193   std::string aKey = std::string(theNodeName) + ":" + std::string(theNodeAttribute);
194   bool result = false;
195   std::map<std::string, std::string>::iterator anEntry = myCachedAttributes.find(aKey);
196   if( anEntry != myCachedAttributes.end()) {
197     myCachedAttributes.erase(anEntry);
198     result = true;
199   }
200   return result;
201 }
202
203 const char* Config_XMLReader::encoding() const
204 {
205   return (const char*) myXmlDoc->encoding;
206 }