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