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