Salome HOME
Merge branch 'master' into Dev_1.1.0
[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     char* anEnv = getenv("NEW_GEOM_CONFIG_FILE");
45     if (anEnv) {
46       prefix = std::string(anEnv);
47     }
48   }
49 #ifdef WIN32
50     prefix += "\\";
51 #else
52     prefix += "/";
53 #endif
54   myDocumentPath = prefix + theXmlFileName;
55   std::ifstream aTestFile(myDocumentPath);
56   if (!aTestFile) Events_Error::send("Unable to open " + myDocumentPath);
57   aTestFile.close();
58 }
59
60 Config_XMLReader::~Config_XMLReader()
61 {
62   xmlFreeDoc(myXmlDoc);
63 }
64
65 void Config_XMLReader::readAll()
66 {
67   xmlNodePtr aRoot = findRoot();
68   readRecursively(aRoot);
69 }
70
71 void Config_XMLReader::processNode(xmlNodePtr theNode)
72 {
73   if (isNode(theNode, NODE_SOURCE, NULL)) {
74     std::string aSourceFile = getProperty(theNode, SOURCE_FILE);
75     Config_XMLReader aSourceReader = Config_XMLReader(aSourceFile);
76     readRecursively(aSourceReader.findRoot());
77 #ifdef _DEBUG
78     //std::cout << "Config_XMLReader::sourced node: " << aSourceFile << std::endl;
79 #endif
80   }
81 }
82
83 void Config_XMLReader::cleanup(xmlNodePtr)
84 {
85   // do nothing;
86 }
87
88 bool Config_XMLReader::processChildren(xmlNodePtr aNode)
89 {
90   return true;
91 }
92
93 xmlNodePtr Config_XMLReader::findRoot()
94 {
95   if (myXmlDoc == NULL) {
96     myXmlDoc = xmlParseFile(myDocumentPath.c_str());
97   }
98   if (myXmlDoc == NULL) {
99 #ifdef _DEBUG
100     std::cout << "Config_XMLReader::import: " << "Document " << myDocumentPath
101     << " is not parsed successfully." << std::endl;
102 #endif
103     return NULL;
104   }
105   xmlNodePtr aRoot = xmlDocGetRootElement(myXmlDoc);
106 #ifdef _DEBUG
107   if(aRoot == NULL) {
108     std::cout << "Config_XMLReader::import: " << "Error: empty document";
109   }
110 #endif
111   return aRoot;
112 }
113
114 void Config_XMLReader::readRecursively(xmlNodePtr theParent)
115 {
116   if (!theParent)
117     return;
118   xmlNodePtr aNode = theParent->xmlChildrenNode;
119   for (; aNode; aNode = aNode->next) {
120     //Still no text processing in features...
121     if (!isElementNode(aNode)) {
122       continue;
123     }
124     processNode(aNode);
125     if (processChildren(aNode)) {
126       readRecursively(aNode);
127     }
128     cleanup(aNode);
129   }
130 }
131
132 xmlNodePtr Config_XMLReader::node(void* theNode)
133 {
134   return static_cast<xmlNodePtr>(theNode);
135 }
136
137 std::string Config_XMLReader::getNodeName(xmlNodePtr theNode)
138 {
139   std::string result = "";
140   char* aPropChars = (char*) theNode->name;
141   if (!aPropChars || aPropChars[0] == 0)
142     return result;
143   result = std::string(aPropChars);
144   return result;
145 }
146
147 void Config_XMLReader::storeAttribute(xmlNodePtr theNode, const char* theAttribute)
148 {
149   std::string aKey = getNodeName(theNode) + ":" + std::string(theAttribute);
150   std::string aValue = getProperty(theNode, theAttribute);
151   if(!aValue.empty()) {
152     myCachedAttributes[aKey] = aValue;
153   }
154 }
155
156 std::string Config_XMLReader::restoreAttribute(xmlNodePtr theNode, const char* theAttribute)
157 {
158   return restoreAttribute(getNodeName(theNode).c_str(), theAttribute);
159 }
160
161 std::string Config_XMLReader::restoreAttribute(const char* theNodeName, const char* theAttribute)
162 {
163   std::string aKey = std::string(theNodeName) + ":" + std::string(theAttribute);
164   std::string result = "";
165   if(myCachedAttributes.find(aKey) != myCachedAttributes.end()) {
166     result = myCachedAttributes[aKey];
167   }
168   return result;
169 }
170
171 bool Config_XMLReader::cleanupAttribute(xmlNodePtr theNode, const char* theNodeAttribute)
172 {
173   return cleanupAttribute(getNodeName(theNode).c_str(), theNodeAttribute);
174 }
175
176 bool Config_XMLReader::cleanupAttribute(const char* theNodeName, const char* theNodeAttribute)
177 {
178   std::string aKey = std::string(theNodeName) + ":" + std::string(theNodeAttribute);
179   bool result = false;
180   std::map<std::string, std::string>::iterator anEntry = myCachedAttributes.find(aKey);
181   if( anEntry != myCachedAttributes.end()) {
182     myCachedAttributes.erase(anEntry);
183     result = true;
184   }
185   return result;
186 }