Salome HOME
Initialisation de la base KERNEL avec la version operationnelle de KERNEL_SRC issue...
[modules/kernel.git] / src / NamingService / SALOME_NamingService.cxx
1 using namespace std;
2 // File: SALOME_NamingService.cxx
3 // Created: Tue June 12 2001
4 // Author: Estelle Deville
5 // Project: SALOME
6 // Copyright : CEA/DEN/DMSS/LGLS
7 // $Header$
8
9 //----------------------------------------------------------------------
10 #include "SALOME_NamingService.hxx"
11 #include "ServiceUnreachable.hxx"
12 #include <iostream>
13 #include <cstring>
14
15 //----------------------------------------------------------------------
16 /*! Function : SALOME_NamingService
17  *  Purpose  : Constructor and Initialisation of _root_context
18  */
19 //----------------------------------------------------------------------
20
21 SALOME_NamingService::SALOME_NamingService()
22 {
23   MESSAGE("SALOME_NamingService default constructor");
24   _orb = CORBA::ORB::_nil();
25 }
26
27 //----------------------------------------------------------------------
28 /*! Function : SALOME_NamingService
29  * \param orb CORBA::ORB_ptr arguments
30  */
31 //----------------------------------------------------------------------
32
33 SALOME_NamingService::SALOME_NamingService(CORBA::ORB_ptr orb)
34 {
35   MESSAGE("SALOME_NamingService creation");
36   _orb = orb ;
37   _initialize_root_context();
38 }
39
40 //----------------------------------------------------------------------
41 /*! Function : ~SALOME_NamingService
42  *  Purpose  : Destructor
43  */
44 //----------------------------------------------------------------------
45
46 SALOME_NamingService::~SALOME_NamingService()
47 {
48   MESSAGE("SALOME_NamingService destruction");
49 }
50
51 //----------------------------------------------------------------------
52 /*! Function : init_orb
53  *  initialize ORB reference after default constructor
54  */
55 //----------------------------------------------------------------------
56
57 void SALOME_NamingService::init_orb(CORBA::ORB_ptr orb)
58 {
59   // MESSAGE("SALOME_NamingService initialisation");
60   _orb = orb ;
61   _initialize_root_context();
62 }
63
64
65 //----------------------------------------------------------------------
66 /*! Function : Register
67  *  Method to create an association in the NamingService between ObjRef
68  *  and Path.
69  *  If the NamingService is out, the exception ServiceUnreachable is thrown
70  * \param ObjRef CORBA::Object_ptr arguments
71  * \param Path const char* arguments
72  */ 
73 //----------------------------------------------------------------------
74
75 void SALOME_NamingService::Register(CORBA::Object_ptr ObjRef,
76                                     const char* Path) 
77   throw(ServiceUnreachable)
78 {
79   // MESSAGE("BEGIN OF Register: "<< Path);
80   int dimension_Path = strlen(Path) + 1;
81   char** resultat_resolve_Path = new char* [dimension_Path];
82
83   // _current_context is replaced to the _root_context 
84   // if the Path begins whith '/'
85   if (Path[0]=='/')  {
86     _current_context = _root_context;
87     //    MESSAGE("Gone to the _root_context");
88   }
89   
90   //the resolution of the directory path has to be done
91   //to place the currect_context to the correct node
92   int dimension_resultat = 0;
93   _result_resolve_Path (Path, dimension_resultat, resultat_resolve_Path);
94     
95   CosNaming::Name _context_name;
96   CORBA::Boolean _not_exist = false ;
97   CosNaming::NamingContext_var _temp_context;
98   
99   if(dimension_resultat>1)
100     {  
101       // A directory is treated (not only an object name)
102       // We had to test if the directory where ObjRef should be recorded 
103       // is already done
104       // If not, the new context has to be created
105
106       //      MESSAGE("A complet Path has to be treated, not only an object name");
107       _context_name.length(dimension_resultat-1);
108
109       _create_context_name_dir(resultat_resolve_Path,dimension_resultat-1,
110                                _context_name);  
111
112       try
113         {
114           CORBA::Object_var _obj = _current_context->resolve(_context_name);
115           _current_context = CosNaming::NamingContext::_narrow(_obj);
116         } 
117       catch (CosNaming::NamingContext::NotFound &) 
118         {
119           // failed to resolve, therefore assume cold start
120           _not_exist = true;
121         } 
122       catch (CosNaming::NamingContext::InvalidName &) 
123         {
124           INFOS("!!!Register() : CosNaming::NamingContext::InvalidName"); 
125         }
126       catch (CosNaming::NamingContext::CannotProceed &)
127         {
128           INFOS("!!!Register() : CosNaming::NamingContext::CannotProceed");
129         }
130       catch(CORBA::COMM_FAILURE&)
131         {
132           INFOS("!!!Register() : CORBA::COMM_FAILURE : unable to contact"
133                << " the naming service"); 
134           throw ServiceUnreachable();
135         }
136       if(_not_exist)
137         {
138           try
139             {
140               _context_name.length(1);
141               // MESSAGE("The Path indicated is not yet created. It will soon be done");
142               for (int i = 0 ; i <dimension_resultat -1 ;i++)
143                 {
144                   _context_name[0].id =
145                     CORBA::string_dup(resultat_resolve_Path[i]);
146                   _context_name[0].kind = CORBA::string_dup("dir");
147                   // SCRUTE(_context_name[0].id);
148                   //The Path could be in part already created. 
149                   //We had to test it
150                   try 
151                     {
152                       // this context is already created. 
153                       // Nothing to be done
154                       CORBA::Object_var _obj = 
155                         _current_context->resolve(_context_name);
156                       _current_context = 
157                         CosNaming::NamingContext::_narrow(_obj);
158                       //MESSAGE("This context was already created");
159                     } 
160                   catch (CosNaming::NamingContext::NotFound &) 
161                     {
162                       // This context is not created. It will be done
163                       _temp_context =
164                         _current_context->bind_new_context(_context_name);
165                       _current_context = _temp_context;
166                       //MESSAGE("This context was'nt created, it's now done");
167                     }
168                 }
169             }
170           catch (CosNaming::NamingContext::AlreadyBound&)
171             {
172               INFOS("!!!Register() : CosNaming::NamingContext::AlreadyBound");  
173             }
174           catch(CosNaming::NamingContext::NotFound& ex)
175             {
176               CosNaming::Name n = ex.rest_of_name;
177               if (ex.why == CosNaming::NamingContext::missing_node)
178                 INFOS("Register() : " << (char *) n[0].id
179                       << " (" << (char *) n[0].kind << ") not found");
180               if (ex.why == CosNaming::NamingContext::not_context)
181                 INFOS("Register() : " << (char *) n[0].id
182                      << " (" << (char *) n[0].kind
183                      << ") is not a context");
184               if (ex.why == CosNaming::NamingContext::not_object)
185                 INFOS("Register() : " << (char *) n[0].id
186                      << " (" << (char *) n[0].kind
187                      << ") is not an object");
188             }
189           catch(CosNaming::NamingContext::CannotProceed&)
190             {
191               INFOS("!!!Register() : CosNaming::NamingContext::CannotProceed");
192             } 
193           catch(CosNaming::NamingContext::InvalidName&) 
194             {
195               INFOS("!!!Register() : CosNaming::NamingContext::InvalidName");
196             }
197           catch(CORBA::COMM_FAILURE&)
198             {
199               INFOS("!!!Register() :CORBA::COMM_FAILURE : unable to contact"
200                    << " the naming service"); 
201               throw ServiceUnreachable();
202             }
203         }       
204     }
205
206   // The current directory is now the directory where the object should 
207   // be recorded
208   _context_name.length(1);
209   try 
210     {
211       // the last element is an object an not a directory
212       _context_name[0].id = 
213         CORBA::string_dup(resultat_resolve_Path[dimension_resultat -1]);
214       _context_name[0].kind = CORBA::string_dup("object");
215       //SCRUTE(_context_name[0].id);
216         
217       _current_context->bind(_context_name, ObjRef);
218       // MESSAGE("A new element " << _context_name[0].id 
219       //           << " is recorded in the _current_context");   
220     }
221   catch(CosNaming::NamingContext::NotFound& ex)
222     {
223       CosNaming::Name n = ex.rest_of_name;
224       if (ex.why == CosNaming::NamingContext::missing_node)
225         INFOS("Register() : "  << (char *) n[0].id
226               << " ("  << (char *) n[0].kind << ") not found");
227       if (ex.why == CosNaming::NamingContext::not_context)
228         INFOS("Register() : " << (char *) n[0].id
229              << " (" << (char *) n[0].kind
230              << ") is not a context");
231       if (ex.why == CosNaming::NamingContext::not_object)
232         INFOS("Register() : " << (char *) n[0].id
233              << " (" << (char *) n[0].kind
234              << ") is not an object");
235     }
236   catch(CosNaming::NamingContext::CannotProceed&)
237     {
238       INFOS("!!!Register() : CosNaming::NamingContext::CannotProceed"); 
239     } 
240   catch(CosNaming::NamingContext::InvalidName&) 
241     {
242       INFOS("!!!Register() : CosNaming::NamingContext::InvalidName"); 
243     }
244   catch(CosNaming::NamingContext::AlreadyBound&) 
245     {
246       INFOS("!!!Register() : CosNaming::NamingContext::AlreadyBound, object will be rebind"); 
247       _current_context->rebind(_context_name, ObjRef);
248     }
249   catch(CORBA::COMM_FAILURE&)
250     {
251       INFOS("!!!Register() :CORBA::COMM_FAILURE : unable to contact"
252             << " the naming service");
253       throw ServiceUnreachable();
254     }
255   
256   
257   // Memory destruction
258   for (int i = 0 ; i <dimension_resultat ;i++) 
259     {
260       delete [] resultat_resolve_Path[i];     
261     }
262   delete[] resultat_resolve_Path ;
263 }
264
265 //----------------------------------------------------------------------
266 /*! Function : Resolve 
267  *  Purpose  : method to get the ObjRef of a symbolic name
268  *  If the NamingService is out, the exception ServiceUnreachable is thrown 
269  * \param Path const char* arguments
270  * \return the object reference
271  */
272 //----------------------------------------------------------------------
273
274 CORBA::Object_ptr SALOME_NamingService::Resolve(const char* Path)
275   throw(ServiceUnreachable)
276 {
277   //MESSAGE("BEGIN OF Resolve: " << Path);
278   int dimension_Path = strlen(Path) + 1;
279   char** resultat_resolve_Path = new char* [dimension_Path];
280
281   // _current_context is replaced to the _root_context 
282   // if the Path begins whith '/'
283   if (Path[0]=='/') _current_context = _root_context;
284
285   
286   //the resolution of the directory path has to be done
287   //to place the currect_context to the correct node
288   int dimension_resultat = 0;
289   _result_resolve_Path (Path, dimension_resultat, resultat_resolve_Path);
290     
291   CosNaming::Name _context_name;
292   _context_name.length(dimension_resultat);
293   CORBA::Object_ptr _obj = NULL ;
294     
295   _create_context_name_dir(resultat_resolve_Path,dimension_resultat-1,
296                            _context_name);
297   // the last element is an object an not a directory
298   _context_name[dimension_resultat -1].id = 
299     CORBA::string_dup(resultat_resolve_Path[dimension_resultat -1]);
300   _context_name[dimension_resultat -1].kind = CORBA::string_dup("object");
301   // SCRUTE(_context_name[dimension_resultat -1].id);
302   ASSERT(!CORBA::is_nil(_current_context));
303   // Context creation
304   try 
305     {
306       _obj =_current_context->resolve(_context_name);
307     }
308   catch(CosNaming::NamingContext::NotFound& ex)
309     {
310       CosNaming::Name n = ex.rest_of_name;
311       if (ex.why == CosNaming::NamingContext::missing_node)
312         INFOS("Resolve() : " << (char *) n[0].id
313               << " (" << (char *) n[0].kind << ") not found");
314       if (ex.why == CosNaming::NamingContext::not_context)
315         INFOS("Resolve() : "
316              << (char *) n[0].id  << " (" << (char *) n[0].kind
317              << ") is not a context");
318       if (ex.why == CosNaming::NamingContext::not_object)
319         INFOS("Resolve() : " << (char *) n[0].id
320              << " (" << (char *) n[0].kind
321              << ") is not an object");
322     }
323   catch(CosNaming::NamingContext::CannotProceed&)
324     {
325       INFOS("!!!Resolve() : CosNaming::NamingContext::CannotProceed"); 
326     } 
327   catch(CosNaming::NamingContext::InvalidName&) 
328     {
329       INFOS("!!!Resolve() : CosNaming::NamingContext::InvalidName"); 
330     }
331   catch(CORBA::COMM_FAILURE&)
332     {
333       INFOS("!!!Resolve() :CORBA::COMM_FAILURE : unable to contact"
334             << "the naming service");
335       throw ServiceUnreachable();
336     }
337   // Memory destruction
338   for (int i = 0 ; i <dimension_resultat ;i++) 
339     {
340       delete [] resultat_resolve_Path[i];     
341     }
342   delete[] resultat_resolve_Path ;
343   
344   return _obj;
345 }
346
347 //----------------------------------------------------------------------
348 /*!  Function : Find
349  *  Purpose  : method to research a name from the current directory 
350  *            of the naming service. 
351  *  The naming service changes directory to go to the directory where 
352  *  the last occurence was found.
353  *  If the NamingService is out, the exception ServiceUnreachable is thrown
354  *  \param name const char* arguments
355  *  \return the number of occurences found
356  *  \sa _Find
357  */   
358 //----------------------------------------------------------------------
359
360 int SALOME_NamingService::Find(const char* name)
361   throw(ServiceUnreachable)
362 {
363   // MESSAGE("BEGIN OF Find " << name);
364   CORBA::Long occurence_number = 0 ; 
365   try
366     {
367       _Find(name,occurence_number);
368     }
369   catch(CORBA::COMM_FAILURE&)
370     {
371       INFOS("!!!Find() : CORBA::COMM_FAILURE : unable to contact"
372            << " the naming service"); 
373       throw ServiceUnreachable();
374     }
375   return occurence_number;
376 }
377
378 //----------------------------------------------------------------------
379 /*! Function : Create_Directory 
380  *  Purpose  : method to create a directory from the current directory.
381  * If the NamingService is out, the exception ServiceUnreachable is thrown
382  *  \param Path const char* arguments
383  *  \return a boolean to indicate if the creation succeeded
384  */
385 //----------------------------------------------------------------------
386
387 bool SALOME_NamingService::Create_Directory(const char* Path)
388   throw(ServiceUnreachable)
389 {
390   //MESSAGE("BEGIN OF Create_Directory");
391   int dimension_Path = strlen(Path) + 1;
392   char** resultat_resolve_Path= new char* [dimension_Path];;
393   CORBA::Boolean _return_code = true ;
394
395   // _current_context is replaced to the _root_context 
396   // if the Path begins whith '/'
397   if (Path[0]=='/') _current_context = _root_context;
398
399   int dimension_resultat = 0;
400   _result_resolve_Path (Path, dimension_resultat, resultat_resolve_Path);
401
402  
403   // We had to test if a part of the directory to treat 
404   // is already done
405   // If not, the new context has to be created
406  
407   CosNaming::Name _context_name;
408   _context_name.length(1);
409   CosNaming::NamingContext_var _temp_context;
410   ASSERT(!CORBA::is_nil(_current_context));
411   // Context creation
412   try
413     {
414         
415       for (int i = 0 ; i <dimension_resultat ;i++)
416         {
417           _context_name[0].id =
418             CORBA::string_dup(resultat_resolve_Path[i]);
419           _context_name[0].kind = CORBA::string_dup("dir");
420           // SCRUTE(_context_name[0].id);
421           //The Path could be in part already created. 
422           //We had to test it
423           try 
424             {
425               // this context is already created. 
426               // Nothing to be done
427               CORBA::Object_var _obj = 
428                 _current_context->resolve(_context_name);
429               _current_context = 
430                 CosNaming::NamingContext::_narrow(_obj);
431               MESSAGE("This context was already created");
432                 } 
433           catch (CosNaming::NamingContext::NotFound &) 
434             {
435               // This context is not created. It will be done
436               _temp_context =
437                 _current_context->bind_new_context(_context_name);
438               _current_context = _temp_context;
439               MESSAGE("This context was'nt created, it's now done");
440                 }
441         }
442     }
443   catch (CosNaming::NamingContext::AlreadyBound&)
444     {
445       INFOS("!!! Create_Directory() CosNaming::NamingContext::AlreadyBound");
446       _return_code = false;     
447     }
448   catch(CosNaming::NamingContext::NotFound& ex)
449     {
450       _return_code = false;
451       CosNaming::Name n = ex.rest_of_name;
452       if (ex.why == CosNaming::NamingContext::missing_node)
453         INFOS("Create_Directory() : " << (char *) n[0].id
454               << " (" << (char *) n[0].kind << ") not found");
455       if (ex.why == CosNaming::NamingContext::not_context)
456         INFOS("Create_Directory() : " << (char *) n[0].id
457              << " (" << (char *) n[0].kind
458              << ") is not a context");
459       if (ex.why == CosNaming::NamingContext::not_object)
460         INFOS("Create_Directory() : " << (char *) n[0].id
461              << " (" << (char *) n[0].kind
462              << ") is not an object");
463     }
464   catch(CosNaming::NamingContext::CannotProceed&)
465     {
466       _return_code = false;
467       INFOS("!!!Create_Directory():CosNaming::NamingContext::CannotProceed"); 
468     } 
469   catch(CosNaming::NamingContext::InvalidName&) 
470     {
471       _return_code = false;
472       INFOS("!!!Create_Directory():CosNaming::NamingContext::InvalidName");
473     }
474   catch(CORBA::COMM_FAILURE&)
475     {
476       _return_code = false;
477       INFOS("!!!Register() :CORBA::COMM_FAILURE : unable to contact"
478            << " the naming service"); 
479       throw ServiceUnreachable();
480     }
481   // Memory destruction
482   for (int i = 0 ; i <dimension_resultat;i++) 
483     {
484       delete [] resultat_resolve_Path[i];     
485     }
486   delete[] resultat_resolve_Path ;
487   return _return_code;
488 }
489
490 //----------------------------------------------------------------------
491 /*! Function : Change_Directory 
492  *  Purpose  : method to change the current directory to the
493  *             directory Path indicated in "in" Parameter.
494  *  If Path ="/", the current directory changes to the root directory.
495  *  If the NamingService is out, the exception ServiceUnreachable is thrown.
496  * \param Path const char* arguments
497  * \return a boolean to indicate if the change succeeded
498  */
499 //----------------------------------------------------------------------
500
501 bool SALOME_NamingService::Change_Directory(const char* Path)
502   throw(ServiceUnreachable)
503 {
504   //MESSAGE("BEGIN OF Change_Directory " << Path);
505   int dimension_Path = strlen(Path) + 1;
506   char** resultat_resolve_Path = new char* [dimension_Path];
507   CORBA::Boolean _return_code = true ;
508
509   // _current_context is replaced to the _root_context 
510   // if the Path begins whith '/'
511   if (Path[0]=='/') _current_context = _root_context;
512
513   if ((Path[0]=='/') && (dimension_Path == 2))
514     {
515       MESSAGE("Change_Directory is called to go to the root_context");
516     }
517   //nothing to de done, the change_dur is called to go to the root_context
518   // no Path to resolve
519   else
520     //the resolution of the directory path has to be done
521     //to place the currect_context to the correct node
522     {
523       int dimension_resultat = 0;
524       _result_resolve_Path(Path,dimension_resultat,resultat_resolve_Path);
525           
526       CosNaming::Name _context_name;
527       _context_name.length(dimension_resultat);
528       CORBA::Object_var _obj;
529
530       _create_context_name_dir(resultat_resolve_Path,dimension_resultat,
531                                _context_name);
532
533       ASSERT(!CORBA::is_nil(_current_context));
534       // Context creation
535       try 
536         {
537           _obj =_current_context->resolve(_context_name);
538           _current_context = CosNaming::NamingContext::_narrow(_obj);
539           ASSERT(!CORBA::is_nil(_current_context))
540             }
541       catch(CosNaming::NamingContext::NotFound& ex)
542         {
543           _return_code = false;
544           CosNaming::Name n = ex.rest_of_name;
545           if (ex.why == CosNaming::NamingContext::missing_node)
546             MESSAGE( "Change_Directory() : " << (char *) n[0].id
547                   << " (" << (char *) n[0].kind << ") not found")
548           if (ex.why == CosNaming::NamingContext::not_context)
549             MESSAGE("Change_Directory() : " << (char *) n[0].id
550                  << " (" << (char *) n[0].kind
551                  << ") is not a context" )
552           if (ex.why == CosNaming::NamingContext::not_object)
553             MESSAGE( "Change_Directory() : " << (char *) n[0].id
554                  << " (" << (char *) n[0].kind
555                  << ") is not an object" )
556         }
557       catch(CosNaming::NamingContext::CannotProceed&)
558         {
559           _return_code = false;
560           MESSAGE( "!!!Change_Directory() : CosNaming::NamingContext::CannotProceed" )
561         } 
562       catch(CosNaming::NamingContext::InvalidName&) 
563         {
564           _return_code = false;
565           MESSAGE( "!!!Change_Directory() : CosNaming::NamingContext::InvalidName" )
566         }
567       catch(CORBA::COMM_FAILURE&)
568         {
569           _return_code = false;
570           MESSAGE( "!!!Change_Directory() :CORBA::COMM_FAILURE : unable to contact"
571                << "the naming service")
572           throw ServiceUnreachable();
573         }
574       // Memory destruction
575       for (int i = 0 ; i <dimension_resultat ;i++) 
576         {
577           delete [] resultat_resolve_Path[i];     
578         }
579       delete[] resultat_resolve_Path ;
580     }
581   return _return_code;
582 }
583
584 //----------------------------------------------------------------------
585 /*! Function : Current_Directory 
586  *  Purpose  : method to get the current directory.
587  *  If the NamingService is out, the exception ServiceUnreachable is thrown
588  * \return the path of the current_context
589  * \sa  _current_directory
590  */ 
591 //----------------------------------------------------------------------
592
593 char* SALOME_NamingService::Current_Directory()
594   throw(ServiceUnreachable)
595 {
596   //MESSAGE("BEGIN OF Current_Directory");  
597
598   CosNaming::NamingContext_var _ref_context = _current_context;
599
600   int i = 0;
601   int length_path = 0;
602   char** result_path = new char*[50]; // 50 is it enough?
603
604  
605   // We go to the root_context to begin the search from the root
606   _current_context = _root_context ;
607   CORBA::Boolean _continue = true ;
608   try
609     {
610       _current_directory(result_path,i,_ref_context,_continue );
611     }
612   catch(CORBA::COMM_FAILURE&)
613     {
614       MESSAGE("!!!Current_Directory(): CORBA::COMM_FAILURE : unable to contact"
615            << " the naming service" )
616       throw ServiceUnreachable();
617     }
618   for (int k = 0 ; k <i ;k++) 
619     { 
620       // We count the length of the char* + 1 for the '/' to separate
621       // the directories
622       length_path = length_path + strlen(result_path[k]) + 1;
623     }
624   char* return_Path = new char[length_path +1];
625   return_Path[0] = '/' ;
626   return_Path[1] = '\0' ;
627   for (int k = 0 ; k <i ;k++) 
628     { 
629       //SCRUTE(result_path[k])
630         strcat(return_Path,result_path[k]);
631       strcat(return_Path,"/");
632     }
633   //SCRUTE(return_Path)
634     _current_context = _ref_context ;
635  
636   return return_Path;
637 }
638
639 //----------------------------------------------------------------------
640 /*! Function : list
641  *  Purpose  : method to list and print all the context contained from
642  *            the current context
643  *  If the NamingService is out, the exception ServiceUnreachable is thrown
644  */ 
645 //----------------------------------------------------------------------
646
647 void SALOME_NamingService::list()
648   throw(ServiceUnreachable)
649 {
650   MESSAGE("Begin of list");
651   CosNaming::BindingList_var _binding_list;
652   CosNaming::BindingIterator_var _binding_iterator;
653   unsigned long nb=0 ; // for using only the BindingIterator to access the bindings
654   CosNaming::Binding_var _binding ;
655   CosNaming::NamingContext_var _ref_context = _current_context;
656   _current_context->list(nb, _binding_list, _binding_iterator) ;
657
658   while (_binding_iterator->next_one(_binding)) {
659     CosNaming::Name _bindingName = _binding->binding_name;
660     if (_binding->binding_type == CosNaming::ncontext) {
661       MESSAGE( "Context : " << _bindingName[0].id );
662       try
663         {
664           Change_Directory(_bindingName[0].id);
665         }
666       catch (ServiceUnreachable&)
667         {
668           MESSAGE( "!!!list(): ServiceUnreachable" )
669           throw ServiceUnreachable(); 
670         }
671
672       list();
673       _current_context = _ref_context ;
674     }
675     else if (_binding->binding_type == CosNaming::nobject) {
676       MESSAGE( "Object : " << _bindingName[0].id );
677     }
678   }
679   _binding_iterator->destroy();
680 }
681
682 //----------------------------------------------------------------------
683 /*! Function : list_directory
684  *  Purpose  : method to get all the contexts contained in the current 
685  *             directory
686  *             Get only objects, isn't iterative 
687  *  If the NamingService is out, the exception ServiceUnreachable is thrown
688  */ 
689 //----------------------------------------------------------------------
690 vector<string> SALOME_NamingService::list_directory()
691   throw(ServiceUnreachable)
692 {
693   vector<string> _list ;
694   _list.resize(0);
695   CosNaming::BindingList_var _binding_list;
696   CosNaming::BindingIterator_var _binding_iterator;
697   unsigned long nb=0 ; // for using only the BindingIterator to access the bindings
698   CosNaming::Binding_var _binding ;
699   CosNaming::NamingContext_var _ref_context = _current_context;
700   _current_context->list(nb, _binding_list, _binding_iterator) ;
701
702   while (_binding_iterator->next_one(_binding)) {
703     CosNaming::Name _bindingName = _binding->binding_name;
704     if (_binding->binding_type == CosNaming::nobject) {
705       _list.push_back(CORBA::string_dup(_bindingName[0].id));
706     }
707   }
708   //for (unsigned int ind = 0; ind < _list.size(); ind++)
709   //  MESSAGE("list_directory : Object : " << _list[ind]);
710
711   _binding_iterator->destroy();
712   return _list;
713 }
714
715
716 //----------------------------------------------------------------------
717 /*! Function : Destroy_Name 
718  *  Purpose  : method to destroy an association Path-Object Reference.
719  *             WARNING : The complete Path should be given.
720  *  If the NamingService is out, the exception ServiceUnreachable is thrown 
721  * \param Path const char* arguments
722  */
723 //----------------------------------------------------------------------
724
725 void SALOME_NamingService::Destroy_Name(const char* Path)
726   throw(ServiceUnreachable)
727 {
728   MESSAGE("BEGIN OF Destroy_Name");
729   int dimension_Path = strlen(Path) + 1;
730   char** resultat_resolve_Path = new char* [dimension_Path];
731
732   // _current_context is replaced to the _root_context 
733   // if the Path begins whith '/'
734   if (Path[0]=='/') _current_context = _root_context;
735
736   
737   //the resolution of the directory path has to be done
738   //to place the currect_context to the correct node
739   int dimension_resultat = 0;
740   _result_resolve_Path (Path, dimension_resultat, resultat_resolve_Path);
741     
742   CosNaming::Name _context_name;
743   if (dimension_resultat>1)
744     {
745       // We go in the directory where the object to destroy is
746       _context_name.length(dimension_resultat-1);
747   
748       _create_context_name_dir(resultat_resolve_Path,dimension_resultat -1,
749                                _context_name); 
750       try
751         {
752           CORBA::Object_var _obj = _current_context->resolve(_context_name);
753           _current_context = CosNaming::NamingContext::_narrow(_obj);
754         } 
755       catch (CosNaming::NamingContext::NotFound& ex) 
756         {
757           CosNaming::Name n = ex.rest_of_name;
758           if (ex.why == CosNaming::NamingContext::missing_node)
759             MESSAGE(  "Destroy_Name() : " << (char *) n[0].id
760                   << " (" << (char *) n[0].kind << ") not found" )
761           if (ex.why == CosNaming::NamingContext::not_context)
762             MESSAGE( "Destroy_Name() : " << (char *) n[0].id
763                  << " (" << (char *) n[0].kind
764                  << ") is not a context" )
765           if (ex.why == CosNaming::NamingContext::not_object)
766             MESSAGE( "Destroy_Name() : " << (char *) n[0].id
767                  << " ("  << (char *) n[0].kind
768                  << ") is not an object" )
769         } 
770       catch (CosNaming::NamingContext::InvalidName &) 
771         {
772           MESSAGE( "!!!Destroy_Name() : CosNaming::NamingContext::InvalidName" )
773         }
774       catch (CosNaming::NamingContext::CannotProceed &)
775         {
776           MESSAGE( "!!!Destroy_Name(): CosNaming::NamingContext::CannotProceed" )
777         }
778       catch(CORBA::COMM_FAILURE&)
779         {
780           MESSAGE( "!!!Destroy_Name() : CORBA::COMM_FAILURE : unable to contact"
781                << " the naming service")
782           throw ServiceUnreachable();
783         }
784     }
785
786   // the last element is the object to destroy
787   _context_name.length(1);  
788   _context_name[0].id = 
789     CORBA::string_dup(resultat_resolve_Path[dimension_resultat -1]);
790   _context_name[0].kind = CORBA::string_dup("object");
791   SCRUTE(_context_name[0].id);
792   ASSERT(!CORBA::is_nil(_current_context));
793   // Object destruction
794   try 
795     {
796       _current_context->unbind(_context_name);
797       MESSAGE( "The object " << _context_name[0].id  << " has been deleted" )
798     }
799   catch(CosNaming::NamingContext::NotFound& ex)
800     {
801       CosNaming::Name n = ex.rest_of_name;
802       if (ex.why == CosNaming::NamingContext::missing_node)
803         MESSAGE(  "Destroy_Name() : " << (char *) n[0].id
804               << " (" << (char *) n[0].kind << ") not found" )
805       if (ex.why == CosNaming::NamingContext::not_context)
806         MESSAGE( "Destroy_Name() : " << (char *) n[0].id
807              << " (" << (char *) n[0].kind
808              << ") is not a context" )
809       if (ex.why == CosNaming::NamingContext::not_object)
810         MESSAGE( "Destroy_Name() : " << (char *) n[0].id
811              << " ("  << (char *) n[0].kind
812              << ") is not an object" )
813     }
814   catch(CosNaming::NamingContext::CannotProceed&)
815     {
816       MESSAGE( "!!!Destroy_Name() : CosNaming::NamingContext::CannotProceed")
817     } 
818   catch(CosNaming::NamingContext::InvalidName&) 
819     {
820       MESSAGE( "!!!Destroy_Name() : CosNaming::NamingContext::InvalidName")
821     }
822   catch(CORBA::COMM_FAILURE&)
823     {
824       MESSAGE( "!!!Destroy_Name() :CORBA::COMM_FAILURE : unable to contact" 
825            << " the naming service") 
826       throw ServiceUnreachable();
827     }
828   // Memory destruction
829   for (int i = 0 ; i <dimension_resultat ;i++) 
830     {
831       delete [] resultat_resolve_Path[i];     
832     }
833   delete[] resultat_resolve_Path ;
834 }
835
836 //----------------------------------------------------------------------
837 /*! Function : Destroy_Directory.
838  *  Purpose  : method to destroy a directory if it is empty.
839  *  WARNING : The complete Path  to the directory (from the root_context)
840  *  to destroy should be given.
841  *  If the NamingService is out, the exception ServiceUnreachable is thrown.
842  * \param Path const char* arguments
843  */
844 //----------------------------------------------------------------------
845
846 void SALOME_NamingService::Destroy_Directory(const char* Path)
847   throw(ServiceUnreachable)
848 {
849   MESSAGE("BEGIN OF Destroy_Directory");
850   int dimension_Path = strlen(Path) + 1;
851   char** resultat_resolve_Path = new char* [dimension_Path];
852
853   // _current_context is replaced to the _root_context 
854   // if the Path begins whith '/'
855   if (Path[0]=='/') _current_context = _root_context;
856
857   CosNaming::NamingContext_var _ref_context = _current_context;
858  
859   //the resolution of the directory path has to be done
860   //to place the currect_context to the correct node
861   int dimension_resultat = 0;
862   _result_resolve_Path (Path, dimension_resultat, resultat_resolve_Path);
863     
864   CosNaming::Name _context_name;
865   if (dimension_resultat>1)
866     {
867       // We go in the directory where the context to destroy is
868       _context_name.length(dimension_resultat-1);
869   
870       _create_context_name_dir(resultat_resolve_Path,dimension_resultat -1,
871                                _context_name); 
872       try
873         {
874           CORBA::Object_var _obj = _current_context->resolve(_context_name);
875           _current_context = CosNaming::NamingContext::_narrow(_obj);
876           _ref_context = _current_context ;
877         } 
878       catch (CosNaming::NamingContext::NotFound& ex) 
879         {
880           CosNaming::Name n = ex.rest_of_name;
881           if (ex.why == CosNaming::NamingContext::missing_node)
882             MESSAGE(  "Destroy_Directory() : " << (char *) n[0].id
883                   << " (" << (char *) n[0].kind << ") not found")
884           if (ex.why == CosNaming::NamingContext::not_context)
885             MESSAGE( "Destroy_Directory() : " << (char *) n[0].id
886                  << " (" << (char *) n[0].kind
887                  << ") is not a context" )
888           if (ex.why == CosNaming::NamingContext::not_object)
889             MESSAGE( "Destroy_Directory() : " << (char *) n[0].id
890                  << " ("  << (char *) n[0].kind
891                  << ") is not an object" )
892         } 
893       catch (CosNaming::NamingContext::InvalidName &) 
894         {
895           MESSAGE( "!!!Destroy_Directory() : CosNaming::NamingContext::InvalidName" )
896         }
897       catch (CosNaming::NamingContext::CannotProceed &)
898         {
899           MESSAGE("!!!Destroy_Directory(): CosNaming::NamingContext::CannotProceed" )
900         }
901       catch(CORBA::COMM_FAILURE&)
902         {
903           MESSAGE( "!!!Destroy_Directory() : CORBA::COMM_FAILURE : unable to contact"
904                << " the naming service" )
905           throw ServiceUnreachable();
906         }
907     }
908
909   // the last element is the context to destroy
910   _context_name.length(1);  
911   _context_name[0].id = 
912     CORBA::string_dup(resultat_resolve_Path[dimension_resultat -1]);
913   _context_name[0].kind = CORBA::string_dup("dir");
914   SCRUTE(_context_name[0].id);
915
916   try
917     {
918       // We go in the context to destroy
919       CORBA::Object_var _obj = _current_context->resolve(_context_name);
920       _current_context = CosNaming::NamingContext::_narrow(_obj);
921     } 
922   catch (CosNaming::NamingContext::NotFound& ex) 
923     {
924       CosNaming::Name n = ex.rest_of_name;
925       if (ex.why == CosNaming::NamingContext::missing_node)
926         MESSAGE(  "Destroy_Directory() : " << (char *) n[0].id
927               << " (" << (char *) n[0].kind << ") not found" )
928       if (ex.why == CosNaming::NamingContext::not_context)
929         MESSAGE( "Destroy_Directory() : " << (char *) n[0].id
930              << " (" << (char *) n[0].kind
931              << ") is not a context" )
932       if (ex.why == CosNaming::NamingContext::not_object)
933         MESSAGE( "Destroy_Directory() : " << (char *) n[0].id
934              << " ("  << (char *) n[0].kind
935              << ") is not an object" )
936     } 
937   catch (CosNaming::NamingContext::InvalidName &) 
938     {
939       MESSAGE( "!!!Destroy_Directory() : CosNaming::NamingContext::InvalidName" )
940     }
941   catch (CosNaming::NamingContext::CannotProceed &)
942     {
943       MESSAGE( "!!!Destroy_Directory(): CosNaming::NamingContext::CannotProceed" )
944     }
945   catch(CORBA::COMM_FAILURE&)
946     {
947       MESSAGE( "!!!Destroy_Directory() : CORBA::COMM_FAILURE : unable to contact"
948            << " the naming service" )
949       throw ServiceUnreachable();
950     }
951
952   ASSERT(!CORBA::is_nil(_current_context));
953   // Context Destruction
954   try 
955     {
956       _current_context->destroy();
957       MESSAGE( "The context " << _context_name[0].id << " has been deleted" )
958     }
959   catch(CosNaming::NamingContext::NotEmpty&)
960     {
961       MESSAGE( "!!!Destroy_Directory() : CosNaming::NamingContext::NoEmpty "
962            << Path << " is not empty" )
963     } 
964   catch(CORBA::COMM_FAILURE&)
965     {
966       MESSAGE( "!!!Destroy_Directory() :CORBA::COMM_FAILURE : "
967            << "unable to contact the naming service") 
968       throw ServiceUnreachable();
969     }
970   // We go to the directory just before the context to delete
971   _current_context = _ref_context ; 
972   try
973     {
974       _current_context->unbind(_context_name);
975       MESSAGE( "The bind to the context " << _context_name[0].id  << " has been deleted" )
976     }
977   catch(CosNaming::NamingContext::NotFound& ex)
978     {
979       CosNaming::Name n = ex.rest_of_name;
980       if (ex.why == CosNaming::NamingContext::missing_node)
981         MESSAGE(  "Destroy_Directory() : " << (char *) n[0].id
982               << " (" << (char *) n[0].kind << ") not found" )
983       if (ex.why == CosNaming::NamingContext::not_context)
984         MESSAGE( "Destroy_Directory() : " << (char *) n[0].id
985              << " (" << (char *) n[0].kind
986              << ") is not a context" )
987       if (ex.why == CosNaming::NamingContext::not_object)
988         MESSAGE( "Destroy_Directory() : " << (char *) n[0].id
989              << " ("  << (char *) n[0].kind
990              << ") is not an object" )
991     }
992   catch(CosNaming::NamingContext::CannotProceed&)
993     {
994       MESSAGE( "!!!Destroy_Directory() : CosNaming::NamingContext::CannotProceed")
995     } 
996   catch(CosNaming::NamingContext::InvalidName&) 
997     {
998       MESSAGE( "!!!Destroy_Directory() : CosNaming::NamingContext::InvalidName")
999     }
1000   catch(CORBA::COMM_FAILURE&)
1001     {
1002       MESSAGE( "!!!Destroy_Directory() :CORBA::COMM_FAILURE : unable to contact" 
1003            << " the naming service") 
1004       throw ServiceUnreachable();
1005     }
1006   // Memory destruction
1007   for (int i = 0 ; i <dimension_resultat ;i++) 
1008     {
1009       delete [] resultat_resolve_Path[i];     
1010     }
1011   delete[] resultat_resolve_Path ;
1012 }
1013
1014 //----------------------------------------------------------------------
1015 /*! Function : _initialize_root_context
1016  * Purpose  :  method called by constructor to initialize _root_context
1017  */
1018 //----------------------------------------------------------------------
1019
1020 void SALOME_NamingService::_initialize_root_context()
1021 {
1022   //MESSAGE("Get the root context");
1023   try
1024     {
1025       CORBA::Object_var obj = _orb->resolve_initial_references("NameService");
1026       _root_context = CosNaming::NamingContext::_narrow(obj);
1027       _current_context = _root_context ;
1028       ASSERT(!CORBA::is_nil(_root_context)); 
1029     }
1030
1031   catch(CORBA::COMM_FAILURE&)
1032     {
1033       INFOS("CORBA::COMM_FAILURE: unable to contact the naming service");
1034       throw ServiceUnreachable();
1035     }
1036   catch(...)
1037     {
1038       INFOS("Unknown Exception: unable to contact the naming service");
1039       throw ServiceUnreachable();
1040     }
1041 }
1042
1043 //----------------------------------------------------------------------
1044 /*! Function : _resolve_Path
1045  * Purpose  : method to decompose a Path : /Kernel/Services/Sessions.
1046  * 
1047  * \return a char* containing the first char between '/' (in this case Kernel)
1048  */
1049 //----------------------------------------------------------------------
1050
1051 char* SALOME_NamingService::_resolve_Path(char* Path)
1052 {
1053   int i = 0 ;
1054   int length = strlen(Path);
1055   char *resultat;
1056
1057   if (length==0) return NULL;
1058   else
1059     {
1060       while ((i<length) && (Path[i]!='/'))
1061         i++;
1062       resultat = new char[i+1];
1063       strncpy(resultat,Path,i);
1064       resultat[i]='\0';    
1065       return resultat;
1066     }
1067 }
1068
1069 //----------------------------------------------------------------------
1070 /*! Function : _result_resolve_Path.
1071  *  Purpose  : method to decompose a Path : /Kernel/Services/Sessions.
1072  *  Gives an array of char* containing Kernel, Services, Sessions.
1073  * \param  Path const char* arguments, the Path to decompose
1074  * \param j int& arguments, the size of the array of char*
1075  * \param resultat_resolve_Path char** arguments
1076  */
1077 //----------------------------------------------------------------------
1078
1079 void 
1080 SALOME_NamingService::_result_resolve_Path(const char* Path, 
1081                                            int& j, 
1082                                            char ** resultat_resolve_Path)
1083 {  
1084   //MESSAGE("BEGIN OF _result_resolve_Path");
1085   int dimension_Path = strlen(Path) + 1;
1086   char** temp= new char* [dimension_Path];
1087   char** tempslash = new char* [dimension_Path];
1088
1089   temp[j] = new char[dimension_Path];
1090   strcpy(temp[j],Path);
1091
1092   while (strlen(temp[j])>0)
1093     {
1094       // temp[j] contains the characters to be treated :
1095       //  (Path - characters already treted)
1096       // tempslash[j] = temp[j] if the string temp[j] doesn't begin whith '/'
1097       // tempslash[j] = temp[j] without '/' if the string begins whith '/'
1098       int length_temp = strlen(temp[j]);
1099       if (temp[j][0]=='/')
1100         {
1101           // the characters to be treated begin whith '/'
1102           // we don't have to take the '/'
1103           tempslash[j] = new char [length_temp] ;
1104           for (int k = 0; k < length_temp-1; k++) 
1105             tempslash[j][k] = temp[j][k+1];
1106           tempslash[j][length_temp-1]='\0';
1107         }
1108       else
1109         {
1110           //the characters to be trated don't begin with '/'
1111           // Nothing to be done on the char
1112           tempslash[j] = new char [length_temp+1] ;
1113           strcpy(tempslash[j],temp[j]);   
1114         }
1115       // decomposition of the Path 
1116       resultat_resolve_Path[j]= _resolve_Path(tempslash[j]);
1117       //SCRUTE(resultat_resolve_Path[j]);
1118
1119       int length_resultat = strlen(resultat_resolve_Path[j]) ;
1120       int dimension_temp = length_temp -length_resultat ;
1121       j++;
1122       temp[j] = new char[dimension_temp +1];
1123       for (int i = 0 ; i <dimension_temp  ;i++)
1124         {
1125           temp[j][i] =tempslash[j-1][i+ length_resultat];
1126         }
1127       temp[j][dimension_temp]= '\0';
1128       //SCRUTE(temp[j]);
1129     } 
1130   // Memory destruction
1131   for (int i = 0 ; i <j;i++) 
1132     {
1133       delete [] temp[i];
1134       delete [] tempslash[i];    
1135     }
1136   delete[] temp;
1137   delete [] tempslash ;
1138 }
1139
1140 //----------------------------------------------------------------------
1141 /*! Function : _Find.
1142  *  Purpose  : method to research a name from the current directory 
1143  *             of the naming service.   
1144  *  The naming service changes directory to go to the directory where 
1145  *  the last occurence was found.
1146  *  \param name const char* arguments
1147  *  \param occurence_number CORBA::LONG (by value)
1148  */   
1149 //----------------------------------------------------------------------
1150
1151 void SALOME_NamingService::_Find(const char* name, 
1152                                  CORBA::Long& occurence_number)
1153 {
1154   //MESSAGE("BEGIN OF _Find") SCRUTE(name); 
1155   CosNaming::BindingList_var _binding_list;
1156   CosNaming::BindingIterator_var _binding_iterator;
1157   unsigned long nb=0 ; //for using only the BindingIterator 
1158                        // to access the bindings
1159   CosNaming::Binding_var _binding ;
1160   CosNaming::NamingContext_var _ref_context = _current_context;
1161   CosNaming::NamingContext_var _found_context = _current_context;
1162
1163   _current_context->list(nb, _binding_list, _binding_iterator) ;
1164
1165   while (_binding_iterator->next_one(_binding)) {
1166     CosNaming::Name _bindingName = _binding->binding_name;
1167     if (_binding->binding_type == CosNaming::ncontext) {
1168       // We work on a directory, the search should be done in this directory
1169       Change_Directory(_bindingName[0].id);
1170       _Find(name,occurence_number);
1171       // We'll go back to the initial context
1172       _current_context = _ref_context ;
1173     }
1174     else if (_binding->binding_type == CosNaming::nobject) {
1175       // We work on an object...
1176       if (!strcmp( _bindingName[0].id,name))
1177         {
1178           //MESSAGE("One occurence was found");
1179           occurence_number++;
1180           // We keep in memory the directory where one occurence was found
1181           _found_context = _current_context ;
1182         }
1183     }
1184   }
1185   _binding_iterator->destroy();  
1186   // We go to the last directory where an occurence was found
1187   _current_context = _found_context ;
1188   //SCRUTE(occurence_number);
1189 }
1190
1191 //----------------------------------------------------------------------
1192 /*! Function : _create_context_name_dir.
1193  *  Purpose  : method to create a Context_name from an array of char.
1194  *             The number of elements to be copied are indicated 
1195  *             with lenth_copy.
1196  *
1197  * \param resultat_resolve_Path char** arguments
1198  * \param length_copy int arguments
1199  * \param _context_name CosNaming::Name arguments (by value)
1200  */
1201 //----------------------------------------------------------------------
1202
1203 void 
1204 SALOME_NamingService::_create_context_name_dir(char** resultat_resolve_Path
1205                                                ,int length_copy,
1206                                                CosNaming::Name& _context_name) 
1207 {
1208   //MESSAGE("BEGIN OF _create_context_name_dir");
1209   for (int i = 0 ; i < length_copy;i++)
1210     {
1211       _context_name[i].id = CORBA::string_dup(resultat_resolve_Path[i]);
1212       _context_name[i].kind = CORBA::string_dup("dir");
1213       //SCRUTE(_context_name[i].id);
1214     }
1215 }
1216
1217 //----------------------------------------------------------------------
1218 /*! Function : _current_directory.
1219  * Purpose  : method to parse the naming service tree to find a context
1220  *            and determine the path to go to this context from the 
1221  *            _root_context.
1222  *  \param result_path char** arguments
1223  *  \param length_result int arguments by value
1224  *  \param context_to_found CosNaming::NamingContext_var arguments
1225  *  \param _continue boolean arguments
1226  */
1227 //----------------------------------------------------------------------
1228
1229 void
1230 SALOME_NamingService::_current_directory(char** result_path,
1231                                          int& length_result,
1232                                          CosNaming::NamingContext_var context_to_found,
1233                                          CORBA::Boolean& _continue) 
1234 {
1235   //MESSAGE("BEGIN OF _current_Directory");  
1236   CosNaming::BindingList_var _binding_list;
1237   CosNaming::BindingIterator_var _binding_iterator;
1238   unsigned long nb=0 ; //for using only the BindingIterator 
1239                        // to access the bindings
1240   CosNaming::Binding_var _binding ;
1241   CosNaming::NamingContext_var _ref_context = _current_context;
1242   CosNaming::NamingContext_var _temp_context = _current_context;
1243  
1244   _current_context->list(nb, _binding_list, _binding_iterator) ;
1245
1246   while ((_binding_iterator->next_one(_binding)) && _continue) {
1247     CosNaming::Name _bindingName = _binding->binding_name;
1248     if (_binding->binding_type == CosNaming::ncontext)
1249       {
1250         // We work on a directory, the search should be done in this directory
1251  
1252         result_path[length_result] = new char(strlen(_bindingName[0].id) + 1);
1253         strcpy(result_path[length_result],_bindingName[0].id);
1254         //SCRUTE(result_path[length_result])
1255           length_result++;
1256
1257         CORBA::Object_var  _obj =_current_context->resolve(_bindingName);
1258         _temp_context = CosNaming::NamingContext::_narrow(_obj);
1259
1260         if (_temp_context->_is_equivalent(context_to_found)) 
1261           {
1262             //MESSAGE("The context is found, we stop the search");
1263             _continue = false; 
1264             //SCRUTE(_continue);
1265           }
1266         if(_continue)
1267           {
1268             //SCRUTE(_bindingName[0].id);
1269             Change_Directory(_bindingName[0].id);
1270             _current_directory(result_path,length_result,
1271                                context_to_found, _continue );
1272             if (_continue)
1273               {
1274                 // We'll go back to the initial context
1275                 _current_context = _ref_context ;
1276                 //MESSAGE("Just before the delete of ")
1277                 //SCRUTE(result_path[length_result-1]);
1278                 delete result_path[length_result-1];
1279                 length_result--;
1280               }
1281           }
1282       }
1283   }
1284   _binding_iterator->destroy();  
1285   // We go to the last directory where an occurence was found
1286   _current_context = _ref_context ; 
1287 }
1288 //----------------------------------------------------------------------