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