Salome HOME
Merge branch 'master' of newgeom:newgeom.git
[modules/shaper.git] / src / Config / Config_XMLReader.cpp
1 /*
2  * Config_XMLReader.cpp
3  *
4  *  Created on: Mar 14, 2014
5  *      Author: sbh
6  */
7
8 #include <Config_XMLReader.h>
9 #include <Config_Keywords.h>
10 #include <Config_Common.h>
11
12 #include <Events_Loop.h>
13 #include <libxml/parser.h>
14 #include <libxml/tree.h>
15
16 /*
17 #ifdef WIN32
18 //For GetModuleFileNameW
19 #include <windows.h>
20 #endif
21 */
22
23 #ifdef _DEBUG
24 #include <iostream>
25 #endif
26
27 Config_XMLReader::Config_XMLReader(const std::string& theXmlFileName)
28     : myXmlDoc(NULL)
29 {
30   std::string prefix = "";
31   /*
32    * Get path to *.xml files (typically ./bin/../plugins/)
33
34    * the problem: application may be launched using python executable,
35    * to use environment variable (at least for the current moment)
36    */
37   char* anEnv = getenv("NEW_GEOM_CONFIG_FILE");
38   if (anEnv) {
39     prefix = std::string(anEnv) + "/";
40   }
41
42   myDocumentPath = prefix + theXmlFileName;
43 }
44
45 Config_XMLReader::~Config_XMLReader()
46 {
47   xmlFreeDoc(myXmlDoc);
48 }
49
50 /*
51  * Read all nodes in associated xml file,
52  * recursively if processChildren(xmlNode) is true for the xmlNode.
53  * For each read node the processNode will be called.
54  */
55 void Config_XMLReader::readAll()
56 {
57   xmlNodePtr aRoot = findRoot();
58   readRecursively(aRoot);
59 }
60
61 /*
62  * Allows to customize reader's behavior for a node. Virtual.
63  * The default impl does nothing. (In debug mode prints
64  * some info)
65  */
66 void Config_XMLReader::processNode(xmlNodePtr theNode)
67 {
68   if (isNode(theNode, NODE_SOURCE, NULL)) {
69     std::string aSourceFile = getProperty(theNode, SOURCE_FILE);
70     Config_XMLReader aSourceReader = Config_XMLReader(aSourceFile);
71     readRecursively(aSourceReader.findRoot());
72     #ifdef _DEBUG
73     std::cout << "Config_XMLReader::sourced node: " << aSourceFile << std::endl;
74     #endif
75   }
76 }
77
78 /*
79  * Defines which nodes should be processed recursively. Virtual.
80  * The default impl is to read all nodes.
81  */
82 bool Config_XMLReader::processChildren(xmlNodePtr aNode)
83 {
84   return true;
85 }
86
87 /*
88  *
89  */
90 xmlNodePtr Config_XMLReader::findRoot()
91 {
92   myXmlDoc = xmlParseFile(myDocumentPath.c_str());
93   if (myXmlDoc == NULL) {
94 #ifdef _DEBUG
95     std::cout << "Config_XMLReader::import: " << "Document " << myDocumentPath
96     << " is not parsed successfully." << std::endl;
97 #endif
98     return NULL;
99   }
100   xmlNodePtr aRoot = xmlDocGetRootElement(myXmlDoc);
101 #ifdef _DEBUG
102   if(aRoot == NULL) {
103     std::cout << "Config_XMLReader::import: " << "Error: empty document";
104   }
105 #endif
106   return aRoot;
107 }
108
109 /*
110  * Calls processNode() for each child (for some - recursively)
111  * of the given node.
112  * \sa ReadAll()
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     processNode(aNode);
121     if (processChildren(aNode)) {
122       readRecursively(aNode);
123     }
124   }
125 }
126
127 /*
128  * void* -> xmlNodePtr
129  */
130 xmlNodePtr Config_XMLReader::node(void* theNode)
131 {
132   return static_cast<xmlNodePtr>(theNode);
133 }
134
135 /*
136  * Returns named property for a given node as std::string.
137  */
138 std::string Config_XMLReader::getProperty(xmlNodePtr theNode, const char* name)
139 {
140   std::string result = "";
141   char* aPropChars = (char*) xmlGetProp(theNode, BAD_CAST name);
142   if (!aPropChars || aPropChars[0] == 0)
143     return result;
144   result = std::string(aPropChars);
145   return result;
146 }
147