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