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