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