]> SALOME platform Git repositories - modules/geom.git/blob - src/GEOMUtils/GEOMUtils_XmlHandler.cxx
Salome HOME
Update copyrights
[modules/geom.git] / src / GEOMUtils / GEOMUtils_XmlHandler.cxx
1 // Copyright (C) 2013-2019  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "GEOMUtils_XmlHandler.hxx"
21
22 #include <libxml/parser.h>
23 #include <algorithm>
24
25 #ifdef WIN32
26 #include <windows.h>
27 #else
28 #include <unistd.h>
29 #endif
30
31 //#define MYDEBUG
32
33 namespace
34 {
35   const char*    env_var     = "GEOM_PluginsList";
36   
37   const xmlChar* root_tag    = (xmlChar*)"geom-plugins";
38   const xmlChar* plugin_tag  = (xmlChar*)"geom-plugin";
39   const xmlChar* name_tag    = (xmlChar*)"name";
40   const xmlChar* server_tag  = (xmlChar*)"server-lib";
41   const xmlChar* gui_tag     = (xmlChar*)"gui-lib";
42   const xmlChar* actions_tag = (xmlChar*)"actions";
43   const xmlChar* action_tag  = (xmlChar*)"action";
44   const xmlChar* label_tag   = (xmlChar*)"label";
45   const xmlChar* icon_tag    = (xmlChar*)"icon";
46   const xmlChar* menu_tag    = (xmlChar*)"menu";
47   const xmlChar* tooltip_tag = (xmlChar*)"tooltip";
48   const xmlChar* status_tag  = (xmlChar*)"status-bar";
49   const xmlChar* accel_tag   = (xmlChar*)"accel";
50
51   std::string toUpper( const std::string& s )
52   {
53     std::string r = s;
54     std::transform( r.begin(), r.end(), r.begin(), toupper );
55     return r;
56   }
57
58   std::string toLower( const std::string& s )
59   {
60     std::string r = s;
61     std::transform( r.begin(), r.end(), r.begin(), tolower );
62     return r;
63   }
64
65   std::string readXmlAttribute(xmlNodePtr node, const xmlChar* attribute)
66   {
67     std::string result = "";
68     xmlChar* strAttr = xmlGetProp(node, attribute);
69     if (strAttr != NULL) {
70       result = (char*)strAttr;
71       xmlFree(strAttr);
72     }
73     return result;
74   }
75
76   std::list<std::string> getPluginXMLFiles()
77   {
78     std::list<std::string> xmlPaths;
79
80 #ifdef WIN32
81     std::string sep = "\\";
82 #else
83     std::string sep = "/";
84 #endif
85
86     if ( const char* var = getenv( env_var ) )
87     {
88       std::string plugins = var;
89
90       std::string::size_type from = 0, pos;
91       while ( from < plugins.size() )
92       {
93         pos = plugins.find( ':', from );
94         std::string plugin;
95         if ( pos != std::string::npos )
96           plugin = plugins.substr( from, pos-from );
97         else
98           plugin = plugins.substr( from ), pos = plugins.size();
99         from = pos + 1;
100         
101         if ( plugin.size() == 0 ) continue;
102         
103         std::string pluginRoot    = toUpper( plugin+"_ROOT_DIR" );
104
105         const char* rootDirGeom   = getenv( "GEOM_ROOT_DIR" );
106         const char* rootDirPlugin = getenv( pluginRoot.c_str() );
107
108         bool fileOK = false;
109         if ( rootDirGeom ) {
110           std::string xmlPath = rootDirGeom;
111           if ( xmlPath[ xmlPath.size()-1 ] != sep[0] )
112             xmlPath += sep;
113           xmlPath += "share" + sep + "salome" + sep + "resources" + sep + "geom" + sep + plugin + ".xml";
114 #ifdef WIN32
115
116 #ifdef UNICODE
117           //RNV: this is workaround for providing compilation,
118           //     path should be processed as unicode string.
119           size_t length = strlen(xmlPath.c_str()) + sizeof(char);
120           wchar_t* aPath = new wchar_t[length + 1];
121           memset(aPath, '\0', length);
122           mbstowcs(aPath, xmlPath.c_str(), length);
123 #else
124           const char* aPath = xmlPath.c_str();
125 #endif
126           fileOK = (GetFileAttributes(aPath) != INVALID_FILE_ATTRIBUTES);
127 #if UNICODE
128           delete aPath;
129 #endif
130 #else
131           fileOK = (access(xmlPath.c_str(), F_OK) == 0);
132 #endif
133           if ( fileOK )
134             xmlPaths.push_back( xmlPath );
135         }
136         if ( !fileOK && rootDirPlugin ) {
137           std::string xmlPath = rootDirPlugin;
138           if ( xmlPath[ xmlPath.size()-1 ] != sep[0] )
139             xmlPath += sep;
140           xmlPath += "share" + sep + "salome" + sep + "resources" + sep + toLower(plugin) + sep + plugin + ".xml";
141 #ifdef WIN32      
142 #ifdef UNICODE
143           size_t length = strlen(xmlPath.c_str()) + sizeof(char);
144           wchar_t* aPath = new wchar_t[length+1];
145           memset(aPath, '\0', length);
146           mbstowcs(aPath, xmlPath.c_str(), length);
147 #else
148           const char* aPath = xmlPath.c_str();
149 #endif
150           fileOK = (GetFileAttributes(aPath) != INVALID_FILE_ATTRIBUTES);
151 #if UNICODE
152           delete aPath;
153 #endif
154 #else
155           fileOK = (access(xmlPath.c_str(), F_OK) == 0);
156 #endif
157           if ( fileOK )
158             xmlPaths.push_back( xmlPath );
159         }
160       }
161     }
162     return xmlPaths;
163   }
164
165 #ifdef MYDEBUG
166   void dumpinfo(const GEOMUtils::PluginInfo& info)
167   {
168     printf("DUMPING PLUGIN INFO\n");
169     GEOMUtils::PluginInfo::const_iterator it;
170     for (it = info.begin(); it != info.end(); ++it) {
171       GEOMUtils::PluginData pdata = *it;
172       printf("Plugin: %s\n", pdata.name.c_str());
173       printf("  serverLib = %s\n", pdata.serverLib.c_str());
174       printf("  clientLib = %s\n", pdata.clientLib.c_str());
175       printf("  actions:\n");
176       std::list<GEOMUtils::ActionData>::const_iterator ait;
177       for (ait = pdata.actions.begin(); ait != pdata.actions.end(); ++ait) {
178         GEOMUtils::ActionData adata = *ait;
179         printf("     label      = %s\n", adata.label.c_str());
180         printf("     icon       = %s\n", adata.icon.c_str());
181         printf("     menuText   = %s\n", adata.menuText.c_str());
182         printf("     toolTip    = %s\n", adata.toolTip.c_str());
183         printf("     statusText = %s\n", adata.statusText.c_str());
184         printf("\n");
185       }
186       printf("-----\n");
187     }
188   }
189 #endif
190 }
191
192 namespace GEOMUtils
193 {
194   PluginInfo ReadPluginInfo()
195   {
196     PluginInfo info;
197
198     std::list<std::string> xmlPaths = getPluginXMLFiles();
199
200     std::list<std::string>::const_iterator fit;
201
202     for ( fit = xmlPaths.begin(); fit != xmlPaths.end(); ++fit )
203     {
204       std::string fileName = *fit;
205       
206       int options = XML_PARSE_HUGE | XML_PARSE_NOCDATA;
207       xmlDocPtr doc = xmlReadFile( fileName.c_str(), NULL, options );
208       
209       if ( doc )
210       {
211         // get root node
212         xmlNodePtr root = xmlDocGetRootElement(doc);
213         
214         // check if it is plugins container node
215         if (xmlStrcmp(root->name, root_tag) == 0)
216         {
217           // iterate through children, to get plugins data
218           for (xmlNodePtr node = root->children; node; node = node->next)
219           {
220             if (xmlStrcmp(node->name, plugin_tag) == 0)
221             {
222               // plugin node
223               PluginData data;
224               data.name      = readXmlAttribute(node, name_tag);
225               data.serverLib = readXmlAttribute(node, server_tag);
226               data.clientLib = readXmlAttribute(node, gui_tag);
227               // iterate through children, to find actions container node
228               for (xmlNodePtr subnode = node->children; subnode; subnode = subnode->next)
229               {
230                 if (xmlStrcmp(subnode->name, actions_tag) == 0)
231                 {
232                   // actions container node
233                   // iterate through children, to get actions data
234                   for (xmlNodePtr subsubnode = subnode->children; subsubnode; subsubnode = subsubnode->next)
235                   {
236                     if (xmlStrcmp(subsubnode->name, action_tag) == 0)
237                     {
238                       // action node
239                       ActionData action;
240                       action.label      = readXmlAttribute(subsubnode, label_tag);
241                       action.icon       = readXmlAttribute(subsubnode, icon_tag);
242                       action.menuText   = readXmlAttribute(subsubnode, menu_tag);
243                       action.toolTip    = readXmlAttribute(subsubnode, tooltip_tag);
244                       action.statusText = readXmlAttribute(subsubnode, status_tag);
245                       action.accel      = readXmlAttribute(subsubnode, accel_tag);
246                       if (action.label != "")
247                         data.actions.push_back(action);
248                     } // end action node
249                   } // end iteration through actions container node children
250                 } // end actions container node
251               } // end iterations through plugin node children
252               
253               if (data.name != "")
254                 info.push_back(data);
255             } // end plugin node
256           } // end iterations through plugins container node children
257         } // end root node
258         
259         xmlFreeDoc(doc);
260         //xmlCleanupParser();//vsr: xmlCleanupParser should not be called from the application
261       } // end xml doc
262     }
263 #ifdef MYDEBUG
264     dumpinfo(info);
265 #endif
266     return info;
267   }
268 }