Salome HOME
Processing of 'selection_filter' xml nodes added.
[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 #include <Config_ValidatorMessage.h>
12 #include <Config_SelectionFilterMessage.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 /*
66  * Read all nodes in associated xml file,
67  * recursively if processChildren(xmlNode) is true for the xmlNode.
68  * For each read node the processNode will be called.
69  */
70 void Config_XMLReader::readAll()
71 {
72   xmlNodePtr aRoot = findRoot();
73   readRecursively(aRoot);
74 }
75
76 /*
77  * Allows to customize reader's behavior for a node. Virtual.
78  * The default impl does nothing. (In debug mode prints
79  * some info)
80  */
81 void Config_XMLReader::processNode(xmlNodePtr theNode)
82 {
83   if (isNode(theNode, NODE_SOURCE, NULL)) {
84     std::string aSourceFile = getProperty(theNode, SOURCE_FILE);
85     Config_XMLReader aSourceReader = Config_XMLReader(aSourceFile);
86     readRecursively(aSourceReader.findRoot());
87 #ifdef _DEBUG
88     std::cout << "Config_XMLReader::sourced node: " << aSourceFile << std::endl;
89 #endif
90   } else if (isNode(theNode, NODE_VALIDATOR, NULL)) {
91     processValidator(theNode);
92   } else if (isNode(theNode, NODE_SELFILTER, NULL)) {
93     processSelectionFilter(theNode);
94   }
95 }
96
97 /*
98  * Defines which nodes should be processed recursively. Virtual.
99  * The default impl is to read all nodes.
100  */
101 bool Config_XMLReader::processChildren(xmlNodePtr aNode)
102 {
103   return true;
104 }
105
106 /*
107  *
108  */
109 xmlNodePtr Config_XMLReader::findRoot()
110 {
111   if (myXmlDoc == NULL) {
112     myXmlDoc = xmlParseFile(myDocumentPath.c_str());
113   }
114   if (myXmlDoc == NULL) {
115 #ifdef _DEBUG
116     std::cout << "Config_XMLReader::import: " << "Document " << myDocumentPath
117     << " is not parsed successfully." << std::endl;
118 #endif
119     return NULL;
120   }
121   xmlNodePtr aRoot = xmlDocGetRootElement(myXmlDoc);
122 #ifdef _DEBUG
123   if(aRoot == NULL) {
124     std::cout << "Config_XMLReader::import: " << "Error: empty document";
125   }
126 #endif
127   return aRoot;
128 }
129
130 /*
131  * Calls processNode() for each child (for some - recursively)
132  * of the given node.
133  * \sa ReadAll()
134  */
135 void Config_XMLReader::readRecursively(xmlNodePtr theParent)
136 {
137   if (!theParent)
138     return;
139   xmlNodePtr aNode = theParent->xmlChildrenNode;
140   for (; aNode; aNode = aNode->next) {
141     //Still no text processing in features...
142     if (!isElementNode(aNode)) {
143       continue;
144     }
145     processNode(aNode);
146     if (processChildren(aNode)) {
147       readRecursively(aNode);
148     }
149   }
150 }
151
152 /*
153  * void* -> xmlNodePtr
154  */
155 xmlNodePtr Config_XMLReader::node(void* theNode)
156 {
157   return static_cast<xmlNodePtr>(theNode);
158 }
159
160 std::string Config_XMLReader::getNodeName(xmlNodePtr theNode)
161 {
162   std::string result = "";
163   char* aPropChars = (char*) theNode->name;
164   if (!aPropChars || aPropChars[0] == 0)
165     return result;
166   result = std::string(aPropChars);
167   return result;
168 }
169
170 void Config_XMLReader::processValidator(xmlNodePtr theNode)
171 {
172   Events_ID aValidatoEvent = Events_Loop::eventByName(EVENT_VALIDATOR_LOADED);
173   Events_Loop* aEvLoop = Events_Loop::loop();
174   std::shared_ptr<Config_ValidatorMessage> 
175     aMessage(new Config_ValidatorMessage(aValidatoEvent, this));
176   std::string aValidatorId;
177   std::list<std::string> aValidatorParameters;
178   getValidatorInfo(theNode, aValidatorId, aValidatorParameters);
179   aMessage->setValidatorId(aValidatorId);
180   aMessage->setValidatorParameters(aValidatorParameters);
181   xmlNodePtr aFeatureOrWdgNode = theNode->parent;
182   if (isNode(aFeatureOrWdgNode, NODE_FEATURE, NULL)) {
183     aMessage->setFeatureId(getProperty(aFeatureOrWdgNode, _ID));
184   } else {
185     aMessage->setAttributeId(getProperty(aFeatureOrWdgNode, _ID));
186     aMessage->setFeatureId(myCurrentFeature);
187   }
188   aEvLoop->send(aMessage);
189 }
190
191 void Config_XMLReader::processSelectionFilter(xmlNodePtr theNode)
192 {
193   Events_ID aFilterEvent = Events_Loop::eventByName(EVENT_SELFILTER_LOADED);
194   Events_Loop* aEvLoop = Events_Loop::loop();
195   std::shared_ptr<Config_SelectionFilterMessage> aMessage =
196       std::make_shared<Config_SelectionFilterMessage>(aFilterEvent, this);
197   std::string aSelectionFilterId = getProperty(theNode, _ID);
198   aMessage->setSelectionFilterId(aSelectionFilterId);
199   xmlNodePtr aFeatureOrWdgNode = theNode->parent;
200   if (isNode(aFeatureOrWdgNode, NODE_FEATURE, NULL)) {
201     aMessage->setFeatureId(getProperty(aFeatureOrWdgNode, _ID));
202   } else {
203     aMessage->setAttributeId(getProperty(aFeatureOrWdgNode, _ID));
204     aMessage->setFeatureId(myCurrentFeature);
205   }
206   aEvLoop->send(aMessage);
207 }