Salome HOME
Merge branch 'occ/psutil'
[modules/kernel.git] / src / ModuleCatalog / SALOME_ModuleCatalog_impl.cxx
1 // Copyright (C) 2007-2021  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  SALOME ModuleCatalog : implementation of ModuleCatalog server which parsers xml description of modules
24 //  File   : SALOME_ModuleCatalog_impl.cxx
25 //  Author : Estelle Deville
26 //  Module : SALOME
27 //  $Header$
28 //
29 #include "SALOME_ModuleCatalog_impl.hxx"
30 #include "SALOME_ModuleCatalog_Acomponent_impl.hxx"
31 #include "SALOME_ModuleCatalog_Handler.hxx"
32 #include <libxml/parser.h>
33 #include <fstream>
34 #include <map>
35 #include "utilities.h"
36
37 #include <Basics_Utils.hxx>
38
39 #ifdef WIN32
40 # include <process.h>
41 # include <windows.h>
42 #include <fcntl.h>  
43 #include <sys/types.h>  
44 #include <sys/stat.h> 
45 #include <io.h>
46 #include <stdio.h>
47 #include <stddef.h>
48 #include <stdlib.h>
49 #include <wchar.h>
50 #else
51 # include <unistd.h>
52 #endif
53
54 #ifdef _DEBUG_
55 static int MYDEBUG = 0;
56 #else
57 static int MYDEBUG = 0;
58 #endif
59
60 static const char* SEPARATOR     = "::";
61 static const char* OLD_SEPARATOR = ":";
62
63 SALOME_ModuleCatalog::ModuleCatalog_ptr KERNEL::getModuleComponentServantSA(const char *listOfCatalogs)
64 {
65   static SALOME_ModuleCatalog::ModuleCatalog_var moduleCata;
66   if(CORBA::is_nil(moduleCata))
67   {
68     CORBA::ORB_ptr orb = KERNEL::getORB();
69     constexpr int NB_OF_ELT_IN_CMD = 3;
70     char *argv[NB_OF_ELT_IN_CMD] = {"SALOME_ModuleCatalog_Server","-common",nullptr};
71     if(listOfCatalogs)
72       argv[2] = const_cast<char*>(listOfCatalogs);
73     SALOME_ModuleCatalogImpl *servant = new SALOME_ModuleCatalogImpl(NB_OF_ELT_IN_CMD,argv,orb);
74     moduleCata = servant->_this();
75   }
76   return SALOME_ModuleCatalog::ModuleCatalog::_duplicate(moduleCata);
77 }
78
79 std::list<std::string> splitStringToList(const std::string& theString, const std::string& theSeparator)
80 {
81   std::list<std::string> aList;
82
83   size_t sepLen = theSeparator.length();
84   size_t startPos = 0, sepPos = theString.find(theSeparator, startPos);
85
86   while (1)
87     {
88       std::string anItem ;
89       if(sepPos != std::string::npos)
90         anItem = theString.substr(startPos, sepPos - startPos);
91       else
92         anItem = theString.substr(startPos);
93       if (anItem.length() > 0)
94         aList.push_back(anItem);
95       if(sepPos == std::string::npos)
96         break;
97       startPos = sepPos + sepLen;
98       sepPos = theString.find(theSeparator, startPos);
99     }
100
101   return aList;
102 }
103
104 class SALOME_ModuleCatalogImpl::Private
105 {
106   friend class SALOME_ModuleCatalogImpl;
107 public:
108   //! method to parse one module catalog
109   /*! 
110     \param file const char* arguments
111     \param modulelist ParserComponents arguments
112     \param pathlist ParserPathPrefixes arguments
113     \param typeMap ParserTypes arguments
114   */
115   void _parse_xml_file(const char* file, 
116                        ParserComponents & modulelist, 
117                        ParserPathPrefixes & pathlist,
118                        ParserTypes& typeMap,
119                        TypeList& typeList);
120
121   //! method to find component in the parser list
122   /*!
123     \param name  string argument
124     \return pointer on a component, NULL if not found
125   */
126   ParserComponent *findComponent(const std::string & name);
127
128   //! method to create a CORBA component description from parser
129   /*!
130     \param C_corba  Component argument
131     \param C_parser const ParserComponent argument
132   */
133   void duplicate(SALOME_ModuleCatalog::ComponentDef & C_corba,
134                  const ParserComponent & C_parser);
135     
136   //! method to create a CORBA interface description from parser
137   /*!
138     \param I_corba  DefinitionInterface argument
139     \param I_parser const ParserInterface argument
140   */
141   void duplicate(SALOME_ModuleCatalog::DefinitionInterface & I_corba,
142                  const ParserInterface & I_parser);
143   
144   //! method to create a CORBA service description from parser
145   /*!
146     \param S_corba  Service argument
147     \param S_parser const ParserService argument
148   */
149   void duplicate(SALOME_ModuleCatalog::Service & S_corba,
150                  const ParserService & service);
151   
152   //! method to create a CORBA parameter description from parser
153   /*!
154     \param P_corba  ServicesParameter argument
155     \param P_parser const ParserParameter argument
156   */
157   void duplicate(SALOME_ModuleCatalog::ServicesParameter & P_corba,
158                  const ParserParameter & P_parser);
159   
160   //! method to create a CORBA datastream parameter description from parser
161   /*!
162     \param P_corba  ServicesDataStreamParameter argument
163     \param P_parser const ParserDataStreamParameter argument
164   */
165   void duplicate(SALOME_ModuleCatalog::ServicesDataStreamParameter & P_corba,
166                  const ParserDataStreamParameter & P_parser);
167   
168   //! method to create the path prefix structures from the catalog parsing
169   /*!
170     \param paths ParserPathPrefixes arguments
171     \return the paths
172   */
173   void duplicate(ParserPathPrefixes & p_out, const ParserPathPrefixes & P_in);
174
175  //! method to verify path prefix content
176   /*!
177     \param pathlist ListOfParserPathPrefix arguments
178     \return true if verification is OK
179   */
180   bool _verify_path_prefix(ParserPathPrefixes & pathlist);
181
182   // Theses variables will contain the path to the general and personal catalogs
183   char* _general_path;
184   char* _personal_path;
185
186   // These variables will contain the information on the general common catalog
187   ParserComponents    _general_module_list ;
188   ParserPathPrefixes  _general_path_list ;
189   ParserTypes _typeMap;
190   TypeList _typeList;
191
192   // These variables will contain the information on the personal catalog
193   ParserComponents    _personal_module_list ;
194   ParserPathPrefixes  _personal_path_list ; 
195
196   std::map <std::string, SALOME_ModuleCatalog::DataStreamDependency> 
197   DataStreamDepConvert;
198
199   std::map <ParserComponentType, SALOME_ModuleCatalog::ComponentType> 
200   ComponentTypeConvert;
201 };
202
203 //----------------------------------------------------------------------
204 // Function : SALOME_ModuleCatalogImpl
205 // Purpose  : Constructor 
206 //----------------------------------------------------------------------
207 SALOME_ModuleCatalogImpl::SALOME_ModuleCatalogImpl(int argc, char** argv, CORBA::ORB_ptr orb) : _orb(orb)
208 {
209   myPrivate = new Private;
210   if(MYDEBUG) MESSAGE("Catalog creation");
211   /* Init libxml */
212   xmlInitParser();
213
214   // Conversion rules for component types
215   myPrivate->ComponentTypeConvert[GEOM]
216     = SALOME_ModuleCatalog::GEOM;
217   myPrivate->ComponentTypeConvert[MESH]
218     = SALOME_ModuleCatalog::MESH;
219   myPrivate->ComponentTypeConvert[Med]
220     = SALOME_ModuleCatalog::Med;
221   myPrivate->ComponentTypeConvert[SOLVER]
222     = SALOME_ModuleCatalog::SOLVER;
223   myPrivate->ComponentTypeConvert[DATA]
224     = SALOME_ModuleCatalog::DATA;
225   myPrivate->ComponentTypeConvert[VISU]
226     = SALOME_ModuleCatalog::VISU;
227   myPrivate->ComponentTypeConvert[SUPERV]
228     = SALOME_ModuleCatalog::SUPERV;
229   myPrivate->ComponentTypeConvert[OTHER]
230     = SALOME_ModuleCatalog::OTHER;
231
232   // Conversion rules for datastream parameters dependency
233   myPrivate->DataStreamDepConvert["UNDEFINED"] 
234     = SALOME_ModuleCatalog::DATASTREAM_UNDEFINED;
235   myPrivate->DataStreamDepConvert["T"]
236     = SALOME_ModuleCatalog::DATASTREAM_TEMPORAL;
237   myPrivate->DataStreamDepConvert["I"] 
238     = SALOME_ModuleCatalog::DATASTREAM_ITERATIVE;
239
240   // Empty used variables
241   myPrivate->_general_module_list.resize(0);
242   myPrivate->_general_path_list.resize(0);
243
244   myPrivate->_personal_module_list.resize(0);
245   myPrivate->_personal_path_list.resize(0);
246   
247   // Parse the arguments given at server run
248   if (!_parseArguments(argc, argv,&myPrivate->_general_path,&myPrivate->_personal_path))
249     if(MYDEBUG) MESSAGE( "Error while argument parsing" );
250
251   // Test existency of files
252   if (myPrivate->_general_path == NULL)
253   {
254     if(MYDEBUG) MESSAGE( "Error the general catalog should be indicated" );
255   }
256   else
257   {
258     // Affect the _general_module_list and _general_path_list members
259     // with the common catalog
260
261     std::list<std::string> dirList;
262
263 #ifdef WIN32
264     dirList = splitStringToList(myPrivate->_general_path, SEPARATOR);
265 #else
266     //check for new format
267     bool isNew = (std::string( myPrivate->_general_path ).find(SEPARATOR) != std::string::npos);
268     if ( isNew ) {
269       //using new format
270       dirList = splitStringToList(myPrivate->_general_path, SEPARATOR);
271     } else {
272       //support old format
273       dirList = splitStringToList(myPrivate->_general_path, OLD_SEPARATOR);
274     }
275 #endif
276
277     for (std::list<std::string>::iterator iter = dirList.begin(); iter != dirList.end(); iter++)
278     {
279       std::string aPath = (*iter);
280       //remove inverted commas from filename
281       while (aPath.find('\"') != std::string::npos)
282         aPath.erase(aPath.find('\"'), 1);
283
284       myPrivate->_parse_xml_file(aPath.c_str(), 
285                                  myPrivate->_general_module_list, 
286                                  myPrivate->_general_path_list,
287                                  myPrivate->_typeMap,
288                                  myPrivate->_typeList);
289     }
290
291     // Verification of _general_path_list content
292     if (!myPrivate->_verify_path_prefix(myPrivate->_general_path_list)) {
293       if(MYDEBUG) MESSAGE( "Error while parsing the general path list, "
294                            "different paths are associated to the same computer," 
295                            "the first one will be chosen");
296     } else {
297       if(MYDEBUG) MESSAGE("General path list OK");
298     }
299
300     if (myPrivate->_personal_path != NULL) {
301       // Initialize the _personal_module_list and 
302       // _personal_path_list members with the personal catalog files
303       myPrivate->_parse_xml_file(myPrivate->_personal_path,
304                                  myPrivate->_personal_module_list, 
305                                  myPrivate->_personal_path_list,
306                                  myPrivate->_typeMap,
307                                  myPrivate->_typeList);
308       
309       // Verification of _general_path_list content
310       if(!myPrivate->_verify_path_prefix(myPrivate->_personal_path_list)){
311         if(MYDEBUG) MESSAGE("Error while parsing the personal path list, "
312                             "different paths are associated to the same computer, "
313                             "the first one will be chosen" );
314       }else {
315         if(MYDEBUG) MESSAGE("Personal path list OK");
316       }
317     }else 
318       if(MYDEBUG) MESSAGE("No personal catalog indicated or error while "
319                           "opening the personal catalog");
320   }
321 }
322
323 //----------------------------------------------------------------------
324 // Function : ~SALOME_ModuleCatalogImpl
325 // Purpose  : Destructor 
326 //----------------------------------------------------------------------
327 SALOME_ModuleCatalogImpl::~SALOME_ModuleCatalogImpl()
328 {
329   if(MYDEBUG) MESSAGE("Catalog Destruction");
330   delete myPrivate;
331 }
332
333
334 //! Get the list of all types of the catalog
335 /*!
336  *   \return  the list of types
337  */
338 SALOME_ModuleCatalog::ListOfTypeDefinition* SALOME_ModuleCatalogImpl::GetTypes()
339 {
340   SALOME_ModuleCatalog::ListOfTypeDefinition_var type_list = new SALOME_ModuleCatalog::ListOfTypeDefinition();
341   type_list->length((CORBA::ULong)myPrivate->_typeList.size());
342
343   for (unsigned int ind = 0 ; ind < myPrivate->_typeList.size() ; ind++)
344     {
345       //no real need to call string_dup, omniorb calls it on operator= (const char *) but it is safer
346       type_list[ind].name=CORBA::string_dup(myPrivate->_typeList[ind].name.c_str());
347       type_list[ind].kind=SALOME_ModuleCatalog::NONE;
348       if(myPrivate->_typeList[ind].kind=="double")
349         type_list[ind].kind=SALOME_ModuleCatalog::Dble;
350       else if(myPrivate->_typeList[ind].kind=="int")
351         type_list[ind].kind=SALOME_ModuleCatalog::Int;
352       else if(myPrivate->_typeList[ind].kind=="bool")
353         type_list[ind].kind=SALOME_ModuleCatalog::Bool;
354       else if(myPrivate->_typeList[ind].kind=="string")
355         type_list[ind].kind=SALOME_ModuleCatalog::Str;
356       else if(myPrivate->_typeList[ind].kind=="objref")
357         {
358           type_list[ind].kind=SALOME_ModuleCatalog::Objref;
359           type_list[ind].id=CORBA::string_dup(myPrivate->_typeList[ind].id.c_str());
360           //bases
361           type_list[ind].bases.length((CORBA::ULong)myPrivate->_typeList[ind].bases.size());
362           std::vector<std::string>::const_iterator miter;
363           miter=myPrivate->_typeList[ind].bases.begin();
364           int n_memb=0;
365           while(miter != myPrivate->_typeList[ind].bases.end())
366             {
367               type_list[ind].bases[n_memb]=CORBA::string_dup(miter->c_str());
368               miter++;
369               n_memb++;
370             }
371         }
372       else if(myPrivate->_typeList[ind].kind=="sequence")
373         {
374           type_list[ind].kind=SALOME_ModuleCatalog::Seq;
375           type_list[ind].content=CORBA::string_dup(myPrivate->_typeList[ind].content.c_str());
376         }
377       else if(myPrivate->_typeList[ind].kind=="array")
378         {
379           type_list[ind].kind=SALOME_ModuleCatalog::Array;
380           type_list[ind].content=CORBA::string_dup(myPrivate->_typeList[ind].content.c_str());
381         }
382       else if(myPrivate->_typeList[ind].kind=="struct")
383         {
384           type_list[ind].kind=SALOME_ModuleCatalog::Struc;
385           //members
386           type_list[ind].members.length((CORBA::ULong)myPrivate->_typeList[ind].members.size());
387
388           std::vector< std::pair<std::string,std::string> >::const_iterator miter;
389           miter=myPrivate->_typeList[ind].members.begin();
390           int n_memb=0;
391           while(miter != myPrivate->_typeList[ind].members.end())
392             {
393               type_list[ind].members[n_memb].name=CORBA::string_dup(miter->first.c_str());
394               type_list[ind].members[n_memb].type=CORBA::string_dup(miter->second.c_str());
395               n_memb++;
396               miter++;
397             }
398         }
399     }
400   return type_list._retn();
401 }
402
403 //----------------------------------------------------------------------
404 // Function : GetComputerList
405 // Purpose  : get a computer list
406 //----------------------------------------------------------------------
407 SALOME_ModuleCatalog::ListOfComputers* 
408 SALOME_ModuleCatalogImpl::GetComputerList()
409 {
410   SALOME_ModuleCatalog::ListOfComputers_var _list_computers = 
411     new SALOME_ModuleCatalog::ListOfComputers;
412   return _list_computers._retn();
413 }
414
415 //----------------------------------------------------------------------
416 // Function : GetPathPrefix
417 // Purpose  : get the PathPrefix of a computer
418 //----------------------------------------------------------------------
419 char* 
420 SALOME_ModuleCatalogImpl::GetPathPrefix(const char* machinename) {
421   if(MYDEBUG) MESSAGE("Begin of GetPathPrefix");
422   // Variables initialisation
423   std::string _path;
424   bool _find = false;
425
426   // Parse all the path prefixes
427   // looking for the wanted computer
428   for (unsigned int ind = 0; ind < myPrivate->_personal_path_list.size() && !_find; ind++)
429   {
430     for (unsigned int ind1 = 0; ind1 < myPrivate->_personal_path_list[ind].listOfComputer.size() && !_find; ind1++)
431     {
432       if ( myPrivate->_personal_path_list[ind].listOfComputer[ind1] == machinename )
433       {
434         _find = true;
435         // Wanted computer
436         // affect the path to be returned
437         _path = myPrivate->_personal_path_list[ind].path;
438       }
439     }
440   }
441
442   for (unsigned int ind = 0; ind < myPrivate->_general_path_list.size() && !_find; ind++)
443   {
444     for (unsigned int ind1 = 0; ind1 < myPrivate->_general_path_list[ind].listOfComputer.size() && !_find; ind1++)
445     {
446       if (myPrivate->_general_path_list[ind].listOfComputer[ind1] == machinename)
447       {
448         _find = true;
449         // Wanted computer
450         // affect the path to be returned
451         _path = myPrivate->_general_path_list[ind].path;
452       }
453     }
454   }
455   return CORBA::string_dup(_path.c_str()) ;
456 }
457
458 //----------------------------------------------------------------------
459 // Function : GetComponentList
460 // Purpose  : get a component list
461 //            If a component is defined in the personal catalog and 
462 //            in the general catalog (same name), the component defined
463 //            in the personal catalog is used
464 //----------------------------------------------------------------------
465 SALOME_ModuleCatalog::ListOfComponents* 
466 SALOME_ModuleCatalogImpl::GetComponentList()
467 {
468   if(MYDEBUG) MESSAGE("Begin of GetComponentList");
469   SALOME_ModuleCatalog::ListOfComponents_var _list_components = 
470     new SALOME_ModuleCatalog::ListOfComponents;
471
472   _list_components->length((CORBA::ULong)myPrivate->_personal_module_list.size());
473
474   // All the components defined in the personal catalog are taken
475   for(unsigned int ind=0; ind < myPrivate->_personal_module_list.size();ind++){
476     _list_components[ind]=(myPrivate->_personal_module_list[ind].name).c_str();
477     if(MYDEBUG) SCRUTE(_list_components[ind]) ;
478   }
479
480   size_t indice = myPrivate->_personal_module_list.size();
481   bool _find = false;
482   
483   // The components in the general catalog are taken only if they're
484   // not defined in the personal catalog
485   for(unsigned int ind=0; ind < myPrivate->_general_module_list.size();ind++){
486     _find = false;
487     for(unsigned int ind1=0; ind1 < myPrivate->_personal_module_list.size();ind1++){
488       // searching if the component is already defined in 
489       // the personal catalog
490       if ((myPrivate->_general_module_list[ind].name.compare(myPrivate->_personal_module_list[ind1].name)) == 0)
491         _find = true;
492     }
493     if(!_find){
494       if(MYDEBUG) MESSAGE("A new component " << myPrivate->_general_module_list[ind].name 
495                           << " has to be to added in the list");
496       _list_components->length((CORBA::ULong)indice+1);
497       // The component is not already defined => has to be taken
498       _list_components[(CORBA::ULong)indice]=(myPrivate->_general_module_list[ind].name).c_str();
499       if(MYDEBUG) SCRUTE(_list_components[(CORBA::ULong)indice]) ;
500       
501       indice++;
502     }else{
503       if(MYDEBUG) MESSAGE("The component " <<myPrivate->_general_module_list[ind].name 
504                           << " was already defined in the personal catalog") ;
505     }
506   }
507   
508   if(MYDEBUG) MESSAGE ( "End of GetComponentList" );
509   return _list_components._retn();
510 }
511
512
513 //----------------------------------------------------------------------
514 // Function : GetComponentIconeList
515 // Purpose  : get a component list of component name and component icone
516 //            If a component is defined in the personal catalog and 
517 //            in the general catalog (same name), the component defined
518 //            in the personal catalog is used
519 //----------------------------------------------------------------------
520 SALOME_ModuleCatalog::ListOfIAPP_Affich* 
521 SALOME_ModuleCatalogImpl::GetComponentIconeList()
522 {
523   if(MYDEBUG) MESSAGE("Begin of GetComponentIconeList");
524
525   SALOME_ModuleCatalog::ListOfIAPP_Affich_var _list_components_icone = 
526     new SALOME_ModuleCatalog::ListOfIAPP_Affich;
527
528   _list_components_icone->length((CORBA::ULong)myPrivate->_personal_module_list.size());
529
530   // All the components defined in the personal catalog are taken
531   for(unsigned int ind=0; ind < myPrivate->_personal_module_list.size();ind++){
532     _list_components_icone[ind].modulename=(myPrivate->_personal_module_list[ind].name).c_str();
533     _list_components_icone[ind].moduleusername=(myPrivate->_personal_module_list[ind].username).c_str();
534     _list_components_icone[ind].moduleicone=(myPrivate->_personal_module_list[ind].icon).c_str();
535     _list_components_icone[ind].moduleversion=(myPrivate->_personal_module_list[ind].version).c_str();
536     _list_components_icone[ind].modulecomment=(myPrivate->_personal_module_list[ind].comment).c_str();
537     //if(MYDEBUG) SCRUTE(_list_components_icone[ind].modulename); 
538     //if(MYDEBUG) SCRUTE(_list_components_icone[ind].moduleicone);
539   }
540   
541   size_t indice = myPrivate->_personal_module_list.size();
542   bool _find = false;
543   
544   // The components in the general catalog are taken only if they're
545   // not defined in the personal catalog
546   for(unsigned int ind=0; ind < myPrivate->_general_module_list.size();ind++){
547     _find = false;
548     for(unsigned int ind1=0; ind1 < myPrivate->_personal_module_list.size();ind1++){
549       // searching if the component is aleready defined in 
550       // the personal catalog
551       if((myPrivate->_general_module_list[ind].name.compare(myPrivate->_personal_module_list[ind1].name)) == 0)
552         _find = true;
553     }
554     if(!_find){
555       //          if(MYDEBUG) MESSAGE("A new component " << _general_module_list[ind].name << " has to be to added in the list");
556       _list_components_icone->length((CORBA::ULong)indice+1);
557       // The component is not already defined => has to be taken
558       _list_components_icone[(CORBA::ULong)indice].modulename=myPrivate->_general_module_list[ind].name.c_str();  
559       _list_components_icone[(CORBA::ULong)indice].moduleusername=myPrivate->_general_module_list[ind].username.c_str();  
560       _list_components_icone[(CORBA::ULong)indice].moduleicone=myPrivate->_general_module_list[ind].icon.c_str(); 
561       _list_components_icone[(CORBA::ULong)indice].moduleversion=myPrivate->_general_module_list[ind].version.c_str();
562       _list_components_icone[(CORBA::ULong)indice].modulecomment=myPrivate->_general_module_list[ind].comment.c_str();
563       //if(MYDEBUG) SCRUTE(_list_components_icone[(CORBA::ULong)indice].modulename) ;
564       //if(MYDEBUG) SCRUTE(_list_components_icone[(CORBA::ULong)indice].moduleicone);
565       
566       indice++;
567     }
568     // else 
569     //if(MYDEBUG) MESSAGE("The component " <<_general_module_list[ind].name << " was already defined in the personal catalog"); 
570   }
571   
572   return _list_components_icone._retn() ;
573 }
574
575 //----------------------------------------------------------------------
576 // Function : GetTypedComponentList
577 // Purpose  : get a component list of a wanted type
578 //            If a component is defined in the personal catalog and 
579 //            in the general catalog (same name), the component defined
580 //            in the personal catalog is used
581 //----------------------------------------------------------------------
582 SALOME_ModuleCatalog::ListOfComponents* 
583 SALOME_ModuleCatalogImpl::GetTypedComponentList(SALOME_ModuleCatalog::ComponentType component_type)
584 {
585   if(MYDEBUG) MESSAGE("Begin of GetTypedComponentList");
586   SALOME_ModuleCatalog::ListOfComponents_var _list_typed_component = 
587     new SALOME_ModuleCatalog::ListOfComponents;
588   int _j = 0;
589
590   _list_typed_component->length(0);
591   // Transform SALOME_ModuleCatalog::ComponentType in ParserComponentType
592   ParserComponentType _temp_component_type = OTHER;
593   switch(component_type){
594   case SALOME_ModuleCatalog::GEOM:
595     _temp_component_type = GEOM ;
596     break;
597   case SALOME_ModuleCatalog::MESH:
598     _temp_component_type = MESH;
599     break;   
600   case SALOME_ModuleCatalog::Med:
601     _temp_component_type = Med;
602     break;    
603   case SALOME_ModuleCatalog::SOLVER:   
604     _temp_component_type = SOLVER;
605     break;
606   case SALOME_ModuleCatalog::DATA:
607     _temp_component_type = DATA;
608     break;
609   case SALOME_ModuleCatalog::VISU:
610     _temp_component_type = VISU;
611     break;  
612   case SALOME_ModuleCatalog::SUPERV:
613     _temp_component_type = SUPERV;
614     break;
615   case SALOME_ModuleCatalog::OTHER:
616     _temp_component_type = OTHER;
617     break;
618   }
619
620   // All the components in the personal catalog are taken
621   for (unsigned int ind=0; ind < myPrivate->_personal_module_list.size();ind++)
622     {
623       if  (myPrivate->_personal_module_list[ind].type == _temp_component_type)
624         {
625           _list_typed_component->length(_j + 1); 
626            _list_typed_component[_j] = myPrivate->_personal_module_list[ind].name.c_str();
627           //if(MYDEBUG) SCRUTE(_list_typed_component[_j]);
628           _j++;
629         }
630     }
631
632   int indice = _list_typed_component->length() ;
633   bool _find = false;
634   
635   // The components in the general catalog are taken only if they're
636   // not defined in the personal catalog
637   for (unsigned int ind=0; ind < myPrivate->_general_module_list.size();ind++)
638     {
639       _find = false;
640
641       if(myPrivate->_general_module_list[ind].type == _temp_component_type)
642         {
643           for (unsigned int ind1=0; ind1 < myPrivate->_personal_module_list.size();ind1++)
644             {
645               // searching if the component is aleready defined in 
646               // the personal catalog
647               if ((myPrivate->_general_module_list[ind].name.compare(myPrivate->_personal_module_list[ind1].name)) == 0)
648                 _find = true;
649             }
650           if (!_find)
651             {
652               //if(MYDEBUG) MESSAGE("A new component " << _general_module_list[ind].name << " has to be to added in the list");
653               _list_typed_component->length(indice+1);
654               // The component is not already defined => has to be taken
655               _list_typed_component[indice]=(myPrivate->_general_module_list[ind].name).c_str();   
656               //if(MYDEBUG) SCRUTE(_list_typed_component[indice]) ;
657
658               indice++;
659             }
660           //else 
661             //if(MYDEBUG) MESSAGE("The component " <<_general_module_list[ind].name << " was already defined in the personal catalog") ;
662         }
663     }
664
665
666   return _list_typed_component._retn();
667 }
668
669 //----------------------------------------------------------------------
670 // Function : GetComponent
671 // Purpose  : get a component 
672 //            If a component is defined in the personal catalog and 
673 //            in the general catalog (same name), the component defined
674 //            in the personal catalog is used
675 //----------------------------------------------------------------------
676 SALOME_ModuleCatalog::Acomponent_ptr 
677 SALOME_ModuleCatalogImpl::GetComponent(const char* name)
678 {
679   // Looking for component named "componentname" in the personal catalog
680   // If found, get name, interfaces and constraint
681   // If not found, looking for component named "componentname" in
682   // the general catalog
683   // If found, get name, interfaces and constraint
684   // If not found, NULL pointer is returned
685
686   std::string s(name);
687   ParserComponent *C_parser = NULL;
688   //ParserPathPrefixes *pp = NULL;
689
690   SALOME_ModuleCatalog::Acomponent_ptr compo
691     = SALOME_ModuleCatalog::Acomponent::_nil();
692   C_parser = myPrivate->findComponent(s);
693   if (C_parser) {
694     
695     //    DebugParserComponent(*C_parser);
696
697     SALOME_ModuleCatalog::ComponentDef C_corba;
698     myPrivate->duplicate(C_corba, *C_parser);
699
700     
701     SALOME_ModuleCatalog_AcomponentImpl * aComponentImpl = 
702       new SALOME_ModuleCatalog_AcomponentImpl(C_corba);
703     
704     compo = aComponentImpl->_this();
705   }
706   else {
707     // Not found in the personal catalog and in the general catalog
708     // return NULL object
709     if(MYDEBUG) MESSAGE("Component with name  " << name 
710                         << " not found in catalog");
711   }
712   
713   return compo;
714 }
715
716 SALOME_ModuleCatalog::ComponentDef *
717 SALOME_ModuleCatalogImpl::GetComponentInfo(const char *name)
718 {
719   std::string s(name);
720
721   ParserComponent * C_parser = myPrivate->findComponent(s);
722   
723   if (C_parser) {
724     
725     SALOME_ModuleCatalog::ComponentDef * C_corba 
726       = new SALOME_ModuleCatalog::ComponentDef; 
727     myPrivate->duplicate(*C_corba, *C_parser);
728     return C_corba;
729   }
730
731   return NULL;
732 }
733
734 void SALOME_ModuleCatalogImpl::ping()
735 {
736 }
737
738 CORBA::Long SALOME_ModuleCatalogImpl::getPID()
739
740   return 
741 #ifndef WIN32
742     (CORBA::Long)getpid();
743 #else
744     (CORBA::Long)_getpid();
745 #endif
746 }
747
748 void SALOME_ModuleCatalogImpl::ShutdownWithExit()
749 {
750   exit( EXIT_SUCCESS );
751 }
752
753 void SALOME_ModuleCatalogImpl::shutdown()
754 {
755   if (!CORBA::is_nil(_orb)) _orb->shutdown(0);
756 }
757
758
759
760 //----------------------------------------------------------------------
761 // Function : _parseArguments
762 // Purpose  : parse arguments to get general and personal catalog files
763 //----------------------------------------------------------------------
764 bool
765 SALOME_ModuleCatalogImpl::_parseArguments(int argc, char **argv, 
766                                           char **_general, 
767                                           char** _personal)
768 {
769   bool _return_value = true;
770   *_general = NULL;
771   *_personal = NULL ;
772   for (int ind = 0; ind < argc ; ind++)
773     {
774
775       if (strcmp(argv[ind],"-help") == 0)
776         {
777           INFOS( "Usage: " << argv[0] 
778                  << " -common 'path to general catalog' "
779                  " -personal 'path to personal catalog' "
780                  " -ORBInitRef NameService=corbaname::localhost");
781             _return_value = false ;
782         }
783
784       if (strcmp(argv[ind],"-common") == 0)
785         {
786           if (ind + 1 < argc)
787             {
788               // General catalog file
789               *_general = argv[ind + 1] ;
790             }
791         }
792       else if (strcmp(argv[ind],"-personal") == 0)
793         {
794           if (ind + 1 < argc)
795             {
796               // Personal catalog file
797               *_personal = argv[ind + 1] ;
798             }
799         }
800     }
801   return _return_value;
802 }
803
804 ParserComponent *
805 SALOME_ModuleCatalogImpl::Private::findComponent(const std::string & name)
806 {
807   ParserComponent * C_parser = NULL;
808
809   if (!C_parser)
810     for (unsigned int ind=0; ind < _personal_module_list.size();ind++)
811       {
812         if (name.compare(_personal_module_list[ind].name) == 0)
813           {
814             if(MYDEBUG) MESSAGE("Component named " << name 
815                                 << " found in the personal catalog");
816             C_parser = &(_personal_module_list[ind]);
817             break;
818           }
819       }
820
821   if (!C_parser)
822     for (unsigned int ind=0; ind < _general_module_list.size();ind++)
823       {
824         if (name.compare(_general_module_list[ind].name) == 0)
825           {
826             //      if(MYDEBUG) MESSAGE("Component named " << name 
827             //                  << " found in the general catalog");
828             C_parser = &(_general_module_list[ind]);
829             break;
830           }
831       }
832
833   return C_parser;
834 }
835
836 //----------------------------------------------------------------------
837 // Function : _parse_xml_file
838 // Purpose  : parse one module catalog 
839 //----------------------------------------------------------------------
840 void 
841 SALOME_ModuleCatalogImpl::Private::_parse_xml_file(const char* file, 
842                                                    ParserComponents& modulelist, 
843                                                    ParserPathPrefixes& pathList,
844                                                    ParserTypes& typeMap,
845                                                    TypeList& typeList)
846 {
847   if(MYDEBUG) BEGIN_OF("_parse_xml_file");
848   if(MYDEBUG) SCRUTE(file);
849
850   //Local path and module list for the file to parse
851   ParserPathPrefixes  _pathList;
852   ParserComponents    _moduleList;
853  
854   SALOME_ModuleCatalog_Handler* handler = new SALOME_ModuleCatalog_Handler(_pathList,_moduleList,typeMap,typeList);
855 #if defined(WIN32)
856   const wchar_t* w_file = Kernel_Utils::utf8_decode(file);
857   FILE* aFile  = _wfopen(w_file, L"r");
858 #else
859   FILE* aFile = fopen(file, "r");
860 #endif
861   
862   if (aFile != NULL)
863     {
864       xmlDocPtr aDoc = xmlReadFile(file, NULL, 0);
865       
866       if (aDoc != NULL) 
867         handler->ProcessXmlDocument(aDoc);
868       else
869         MESSAGE("ModuleCatalog: could not parse file "<<file);
870
871       xmlFreeDoc(aDoc);
872       fclose(aFile);
873     }
874   else
875     MESSAGE("ModuleCatalog: file "<<file<<" is not readable.");
876   
877   delete handler;
878   
879   unsigned int i, j;
880
881   for ( i = 0; i < _moduleList.size(); i++) {
882     for (j=0; j<modulelist.size(); j++) {
883       if (modulelist[j].name == _moduleList[i].name)
884         break;
885     }
886     if (j < modulelist.size())
887       modulelist[j] = _moduleList[i];
888     else
889       modulelist.push_back(_moduleList[i]);
890   }
891
892   for ( i=0; i < _pathList.size(); i++)
893     pathList.push_back(_pathList[i]) ;
894
895   for (j=0; j<modulelist.size(); j++)
896     modulelist[j].prefixes = pathList;
897 }
898
899 void 
900 SALOME_ModuleCatalogImpl::ImportXmlCatalogFile(const char* file)
901 {
902   myPrivate->_parse_xml_file(file, myPrivate->_personal_module_list, myPrivate->_personal_path_list,myPrivate->_typeMap,myPrivate->_typeList);
903 }
904
905
906 //
907 //  Duplicate functions create a Corba structure (component,
908 //  interface, service, parameter) from the corresponding C++ 
909 //  parser structure
910 //
911
912 //----------------------------------------------------------------------
913 // Function : duplicate
914 // Purpose  : create a component from the catalog parsing
915 //----------------------------------------------------------------------
916 void SALOME_ModuleCatalogImpl::Private::duplicate
917 (SALOME_ModuleCatalog::ComponentDef & C_corba, 
918  const ParserComponent & C_parser)
919 {
920   C_corba.name = CORBA::string_dup(C_parser.name.c_str());
921   C_corba.username = CORBA::string_dup(C_parser.username.c_str());
922   C_corba.icon = CORBA::string_dup(C_parser.icon.c_str());
923   C_corba.type = ComponentTypeConvert[C_parser.type];
924   if(C_parser.implementationType == "EXE")
925     C_corba.implementationType=SALOME_ModuleCatalog::EXE;
926   else if(C_parser.implementationType == "CEXE")
927     C_corba.implementationType=SALOME_ModuleCatalog::CEXE;
928   else if(C_parser.implementationType == "PY")
929     C_corba.implementationType=SALOME_ModuleCatalog::PY;
930   else
931     C_corba.implementationType=SALOME_ModuleCatalog::SO;
932   C_corba.implname = CORBA::string_dup(C_parser.implementationName.c_str());
933
934   size_t _length = C_parser.interfaces.size();
935   C_corba.interfaces.length((CORBA::ULong)_length);
936   
937   for (unsigned int ind = 0; ind < _length; ind++)
938     duplicate(C_corba.interfaces[ind], C_parser.interfaces[ind]);
939 }
940
941
942 //----------------------------------------------------------------------
943 // Function : duplicate
944 // Purpose  : create an interface from the catalog parsing
945 //----------------------------------------------------------------------
946 void SALOME_ModuleCatalogImpl::Private::duplicate
947 (SALOME_ModuleCatalog::DefinitionInterface & I_corba,
948  const ParserInterface & I_parser)
949 {
950   //duplicate interface name
951   I_corba.interfacename = CORBA::string_dup(I_parser.name.c_str());
952   
953   // duplicate service list
954   size_t _length = I_parser.services.size();
955   //  if(MYDEBUG) SCRUTE(_length);
956   //  I_corba.interfaceservicelist 
957   //  = new SALOME_ModuleCatalog::ListOfInterfaceService;
958   I_corba.interfaceservicelist.length((CORBA::ULong)_length);
959   
960   for (unsigned int ind1 = 0; ind1 < _length ; ind1 ++)
961     duplicate(I_corba.interfaceservicelist[ind1],
962               I_parser.services[ind1]);
963 }
964
965 //----------------------------------------------------------------------
966 // Function : duplicate
967 // Purpose  : create a service from the catalog parsing
968 //----------------------------------------------------------------------
969 void SALOME_ModuleCatalogImpl::Private::duplicate
970 (SALOME_ModuleCatalog::Service & S_corba,
971  const ParserService & S_parser)
972 {
973   // duplicate service name
974   S_corba.ServiceName = CORBA::string_dup(S_parser.name.c_str());
975   
976   // duplicate service by default
977   S_corba.Servicebydefault = S_parser.byDefault;
978
979   S_corba.TypeOfNode = S_parser.typeOfNode;
980
981   size_t _length;
982
983   // duplicate in Parameters
984   _length = S_parser.inParameters.size();
985   S_corba.ServiceinParameter.length((CORBA::ULong)_length);
986
987   for (unsigned int ind2 = 0; ind2 < _length ; ind2 ++)
988     duplicate(S_corba.ServiceinParameter[ind2],
989               S_parser.inParameters[ind2]);
990   
991   // duplicate out Parameters
992   _length = S_parser.outParameters.size();
993   S_corba.ServiceoutParameter.length((CORBA::ULong)_length);
994
995   for (unsigned int ind2 = 0; ind2 < _length ; ind2 ++)
996     duplicate(S_corba.ServiceoutParameter[ind2],
997               S_parser.outParameters[ind2]);
998   
999   // duplicate in DataStreamParameters
1000   _length = S_parser.inDataStreamParameters.size();
1001   S_corba.ServiceinDataStreamParameter.length((CORBA::ULong)_length);
1002
1003   for (unsigned int ind2 = 0; ind2 < _length ; ind2 ++)
1004     duplicate(S_corba.ServiceinDataStreamParameter[ind2],
1005               S_parser.inDataStreamParameters[ind2]);
1006   
1007   // duplicate out DataStreamParameters
1008   _length = S_parser.outDataStreamParameters.size();
1009   //  if(MYDEBUG) SCRUTE(_length);
1010   S_corba.ServiceoutDataStreamParameter.length((CORBA::ULong)_length);
1011
1012   for (unsigned int ind2 = 0; ind2 < _length ; ind2 ++)
1013     duplicate(S_corba.ServiceoutDataStreamParameter[ind2],
1014               S_parser.outDataStreamParameters[ind2]);
1015 }
1016
1017 //----------------------------------------------------------------------
1018 // Function : duplicate
1019 // Purpose  : create a service parameter from the catalog parsing
1020 //----------------------------------------------------------------------
1021 void SALOME_ModuleCatalogImpl::Private::duplicate
1022 (SALOME_ModuleCatalog::ServicesParameter & P_corba,
1023  const ParserParameter & P_parser)
1024 {
1025   // duplicate parameter name
1026   P_corba.Parametername = CORBA::string_dup(P_parser.name.c_str());
1027   
1028   // duplicate parameter type
1029   P_corba.Parametertype = CORBA::string_dup(P_parser.type.c_str());
1030 }
1031
1032
1033 //----------------------------------------------------------------------
1034 // Function : duplicate
1035 // Purpose  : create a service datastream parameter from the catalog parsing
1036 //----------------------------------------------------------------------
1037 void SALOME_ModuleCatalogImpl::Private::duplicate
1038 (SALOME_ModuleCatalog::ServicesDataStreamParameter & P_corba,
1039  const ParserDataStreamParameter & P_parser)
1040 {
1041   std::map < std::string, 
1042     SALOME_ModuleCatalog::DataStreamDependency >::const_iterator it_dep;
1043
1044   // duplicate parameter name
1045   P_corba.Parametername = CORBA::string_dup(P_parser.name.c_str());
1046   
1047   // duplicate parameter type
1048
1049   // doesn't work ??? 
1050   //   it_type = DataStreamTypeConvert.find(P_parser.type);
1051   //   P_corba.Parametertype
1052   //     = (it_type == DataStreamTypeConvert.end()) 
1053   //     ? it_type->second : SALOME_ModuleCatalog::DATASTREAM_UNKNOWN;
1054
1055   P_corba.Parametertype = CORBA::string_dup(P_parser.type.c_str());
1056
1057   // duplicate parameter dependency
1058   
1059   if(MYDEBUG) SCRUTE(P_parser.dependency);
1060   P_corba.Parameterdependency = SALOME_ModuleCatalog::DATASTREAM_UNDEFINED;
1061   for (it_dep = DataStreamDepConvert.begin(); 
1062        it_dep != DataStreamDepConvert.end(); 
1063        it_dep++)
1064     if (P_parser.dependency.compare(it_dep->first) == 0) {
1065       P_corba.Parameterdependency = it_dep->second;
1066       break;
1067     }
1068
1069   if(MYDEBUG) SCRUTE(P_corba.Parameterdependency);
1070 }
1071
1072 //----------------------------------------------------------------------
1073 // Function : duplicate
1074 // Purpose  : create the path prefix structures from the catalog parsing
1075 //----------------------------------------------------------------------
1076 void
1077 SALOME_ModuleCatalogImpl::Private::duplicate(ParserPathPrefixes &L_out, 
1078                                              const ParserPathPrefixes &L_in)
1079 {
1080   L_out = L_in;
1081 }
1082
1083
1084 //----------------------------------------------------------------------
1085 // Function : _verify_path_prefix
1086 // Purpose  : verify the path prefix structures from the catalog parsing
1087 //            Verify that there only one path prefix associated to a 
1088 //            particular computer
1089 //----------------------------------------------------------------------
1090 bool
1091 SALOME_ModuleCatalogImpl::Private::_verify_path_prefix(ParserPathPrefixes & pathList)
1092 {
1093   bool _return_value = true;
1094   std::vector<std::string> _machine_list;
1095
1096   // Fill a list of all computers indicated in the path list
1097   for (unsigned int ind = 0; ind < pathList.size(); ind++)
1098     { 
1099       for (unsigned int ind1 = 0 ; ind1 < pathList[ind].listOfComputer.size(); ind1++)
1100         {
1101           _machine_list.push_back(pathList[ind].listOfComputer[ind1]);
1102         }
1103     }
1104
1105   // Parse if a computer name is twice in the list of computers
1106   for (unsigned int ind = 0; ind < _machine_list.size(); ind++)
1107     {
1108      for (unsigned int ind1 = ind+1 ; ind1 < _machine_list.size(); ind1++)
1109        {
1110          if(_machine_list[ind].compare(_machine_list[ind1]) == 0)
1111            {
1112              if(MYDEBUG) MESSAGE( "The computer " << _machine_list[ind] << " is indicated more than once in the path list");
1113              _return_value = false; 
1114            }
1115        }
1116     }
1117   return _return_value;
1118 }