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