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