Salome HOME
bos #26457 Factorization of ORB initialization
[modules/kernel.git] / src / NamingService / SALOME_NamingService.cxx
1 // Copyright (C) 2007-2021  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 NamingService : wrapping NamingService services
24 //  File   : SALOME_NamingService.cxx
25 //  Author : Estelle Deville
26 //  Module : SALOME
27 //  $Header$
28 //
29 #include "SALOME_NamingService.hxx"
30 #include "ServiceUnreachable.hxx"
31 #include "OpUtil.hxx"
32
33 #include "utilities.h"
34
35 #include <iostream>
36 #include <cstring>
37 #include <string>
38 #include <cstdio>
39
40 #ifdef WIN32
41 #define strdup _strdup
42 #endif
43
44 /*! \class SALOME_NamingService
45     \brief A class to manage the SALOME naming service
46
47 */
48
49 // ============================================================================
50 /*! \brief Default Constructor without ORB reference.
51  *
52  *  After Default Constructor, one needs to initialize ORB.
53  *  \sa init_orb(CORBA::ORB_ptr orb), SALOME_NamingService(CORBA::ORB_ptr orb)
54  */
55 // ============================================================================
56
57 SALOME_NamingService::SALOME_NamingService()
58 {
59   _orb = CORBA::ORB::_nil();
60   _root_context = CosNaming::NamingContext::_nil();
61 }
62
63 // ============================================================================
64 /*! \brief Standard Constructor, with ORB reference.
65  *
66  * Initializes the naming service root context
67  * \param orb CORBA::ORB_ptr arguments
68  */
69 // ============================================================================
70
71 SALOME_NamingService::SALOME_NamingService(CORBA::ORB_ptr orb)
72 {
73   _orb = CORBA::ORB::_duplicate(orb);
74   _initialize_root_context();
75 }
76
77 SALOME_NamingService_Abstract *SALOME_NamingService::clone()
78 {
79   return new SALOME_NamingService(_orb);
80 }
81
82 // ============================================================================
83 /*! \brief Standard destructor.
84  *
85  *  The standard destructor does nothing special.
86  */
87 // ============================================================================
88
89 SALOME_NamingService::~SALOME_NamingService()
90 {
91   // Problem MESSAGE with singleton: late destruction,
92   // after trace system destruction ?
93   //MESSAGE("SALOME_NamingService destruction");
94 }
95
96 std::vector< std::string > SALOME_NamingService::repr()
97 {
98   return std::vector< std::string >();
99 }
100
101 // ============================================================================
102 /*! \brief initializes ORB reference and naming service root context.
103  *
104  *  Initializes ORB reference and naming service root context.
105  *  For use after default constructor.
106  *  If param orb is null, the orb is initialized
107  *  \param orb CORBA::ORB_ptr arguments
108  */
109 // ============================================================================
110
111 void SALOME_NamingService::init_orb(CORBA::ORB_ptr orb)
112 {
113   Utils_Locker lock (&_myMutex);
114   if(orb)
115     _orb = CORBA::ORB::_duplicate(orb);
116   else
117     _orb = KERNEL::GetRefToORB(); // Here we make the assumption that the orb has already been initialized
118
119   _initialize_root_context();
120 }
121
122 // ============================================================================
123 /*! \brief Registers a CORBA object reference under a path.
124  *
125  * Registers a CORBA object reference under a path. If the path ends with '/',
126  * only a directory is created.
127  * If the NamingService is out, the exception ServiceUnreachable is thrown.
128  * \param ObjRef CORBA object reference to associate to the path. To create
129  *               only a directory, give nil pointer.
130  * \param Path   A relative or absolute pathname to store the object reference.
131  *               If the pathname begins with a '/', pathname is taken
132  *               as an absolute pathname. Else, pathname is taken as a relative
133  *               path, to current context. Prefer absolute pathname, relative
134  *               pathname are not safe, when SALOME_NamingService object is
135  *               shared or use in multithreaded context.
136  *               If the path ends with '/', only a directory is created.
137  * \sa           Change_Directory(const char* Path),
138  *               Create_Directory(const char* Path)
139  *               CORBA::Object_ptr Resolve(const char* Path)
140  */
141 // ============================================================================
142
143 void SALOME_NamingService::Register(CORBA::Object_ptr ObjRef,
144                                     const char* Path)
145   
146 {
147   Utils_Locker lock (&_myMutex);
148
149   // --- _current_context is replaced to the _root_context
150   //     if the Path begins with '/'
151
152   if (Path[0] == '/'){
153     _current_context = _root_context;
154   }
155
156   // --- the resolution of the directory path has to be done
157   //      to place the current_context to the correct node
158
159   CosNaming::Name context_name;
160   std::vector<std::string> splitPath;
161   int dimension_resultat = _createContextNameDir(Path,
162                                                  context_name,
163                                                  splitPath,
164                                                  true);
165
166   CORBA::Boolean not_exist = false;
167
168   if (dimension_resultat > 0){
169     // A directory is treated (not only an object name)
170     // test if the directory where ObjRef should be recorded already exists
171     // If not, create the new context
172
173     try{
174       CORBA::Object_var obj = _current_context->resolve(context_name);
175       _current_context = CosNaming::NamingContext::_narrow(obj);
176     }
177
178     catch (CosNaming::NamingContext::NotFound &){
179       // --- failed to resolve, therefore assume cold start
180       not_exist = true;
181     }
182
183     catch (CosNaming::NamingContext::InvalidName &){
184       INFOS("Register() : CosNaming::NamingContext::InvalidName");
185     }
186
187     catch (CosNaming::NamingContext::CannotProceed &){
188       INFOS("Register() : CosNaming::NamingContext::CannotProceed");
189     }
190
191     catch (CORBA::SystemException&){
192       INFOS("Register() : CORBA::SystemException: "
193             << "unable to contact the naming service");
194       throw ServiceUnreachable();
195     }
196
197     if (not_exist){
198       try{
199         context_name.length(1);
200         for (int i = 0 ; i < dimension_resultat ;i++){
201           context_name[0].id = CORBA::string_dup(splitPath[i].c_str());
202           context_name[0].kind = CORBA::string_dup("dir");
203           // SCRUTE(_context_name[0].id);
204           // --- check if the path is created
205           try{
206             // --- if the context is already created, nothing to do
207             CORBA::Object_var obj = _current_context->resolve(context_name);
208             _current_context = CosNaming::NamingContext::_narrow(obj);
209           }
210
211           catch (CosNaming::NamingContext::NotFound &){
212             try{
213               // --- the context must be created
214               CosNaming::NamingContext_var temp_context =
215                 _current_context->bind_new_context(context_name);
216               _current_context = temp_context;
217             }
218             catch (CosNaming::NamingContext::AlreadyBound&){
219               CORBA::Object_var obj = _current_context->resolve(context_name);
220               _current_context = CosNaming::NamingContext::_narrow(obj);
221             }
222           }
223         }
224       }
225
226       catch (CosNaming::NamingContext::AlreadyBound&){
227         INFOS("Register() : CosNaming::NamingContext::AlreadyBound");
228       }
229
230       catch (CosNaming::NamingContext::NotFound& ex){
231         CosNaming::Name n = ex.rest_of_name;
232
233         if (ex.why == CosNaming::NamingContext::missing_node)
234           INFOS("Register() : " << (char *) n[0].id
235                 << " (" << (char *) n[0].kind << ") not found");
236
237         if (ex.why == CosNaming::NamingContext::not_context)
238           INFOS("Register() : " << (char *) n[0].id
239                 << " (" << (char *) n[0].kind
240                 << ") is not a context");
241
242         if (ex.why == CosNaming::NamingContext::not_object)
243           INFOS("Register() : " << (char *) n[0].id
244                 << " (" << (char *) n[0].kind
245                 << ") is not an object");
246       }
247
248       catch (CosNaming::NamingContext::CannotProceed&){
249         INFOS("Register(): CosNaming::NamingContext::CannotProceed");
250       }
251
252       catch (CosNaming::NamingContext::InvalidName&){
253         INFOS("Register(): CosNaming::NamingContext::InvalidName");
254       }
255
256       catch (CORBA::SystemException&){
257         INFOS("Register():CORBA::SystemException: "
258               << "unable to contact the naming service");
259         throw ServiceUnreachable();
260       }
261     }
262   }
263
264   // --- The current directory is now the directory where the object should
265   //     be recorded
266
267   size_t sizePath = splitPath.size();
268   if (sizePath > (size_t)dimension_resultat){
269     ASSERT(sizePath == (size_t)dimension_resultat+1);
270     context_name.length(1);
271
272     try{
273       // --- the last element is an object and not a directory
274
275       context_name[0].id = CORBA::string_dup(splitPath[dimension_resultat].c_str());
276       context_name[0].kind = CORBA::string_dup("object");
277       //SCRUTE(context_name[0].id);
278
279       _current_context->bind(context_name, ObjRef);
280     }
281
282     catch (CosNaming::NamingContext::NotFound& ex){
283       CosNaming::Name n = ex.rest_of_name;
284
285       if (ex.why == CosNaming::NamingContext::missing_node)
286         INFOS("Register() : " << (char *) n[0].id
287               << " (" << (char *) n[0].kind << ") not found");
288
289       if (ex.why == CosNaming::NamingContext::not_context)
290         INFOS("Register() : " << (char *) n[0].id
291               << " (" << (char *) n[0].kind
292               << ") is not a context");
293
294       if (ex.why == CosNaming::NamingContext::not_object)
295         INFOS("Register() : " << (char *) n[0].id
296               << " (" << (char *) n[0].kind
297               << ") is not an object");
298     }
299
300     catch (CosNaming::NamingContext::CannotProceed&){
301       INFOS("Register(): CosNaming::NamingContext::CannotProceed");
302     }
303
304     catch (CosNaming::NamingContext::InvalidName&){
305       INFOS("Register(): CosNaming::NamingContext::InvalidName");
306     }
307
308     catch (CosNaming::NamingContext::AlreadyBound&){
309       INFOS("Register(): CosNaming::NamingContext::AlreadyBound, "
310             << "object will be rebind");
311       _current_context->rebind(context_name, ObjRef);
312     }
313
314     catch (CORBA::SystemException&){
315       INFOS("!!!Register(): CORBA::SystemException: "
316             << "unable to contact the naming service");
317       throw ServiceUnreachable();
318     }
319   }
320 }
321
322 // ============================================================================
323 /*! \brief get the CORBA object reference associated to a name.
324  *
325  *  get the CORBA object reference associated to a complete name with a path.
326  *  If the NamingService is out, the exception ServiceUnreachable is thrown
327  * \param Path pathname. If the pathname begins with a '/', pathname is taken
328  *             as an absolute pathname. Else, pathname is taken as a relative
329  *             path, to current context. Prefer absolute pathname, relative
330  *             pathname are not safe, when SALOME_NamingService object is
331  *             shared or use in multithreaded context.
332  * \return the object reference if it exists under the pathname,
333  *             or nil reference in other cases.
334  * \sa         Register(CORBA::Object_ptr ObjRef, const char* Path),
335  *             Change_Directory(const char* Path)
336  */
337 // ============================================================================
338
339 CORBA::Object_ptr SALOME_NamingService::Resolve(const char* Path)
340   
341 {
342   Utils_Locker lock (&_myMutex);
343
344   // --- _current_context is replaced to the _root_context
345   //     if the Path begins with '/'
346
347   if (Path[0] == '/')
348     {
349       _current_context = _root_context;
350     }
351
352   // --- the resolution of the directory path has to be done
353   //     to place the current_context to the correct node
354
355   CosNaming::Name context_name;
356   std::vector<std::string> splitPath;
357   _createContextNameDir(Path,
358                                                  context_name,
359                                                  splitPath,
360                                                  false);
361
362   ASSERT(!CORBA::is_nil(_current_context));
363
364   CORBA::Object_var obj =  CORBA::Object::_nil();
365
366   try
367     {
368       obj = _current_context->resolve(context_name);
369     }
370
371   catch (CosNaming::NamingContext::NotFound& ex)
372     {
373       CosNaming::Name n = ex.rest_of_name;
374
375       if (ex.why == CosNaming::NamingContext::missing_node)
376         MESSAGE("Resolve() : " << (char *) n[0].id
377               << " (" << (char *) n[0].kind << ") not found");
378
379       if (ex.why == CosNaming::NamingContext::not_context)
380         INFOS("Resolve() : "
381               << (char *) n[0].id << " (" << (char *) n[0].kind
382               << ") is not a context");
383
384       if (ex.why == CosNaming::NamingContext::not_object)
385         INFOS("Resolve() : " << (char *) n[0].id
386               << " (" << (char *) n[0].kind
387               << ") is not an object");
388     }
389
390   catch (CosNaming::NamingContext::CannotProceed&)
391     {
392       INFOS("Resolve(): CosNaming::NamingContext::CannotProceed");
393     }
394
395   catch (CosNaming::NamingContext::InvalidName&)
396     {
397       INFOS("Resolve(): CosNaming::NamingContext::InvalidName");
398     }
399
400   catch (CORBA::SystemException&)
401     {
402       INFOS("Resolve():CORBA::SystemException : unable to contact"
403             << "the naming service");
404       throw ServiceUnreachable();
405     }
406
407   return obj._retn();
408 }
409
410 // ============================================================================
411 /*! \brief get the CORBA object reference associated to an incomplete name.
412  *
413  *  get the CORBA object reference associated to an incomplete name with a
414  *  path. Look for the first occurrence of name*.
415  *  If the NamingService is out, the exception ServiceUnreachable is thrown
416  * \param Path pathname under the form "/path/name" (Absolute reference !)
417  *             search the fist reference like "/path(.dir)/name*(.kind)"
418  * \return     the object reference if found, or nil reference.
419  * \sa         Resolve(const char* Path)
420  */
421 // ============================================================================
422
423 CORBA::Object_ptr SALOME_NamingService::ResolveFirst(const char* Path)
424   
425 {
426   Utils_Locker lock (&_myMutex);
427
428   std::string thePath = Path;
429   std::string basePath = "";
430   std::string name = thePath;
431
432   std::string::size_type idx = thePath.rfind('/');
433
434   if (idx != std::string::npos) // at least one '/' found
435     {
436       basePath = thePath.substr(0, idx);
437       name = thePath.substr(idx + 1);
438 //       SCRUTE(basePath);
439     }
440
441 //   SCRUTE(name);
442   CORBA::Object_var obj = CORBA::Object::_nil();
443
444   bool isOk = false;
445   if (basePath.empty())
446     isOk =true;
447   else
448     isOk = Change_Directory(basePath.c_str());
449
450   if (isOk)
451     {
452       std::vector<std::string> listElem = list_directory();
453       std::vector<std::string>::iterator its = listElem.begin();
454
455       while (its != listElem.end())
456         {
457           if ((*its).find(name) == 0)
458             {
459               return Resolve((*its).c_str());
460             }
461
462           its++;
463         }
464     }
465
466   return obj._retn();
467 }
468
469 // ============================================================================
470 /*! \brief find a component instance from hostname, containername,
471  *         componentName and number of processors.
472  *
473  *  find a component instance from hostname, containername, componentName and
474  *  number of processors.
475  *  If the NamingService is out, the exception ServiceUnreachable is thrown.
476  * \param hostname      name of the machine on which the component is searched.
477  * \param containerName name of the container in which the component is
478                         instantiated.
479  * \param componentName name of the component we are looking for an existing
480                         instance.
481  * \param nbproc        in case of multi processor machine, container name is
482  *                      suffixed with _nbproc.
483  * \return the object reference
484  */
485 // ============================================================================
486
487 CORBA::Object_ptr
488 SALOME_NamingService::ResolveComponent(const char* hostname,
489                                        const char* containerName,
490                                        const char* componentName,
491                                        const int nbproc)
492   
493 {
494   Utils_Locker lock (&_myMutex);
495
496   std::string name = "/Containers/";
497
498   name += hostname;
499
500   if ( strlen(containerName) != 0 )
501     {
502       name += "/";
503
504       if ( nbproc >= 1 )
505         {
506           char *newContainerName = new char[strlen(containerName) + 8];
507           sprintf(newContainerName, "%s_%d", containerName, nbproc);
508           name += newContainerName;
509           delete [] newContainerName;
510         }
511
512       else
513         name += containerName;
514
515       name += "/";
516
517       name += componentName;
518
519       return ResolveFirst(name.c_str());
520     }
521
522   else
523     {
524       SCRUTE(name);
525       std::string basename = name;
526       if (Change_Directory(basename.c_str()))
527         {
528           std::vector<std::string> contList = list_subdirs();
529
530           for (unsigned int ind = 0; ind < contList.size(); ind++)
531             {
532               name = contList[ind].c_str();
533
534               if ( nbproc >= 1 )
535                 {
536                   char *str_nbproc = new char[16];
537                   sprintf(str_nbproc, "_%d", nbproc);
538                   if( strstr(name.c_str(),str_nbproc) == NULL)
539                     continue; // check only containers with _%d in name
540                   delete [] str_nbproc;
541                 }
542
543               name += "/";
544               name += componentName;
545               SCRUTE(name);
546               CORBA::Object_ptr obj = ResolveFirst(name.c_str());
547
548               if ( !CORBA::is_nil(obj) )
549                 return obj;
550               else
551                 Change_Directory(basename.c_str());
552             }
553         }
554
555       return CORBA::Object::_nil();
556     }
557 }
558
559 // ============================================================================
560 /*! \brief search a name in current directory.
561  *
562  *  Search a name in the current directory. after call, the current directory
563  *  is changed to the directory containing the last occurrence of name found.
564  *  If no occurrence found (see return value), current directory remains
565  *  unchanged.
566  *
567  * \param  name the name to search.
568  * \return number of occurrences found.
569  * \sa Change_Directory(const char* Path)
570  */
571 // ============================================================================
572
573 int SALOME_NamingService::Find(const char* name)
574
575 {
576   Utils_Locker lock (&_myMutex);
577
578   CORBA::Long occurence_number = 0 ;
579
580   try
581     {
582       _Find(name, occurence_number);
583     }
584
585   catch (CORBA::SystemException&)
586     {
587       INFOS("!!!Find() : CORBA::SystemException : unable to contact"
588             << " the naming service");
589       throw ServiceUnreachable();
590     }
591
592   return occurence_number;
593 }
594
595 // ============================================================================
596 /*! \brief Creates a directory (context_name)
597  *
598  *  Creates a directory (context_name) relative to the current directory
599  *  (current context) or relative to the root directory (root context), if
600  *  the path given begins with a '/'.
601  *  If the NamingService is out, the exception ServiceUnreachable is thrown.
602  * \param Path   A relative or absolute pathname to store the object reference.
603  *               If the pathname begins with a '/', pathname is taken
604  *               as an absolute pathname. Else, pathname is taken as a relative
605  *               path, to current context. Prefer absolute pathname, relative
606  *               pathname are not safe, when SALOME_NamingService object is
607  *               shared or use in multithreaded context.
608  *  \return true if successful
609  *          (creation not strictly guaranteed if true, because Register may
610  *           catch some specific unlikely exception without throw anything
611  *           --- to be corrected ---)
612  *  \sa RegisterCORBA::Object_ptr ObjRef, const char* Path)
613  */
614 // ============================================================================
615
616 bool SALOME_NamingService::Create_Directory(const char* Path) 
617 {
618   Utils_Locker lock (&_myMutex);
619
620   std::string path(Path);
621
622   // --- if path empty, nothing to create, no context change
623
624   if (path.empty())
625     return false;
626
627   // --- if path ='/', nothing to create, only change to root_context
628
629   if (path == "/")
630     {
631       _current_context = _root_context;
632       return true;
633     }
634
635   // --- path must end with '/'
636
637   if (path[path.length()-1] != '/') path += '/';
638
639   Register(CORBA::Object::_nil(), path.c_str());
640   return true;
641 }
642
643 // ============================================================================
644 /*! \brief change current directory to the given path
645  *
646  *  change the current directory to the given path in parameter.
647  *  Warning: avoid use when the SALOME_NamingService instance is shared by
648  *  several threads (current context may be modified by another thread).
649  *  If the path is empty, nothing done return OK.
650  *  If Path ="/", the current directory changes to the root directory.
651  *  If the NamingService is out, the exception ServiceUnreachable is thrown.
652  * \param  Path the new current directory
653  * \return true if the change succeeded
654  */
655 // ============================================================================
656
657 bool SALOME_NamingService::Change_Directory(const char* Path) 
658 {
659   Utils_Locker lock (&_myMutex);
660
661   std::string path(Path);
662
663   // --- if path empty, nothing to do
664
665   if (path.empty())
666     return true;
667
668   // --- if path ='/', nothing to resolve, only change to root_context
669
670   if (path == "/")
671     {
672       _current_context = _root_context;
673       return true;
674     }
675
676   CosNaming::NamingContext_var current_context = _current_context;
677   bool changeOK = false;
678
679   // --- replace _current_context with _root_context if Path begins with '/'
680
681   if (path[0] == '/')
682     current_context = _root_context;
683
684   // --- need to resolve directory path
685
686   ASSERT(!CORBA::is_nil(current_context));
687
688   if (path[path.length()-1] != '/') path += '/';
689 //   SCRUTE(path);
690   CosNaming::Name context_name;
691   std::vector<std::string> splitPath;
692   _createContextNameDir(path.c_str(),
693                                                  context_name,
694                                                  splitPath,
695                                                  true);
696
697   // --- Context creation
698
699   try
700     {
701       CORBA::Object_var obj = current_context->resolve(context_name);
702       current_context = CosNaming::NamingContext::_narrow(obj);
703       ASSERT(!CORBA::is_nil(current_context));
704       _current_context = current_context;
705       changeOK = true;
706     }
707
708   catch (CosNaming::NamingContext::NotFound& ex)
709     {
710       CosNaming::Name n = ex.rest_of_name;
711
712       if (ex.why == CosNaming::NamingContext::missing_node)
713         MESSAGE( "Change_Directory() : " << (char *) n[0].id
714                << " (" << (char *) n[0].kind << ") not found");
715       if (ex.why == CosNaming::NamingContext::not_context)
716         INFOS("Change_Directory() : " << (char *) n[0].id
717               << " (" << (char *) n[0].kind
718                   << ") is not a context" );
719       if (ex.why == CosNaming::NamingContext::not_object)
720         INFOS( "Change_Directory() : " << (char *) n[0].id
721                << " (" << (char *) n[0].kind
722                << ") is not an object" );
723     }
724
725   catch (CosNaming::NamingContext::CannotProceed&)
726     {
727       INFOS("Change_Directory(): CosNaming::NamingContext::CannotProceed");
728     }
729
730   catch (CosNaming::NamingContext::InvalidName&)
731     {
732       INFOS("Change_Directory(): CosNaming::NamingContext::InvalidName");
733     }
734
735   catch (CORBA::SystemException&)
736     {
737       INFOS("Change_Directory():CORBA::SystemException : unable to contact"
738             << "the naming service");
739       throw ServiceUnreachable();
740     }
741
742   return changeOK;
743 }
744
745 // ============================================================================
746 /*! \brief get the current directory path
747  *
748  *  Get the current directory path.
749  *  If the NamingService is out, the exception ServiceUnreachable is thrown.
750  * \return the path of the current_context
751  * \sa  _current_directory
752  */
753 // ============================================================================
754
755 char *SALOME_NamingService::Current_Directory() 
756 {
757   Utils_Locker lock (&_myMutex);
758
759   CosNaming::NamingContext_var ref_context = _current_context;
760
761   std::vector<std::string> splitPath;
762   splitPath.resize(0);
763   int lengthPath = 0;
764   bool notFound = true ;
765
766   // --- start search from root context
767
768   _current_context = _root_context ;
769
770   try
771     {
772       _current_directory(splitPath, lengthPath, ref_context, notFound );
773     }
774
775   catch (CORBA::SystemException&)
776     {
777       INFOS("Current_Directory(): CORBA::SystemException: unable to contact"
778             << " the naming service" )
779       throw ServiceUnreachable();
780     }
781
782   std::string path;
783   lengthPath = (int)splitPath.size(); //!< TODO: conversion from size_t to int
784   for (int k = 0 ; k < lengthPath ;k++)
785     {
786       path += "/";
787       path += splitPath[k];
788     }
789
790   SCRUTE(path)
791   _current_context = ref_context ;
792
793   return strdup(path.c_str());
794 }
795
796 // ============================================================================
797 /*! \brief list recursively all objects in the current context
798  *
799  *  List and print via trace all directories and objects in the current
800  *  context. Trace must be activated: compile option _DEBUG_
801  *  If the NamingService is out, the exception ServiceUnreachable is thrown
802  */
803 // ============================================================================
804
805 void SALOME_NamingService::list() 
806 {
807   Utils_Locker lock (&_myMutex)
808
809     ;
810   CosNaming::BindingList_var binding_list;
811   CosNaming::BindingIterator_var binding_iterator;
812   CosNaming::Binding_var binding ;
813
814   unsigned long nb = 0 ; // --- only for the BindingIterator use,
815                          //     to access the bindings
816
817   CosNaming::NamingContext_var ref_context = _current_context;
818
819   _current_context->list(nb, binding_list, binding_iterator) ;
820
821   if (! CORBA::is_nil(binding_iterator))
822     {
823       while (binding_iterator->next_one(binding))
824         {
825           CosNaming::Name bindingName = binding->binding_name;
826
827           if (binding->binding_type == CosNaming::ncontext)
828             {
829               try
830                 {
831                   Change_Directory(bindingName[0].id);
832                 }
833
834               catch (ServiceUnreachable&)
835                 {
836                   INFOS( "list(): ServiceUnreachable" )
837                     throw ServiceUnreachable();
838                 }
839
840               list();
841               _current_context = ref_context ;
842             }
843
844           else if (binding->binding_type == CosNaming::nobject)
845             {
846               MESSAGE( "list(): no Object : " << bindingName[0].id );
847             }
848         }
849
850       binding_iterator->destroy();
851     }
852 }
853
854 // ============================================================================
855 /*! \brief list all the objects in the current directory.
856  *
857  *  get a list of all the objects in the current directory, without recursion
858  *  on the subdirectories. Only the objects are listed, not the directories.
859  *  If the NamingService is out, the exception ServiceUnreachable is thrown.
860  * \return list of strings with objects found.
861  * \sa vector<string> list_directory_recurs()
862  */
863 // ============================================================================
864
865 std::vector<std::string> SALOME_NamingService::list_directory() 
866 {
867   Utils_Locker lock (&_myMutex);
868   std::vector<std::string> dirList ;
869   dirList.resize(0);
870
871   CosNaming::BindingList_var binding_list;
872   CosNaming::BindingIterator_var binding_iterator;
873   CosNaming::Binding_var binding ;
874
875   unsigned long nb = 0 ; // --- only for the BindingIterator use,
876                          //     to access the bindings
877
878   CosNaming::NamingContext_var ref_context = _current_context;
879
880   _current_context->list(nb, binding_list, binding_iterator);
881
882   if (binding_iterator->_is_nil())
883     return dirList;
884
885   while (binding_iterator->next_one(binding))
886     {
887       CosNaming::Name bindingName = binding->binding_name;
888
889       if (binding->binding_type == CosNaming::nobject)
890         {
891           // remove memory leak
892           // dirList.push_back(CORBA::string_dup(bindingName[0].id));
893           dirList.push_back(std::string(bindingName[0].id));
894         }
895     }
896
897 //   for (unsigned int ind = 0; ind < dirList.size(); ind++)
898 //     MESSAGE("list_directory : Object : " << dirList[ind]);
899
900   binding_iterator->destroy();
901
902   return dirList;
903 }
904
905
906 // ============================================================================
907 /*! \brief list all the subdirectories in the current directory.
908  *
909  *  get a list of all the subdirectories in the current directory,
910  *  without recursion on the subdirectories.
911  *  Only the subdirectories are listed, not the objects.
912  *  If the NamingService is out, the exception ServiceUnreachable is thrown.
913  * \return list of strings with directories found.
914  * \sa vector<string> list_directory()
915  */
916 // ============================================================================
917
918 std::vector<std::string> SALOME_NamingService::list_subdirs() 
919 {
920   Utils_Locker lock (&_myMutex);
921   std::vector<std::string> dirList ;
922   dirList.resize(0);
923
924   CosNaming::BindingList_var binding_list;
925   CosNaming::BindingIterator_var binding_iterator;
926   CosNaming::Binding_var binding ;
927
928   unsigned long nb = 0 ; // --- only for the BindingIterator use,
929                          //     to access the bindings
930
931   CosNaming::NamingContext_var ref_context = _current_context;
932
933   _current_context->list(nb, binding_list, binding_iterator) ;
934
935   if (binding_iterator->_is_nil())
936     return dirList;
937
938   while (binding_iterator->next_one(binding))
939     {
940       CosNaming::Name bindingName = binding->binding_name;
941
942       if (binding->binding_type == CosNaming::ncontext)
943         {
944           dirList.push_back(bindingName[0].id.in());
945         }
946     }
947
948   // for (unsigned int ind = 0; ind < dirList.size(); ind++)
949   //   MESSAGE("list_directory : Object : " << dirList[ind]);
950
951   binding_iterator->destroy();
952
953   return dirList;
954 }
955
956 // ============================================================================
957 /*! \brief  list all the objects in the current directory and subdirectories.
958  *
959  *  get a list of all the objects in the current directory, with recursion
960  *  on the subdirectories. Only the objects are listed, not the directories.
961  *  If the NamingService is out, the exception ServiceUnreachable is thrown.
962  * \return list of strings with objects found.
963  * \sa vector<string> list_directory()
964  */
965 // ============================================================================
966
967 std::vector<std::string> SALOME_NamingService::list_directory_recurs()
968
969 {
970   Utils_Locker lock (&_myMutex);
971
972   std::vector<std::string> dirList ;
973
974   char* currentDir = Current_Directory();
975
976   _list_directory_recurs(dirList, "", currentDir);
977
978   free(currentDir);
979
980   return dirList;
981 }
982
983 // ============================================================================
984 /*! \brief destroy an entry in naming service.
985  *
986  *  Destroy an association Path - Object Reference.
987  *  If the NamingService is out, the exception ServiceUnreachable is thrown
988  * \param Path object path
989  */
990 // ============================================================================
991
992 void SALOME_NamingService::Destroy_Name(const char* Path)
993
994 {
995   Utils_Locker lock (&_myMutex);
996
997   std::string path(Path);
998
999   // --- if path empty, nothing to do
1000
1001   if (path.empty())
1002     return;
1003
1004   // --- if path = '/' not applicable, nothing to do
1005
1006   if (path == "/")
1007     return;
1008
1009   // --- if path begins with '/', set current directory to root context
1010
1011   if (path[0] == '/')
1012     _current_context = _root_context;
1013
1014   // --- context of the directory containing the object
1015
1016   CosNaming::Name context_name;
1017   std::vector<std::string> splitPath;
1018   int dimension_resultat = _createContextNameDir(path.c_str(),
1019                                                  context_name,
1020                                                  splitPath,
1021                                                  true);
1022
1023   bool exist = false;
1024
1025   if (dimension_resultat > 0)
1026     {
1027       // --- path contains a directory, not only an object name
1028       //     switch to the new directory (or return if directory not found)
1029
1030       try
1031         {
1032           CORBA::Object_var obj = _current_context->resolve(context_name);
1033           _current_context = CosNaming::NamingContext::_narrow(obj);
1034           exist = true;
1035         }
1036
1037       catch (CosNaming::NamingContext::NotFound &ex)
1038         {
1039           // --- failed to resolve
1040           exist = false;
1041
1042           CosNaming::Name n = ex.rest_of_name;
1043
1044           if (ex.why == CosNaming::NamingContext::missing_node)
1045             INFOS( "Destroy_Name(): " << (char *) n[0].id
1046                    << " (" << (char *) n[0].kind << ") not found" );
1047           if (ex.why == CosNaming::NamingContext::not_context)
1048             INFOS( "Destroy_Name() : " << (char *) n[0].id
1049                    << " (" << (char *) n[0].kind
1050                    << ") is not a context" );
1051           if (ex.why == CosNaming::NamingContext::not_object)
1052             INFOS( "Destroy_Name() : " << (char *) n[0].id
1053                    << " (" << (char *) n[0].kind
1054                    << ") is not an object" );
1055         }
1056
1057       catch (CosNaming::NamingContext::InvalidName &)
1058         {
1059           INFOS("Destroy_Name: CosNaming::NamingContext::InvalidName");
1060         }
1061
1062       catch (CosNaming::NamingContext::CannotProceed &)
1063         {
1064           INFOS("Destroy_Name: CosNaming::NamingContext::CannotProceed");
1065         }
1066
1067       catch (CORBA::SystemException&)
1068         {
1069           INFOS("Destroy_Name : CORBA::SystemException: "
1070                 << "unable to contact the naming service");
1071           throw ServiceUnreachable();
1072         }
1073
1074       if (! exist) return;
1075     }
1076
1077   ASSERT(!CORBA::is_nil(_current_context));
1078
1079   // --- The current directory is now the directory where the object should
1080   //     be destroyed
1081
1082   size_t sizePath = splitPath.size();
1083   if (sizePath > (size_t)dimension_resultat)
1084     {
1085       ASSERT(sizePath == (size_t)dimension_resultat+1);
1086       context_name.length(1);
1087
1088       try
1089         {
1090           // --- the last element is an object and not a directory
1091
1092           context_name[0].id =
1093             CORBA::string_dup(splitPath[dimension_resultat].c_str());
1094           context_name[0].kind = CORBA::string_dup("object");
1095           //SCRUTE(context_name[0].id);
1096
1097           _current_context->unbind(context_name);
1098           //MESSAGE("The object " << context_name[0].id << " has been deleted");
1099         }
1100
1101       catch (CosNaming::NamingContext::NotFound& ex)
1102         {
1103           CosNaming::Name n = ex.rest_of_name;
1104
1105           if (ex.why == CosNaming::NamingContext::missing_node)
1106             INFOS( "Destroy_Name() : " << (char *) n[0].id
1107                    << " (" << (char *) n[0].kind << ") not found" );
1108           if (ex.why == CosNaming::NamingContext::not_context)
1109             INFOS( "Destroy_Name() : " << (char *) n[0].id
1110                    << " (" << (char *) n[0].kind
1111                    << ") is not a context" );
1112           if (ex.why == CosNaming::NamingContext::not_object)
1113             INFOS( "Destroy_Name() : " << (char *) n[0].id
1114                    << " (" << (char *) n[0].kind
1115                    << ") is not an object" );
1116           }
1117
1118       catch (CosNaming::NamingContext::CannotProceed&)
1119         {
1120           INFOS( "Destroy_Name(): CosNaming::NamingContext::CannotProceed");
1121         }
1122
1123       catch (CosNaming::NamingContext::InvalidName&)
1124         {
1125           INFOS( "Destroy_Name(): CosNaming::NamingContext::InvalidName");
1126         }
1127
1128       catch (CORBA::SystemException&)
1129         {
1130           INFOS( "Destroy_Name(): CORBA::SystemException: unable to contact"
1131                  << " the naming service");
1132           throw ServiceUnreachable();
1133         }
1134     }
1135 }
1136
1137 // ============================================================================
1138 /*! \brief Destroy an empty directory
1139  *
1140  *  Destroy an empty directory in Naming Service.
1141  *  If the NamingService is out, the exception ServiceUnreachable is thrown.
1142  * \param Path directory path
1143  */
1144 // ============================================================================
1145
1146 void SALOME_NamingService::Destroy_Directory(const char* Path) 
1147 {
1148   Utils_Locker lock (&_myMutex);
1149
1150   std::string path(Path);
1151
1152   // --- if path empty, nothing to do
1153
1154   if (path.empty())
1155     return;
1156
1157   // --- if path begins with '/', set current directory to root context
1158
1159   if (path[0] == '/')
1160     _current_context = _root_context;
1161
1162   CosNaming::NamingContext_var ref_context = _current_context;
1163
1164   // --- path must ends with '/' for a directory
1165
1166   if (path[path.size() -1] != '/')
1167     path += '/';
1168
1169   // --- context of the directory
1170
1171   CosNaming::Name context_name;
1172   std::vector<std::string> splitPath;
1173   int dimension_resultat = _createContextNameDir(path.c_str(),
1174                                                  context_name,
1175                                                  splitPath,
1176                                                  true);
1177   bool exist = false;
1178
1179   if (dimension_resultat > 0)
1180     {
1181       // --- path contains a directory, not only an object name
1182       //     switch to the new directory (or return if directory not found)
1183
1184       try
1185         {
1186           CORBA::Object_var obj = _current_context->resolve(context_name);
1187           _current_context = CosNaming::NamingContext::_narrow(obj);
1188           exist = true;
1189         }
1190
1191       catch (CosNaming::NamingContext::NotFound &ex)
1192         {
1193           // --- failed to resolve
1194           exist = false;
1195
1196           CosNaming::Name n = ex.rest_of_name;
1197
1198           if (ex.why == CosNaming::NamingContext::missing_node)
1199             INFOS( "Destroy_Directory(): " << (char *) n[0].id
1200                    << " (" << (char *) n[0].kind << ") not found" );
1201           if (ex.why == CosNaming::NamingContext::not_context)
1202             INFOS( "Destroy_Directory() : " << (char *) n[0].id
1203                    << " (" << (char *) n[0].kind
1204                    << ") is not a context" );
1205           if (ex.why == CosNaming::NamingContext::not_object)
1206             INFOS( "Destroy_Directory() : " << (char *) n[0].id
1207                    << " (" << (char *) n[0].kind
1208                    << ") is not an object" );
1209         }
1210
1211       catch (CosNaming::NamingContext::InvalidName &)
1212         {
1213           INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1214         }
1215
1216       catch (CosNaming::NamingContext::CannotProceed &)
1217         {
1218           INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1219         }
1220
1221       catch (CORBA::SystemException&)
1222         {
1223           INFOS("Destroy_Directory : CORBA::SystemException: "
1224                 << "unable to contact the naming service");
1225           throw ServiceUnreachable();
1226         }
1227
1228       if (! exist) return;
1229     }
1230
1231   ASSERT(!CORBA::is_nil(_current_context));
1232
1233   // --- Context Destruction
1234
1235   bool isContextDestroyed = false;
1236   try
1237     {
1238       _current_context->destroy();
1239       isContextDestroyed = true;
1240     }
1241
1242   catch (CosNaming::NamingContext::NotEmpty&)
1243     {
1244       INFOS( "Destroy_Directory(): CosNaming::NamingContext::NoEmpty "
1245              << path << " is not empty" );
1246     }
1247
1248   catch (CORBA::SystemException&)
1249     {
1250       INFOS( "Destroy_Directory():CORBA::SystemException : "
1251              << "unable to contact the naming service");
1252       throw ServiceUnreachable();
1253     }
1254
1255   // --- go to the reference directory
1256
1257   _current_context = ref_context ;
1258
1259   ASSERT(!CORBA::is_nil(_current_context));
1260
1261   if (isContextDestroyed)
1262     {
1263       try
1264         {
1265           _current_context->unbind(context_name);
1266         }
1267
1268       catch (CosNaming::NamingContext::NotFound& ex)
1269         {
1270           CosNaming::Name n = ex.rest_of_name;
1271
1272           if (ex.why == CosNaming::NamingContext::missing_node)
1273             INFOS( "Destroy_Directory() : " << (char *) n[0].id
1274                    << " (" << (char *) n[0].kind << ") not found" );
1275           if (ex.why == CosNaming::NamingContext::not_context)
1276             INFOS( "Destroy_Directory() : " << (char *) n[0].id
1277                    << " (" << (char *) n[0].kind
1278                    << ") is not a context" );
1279           if (ex.why == CosNaming::NamingContext::not_object)
1280             INFOS( "Destroy_Directory() : " << (char *) n[0].id
1281                    << " (" << (char *) n[0].kind
1282                    << ") is not an object" );
1283         }
1284
1285       catch (CosNaming::NamingContext::CannotProceed&)
1286         {
1287           INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1288         }
1289
1290       catch (CosNaming::NamingContext::InvalidName&)
1291         {
1292           INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1293             }
1294
1295       catch (CORBA::SystemException&)
1296         {
1297           INFOS("Destroy_Directory:CORBA::SystemException : unable to contact"
1298                  << " the naming service");
1299           throw ServiceUnreachable();
1300         }
1301     }
1302 }
1303
1304 // ============================================================================
1305 /*! \brief Destroy a directory with its contents.
1306  *
1307  *  Destroy the objects associations in a directory, and the directory itself,
1308  *  if there is no subdirectories.
1309  *  If the NamingService is out, the exception ServiceUnreachable is thrown.
1310  * \param Path the directory path.
1311  */
1312 // ============================================================================
1313
1314 void SALOME_NamingService::Destroy_FullDirectory(const char* Path) 
1315 {
1316   //no need to lock here because method calls are threadsafe.
1317   if( Change_Directory(Path) )
1318     {
1319       std::vector<std::string> contList = list_directory();
1320
1321       for (unsigned int ind = 0; ind < contList.size(); ind++)
1322         Destroy_Name(contList[ind].c_str());
1323
1324       Destroy_Directory(Path);
1325     }
1326 }
1327
1328 // ============================================================================
1329 /*! \brief  initialize root context (root directory)
1330  *
1331  * the root context initialisation must be done when the SALOME_NamingService
1332  * instance is created and before any other call. See constructors.
1333  */
1334 // ============================================================================
1335
1336 void SALOME_NamingService::_initialize_root_context()
1337 {
1338   //no lock here because initialization is expected to be done once.
1339   try
1340     {
1341       CORBA::Object_var obj = _orb->resolve_initial_references("NameService");
1342       _root_context = CosNaming::NamingContext::_narrow(obj);
1343       _current_context = _root_context ;
1344       ASSERT(!CORBA::is_nil(_root_context));
1345     }
1346
1347   catch (CORBA::SystemException&)
1348     {
1349       INFOS("CORBA::SystemException: unable to contact the naming service");
1350       throw ServiceUnreachable();
1351     }
1352
1353   catch (...)
1354     {
1355       INFOS("Unknown Exception: unable to contact the naming service");
1356       throw ServiceUnreachable();
1357     }
1358 }
1359
1360 // ============================================================================
1361 /*! \brief transform a string path in CosNaming structure.
1362  *
1363  *  Transform a path given as a string in a CosNaming structure.
1364  *  \param path         a relative or absolute path, with or without an object.
1365  *                      An absolute path begins with '/'.
1366  *                      A path without an object ends with '/'.
1367  *  \param context_name CosNaming structure to put the path.
1368  *  \param splitPath    a vector of string with subdirectories and final
1369  *                      object, if any.
1370  *  \param onlyDir      if true, final object (if any) is omitted
1371  *                      in context_name.
1372  *                      if false, final object (if any) is included in
1373  *                      context_name.
1374  *  \return             dimension of context_name
1375  */
1376 // ============================================================================
1377
1378 int
1379 SALOME_NamingService::_createContextNameDir(std::string path,
1380                                             CosNaming::Name& context_name,
1381                                             std::vector<std::string>& splitPath,
1382                                             bool onlyDir)
1383 {
1384   if (path.empty())
1385     return 0;
1386
1387   std::string::size_type begIdx, endIdx;
1388   const std::string delims("/");
1389   splitPath.resize(0);
1390   bool endWithDelim = false;
1391
1392   begIdx = path.find_first_not_of(delims);
1393   while (begIdx != std::string::npos)
1394     {
1395       endIdx = path.find_first_of(delims, begIdx);
1396       if (endIdx == path.length()-1)
1397         endWithDelim = true;
1398       if (endIdx == std::string::npos)
1399         endIdx = path.length();
1400       size_t lsub = endIdx - begIdx;
1401       if (lsub >= 1)
1402         splitPath.push_back(path.substr(begIdx, lsub));
1403       begIdx = path.find_first_not_of(delims, endIdx);
1404     }
1405
1406   int dim;
1407   if (onlyDir)                  // only directory part
1408     {
1409       dim = (int)splitPath.size()-1; // omit final object
1410       if (endWithDelim)         // unless the path ends with a delimiter
1411         dim++;
1412       endWithDelim = true;
1413     }
1414   else
1415     dim = (int)splitPath.size();     // directories and final object
1416
1417   context_name.length((CORBA::ULong)dim);
1418   for (int i=0; i<dim; i++)
1419     {
1420 //       SCRUTE(splitPath[i]);
1421       context_name[i].id = CORBA::string_dup(splitPath[i].c_str());
1422       if (!endWithDelim && (i == dim-1)) // here, the last string is an object
1423         {
1424           context_name[i].kind = CORBA::string_dup("object");
1425 //        MESSAGE("--- " <<splitPath[i] <<".object");
1426         }
1427       else
1428         {
1429           context_name[i].kind = CORBA::string_dup("dir");
1430 //        MESSAGE("--- " <<splitPath[i] <<".dir");
1431         }
1432     }
1433   return dim; //TODO: return <int> or <size_t>?
1434 }
1435
1436 // ============================================================================
1437 /*! \brief search a name in current directory.
1438  *
1439  *  Search a name in the current directory. after call, the current directory
1440  *  is changed to the directory containing the last occurrence of name found.
1441  *  If no occurrence found (see return value), current directory remains
1442  *  unchanged. The call is recursive.
1443  *
1444  * \param  name the name to search.
1445  * \param  occurence_number number of occurrence already found (incremented)
1446  */
1447 // ============================================================================
1448
1449 void SALOME_NamingService::_Find(const char* name,
1450                                  CORBA::Long& occurence_number)
1451 {
1452   CosNaming::BindingList_var binding_list;
1453   CosNaming::BindingIterator_var binding_iterator;
1454   CosNaming::Binding_var binding;
1455
1456   unsigned long nb = 0 ; // --- only for the use of the BindingIterator,
1457                          //     to access the bindings
1458
1459   CosNaming::NamingContext_var ref_context = _current_context;
1460   CosNaming::NamingContext_var found_context = _current_context;
1461
1462   _current_context->list(nb, binding_list, binding_iterator) ;
1463
1464   if (! CORBA::is_nil(binding_iterator))
1465     {
1466       while (binding_iterator->next_one(binding))
1467         {
1468           CosNaming::Name bindingName = binding->binding_name;
1469
1470           if (binding->binding_type == CosNaming::ncontext)
1471             {
1472               // --- We work on a directory,
1473               //     the search should be done in this directory
1474
1475               Change_Directory(bindingName[0].id);
1476               _Find(name, occurence_number);
1477
1478               // --- We'll go back to the initial context
1479
1480               _current_context = ref_context ;
1481             }
1482
1483           else if (binding->binding_type == CosNaming::nobject)
1484             {
1485               // --- We work on an object...
1486
1487               if (!strcmp( bindingName[0].id, name))
1488                 {
1489                   //MESSAGE("One occurrence was found");
1490                   occurence_number++;
1491
1492                   // --- We keep in memory the directory where
1493                   //     one occurrence was found
1494
1495                   found_context = _current_context ;
1496                 }
1497             }
1498         }
1499
1500       binding_iterator->destroy();
1501     }
1502   // --- We go to the last directory where an occurrence was found
1503
1504   _current_context = found_context;
1505
1506   SCRUTE(occurence_number);
1507 }
1508
1509 // ============================================================================
1510 /*! \brief find the current directory path.
1511  *
1512  *  Parse the naming service tree to find the current context and give the
1513  *  associated directory path (relative to root context).
1514  * \param splitPath
1515  * \param lengthResult
1516  * \param contextToFind
1517  * \param notFound
1518  */
1519 // ============================================================================
1520
1521 void
1522 SALOME_NamingService::
1523 _current_directory(std::vector<std::string>& splitPath,
1524                    int& lengthResult,
1525                    CosNaming::NamingContext_var contextToFind,
1526                    bool& notFound)
1527 {
1528   CosNaming::BindingList_var binding_list;
1529   CosNaming::BindingIterator_var binding_iterator;
1530   CosNaming::Binding_var binding;
1531
1532   unsigned long nb = 0 ; // --- only for the BindingIterator use,
1533                          //     to access the bindings
1534
1535   CosNaming::NamingContext_var ref_context = _current_context;
1536   CosNaming::NamingContext_var temp_context = _current_context;
1537
1538   _current_context->list(nb, binding_list, binding_iterator);
1539
1540   if ( !binding_iterator->_is_nil() )
1541     {
1542       while ((binding_iterator->next_one(binding)) && notFound)
1543         {
1544           CosNaming::Name bindingName = binding->binding_name;
1545
1546           if (binding->binding_type == CosNaming::ncontext)
1547             {
1548               // --- directory, search in it
1549
1550               const char* bindingNameid=bindingName[0].id;
1551               splitPath.push_back(bindingNameid);
1552               lengthResult++;
1553
1554               CORBA::Object_var obj = _current_context->resolve(bindingName);
1555               temp_context = CosNaming::NamingContext::_narrow(obj);
1556
1557               if (temp_context->_is_equivalent(contextToFind))
1558                 {
1559                   //MESSAGE("The context is found, we stop the search");
1560                   notFound = false;
1561                   //SCRUTE(notFound);
1562                 }
1563
1564               if (notFound)
1565                 {
1566                   //SCRUTE(bindingName[0].id);
1567                   Change_Directory(bindingName[0].id);
1568                   _current_directory(splitPath,
1569                                      lengthResult,
1570                                      contextToFind,
1571                                      notFound);
1572
1573                   if (notFound)
1574                     {
1575                       // --- go back to the initial context
1576
1577                       _current_context = ref_context;
1578
1579                       // MESSAGE("Just before the delete of "
1580                       //         << splitPath[lengthResult-1]);
1581                       splitPath.pop_back();
1582                       lengthResult--;
1583                     }
1584                 }
1585             }
1586         }
1587
1588       binding_iterator->destroy();
1589     }
1590
1591   // --- return to the last directory where an occurrence was found
1592
1593   _current_context = ref_context ;
1594 }
1595
1596
1597 // ============================================================================
1598 /*! \brief list recursively all objects in the given directory and subdirs.
1599  *
1600  *  get a list of all the objects in the current directory, with recursion
1601  *  on the subdirectories. Only the objects are listed, not the directories.
1602  *  If the NamingService is out, the exception ServiceUnreachable is thrown.
1603  *  _current_context must refer to absCurDirectory.
1604  *
1605  *  \param myList          The list that will be filled.
1606  *  \param relativeSubDir  The directory relative to absCurDirectory in which
1607  *                         the objects are found.
1608  *  \param absCurDirectory The current directory, absolute path
1609  */
1610 // ============================================================================
1611
1612 void SALOME_NamingService::_list_directory_recurs(std::vector<std::string>& myList,
1613                                                   std::string relativeSubDir,
1614                                                   std::string absCurDirectory)
1615 {
1616   CosNaming::BindingList_var binding_list;
1617   CosNaming::BindingIterator_var binding_iterator;
1618   CosNaming::Binding_var binding ;
1619
1620   unsigned long nb = 0 ; // --- only for thethe use of BindingIterator
1621                          //     to access the bindings
1622
1623   std::string absDir;
1624
1625   CosNaming::NamingContext_var ref_context = _current_context;
1626
1627   if (! relativeSubDir.empty())
1628     {
1629       Change_Directory(relativeSubDir.c_str());
1630       absDir = absCurDirectory + "/" + relativeSubDir;
1631     }
1632
1633   else
1634     absDir = absCurDirectory;
1635
1636   SCRUTE(absDir);
1637   _current_context->list(nb, binding_list, binding_iterator) ;
1638
1639   if (! CORBA::is_nil(binding_iterator))
1640     {
1641       while (binding_iterator->next_one(binding))
1642         {
1643           CosNaming::Name bindingName = binding->binding_name;
1644
1645           if (binding->binding_type == CosNaming::ncontext)
1646             {
1647               std::string relativeSdir(bindingName[0].id);
1648               _list_directory_recurs(myList, relativeSdir, absDir);
1649             }
1650
1651           else if (binding->binding_type == CosNaming::nobject)
1652             {
1653               std::string objName(bindingName[0].id);
1654               std::string elt = absDir + "/" + objName;
1655               SCRUTE(elt);
1656               myList.push_back(elt);
1657             }
1658         }
1659
1660       binding_iterator->destroy();
1661     }
1662   if (! relativeSubDir.empty())
1663     {
1664       _current_context = ref_context;
1665     }
1666 }
1667
1668 // ============================================================================
1669 /*! \brief return a stringified reference of root context
1670  *
1671  * \return a stringified reference of root context
1672  */
1673 // ============================================================================
1674
1675 char * SALOME_NamingService::getIORaddr()
1676 {
1677   return _orb->object_to_string(_root_context);
1678 }
1679
1680 /*! \brief get the orb used by the naming service
1681  *
1682  *  \return the orb
1683  */
1684 CORBA::ORB_ptr SALOME_NamingService::orb()
1685 {
1686   return _orb;
1687 }