Salome HOME
#1309 Management of icons: parallel icon of SketchPlugin is loaded from it.
[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 Config_XMLReader::Config_XMLReader(const std::string& theXmlFileName)
31     : myXmlDoc(NULL)
32 {
33   std::string prefix = ""; 
34   Config_Prop* aProp = Config_PropManager::findProp("Plugins", "default_path");
35   if (aProp)
36     prefix = aProp->value();
37   /*
38    * Get path to *.xml files (typically ./bin/../plugins/)
39
40    * the problem: application may be launched using python executable,
41    * to use environment variable (at least for the current moment)
42    */
43   if (prefix.empty())
44     prefix = pluginConfigFile();
45
46 #ifdef WIN32
47     prefix += "\\";
48 #else
49     prefix += "/";
50 #endif
51   myDocumentPath = prefix + theXmlFileName;
52   std::ifstream aTestFile(myDocumentPath);
53   if (!aTestFile) Events_Error::send("Unable to open " + myDocumentPath);
54   aTestFile.close();
55 }
56
57 Config_XMLReader::~Config_XMLReader()
58 {
59   xmlFreeDoc(myXmlDoc);
60 }
61
62 std::string Config_XMLReader::pluginConfigFile()
63 {
64   std::string aValue;
65   char* anEnv = getenv("PLUGINS_CONFIG_FILE");
66   if (anEnv) {
67     aValue = std::string(anEnv);
68   }
69   return aValue;
70 }
71
72 void Config_XMLReader::readAll()
73 {
74   xmlNodePtr aRoot = findRoot();
75   readRecursively(aRoot);
76 }
77
78 void Config_XMLReader::processNode(xmlNodePtr theNode)
79 {
80   if (isNode(theNode, NODE_SOURCE, NULL)) {
81     std::string aSourceFile = getProperty(theNode, SOURCE_FILE);
82     Config_XMLReader aSourceReader = Config_XMLReader(aSourceFile);
83     readRecursively(aSourceReader.findRoot());
84 #ifdef _DEBUG
85     //std::cout << "Config_XMLReader::sourced node: " << aSourceFile << std::endl;
86 #endif
87   }
88 }
89
90 void Config_XMLReader::cleanup(xmlNodePtr)
91 {
92   // do nothing;
93 }
94
95 bool Config_XMLReader::processChildren(xmlNodePtr aNode)
96 {
97   return true;
98 }
99
100 xmlNodePtr Config_XMLReader::findRoot()
101 {
102   if (myXmlDoc == NULL) {
103     myXmlDoc = xmlParseFile(myDocumentPath.c_str());
104   }
105   if (myXmlDoc == NULL) {
106 #ifdef _DEBUG
107     std::cout << "Config_XMLReader::import: " << "Document " << myDocumentPath
108     << " is not parsed successfully." << std::endl;
109 #endif
110     return NULL;
111   }
112   xmlNodePtr aRoot = xmlDocGetRootElement(myXmlDoc);
113 #ifdef _DEBUG
114   if(aRoot == NULL) {
115     std::cout << "Config_XMLReader::import: " << "Error: empty document";
116   }
117 #endif
118   return aRoot;
119 }
120
121 void Config_XMLReader::readRecursively(xmlNodePtr theParent)
122 {
123   if (!theParent)
124     return;
125   xmlNodePtr aNode = theParent->xmlChildrenNode;
126   for (; aNode; aNode = aNode->next) {
127     //Still no text processing in features...
128     if (!isElementNode(aNode)) {
129       continue;
130     }
131     processNode(aNode);
132     if (processChildren(aNode)) {
133       readRecursively(aNode);
134     }
135     cleanup(aNode);
136   }
137 }
138
139 xmlNodePtr Config_XMLReader::node(void* theNode)
140 {
141   return static_cast<xmlNodePtr>(theNode);
142 }
143
144 std::string Config_XMLReader::getNodeName(xmlNodePtr theNode)
145 {
146   std::string result = "";
147   char* aPropChars = (char*) theNode->name;
148   if (!aPropChars || aPropChars[0] == 0)
149     return result;
150   result = std::string(aPropChars);
151   return result;
152 }
153
154 void Config_XMLReader::storeAttribute(xmlNodePtr theNode, const char* theAttribute, bool doClean)
155 {
156   std::string aKey = getNodeName(theNode) + ":" + std::string(theAttribute);
157   std::string aValue = getProperty(theNode, theAttribute);
158   if (doClean || !aValue.empty()) {
159     myCachedAttributes[aKey] = aValue;
160   }
161 }
162
163 std::string Config_XMLReader::restoreAttribute(xmlNodePtr theNode, const char* theAttribute)
164 {
165   return restoreAttribute(getNodeName(theNode).c_str(), theAttribute);
166 }
167
168 std::string Config_XMLReader::restoreAttribute(const char* theNodeName, const char* theAttribute)
169 {
170   std::string aKey = std::string(theNodeName) + ":" + std::string(theAttribute);
171   std::string result = "";
172   if(myCachedAttributes.find(aKey) != myCachedAttributes.end()) {
173     result = myCachedAttributes[aKey];
174   }
175   return result;
176 }
177
178 bool Config_XMLReader::cleanupAttribute(xmlNodePtr theNode, const char* theNodeAttribute)
179 {
180   return cleanupAttribute(getNodeName(theNode).c_str(), theNodeAttribute);
181 }
182
183 bool Config_XMLReader::cleanupAttribute(const char* theNodeName, const char* theNodeAttribute)
184 {
185   std::string aKey = std::string(theNodeName) + ":" + std::string(theNodeAttribute);
186   bool result = false;
187   std::map<std::string, std::string>::iterator anEntry = myCachedAttributes.find(aKey);
188   if( anEntry != myCachedAttributes.end()) {
189     myCachedAttributes.erase(anEntry);
190     result = true;
191   }
192   return result;
193 }