Salome HOME
Fix some compilation warnings
[modules/geom.git] / src / GEOMUtils / GEOMUtils_XmlHandler.cxx
1 // Copyright (C) 2013-2016  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           fileOK = (GetFileAttributes(xmlPath.c_str()) != INVALID_FILE_ATTRIBUTES);
116 #else
117           fileOK = (access(xmlPath.c_str(), F_OK) == 0);
118 #endif
119           if ( fileOK )
120             xmlPaths.push_back( xmlPath );
121         }
122         if ( !fileOK && rootDirPlugin ) {
123           std::string xmlPath = rootDirPlugin;
124           if ( xmlPath[ xmlPath.size()-1 ] != sep[0] )
125             xmlPath += sep;
126           xmlPath += "share" + sep + "salome" + sep + "resources" + sep + toLower(plugin) + sep + plugin + ".xml";
127 #ifdef WIN32
128           fileOK = (GetFileAttributes(xmlPath.c_str()) != INVALID_FILE_ATTRIBUTES);
129 #else
130           fileOK = (access(xmlPath.c_str(), F_OK) == 0);
131 #endif
132           if ( fileOK )
133             xmlPaths.push_back( xmlPath );
134         }
135       }
136     }
137     return xmlPaths;
138   }
139
140 #ifdef MYDEBUG
141   void dumpinfo(const GEOMUtils::PluginInfo& info)
142   {
143     printf("DUMPING PLUGIN INFO\n");
144     GEOMUtils::PluginInfo::const_iterator it;
145     for (it = info.begin(); it != info.end(); ++it) {
146       GEOMUtils::PluginData pdata = *it;
147       printf("Plugin: %s\n", pdata.name.c_str());
148       printf("  serverLib = %s\n", pdata.serverLib.c_str());
149       printf("  clientLib = %s\n", pdata.clientLib.c_str());
150       printf("  actions:\n");
151       std::list<GEOMUtils::ActionData>::const_iterator ait;
152       for (ait = pdata.actions.begin(); ait != pdata.actions.end(); ++ait) {
153         GEOMUtils::ActionData adata = *ait;
154         printf("     label      = %s\n", adata.label.c_str());
155         printf("     icon       = %s\n", adata.icon.c_str());
156         printf("     menuText   = %s\n", adata.menuText.c_str());
157         printf("     toolTip    = %s\n", adata.toolTip.c_str());
158         printf("     statusText = %s\n", adata.statusText.c_str());
159         printf("\n");
160       }
161       printf("-----\n");
162     }
163   }
164 #endif
165 }
166
167 namespace GEOMUtils
168 {
169   PluginInfo ReadPluginInfo()
170   {
171     PluginInfo info;
172
173     std::list<std::string> xmlPaths = getPluginXMLFiles();
174
175     std::list<std::string>::const_iterator fit;
176
177     for ( fit = xmlPaths.begin(); fit != xmlPaths.end(); ++fit )
178     {
179       std::string fileName = *fit;
180       
181       int options = XML_PARSE_HUGE | XML_PARSE_NOCDATA;
182       xmlDocPtr doc = xmlReadFile( fileName.c_str(), NULL, options );
183       
184       if ( doc )
185       {
186         // get root node
187         xmlNodePtr root = xmlDocGetRootElement(doc);
188         
189         // check if it is plugins container node
190         if (xmlStrcmp(root->name, root_tag) == 0)
191         {
192           // iterate through children, to get plugins data
193           for (xmlNodePtr node = root->children; node; node = node->next)
194           {
195             if (xmlStrcmp(node->name, plugin_tag) == 0)
196             {
197               // plugin node
198               PluginData data;
199               data.name      = readXmlAttribute(node, name_tag);
200               data.serverLib = readXmlAttribute(node, server_tag);
201               data.clientLib = readXmlAttribute(node, gui_tag);
202               // iterate through children, to find actions container node
203               for (xmlNodePtr subnode = node->children; subnode; subnode = subnode->next)
204               {
205                 if (xmlStrcmp(subnode->name, actions_tag) == 0)
206                 {
207                   // actions container node
208                   // iterate through children, to get actions data
209                   for (xmlNodePtr subsubnode = subnode->children; subsubnode; subsubnode = subsubnode->next)
210                   {
211                     if (xmlStrcmp(subsubnode->name, action_tag) == 0)
212                     {
213                       // action node
214                       ActionData action;
215                       action.label      = readXmlAttribute(subsubnode, label_tag);
216                       action.icon       = readXmlAttribute(subsubnode, icon_tag);
217                       action.menuText   = readXmlAttribute(subsubnode, menu_tag);
218                       action.toolTip    = readXmlAttribute(subsubnode, tooltip_tag);
219                       action.statusText = readXmlAttribute(subsubnode, status_tag);
220                       action.accel      = readXmlAttribute(subsubnode, accel_tag);
221                       if (action.label != "")
222                         data.actions.push_back(action);
223                     } // end action node
224                   } // end iteration through actions container node children
225                 } // end actions container node
226               } // end iterations through plugin node children
227               
228               if (data.name != "")
229                 info.push_back(data);
230             } // end plugin node
231           } // end iterations through plugins container node children
232         } // end root node
233         
234         xmlFreeDoc(doc);
235         //xmlCleanupParser();//vsr: xmlCleanupParser should not be called from the application
236       } // end xml doc
237     }
238 #ifdef MYDEBUG
239     dumpinfo(info);
240 #endif
241     return info;
242   }
243 }