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