]> SALOME platform Git repositories - modules/kernel.git/blob - src/ModuleCatalog/SALOME_ModuleCatalog_impl.cxx
Salome HOME
fba41d393be07a5beac2d9aff79cdfa1400b9278
[modules/kernel.git] / src / ModuleCatalog / SALOME_ModuleCatalog_impl.cxx
1 // Copyright (C) 2007-2022  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 "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   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       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       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       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       MESSAGE("A new component " << myPrivate->_general_module_list[ind].name 
496                           << " has to be to added in the list");
497       _list_components->length((CORBA::ULong)indice+1);
498       // The component is not already defined => has to be taken
499       _list_components[(CORBA::ULong)indice]=(myPrivate->_general_module_list[ind].name).c_str();
500       SCRUTE(_list_components[(CORBA::ULong)indice]) ;
501       
502       indice++;
503     }else{
504       MESSAGE("The component " <<myPrivate->_general_module_list[ind].name 
505                           << " was already defined in the personal catalog") ;
506     }
507   }
508   
509   MESSAGE("End of GetComponentList");
510   return _list_components._retn();
511 }
512
513
514 //----------------------------------------------------------------------
515 // Function : GetComponentIconeList
516 // Purpose  : get a component list of component name and component icone
517 //            If a component is defined in the personal catalog and 
518 //            in the general catalog (same name), the component defined
519 //            in the personal catalog is used
520 //----------------------------------------------------------------------
521 SALOME_ModuleCatalog::ListOfIAPP_Affich* 
522 SALOME_ModuleCatalogImpl::GetComponentIconeList()
523 {
524   MESSAGE("Begin of GetComponentIconeList");
525
526   SALOME_ModuleCatalog::ListOfIAPP_Affich_var _list_components_icone = 
527     new SALOME_ModuleCatalog::ListOfIAPP_Affich;
528
529   _list_components_icone->length((CORBA::ULong)myPrivate->_personal_module_list.size());
530
531   // All the components defined in the personal catalog are taken
532   for(unsigned int ind=0; ind < myPrivate->_personal_module_list.size();ind++){
533     _list_components_icone[ind].modulename=(myPrivate->_personal_module_list[ind].name).c_str();
534     _list_components_icone[ind].moduleusername=(myPrivate->_personal_module_list[ind].username).c_str();
535     _list_components_icone[ind].moduleicone=(myPrivate->_personal_module_list[ind].icon).c_str();
536     _list_components_icone[ind].moduleversion=(myPrivate->_personal_module_list[ind].version).c_str();
537     _list_components_icone[ind].modulecomment=(myPrivate->_personal_module_list[ind].comment).c_str();
538     //SCRUTE(_list_components_icone[ind].modulename); 
539     //SCRUTE(_list_components_icone[ind].moduleicone);
540   }
541   
542   size_t indice = myPrivate->_personal_module_list.size();
543   bool _find = false;
544   
545   // The components in the general catalog are taken only if they're
546   // not defined in the personal catalog
547   for(unsigned int ind=0; ind < myPrivate->_general_module_list.size();ind++){
548     _find = false;
549     for(unsigned int ind1=0; ind1 < myPrivate->_personal_module_list.size();ind1++){
550       // searching if the component is aleready defined in 
551       // the personal catalog
552       if((myPrivate->_general_module_list[ind].name.compare(myPrivate->_personal_module_list[ind1].name)) == 0)
553         _find = true;
554     }
555     if(!_find){
556       //MESSAGE("A new component " << _general_module_list[ind].name << " has to be to added in the list");
557       _list_components_icone->length((CORBA::ULong)indice+1);
558       // The component is not already defined => has to be taken
559       _list_components_icone[(CORBA::ULong)indice].modulename=myPrivate->_general_module_list[ind].name.c_str();  
560       _list_components_icone[(CORBA::ULong)indice].moduleusername=myPrivate->_general_module_list[ind].username.c_str();  
561       _list_components_icone[(CORBA::ULong)indice].moduleicone=myPrivate->_general_module_list[ind].icon.c_str(); 
562       _list_components_icone[(CORBA::ULong)indice].moduleversion=myPrivate->_general_module_list[ind].version.c_str();
563       _list_components_icone[(CORBA::ULong)indice].modulecomment=myPrivate->_general_module_list[ind].comment.c_str();
564       //SCRUTE(_list_components_icone[(CORBA::ULong)indice].modulename) ;
565       //SCRUTE(_list_components_icone[(CORBA::ULong)indice].moduleicone);
566       
567       indice++;
568     }
569     // else 
570     //MESSAGE("The component " <<_general_module_list[ind].name << " was already defined in the personal catalog"); 
571   }
572   
573   return _list_components_icone._retn() ;
574 }
575
576 //----------------------------------------------------------------------
577 // Function : GetTypedComponentList
578 // Purpose  : get a component list of a wanted type
579 //            If a component is defined in the personal catalog and 
580 //            in the general catalog (same name), the component defined
581 //            in the personal catalog is used
582 //----------------------------------------------------------------------
583 SALOME_ModuleCatalog::ListOfComponents* 
584 SALOME_ModuleCatalogImpl::GetTypedComponentList(SALOME_ModuleCatalog::ComponentType component_type)
585 {
586   MESSAGE("Begin of GetTypedComponentList");
587   SALOME_ModuleCatalog::ListOfComponents_var _list_typed_component = 
588     new SALOME_ModuleCatalog::ListOfComponents;
589   int _j = 0;
590
591   _list_typed_component->length(0);
592   // Transform SALOME_ModuleCatalog::ComponentType in ParserComponentType
593   ParserComponentType _temp_component_type = OTHER;
594   switch(component_type){
595   case SALOME_ModuleCatalog::GEOM:
596     _temp_component_type = GEOM ;
597     break;
598   case SALOME_ModuleCatalog::MESH:
599     _temp_component_type = MESH;
600     break;   
601   case SALOME_ModuleCatalog::Med:
602     _temp_component_type = Med;
603     break;    
604   case SALOME_ModuleCatalog::SOLVER:   
605     _temp_component_type = SOLVER;
606     break;
607   case SALOME_ModuleCatalog::DATA:
608     _temp_component_type = DATA;
609     break;
610   case SALOME_ModuleCatalog::VISU:
611     _temp_component_type = VISU;
612     break;  
613   case SALOME_ModuleCatalog::SUPERV:
614     _temp_component_type = SUPERV;
615     break;
616   case SALOME_ModuleCatalog::OTHER:
617     _temp_component_type = OTHER;
618     break;
619   }
620
621   // All the components in the personal catalog are taken
622   for (unsigned int ind=0; ind < myPrivate->_personal_module_list.size();ind++)
623     {
624       if  (myPrivate->_personal_module_list[ind].type == _temp_component_type)
625         {
626           _list_typed_component->length(_j + 1); 
627            _list_typed_component[_j] = myPrivate->_personal_module_list[ind].name.c_str();
628           //SCRUTE(_list_typed_component[_j]);
629           _j++;
630         }
631     }
632
633   int indice = _list_typed_component->length() ;
634   bool _find = false;
635   
636   // The components in the general catalog are taken only if they're
637   // not defined in the personal catalog
638   for (unsigned int ind=0; ind < myPrivate->_general_module_list.size();ind++)
639     {
640       _find = false;
641
642       if(myPrivate->_general_module_list[ind].type == _temp_component_type)
643         {
644           for (unsigned int ind1=0; ind1 < myPrivate->_personal_module_list.size();ind1++)
645             {
646               // searching if the component is aleready defined in 
647               // the personal catalog
648               if ((myPrivate->_general_module_list[ind].name.compare(myPrivate->_personal_module_list[ind1].name)) == 0)
649                 _find = true;
650             }
651           if (!_find)
652             {
653               //MESSAGE("A new component " << _general_module_list[ind].name << " has to be to added in the list");
654               _list_typed_component->length(indice+1);
655               // The component is not already defined => has to be taken
656               _list_typed_component[indice]=(myPrivate->_general_module_list[ind].name).c_str();   
657               //SCRUTE(_list_typed_component[indice]) ;
658
659               indice++;
660             }
661           //else 
662             //MESSAGE("The component " <<_general_module_list[ind].name << " was already defined in the personal catalog") ;
663         }
664     }
665
666
667   return _list_typed_component._retn();
668 }
669
670 //----------------------------------------------------------------------
671 // Function : GetComponent
672 // Purpose  : get a component 
673 //            If a component is defined in the personal catalog and 
674 //            in the general catalog (same name), the component defined
675 //            in the personal catalog is used
676 //----------------------------------------------------------------------
677 SALOME_ModuleCatalog::Acomponent_ptr 
678 SALOME_ModuleCatalogImpl::GetComponent(const char* name)
679 {
680   // Looking for component named "componentname" in the personal catalog
681   // If found, get name, interfaces and constraint
682   // If not found, looking for component named "componentname" in
683   // the general catalog
684   // If found, get name, interfaces and constraint
685   // If not found, NULL pointer is returned
686
687   std::string s(name);
688   ParserComponent *C_parser = NULL;
689   //ParserPathPrefixes *pp = NULL;
690
691   SALOME_ModuleCatalog::Acomponent_ptr compo
692     = SALOME_ModuleCatalog::Acomponent::_nil();
693   C_parser = myPrivate->findComponent(s);
694   if (C_parser) {
695     
696     //    DebugParserComponent(*C_parser);
697
698     SALOME_ModuleCatalog::ComponentDef C_corba;
699     myPrivate->duplicate(C_corba, *C_parser);
700
701     
702     SALOME_ModuleCatalog_AcomponentImpl * aComponentImpl = 
703       new SALOME_ModuleCatalog_AcomponentImpl(C_corba);
704     
705     compo = aComponentImpl->_this();
706   }
707   else {
708     // Not found in the personal catalog and in the general catalog
709     // return NULL object
710     MESSAGE("Component with name  " << name 
711                         << " not found in catalog");
712   }
713   
714   return compo;
715 }
716
717 SALOME_ModuleCatalog::ComponentDef *
718 SALOME_ModuleCatalogImpl::GetComponentInfo(const char *name)
719 {
720   std::string s(name);
721
722   ParserComponent * C_parser = myPrivate->findComponent(s);
723   
724   if (C_parser) {
725     
726     SALOME_ModuleCatalog::ComponentDef * C_corba 
727       = new SALOME_ModuleCatalog::ComponentDef; 
728     myPrivate->duplicate(*C_corba, *C_parser);
729     return C_corba;
730   }
731
732   return NULL;
733 }
734
735 void SALOME_ModuleCatalogImpl::ping()
736 {
737 }
738
739 CORBA::Long SALOME_ModuleCatalogImpl::getPID()
740
741   return 
742 #ifndef WIN32
743     (CORBA::Long)getpid();
744 #else
745     (CORBA::Long)_getpid();
746 #endif
747 }
748
749 void SALOME_ModuleCatalogImpl::ShutdownWithExit()
750 {
751   exit( EXIT_SUCCESS );
752 }
753
754 void SALOME_ModuleCatalogImpl::shutdown()
755 {
756   if (!CORBA::is_nil(_orb)) _orb->shutdown(0);
757 }
758
759
760
761 //----------------------------------------------------------------------
762 // Function : _parseArguments
763 // Purpose  : parse arguments to get general and personal catalog files
764 //----------------------------------------------------------------------
765 bool
766 SALOME_ModuleCatalogImpl::_parseArguments(int argc, char **argv, 
767                                           char **_general, 
768                                           char** _personal)
769 {
770   bool _return_value = true;
771   *_general = NULL;
772   *_personal = NULL ;
773   for (int ind = 0; ind < argc ; ind++)
774     {
775
776       if (strcmp(argv[ind],"-help") == 0)
777         {
778           INFOS( "Usage: " << argv[0] 
779                  << " -common 'path to general catalog' "
780                  " -personal 'path to personal catalog' "
781                  " -ORBInitRef NameService=corbaname::localhost");
782             _return_value = false ;
783         }
784
785       if (strcmp(argv[ind],"-common") == 0)
786         {
787           if (ind + 1 < argc)
788             {
789               // General catalog file
790               *_general = argv[ind + 1] ;
791             }
792         }
793       else if (strcmp(argv[ind],"-personal") == 0)
794         {
795           if (ind + 1 < argc)
796             {
797               // Personal catalog file
798               *_personal = argv[ind + 1] ;
799             }
800         }
801     }
802   return _return_value;
803 }
804
805 ParserComponent *
806 SALOME_ModuleCatalogImpl::Private::findComponent(const std::string & name)
807 {
808   ParserComponent * C_parser = NULL;
809
810   if (!C_parser)
811     for (unsigned int ind=0; ind < _personal_module_list.size();ind++)
812       {
813         if (name.compare(_personal_module_list[ind].name) == 0)
814           {
815             MESSAGE("Component named " << name 
816                                 << " found in the personal catalog");
817             C_parser = &(_personal_module_list[ind]);
818             break;
819           }
820       }
821
822   if (!C_parser)
823     for (unsigned int ind=0; ind < _general_module_list.size();ind++)
824       {
825         if (name.compare(_general_module_list[ind].name) == 0)
826           {
827             //MESSAGE("Component named " << name 
828             //                  << " found in the general catalog");
829             C_parser = &(_general_module_list[ind]);
830             break;
831           }
832       }
833
834   return C_parser;
835 }
836
837 //----------------------------------------------------------------------
838 // Function : _parse_xml_file
839 // Purpose  : parse one module catalog 
840 //----------------------------------------------------------------------
841 void 
842 SALOME_ModuleCatalogImpl::Private::_parse_xml_file(const char* file, 
843                                                    ParserComponents& modulelist, 
844                                                    ParserPathPrefixes& pathList,
845                                                    ParserTypes& typeMap,
846                                                    TypeList& typeList)
847 {
848   BEGIN_OF("_parse_xml_file");
849   SCRUTE(file);
850
851   //Local path and module list for the file to parse
852   ParserPathPrefixes  _pathList;
853   ParserComponents    _moduleList;
854  
855   SALOME_ModuleCatalog_Handler* handler = new SALOME_ModuleCatalog_Handler(_pathList,_moduleList,typeMap,typeList);
856 #if defined(WIN32)
857   const wchar_t* w_file = Kernel_Utils::utf8_decode(file);
858   FILE* aFile  = _wfopen(w_file, L"r");
859 #else
860   FILE* aFile = fopen(file, "r");
861 #endif
862   
863   if (aFile != NULL)
864     {
865       xmlDocPtr aDoc = xmlReadFile(file, NULL, 0);
866       
867       if (aDoc != NULL) 
868         handler->ProcessXmlDocument(aDoc);
869       else
870         MESSAGE("ModuleCatalog: could not parse file "<<file);
871
872       xmlFreeDoc(aDoc);
873       fclose(aFile);
874     }
875   else
876     MESSAGE("ModuleCatalog: file "<<file<<" is not readable.");
877   
878   delete handler;
879   
880   unsigned int i, j;
881
882   for ( i = 0; i < _moduleList.size(); i++) {
883     for (j=0; j<modulelist.size(); j++) {
884       if (modulelist[j].name == _moduleList[i].name)
885         break;
886     }
887     if (j < modulelist.size())
888       modulelist[j] = _moduleList[i];
889     else
890       modulelist.push_back(_moduleList[i]);
891   }
892
893   for ( i=0; i < _pathList.size(); i++)
894     pathList.push_back(_pathList[i]) ;
895
896   for (j=0; j<modulelist.size(); j++)
897     modulelist[j].prefixes = pathList;
898 }
899
900 void 
901 SALOME_ModuleCatalogImpl::ImportXmlCatalogFile(const char* file)
902 {
903   myPrivate->_parse_xml_file(file, myPrivate->_personal_module_list, myPrivate->_personal_path_list,myPrivate->_typeMap,myPrivate->_typeList);
904 }
905
906
907 //
908 //  Duplicate functions create a Corba structure (component,
909 //  interface, service, parameter) from the corresponding C++ 
910 //  parser structure
911 //
912
913 //----------------------------------------------------------------------
914 // Function : duplicate
915 // Purpose  : create a component from the catalog parsing
916 //----------------------------------------------------------------------
917 void SALOME_ModuleCatalogImpl::Private::duplicate
918 (SALOME_ModuleCatalog::ComponentDef & C_corba, 
919  const ParserComponent & C_parser)
920 {
921   C_corba.name = CORBA::string_dup(C_parser.name.c_str());
922   C_corba.username = CORBA::string_dup(C_parser.username.c_str());
923   C_corba.icon = CORBA::string_dup(C_parser.icon.c_str());
924   C_corba.type = ComponentTypeConvert[C_parser.type];
925   if(C_parser.implementationType == "EXE")
926     C_corba.implementationType=SALOME_ModuleCatalog::EXE;
927   else if(C_parser.implementationType == "CEXE")
928     C_corba.implementationType=SALOME_ModuleCatalog::CEXE;
929   else if(C_parser.implementationType == "PY")
930     C_corba.implementationType=SALOME_ModuleCatalog::PY;
931   else
932     C_corba.implementationType=SALOME_ModuleCatalog::SO;
933   C_corba.implname = CORBA::string_dup(C_parser.implementationName.c_str());
934
935   size_t _length = C_parser.interfaces.size();
936   C_corba.interfaces.length((CORBA::ULong)_length);
937   
938   for (unsigned int ind = 0; ind < _length; ind++)
939     duplicate(C_corba.interfaces[ind], C_parser.interfaces[ind]);
940 }
941
942
943 //----------------------------------------------------------------------
944 // Function : duplicate
945 // Purpose  : create an interface from the catalog parsing
946 //----------------------------------------------------------------------
947 void SALOME_ModuleCatalogImpl::Private::duplicate
948 (SALOME_ModuleCatalog::DefinitionInterface & I_corba,
949  const ParserInterface & I_parser)
950 {
951   //duplicate interface name
952   I_corba.interfacename = CORBA::string_dup(I_parser.name.c_str());
953   
954   // duplicate service list
955   size_t _length = I_parser.services.size();
956   //  SCRUTE(_length);
957   //  I_corba.interfaceservicelist 
958   //  = new SALOME_ModuleCatalog::ListOfInterfaceService;
959   I_corba.interfaceservicelist.length((CORBA::ULong)_length);
960   
961   for (unsigned int ind1 = 0; ind1 < _length ; ind1 ++)
962     duplicate(I_corba.interfaceservicelist[ind1],
963               I_parser.services[ind1]);
964 }
965
966 //----------------------------------------------------------------------
967 // Function : duplicate
968 // Purpose  : create a service from the catalog parsing
969 //----------------------------------------------------------------------
970 void SALOME_ModuleCatalogImpl::Private::duplicate
971 (SALOME_ModuleCatalog::Service & S_corba,
972  const ParserService & S_parser)
973 {
974   // duplicate service name
975   S_corba.ServiceName = CORBA::string_dup(S_parser.name.c_str());
976   
977   // duplicate service by default
978   S_corba.Servicebydefault = S_parser.byDefault;
979
980   S_corba.TypeOfNode = S_parser.typeOfNode;
981
982   size_t _length;
983
984   // duplicate in Parameters
985   _length = S_parser.inParameters.size();
986   S_corba.ServiceinParameter.length((CORBA::ULong)_length);
987
988   for (unsigned int ind2 = 0; ind2 < _length ; ind2 ++)
989     duplicate(S_corba.ServiceinParameter[ind2],
990               S_parser.inParameters[ind2]);
991   
992   // duplicate out Parameters
993   _length = S_parser.outParameters.size();
994   S_corba.ServiceoutParameter.length((CORBA::ULong)_length);
995
996   for (unsigned int ind2 = 0; ind2 < _length ; ind2 ++)
997     duplicate(S_corba.ServiceoutParameter[ind2],
998               S_parser.outParameters[ind2]);
999   
1000   // duplicate in DataStreamParameters
1001   _length = S_parser.inDataStreamParameters.size();
1002   S_corba.ServiceinDataStreamParameter.length((CORBA::ULong)_length);
1003
1004   for (unsigned int ind2 = 0; ind2 < _length ; ind2 ++)
1005     duplicate(S_corba.ServiceinDataStreamParameter[ind2],
1006               S_parser.inDataStreamParameters[ind2]);
1007   
1008   // duplicate out DataStreamParameters
1009   _length = S_parser.outDataStreamParameters.size();
1010   //  SCRUTE(_length);
1011   S_corba.ServiceoutDataStreamParameter.length((CORBA::ULong)_length);
1012
1013   for (unsigned int ind2 = 0; ind2 < _length ; ind2 ++)
1014     duplicate(S_corba.ServiceoutDataStreamParameter[ind2],
1015               S_parser.outDataStreamParameters[ind2]);
1016 }
1017
1018 //----------------------------------------------------------------------
1019 // Function : duplicate
1020 // Purpose  : create a service parameter from the catalog parsing
1021 //----------------------------------------------------------------------
1022 void SALOME_ModuleCatalogImpl::Private::duplicate
1023 (SALOME_ModuleCatalog::ServicesParameter & P_corba,
1024  const ParserParameter & P_parser)
1025 {
1026   // duplicate parameter name
1027   P_corba.Parametername = CORBA::string_dup(P_parser.name.c_str());
1028   
1029   // duplicate parameter type
1030   P_corba.Parametertype = CORBA::string_dup(P_parser.type.c_str());
1031 }
1032
1033
1034 //----------------------------------------------------------------------
1035 // Function : duplicate
1036 // Purpose  : create a service datastream parameter from the catalog parsing
1037 //----------------------------------------------------------------------
1038 void SALOME_ModuleCatalogImpl::Private::duplicate
1039 (SALOME_ModuleCatalog::ServicesDataStreamParameter & P_corba,
1040  const ParserDataStreamParameter & P_parser)
1041 {
1042   std::map < std::string, 
1043     SALOME_ModuleCatalog::DataStreamDependency >::const_iterator it_dep;
1044
1045   // duplicate parameter name
1046   P_corba.Parametername = CORBA::string_dup(P_parser.name.c_str());
1047   
1048   // duplicate parameter type
1049
1050   // doesn't work ??? 
1051   //   it_type = DataStreamTypeConvert.find(P_parser.type);
1052   //   P_corba.Parametertype
1053   //     = (it_type == DataStreamTypeConvert.end()) 
1054   //     ? it_type->second : SALOME_ModuleCatalog::DATASTREAM_UNKNOWN;
1055
1056   P_corba.Parametertype = CORBA::string_dup(P_parser.type.c_str());
1057
1058   // duplicate parameter dependency
1059   
1060   SCRUTE(P_parser.dependency);
1061   P_corba.Parameterdependency = SALOME_ModuleCatalog::DATASTREAM_UNDEFINED;
1062   for (it_dep = DataStreamDepConvert.begin(); 
1063        it_dep != DataStreamDepConvert.end(); 
1064        it_dep++)
1065     if (P_parser.dependency.compare(it_dep->first) == 0) {
1066       P_corba.Parameterdependency = it_dep->second;
1067       break;
1068     }
1069
1070   SCRUTE(P_corba.Parameterdependency);
1071 }
1072
1073 //----------------------------------------------------------------------
1074 // Function : duplicate
1075 // Purpose  : create the path prefix structures from the catalog parsing
1076 //----------------------------------------------------------------------
1077 void
1078 SALOME_ModuleCatalogImpl::Private::duplicate(ParserPathPrefixes &L_out, 
1079                                              const ParserPathPrefixes &L_in)
1080 {
1081   L_out = L_in;
1082 }
1083
1084
1085 //----------------------------------------------------------------------
1086 // Function : _verify_path_prefix
1087 // Purpose  : verify the path prefix structures from the catalog parsing
1088 //            Verify that there only one path prefix associated to a 
1089 //            particular computer
1090 //----------------------------------------------------------------------
1091 bool
1092 SALOME_ModuleCatalogImpl::Private::_verify_path_prefix(ParserPathPrefixes & pathList)
1093 {
1094   bool _return_value = true;
1095   std::vector<std::string> _machine_list;
1096
1097   // Fill a list of all computers indicated in the path list
1098   for (unsigned int ind = 0; ind < pathList.size(); ind++)
1099     { 
1100       for (unsigned int ind1 = 0 ; ind1 < pathList[ind].listOfComputer.size(); ind1++)
1101         {
1102           _machine_list.push_back(pathList[ind].listOfComputer[ind1]);
1103         }
1104     }
1105
1106   // Parse if a computer name is twice in the list of computers
1107   for (unsigned int ind = 0; ind < _machine_list.size(); ind++)
1108     {
1109      for (unsigned int ind1 = ind+1 ; ind1 < _machine_list.size(); ind1++)
1110        {
1111          if(_machine_list[ind].compare(_machine_list[ind1]) == 0)
1112            {
1113              MESSAGE( "The computer " << _machine_list[ind] << " is indicated more than once in the path list");
1114              _return_value = false; 
1115            }
1116        }
1117     }
1118   return _return_value;
1119 }