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