1 // Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SALOME NamingService : wrapping NamingService services
24 // File : SALOME_NamingService.cxx
25 // Author : Estelle Deville
29 #include "SALOME_NamingService.hxx"
30 #include "ServiceUnreachable.hxx"
32 #include "utilities.h"
40 #define strdup _strdup
43 /*! \class SALOME_NamingService
44 \brief A class to manage the SALOME naming service
48 // ============================================================================
49 /*! \brief Default Constructor without ORB reference.
51 * After Default Constructor, one needs to initialize ORB.
52 * \sa init_orb(CORBA::ORB_ptr orb), SALOME_NamingService(CORBA::ORB_ptr orb)
54 // ============================================================================
56 SALOME_NamingService::SALOME_NamingService()
58 _orb = CORBA::ORB::_nil();
59 _root_context = CosNaming::NamingContext::_nil();
62 // ============================================================================
63 /*! \brief Standard Constructor, with ORB reference.
65 * Initializes the naming service root context
66 * \param orb CORBA::ORB_ptr arguments
68 // ============================================================================
70 SALOME_NamingService::SALOME_NamingService(CORBA::ORB_ptr orb)
72 _orb = CORBA::ORB::_duplicate(orb);
73 _initialize_root_context();
76 SALOME_NamingService_Abstract *SALOME_NamingService::clone()
78 return new SALOME_NamingService(_orb);
81 // ============================================================================
82 /*! \brief Standard destructor.
84 * The standard destructor does nothing special.
86 // ============================================================================
88 SALOME_NamingService::~SALOME_NamingService()
90 // Problem MESSAGE with singleton: late destruction,
91 // after trace system destruction ?
92 //MESSAGE("SALOME_NamingService destruction");
95 std::vector< std::string > SALOME_NamingService::repr()
97 return std::vector< std::string >();
100 // ============================================================================
101 /*! \brief initializes ORB reference and naming service root context.
103 * Initializes ORB reference and naming service root context.
104 * For use after default constructor.
105 * If param orb is null, the orb is initialized
106 * \param orb CORBA::ORB_ptr arguments
108 // ============================================================================
110 void SALOME_NamingService::init_orb(CORBA::ORB_ptr orb)
112 Utils_Locker lock (&_myMutex);
114 _orb = CORBA::ORB::_duplicate(orb);
118 _orb = CORBA::ORB_init(argc, 0); // Here we make the assumption that the orb has already been initialized
121 _initialize_root_context();
124 // ============================================================================
125 /*! \brief Registers a CORBA object reference under a path.
127 * Registers a CORBA object reference under a path. If the path ends with '/',
128 * only a directory is created.
129 * If the NamingService is out, the exception ServiceUnreachable is thrown.
130 * \param ObjRef CORBA object reference to associate to the path. To create
131 * only a directory, give nil pointer.
132 * \param Path A relative or absolute pathname to store the object reference.
133 * If the pathname begins with a '/', pathname is taken
134 * as an absolute pathname. Else, pathname is taken as a relative
135 * path, to current context. Prefer absolute pathname, relative
136 * pathname are not safe, when SALOME_NamingService object is
137 * shared or use in multithreaded context.
138 * If the path ends with '/', only a directory is created.
139 * \sa Change_Directory(const char* Path),
140 * Create_Directory(const char* Path)
141 * CORBA::Object_ptr Resolve(const char* Path)
143 // ============================================================================
145 void SALOME_NamingService::Register(CORBA::Object_ptr ObjRef,
149 Utils_Locker lock (&_myMutex);
151 // --- _current_context is replaced to the _root_context
152 // if the Path begins with '/'
155 _current_context = _root_context;
158 // --- the resolution of the directory path has to be done
159 // to place the current_context to the correct node
161 CosNaming::Name context_name;
162 std::vector<std::string> splitPath;
163 int dimension_resultat = _createContextNameDir(Path,
168 CORBA::Boolean not_exist = false;
170 if (dimension_resultat > 0){
171 // A directory is treated (not only an object name)
172 // test if the directory where ObjRef should be recorded already exists
173 // If not, create the new context
176 CORBA::Object_var obj = _current_context->resolve(context_name);
177 _current_context = CosNaming::NamingContext::_narrow(obj);
180 catch (CosNaming::NamingContext::NotFound &){
181 // --- failed to resolve, therefore assume cold start
185 catch (CosNaming::NamingContext::InvalidName &){
186 INFOS("Register() : CosNaming::NamingContext::InvalidName");
189 catch (CosNaming::NamingContext::CannotProceed &){
190 INFOS("Register() : CosNaming::NamingContext::CannotProceed");
193 catch (CORBA::SystemException&){
194 INFOS("Register() : CORBA::SystemException: "
195 << "unable to contact the naming service");
196 throw ServiceUnreachable();
201 context_name.length(1);
202 for (int i = 0 ; i < dimension_resultat ;i++){
203 context_name[0].id = CORBA::string_dup(splitPath[i].c_str());
204 context_name[0].kind = CORBA::string_dup("dir");
205 // SCRUTE(_context_name[0].id);
206 // --- check if the path is created
208 // --- if the context is already created, nothing to do
209 CORBA::Object_var obj = _current_context->resolve(context_name);
210 _current_context = CosNaming::NamingContext::_narrow(obj);
213 catch (CosNaming::NamingContext::NotFound &){
215 // --- the context must be created
216 CosNaming::NamingContext_var temp_context =
217 _current_context->bind_new_context(context_name);
218 _current_context = temp_context;
220 catch (CosNaming::NamingContext::AlreadyBound&){
221 CORBA::Object_var obj = _current_context->resolve(context_name);
222 _current_context = CosNaming::NamingContext::_narrow(obj);
228 catch (CosNaming::NamingContext::AlreadyBound&){
229 INFOS("Register() : CosNaming::NamingContext::AlreadyBound");
232 catch (CosNaming::NamingContext::NotFound& ex){
233 CosNaming::Name n = ex.rest_of_name;
235 if (ex.why == CosNaming::NamingContext::missing_node)
236 INFOS("Register() : " << (char *) n[0].id
237 << " (" << (char *) n[0].kind << ") not found");
239 if (ex.why == CosNaming::NamingContext::not_context)
240 INFOS("Register() : " << (char *) n[0].id
241 << " (" << (char *) n[0].kind
242 << ") is not a context");
244 if (ex.why == CosNaming::NamingContext::not_object)
245 INFOS("Register() : " << (char *) n[0].id
246 << " (" << (char *) n[0].kind
247 << ") is not an object");
250 catch (CosNaming::NamingContext::CannotProceed&){
251 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
254 catch (CosNaming::NamingContext::InvalidName&){
255 INFOS("Register(): CosNaming::NamingContext::InvalidName");
258 catch (CORBA::SystemException&){
259 INFOS("Register():CORBA::SystemException: "
260 << "unable to contact the naming service");
261 throw ServiceUnreachable();
266 // --- The current directory is now the directory where the object should
269 size_t sizePath = splitPath.size();
270 if (sizePath > (size_t)dimension_resultat){
271 ASSERT(sizePath == (size_t)dimension_resultat+1);
272 context_name.length(1);
275 // --- the last element is an object and not a directory
277 context_name[0].id = CORBA::string_dup(splitPath[dimension_resultat].c_str());
278 context_name[0].kind = CORBA::string_dup("object");
279 //SCRUTE(context_name[0].id);
281 _current_context->bind(context_name, ObjRef);
284 catch (CosNaming::NamingContext::NotFound& ex){
285 CosNaming::Name n = ex.rest_of_name;
287 if (ex.why == CosNaming::NamingContext::missing_node)
288 INFOS("Register() : " << (char *) n[0].id
289 << " (" << (char *) n[0].kind << ") not found");
291 if (ex.why == CosNaming::NamingContext::not_context)
292 INFOS("Register() : " << (char *) n[0].id
293 << " (" << (char *) n[0].kind
294 << ") is not a context");
296 if (ex.why == CosNaming::NamingContext::not_object)
297 INFOS("Register() : " << (char *) n[0].id
298 << " (" << (char *) n[0].kind
299 << ") is not an object");
302 catch (CosNaming::NamingContext::CannotProceed&){
303 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
306 catch (CosNaming::NamingContext::InvalidName&){
307 INFOS("Register(): CosNaming::NamingContext::InvalidName");
310 catch (CosNaming::NamingContext::AlreadyBound&){
311 INFOS("Register(): CosNaming::NamingContext::AlreadyBound, "
312 << "object will be rebind");
313 _current_context->rebind(context_name, ObjRef);
316 catch (CORBA::SystemException&){
317 INFOS("!!!Register(): CORBA::SystemException: "
318 << "unable to contact the naming service");
319 throw ServiceUnreachable();
324 // ============================================================================
325 /*! \brief get the CORBA object reference associated to a name.
327 * get the CORBA object reference associated to a complete name with a path.
328 * If the NamingService is out, the exception ServiceUnreachable is thrown
329 * \param Path pathname. If the pathname begins with a '/', pathname is taken
330 * as an absolute pathname. Else, pathname is taken as a relative
331 * path, to current context. Prefer absolute pathname, relative
332 * pathname are not safe, when SALOME_NamingService object is
333 * shared or use in multithreaded context.
334 * \return the object reference if it exists under the pathname,
335 * or nil reference in other cases.
336 * \sa Register(CORBA::Object_ptr ObjRef, const char* Path),
337 * Change_Directory(const char* Path)
339 // ============================================================================
341 CORBA::Object_ptr SALOME_NamingService::Resolve(const char* Path)
344 Utils_Locker lock (&_myMutex);
346 // --- _current_context is replaced to the _root_context
347 // if the Path begins with '/'
351 _current_context = _root_context;
354 // --- the resolution of the directory path has to be done
355 // to place the current_context to the correct node
357 CosNaming::Name context_name;
358 std::vector<std::string> splitPath;
359 _createContextNameDir(Path,
364 ASSERT(!CORBA::is_nil(_current_context));
366 CORBA::Object_var obj = CORBA::Object::_nil();
370 obj = _current_context->resolve(context_name);
373 catch (CosNaming::NamingContext::NotFound& ex)
375 CosNaming::Name n = ex.rest_of_name;
377 if (ex.why == CosNaming::NamingContext::missing_node)
378 MESSAGE("Resolve() : " << (char *) n[0].id
379 << " (" << (char *) n[0].kind << ") not found");
381 if (ex.why == CosNaming::NamingContext::not_context)
383 << (char *) n[0].id << " (" << (char *) n[0].kind
384 << ") is not a context");
386 if (ex.why == CosNaming::NamingContext::not_object)
387 INFOS("Resolve() : " << (char *) n[0].id
388 << " (" << (char *) n[0].kind
389 << ") is not an object");
392 catch (CosNaming::NamingContext::CannotProceed&)
394 INFOS("Resolve(): CosNaming::NamingContext::CannotProceed");
397 catch (CosNaming::NamingContext::InvalidName&)
399 INFOS("Resolve(): CosNaming::NamingContext::InvalidName");
402 catch (CORBA::SystemException&)
404 INFOS("Resolve():CORBA::SystemException : unable to contact"
405 << "the naming service");
406 throw ServiceUnreachable();
412 // ============================================================================
413 /*! \brief get the CORBA object reference associated to an incomplete name.
415 * get the CORBA object reference associated to an incomplete name with a
416 * path. Look for the first occurrence of name*.
417 * If the NamingService is out, the exception ServiceUnreachable is thrown
418 * \param Path pathname under the form "/path/name" (Absolute reference !)
419 * search the fist reference like "/path(.dir)/name*(.kind)"
420 * \return the object reference if found, or nil reference.
421 * \sa Resolve(const char* Path)
423 // ============================================================================
425 CORBA::Object_ptr SALOME_NamingService::ResolveFirst(const char* Path)
428 Utils_Locker lock (&_myMutex);
430 std::string thePath = Path;
431 std::string basePath = "";
432 std::string name = thePath;
434 std::string::size_type idx = thePath.rfind('/');
436 if (idx != std::string::npos) // at least one '/' found
438 basePath = thePath.substr(0, idx);
439 name = thePath.substr(idx + 1);
444 CORBA::Object_var obj = CORBA::Object::_nil();
447 if (basePath.empty())
450 isOk = Change_Directory(basePath.c_str());
454 std::vector<std::string> listElem = list_directory();
455 std::vector<std::string>::iterator its = listElem.begin();
457 while (its != listElem.end())
459 if ((*its).find(name) == 0)
461 return Resolve((*its).c_str());
471 // ============================================================================
472 /*! \brief find a component instance from hostname, containername,
473 * componentName and number of processors.
475 * find a component instance from hostname, containername, componentName and
476 * number of processors.
477 * If the NamingService is out, the exception ServiceUnreachable is thrown.
478 * \param hostname name of the machine on which the component is searched.
479 * \param containerName name of the container in which the component is
481 * \param componentName name of the component we are looking for an existing
483 * \param nbproc in case of multi processor machine, container name is
484 * suffixed with _nbproc.
485 * \return the object reference
487 // ============================================================================
490 SALOME_NamingService::ResolveComponent(const char* hostname,
491 const char* containerName,
492 const char* componentName,
496 Utils_Locker lock (&_myMutex);
498 std::string name = "/Containers/";
502 if ( strlen(containerName) != 0 )
508 char *newContainerName = new char[strlen(containerName) + 8];
509 sprintf(newContainerName, "%s_%d", containerName, nbproc);
510 name += newContainerName;
511 delete [] newContainerName;
515 name += containerName;
519 name += componentName;
521 return ResolveFirst(name.c_str());
527 std::string basename = name;
528 if (Change_Directory(basename.c_str()))
530 std::vector<std::string> contList = list_subdirs();
532 for (unsigned int ind = 0; ind < contList.size(); ind++)
534 name = contList[ind].c_str();
538 char *str_nbproc = new char[16];
539 sprintf(str_nbproc, "_%d", nbproc);
540 if( strstr(name.c_str(),str_nbproc) == NULL)
541 continue; // check only containers with _%d in name
542 delete [] str_nbproc;
546 name += componentName;
548 CORBA::Object_ptr obj = ResolveFirst(name.c_str());
550 if ( !CORBA::is_nil(obj) )
553 Change_Directory(basename.c_str());
557 return CORBA::Object::_nil();
561 // ============================================================================
562 /*! \brief search a name in current directory.
564 * Search a name in the current directory. after call, the current directory
565 * is changed to the directory containing the last occurrence of name found.
566 * If no occurrence found (see return value), current directory remains
569 * \param name the name to search.
570 * \return number of occurrences found.
571 * \sa Change_Directory(const char* Path)
573 // ============================================================================
575 int SALOME_NamingService::Find(const char* name)
578 Utils_Locker lock (&_myMutex);
580 CORBA::Long occurence_number = 0 ;
584 _Find(name, occurence_number);
587 catch (CORBA::SystemException&)
589 INFOS("!!!Find() : CORBA::SystemException : unable to contact"
590 << " the naming service");
591 throw ServiceUnreachable();
594 return occurence_number;
597 // ============================================================================
598 /*! \brief Creates a directory (context_name)
600 * Creates a directory (context_name) relative to the current directory
601 * (current context) or relative to the root directory (root context), if
602 * the path given begins with a '/'.
603 * If the NamingService is out, the exception ServiceUnreachable is thrown.
604 * \param Path A relative or absolute pathname to store the object reference.
605 * If the pathname begins with a '/', pathname is taken
606 * as an absolute pathname. Else, pathname is taken as a relative
607 * path, to current context. Prefer absolute pathname, relative
608 * pathname are not safe, when SALOME_NamingService object is
609 * shared or use in multithreaded context.
610 * \return true if successful
611 * (creation not strictly guaranteed if true, because Register may
612 * catch some specific unlikely exception without throw anything
613 * --- to be corrected ---)
614 * \sa RegisterCORBA::Object_ptr ObjRef, const char* Path)
616 // ============================================================================
618 bool SALOME_NamingService::Create_Directory(const char* Path)
620 Utils_Locker lock (&_myMutex);
622 std::string path(Path);
624 // --- if path empty, nothing to create, no context change
629 // --- if path ='/', nothing to create, only change to root_context
633 _current_context = _root_context;
637 // --- path must end with '/'
639 if (path[path.length()-1] != '/') path += '/';
641 Register(CORBA::Object::_nil(), path.c_str());
645 // ============================================================================
646 /*! \brief change current directory to the given path
648 * change the current directory to the given path in parameter.
649 * Warning: avoid use when the SALOME_NamingService instance is shared by
650 * several threads (current context may be modified by another thread).
651 * If the path is empty, nothing done return OK.
652 * If Path ="/", the current directory changes to the root directory.
653 * If the NamingService is out, the exception ServiceUnreachable is thrown.
654 * \param Path the new current directory
655 * \return true if the change succeeded
657 // ============================================================================
659 bool SALOME_NamingService::Change_Directory(const char* Path)
661 Utils_Locker lock (&_myMutex);
663 std::string path(Path);
665 // --- if path empty, nothing to do
670 // --- if path ='/', nothing to resolve, only change to root_context
674 _current_context = _root_context;
678 CosNaming::NamingContext_var current_context = _current_context;
679 bool changeOK = false;
681 // --- replace _current_context with _root_context if Path begins with '/'
684 current_context = _root_context;
686 // --- need to resolve directory path
688 ASSERT(!CORBA::is_nil(current_context));
690 if (path[path.length()-1] != '/') path += '/';
692 CosNaming::Name context_name;
693 std::vector<std::string> splitPath;
694 _createContextNameDir(path.c_str(),
699 // --- Context creation
703 CORBA::Object_var obj = current_context->resolve(context_name);
704 current_context = CosNaming::NamingContext::_narrow(obj);
705 ASSERT(!CORBA::is_nil(current_context));
706 _current_context = current_context;
710 catch (CosNaming::NamingContext::NotFound& ex)
712 CosNaming::Name n = ex.rest_of_name;
714 if (ex.why == CosNaming::NamingContext::missing_node)
715 MESSAGE( "Change_Directory() : " << (char *) n[0].id
716 << " (" << (char *) n[0].kind << ") not found");
717 if (ex.why == CosNaming::NamingContext::not_context)
718 INFOS("Change_Directory() : " << (char *) n[0].id
719 << " (" << (char *) n[0].kind
720 << ") is not a context" );
721 if (ex.why == CosNaming::NamingContext::not_object)
722 INFOS( "Change_Directory() : " << (char *) n[0].id
723 << " (" << (char *) n[0].kind
724 << ") is not an object" );
727 catch (CosNaming::NamingContext::CannotProceed&)
729 INFOS("Change_Directory(): CosNaming::NamingContext::CannotProceed");
732 catch (CosNaming::NamingContext::InvalidName&)
734 INFOS("Change_Directory(): CosNaming::NamingContext::InvalidName");
737 catch (CORBA::SystemException&)
739 INFOS("Change_Directory():CORBA::SystemException : unable to contact"
740 << "the naming service");
741 throw ServiceUnreachable();
747 // ============================================================================
748 /*! \brief get the current directory path
750 * Get the current directory path.
751 * If the NamingService is out, the exception ServiceUnreachable is thrown.
752 * \return the path of the current_context
753 * \sa _current_directory
755 // ============================================================================
757 char *SALOME_NamingService::Current_Directory()
759 Utils_Locker lock (&_myMutex);
761 CosNaming::NamingContext_var ref_context = _current_context;
763 std::vector<std::string> splitPath;
766 bool notFound = true ;
768 // --- start search from root context
770 _current_context = _root_context ;
774 _current_directory(splitPath, lengthPath, ref_context, notFound );
777 catch (CORBA::SystemException&)
779 INFOS("Current_Directory(): CORBA::SystemException: unable to contact"
780 << " the naming service" )
781 throw ServiceUnreachable();
785 lengthPath = (int)splitPath.size(); //!< TODO: conversion from size_t to int
786 for (int k = 0 ; k < lengthPath ;k++)
789 path += splitPath[k];
793 _current_context = ref_context ;
795 return strdup(path.c_str());
798 // ============================================================================
799 /*! \brief list recursively all objects in the current context
801 * List and print via trace all directories and objects in the current
802 * context. Trace must be activated: compile option _DEBUG_
803 * If the NamingService is out, the exception ServiceUnreachable is thrown
805 // ============================================================================
807 void SALOME_NamingService::list()
809 Utils_Locker lock (&_myMutex)
812 CosNaming::BindingList_var binding_list;
813 CosNaming::BindingIterator_var binding_iterator;
814 CosNaming::Binding_var binding ;
816 unsigned long nb = 0 ; // --- only for the BindingIterator use,
817 // to access the bindings
819 CosNaming::NamingContext_var ref_context = _current_context;
821 _current_context->list(nb, binding_list, binding_iterator) ;
823 if (! CORBA::is_nil(binding_iterator))
825 while (binding_iterator->next_one(binding))
827 CosNaming::Name bindingName = binding->binding_name;
829 if (binding->binding_type == CosNaming::ncontext)
833 Change_Directory(bindingName[0].id);
836 catch (ServiceUnreachable&)
838 INFOS( "list(): ServiceUnreachable" )
839 throw ServiceUnreachable();
843 _current_context = ref_context ;
846 else if (binding->binding_type == CosNaming::nobject)
848 MESSAGE( "list(): no Object : " << bindingName[0].id );
852 binding_iterator->destroy();
856 // ============================================================================
857 /*! \brief list all the objects in the current directory.
859 * get a list of all the objects in the current directory, without recursion
860 * on the subdirectories. Only the objects are listed, not the directories.
861 * If the NamingService is out, the exception ServiceUnreachable is thrown.
862 * \return list of strings with objects found.
863 * \sa vector<string> list_directory_recurs()
865 // ============================================================================
867 std::vector<std::string> SALOME_NamingService::list_directory()
869 Utils_Locker lock (&_myMutex);
870 std::vector<std::string> dirList ;
873 CosNaming::BindingList_var binding_list;
874 CosNaming::BindingIterator_var binding_iterator;
875 CosNaming::Binding_var binding ;
877 unsigned long nb = 0 ; // --- only for the BindingIterator use,
878 // to access the bindings
880 CosNaming::NamingContext_var ref_context = _current_context;
882 _current_context->list(nb, binding_list, binding_iterator);
884 if (binding_iterator->_is_nil())
887 while (binding_iterator->next_one(binding))
889 CosNaming::Name bindingName = binding->binding_name;
891 if (binding->binding_type == CosNaming::nobject)
893 // remove memory leak
894 // dirList.push_back(CORBA::string_dup(bindingName[0].id));
895 dirList.push_back(std::string(bindingName[0].id));
899 // for (unsigned int ind = 0; ind < dirList.size(); ind++)
900 // MESSAGE("list_directory : Object : " << dirList[ind]);
902 binding_iterator->destroy();
908 // ============================================================================
909 /*! \brief list all the subdirectories in the current directory.
911 * get a list of all the subdirectories in the current directory,
912 * without recursion on the subdirectories.
913 * Only the subdirectories are listed, not the objects.
914 * If the NamingService is out, the exception ServiceUnreachable is thrown.
915 * \return list of strings with directories found.
916 * \sa vector<string> list_directory()
918 // ============================================================================
920 std::vector<std::string> SALOME_NamingService::list_subdirs()
922 Utils_Locker lock (&_myMutex);
923 std::vector<std::string> dirList ;
926 CosNaming::BindingList_var binding_list;
927 CosNaming::BindingIterator_var binding_iterator;
928 CosNaming::Binding_var binding ;
930 unsigned long nb = 0 ; // --- only for the BindingIterator use,
931 // to access the bindings
933 CosNaming::NamingContext_var ref_context = _current_context;
935 _current_context->list(nb, binding_list, binding_iterator) ;
937 if (binding_iterator->_is_nil())
940 while (binding_iterator->next_one(binding))
942 CosNaming::Name bindingName = binding->binding_name;
944 if (binding->binding_type == CosNaming::ncontext)
946 dirList.push_back(bindingName[0].id.in());
950 // for (unsigned int ind = 0; ind < dirList.size(); ind++)
951 // MESSAGE("list_directory : Object : " << dirList[ind]);
953 binding_iterator->destroy();
958 // ============================================================================
959 /*! \brief list all the objects in the current directory and subdirectories.
961 * get a list of all the objects in the current directory, with recursion
962 * on the subdirectories. Only the objects are listed, not the directories.
963 * If the NamingService is out, the exception ServiceUnreachable is thrown.
964 * \return list of strings with objects found.
965 * \sa vector<string> list_directory()
967 // ============================================================================
969 std::vector<std::string> SALOME_NamingService::list_directory_recurs()
972 Utils_Locker lock (&_myMutex);
974 std::vector<std::string> dirList ;
976 char* currentDir = Current_Directory();
978 _list_directory_recurs(dirList, "", currentDir);
985 // ============================================================================
986 /*! \brief destroy an entry in naming service.
988 * Destroy an association Path - Object Reference.
989 * If the NamingService is out, the exception ServiceUnreachable is thrown
990 * \param Path object path
992 // ============================================================================
994 void SALOME_NamingService::Destroy_Name(const char* Path)
997 Utils_Locker lock (&_myMutex);
999 std::string path(Path);
1001 // --- if path empty, nothing to do
1006 // --- if path = '/' not applicable, nothing to do
1011 // --- if path begins with '/', set current directory to root context
1014 _current_context = _root_context;
1016 // --- context of the directory containing the object
1018 CosNaming::Name context_name;
1019 std::vector<std::string> splitPath;
1020 int dimension_resultat = _createContextNameDir(path.c_str(),
1027 if (dimension_resultat > 0)
1029 // --- path contains a directory, not only an object name
1030 // switch to the new directory (or return if directory not found)
1034 CORBA::Object_var obj = _current_context->resolve(context_name);
1035 _current_context = CosNaming::NamingContext::_narrow(obj);
1039 catch (CosNaming::NamingContext::NotFound &ex)
1041 // --- failed to resolve
1044 CosNaming::Name n = ex.rest_of_name;
1046 if (ex.why == CosNaming::NamingContext::missing_node)
1047 INFOS( "Destroy_Name(): " << (char *) n[0].id
1048 << " (" << (char *) n[0].kind << ") not found" );
1049 if (ex.why == CosNaming::NamingContext::not_context)
1050 INFOS( "Destroy_Name() : " << (char *) n[0].id
1051 << " (" << (char *) n[0].kind
1052 << ") is not a context" );
1053 if (ex.why == CosNaming::NamingContext::not_object)
1054 INFOS( "Destroy_Name() : " << (char *) n[0].id
1055 << " (" << (char *) n[0].kind
1056 << ") is not an object" );
1059 catch (CosNaming::NamingContext::InvalidName &)
1061 INFOS("Destroy_Name: CosNaming::NamingContext::InvalidName");
1064 catch (CosNaming::NamingContext::CannotProceed &)
1066 INFOS("Destroy_Name: CosNaming::NamingContext::CannotProceed");
1069 catch (CORBA::SystemException&)
1071 INFOS("Destroy_Name : CORBA::SystemException: "
1072 << "unable to contact the naming service");
1073 throw ServiceUnreachable();
1076 if (! exist) return;
1079 ASSERT(!CORBA::is_nil(_current_context));
1081 // --- The current directory is now the directory where the object should
1084 size_t sizePath = splitPath.size();
1085 if (sizePath > (size_t)dimension_resultat)
1087 ASSERT(sizePath == (size_t)dimension_resultat+1);
1088 context_name.length(1);
1092 // --- the last element is an object and not a directory
1094 context_name[0].id =
1095 CORBA::string_dup(splitPath[dimension_resultat].c_str());
1096 context_name[0].kind = CORBA::string_dup("object");
1097 //SCRUTE(context_name[0].id);
1099 _current_context->unbind(context_name);
1100 //MESSAGE("The object " << context_name[0].id << " has been deleted");
1103 catch (CosNaming::NamingContext::NotFound& ex)
1105 CosNaming::Name n = ex.rest_of_name;
1107 if (ex.why == CosNaming::NamingContext::missing_node)
1108 INFOS( "Destroy_Name() : " << (char *) n[0].id
1109 << " (" << (char *) n[0].kind << ") not found" );
1110 if (ex.why == CosNaming::NamingContext::not_context)
1111 INFOS( "Destroy_Name() : " << (char *) n[0].id
1112 << " (" << (char *) n[0].kind
1113 << ") is not a context" );
1114 if (ex.why == CosNaming::NamingContext::not_object)
1115 INFOS( "Destroy_Name() : " << (char *) n[0].id
1116 << " (" << (char *) n[0].kind
1117 << ") is not an object" );
1120 catch (CosNaming::NamingContext::CannotProceed&)
1122 INFOS( "Destroy_Name(): CosNaming::NamingContext::CannotProceed");
1125 catch (CosNaming::NamingContext::InvalidName&)
1127 INFOS( "Destroy_Name(): CosNaming::NamingContext::InvalidName");
1130 catch (CORBA::SystemException&)
1132 INFOS( "Destroy_Name(): CORBA::SystemException: unable to contact"
1133 << " the naming service");
1134 throw ServiceUnreachable();
1139 // ============================================================================
1140 /*! \brief Destroy an empty directory
1142 * Destroy an empty directory in Naming Service.
1143 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1144 * \param Path directory path
1146 // ============================================================================
1148 void SALOME_NamingService::Destroy_Directory(const char* Path)
1150 Utils_Locker lock (&_myMutex);
1152 std::string path(Path);
1154 // --- if path empty, nothing to do
1159 // --- if path begins with '/', set current directory to root context
1162 _current_context = _root_context;
1164 CosNaming::NamingContext_var ref_context = _current_context;
1166 // --- path must ends with '/' for a directory
1168 if (path[path.size() -1] != '/')
1171 // --- context of the directory
1173 CosNaming::Name context_name;
1174 std::vector<std::string> splitPath;
1175 int dimension_resultat = _createContextNameDir(path.c_str(),
1181 if (dimension_resultat > 0)
1183 // --- path contains a directory, not only an object name
1184 // switch to the new directory (or return if directory not found)
1188 CORBA::Object_var obj = _current_context->resolve(context_name);
1189 _current_context = CosNaming::NamingContext::_narrow(obj);
1193 catch (CosNaming::NamingContext::NotFound &ex)
1195 // --- failed to resolve
1198 CosNaming::Name n = ex.rest_of_name;
1200 if (ex.why == CosNaming::NamingContext::missing_node)
1201 INFOS( "Destroy_Directory(): " << (char *) n[0].id
1202 << " (" << (char *) n[0].kind << ") not found" );
1203 if (ex.why == CosNaming::NamingContext::not_context)
1204 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1205 << " (" << (char *) n[0].kind
1206 << ") is not a context" );
1207 if (ex.why == CosNaming::NamingContext::not_object)
1208 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1209 << " (" << (char *) n[0].kind
1210 << ") is not an object" );
1213 catch (CosNaming::NamingContext::InvalidName &)
1215 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1218 catch (CosNaming::NamingContext::CannotProceed &)
1220 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1223 catch (CORBA::SystemException&)
1225 INFOS("Destroy_Directory : CORBA::SystemException: "
1226 << "unable to contact the naming service");
1227 throw ServiceUnreachable();
1230 if (! exist) return;
1233 ASSERT(!CORBA::is_nil(_current_context));
1235 // --- Context Destruction
1237 bool isContextDestroyed = false;
1240 _current_context->destroy();
1241 isContextDestroyed = true;
1244 catch (CosNaming::NamingContext::NotEmpty&)
1246 INFOS( "Destroy_Directory(): CosNaming::NamingContext::NoEmpty "
1247 << path << " is not empty" );
1250 catch (CORBA::SystemException&)
1252 INFOS( "Destroy_Directory():CORBA::SystemException : "
1253 << "unable to contact the naming service");
1254 throw ServiceUnreachable();
1257 // --- go to the reference directory
1259 _current_context = ref_context ;
1261 ASSERT(!CORBA::is_nil(_current_context));
1263 if (isContextDestroyed)
1267 _current_context->unbind(context_name);
1270 catch (CosNaming::NamingContext::NotFound& ex)
1272 CosNaming::Name n = ex.rest_of_name;
1274 if (ex.why == CosNaming::NamingContext::missing_node)
1275 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1276 << " (" << (char *) n[0].kind << ") not found" );
1277 if (ex.why == CosNaming::NamingContext::not_context)
1278 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1279 << " (" << (char *) n[0].kind
1280 << ") is not a context" );
1281 if (ex.why == CosNaming::NamingContext::not_object)
1282 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1283 << " (" << (char *) n[0].kind
1284 << ") is not an object" );
1287 catch (CosNaming::NamingContext::CannotProceed&)
1289 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1292 catch (CosNaming::NamingContext::InvalidName&)
1294 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1297 catch (CORBA::SystemException&)
1299 INFOS("Destroy_Directory:CORBA::SystemException : unable to contact"
1300 << " the naming service");
1301 throw ServiceUnreachable();
1306 // ============================================================================
1307 /*! \brief Destroy a directory with its contents.
1309 * Destroy the objects associations in a directory, and the directory itself,
1310 * if there is no subdirectories.
1311 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1312 * \param Path the directory path.
1314 // ============================================================================
1316 void SALOME_NamingService::Destroy_FullDirectory(const char* Path)
1318 //no need to lock here because method calls are threadsafe.
1319 if( Change_Directory(Path) )
1321 std::vector<std::string> contList = list_directory();
1323 for (unsigned int ind = 0; ind < contList.size(); ind++)
1324 Destroy_Name(contList[ind].c_str());
1326 Destroy_Directory(Path);
1330 // ============================================================================
1331 /*! \brief initialize root context (root directory)
1333 * the root context initialisation must be done when the SALOME_NamingService
1334 * instance is created and before any other call. See constructors.
1336 // ============================================================================
1338 void SALOME_NamingService::_initialize_root_context()
1340 //no lock here because initialization is expected to be done once.
1343 CORBA::Object_var obj = _orb->resolve_initial_references("NameService");
1344 _root_context = CosNaming::NamingContext::_narrow(obj);
1345 _current_context = _root_context ;
1346 ASSERT(!CORBA::is_nil(_root_context));
1349 catch (CORBA::SystemException&)
1351 INFOS("CORBA::SystemException: unable to contact the naming service");
1352 throw ServiceUnreachable();
1357 INFOS("Unknown Exception: unable to contact the naming service");
1358 throw ServiceUnreachable();
1362 // ============================================================================
1363 /*! \brief transform a string path in CosNaming structure.
1365 * Transform a path given as a string in a CosNaming structure.
1366 * \param path a relative or absolute path, with or without an object.
1367 * An absolute path begins with '/'.
1368 * A path without an object ends with '/'.
1369 * \param context_name CosNaming structure to put the path.
1370 * \param splitPath a vector of string with subdirectories and final
1372 * \param onlyDir if true, final object (if any) is omitted
1374 * if false, final object (if any) is included in
1376 * \return dimension of context_name
1378 // ============================================================================
1381 SALOME_NamingService::_createContextNameDir(std::string path,
1382 CosNaming::Name& context_name,
1383 std::vector<std::string>& splitPath,
1389 std::string::size_type begIdx, endIdx;
1390 const std::string delims("/");
1391 splitPath.resize(0);
1392 bool endWithDelim = false;
1394 begIdx = path.find_first_not_of(delims);
1395 while (begIdx != std::string::npos)
1397 endIdx = path.find_first_of(delims, begIdx);
1398 if (endIdx == path.length()-1)
1399 endWithDelim = true;
1400 if (endIdx == std::string::npos)
1401 endIdx = path.length();
1402 size_t lsub = endIdx - begIdx;
1404 splitPath.push_back(path.substr(begIdx, lsub));
1405 begIdx = path.find_first_not_of(delims, endIdx);
1409 if (onlyDir) // only directory part
1411 dim = (int)splitPath.size()-1; // omit final object
1412 if (endWithDelim) // unless the path ends with a delimiter
1414 endWithDelim = true;
1417 dim = (int)splitPath.size(); // directories and final object
1419 context_name.length((CORBA::ULong)dim);
1420 for (int i=0; i<dim; i++)
1422 // SCRUTE(splitPath[i]);
1423 context_name[i].id = CORBA::string_dup(splitPath[i].c_str());
1424 if (!endWithDelim && (i == dim-1)) // here, the last string is an object
1426 context_name[i].kind = CORBA::string_dup("object");
1427 // MESSAGE("--- " <<splitPath[i] <<".object");
1431 context_name[i].kind = CORBA::string_dup("dir");
1432 // MESSAGE("--- " <<splitPath[i] <<".dir");
1435 return dim; //TODO: return <int> or <size_t>?
1438 // ============================================================================
1439 /*! \brief search a name in current directory.
1441 * Search a name in the current directory. after call, the current directory
1442 * is changed to the directory containing the last occurrence of name found.
1443 * If no occurrence found (see return value), current directory remains
1444 * unchanged. The call is recursive.
1446 * \param name the name to search.
1447 * \param occurence_number number of occurrence already found (incremented)
1449 // ============================================================================
1451 void SALOME_NamingService::_Find(const char* name,
1452 CORBA::Long& occurence_number)
1454 CosNaming::BindingList_var binding_list;
1455 CosNaming::BindingIterator_var binding_iterator;
1456 CosNaming::Binding_var binding;
1458 unsigned long nb = 0 ; // --- only for the use of the BindingIterator,
1459 // to access the bindings
1461 CosNaming::NamingContext_var ref_context = _current_context;
1462 CosNaming::NamingContext_var found_context = _current_context;
1464 _current_context->list(nb, binding_list, binding_iterator) ;
1466 if (! CORBA::is_nil(binding_iterator))
1468 while (binding_iterator->next_one(binding))
1470 CosNaming::Name bindingName = binding->binding_name;
1472 if (binding->binding_type == CosNaming::ncontext)
1474 // --- We work on a directory,
1475 // the search should be done in this directory
1477 Change_Directory(bindingName[0].id);
1478 _Find(name, occurence_number);
1480 // --- We'll go back to the initial context
1482 _current_context = ref_context ;
1485 else if (binding->binding_type == CosNaming::nobject)
1487 // --- We work on an object...
1489 if (!strcmp( bindingName[0].id, name))
1491 //MESSAGE("One occurrence was found");
1494 // --- We keep in memory the directory where
1495 // one occurrence was found
1497 found_context = _current_context ;
1502 binding_iterator->destroy();
1504 // --- We go to the last directory where an occurrence was found
1506 _current_context = found_context;
1508 SCRUTE(occurence_number);
1511 // ============================================================================
1512 /*! \brief find the current directory path.
1514 * Parse the naming service tree to find the current context and give the
1515 * associated directory path (relative to root context).
1517 * \param lengthResult
1518 * \param contextToFind
1521 // ============================================================================
1524 SALOME_NamingService::
1525 _current_directory(std::vector<std::string>& splitPath,
1527 CosNaming::NamingContext_var contextToFind,
1530 CosNaming::BindingList_var binding_list;
1531 CosNaming::BindingIterator_var binding_iterator;
1532 CosNaming::Binding_var binding;
1534 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1535 // to access the bindings
1537 CosNaming::NamingContext_var ref_context = _current_context;
1538 CosNaming::NamingContext_var temp_context = _current_context;
1540 _current_context->list(nb, binding_list, binding_iterator);
1542 if ( !binding_iterator->_is_nil() )
1544 while ((binding_iterator->next_one(binding)) && notFound)
1546 CosNaming::Name bindingName = binding->binding_name;
1548 if (binding->binding_type == CosNaming::ncontext)
1550 // --- directory, search in it
1552 const char* bindingNameid=bindingName[0].id;
1553 splitPath.push_back(bindingNameid);
1556 CORBA::Object_var obj = _current_context->resolve(bindingName);
1557 temp_context = CosNaming::NamingContext::_narrow(obj);
1559 if (temp_context->_is_equivalent(contextToFind))
1561 //MESSAGE("The context is found, we stop the search");
1568 //SCRUTE(bindingName[0].id);
1569 Change_Directory(bindingName[0].id);
1570 _current_directory(splitPath,
1577 // --- go back to the initial context
1579 _current_context = ref_context;
1581 // MESSAGE("Just before the delete of "
1582 // << splitPath[lengthResult-1]);
1583 splitPath.pop_back();
1590 binding_iterator->destroy();
1593 // --- return to the last directory where an occurrence was found
1595 _current_context = ref_context ;
1599 // ============================================================================
1600 /*! \brief list recursively all objects in the given directory and subdirs.
1602 * get a list of all the objects in the current directory, with recursion
1603 * on the subdirectories. Only the objects are listed, not the directories.
1604 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1605 * _current_context must refer to absCurDirectory.
1607 * \param myList The list that will be filled.
1608 * \param relativeSubDir The directory relative to absCurDirectory in which
1609 * the objects are found.
1610 * \param absCurDirectory The current directory, absolute path
1612 // ============================================================================
1614 void SALOME_NamingService::_list_directory_recurs(std::vector<std::string>& myList,
1615 std::string relativeSubDir,
1616 std::string absCurDirectory)
1618 CosNaming::BindingList_var binding_list;
1619 CosNaming::BindingIterator_var binding_iterator;
1620 CosNaming::Binding_var binding ;
1622 unsigned long nb = 0 ; // --- only for thethe use of BindingIterator
1623 // to access the bindings
1627 CosNaming::NamingContext_var ref_context = _current_context;
1629 if (! relativeSubDir.empty())
1631 Change_Directory(relativeSubDir.c_str());
1632 absDir = absCurDirectory + "/" + relativeSubDir;
1636 absDir = absCurDirectory;
1639 _current_context->list(nb, binding_list, binding_iterator) ;
1641 if (! CORBA::is_nil(binding_iterator))
1643 while (binding_iterator->next_one(binding))
1645 CosNaming::Name bindingName = binding->binding_name;
1647 if (binding->binding_type == CosNaming::ncontext)
1649 std::string relativeSdir(bindingName[0].id);
1650 _list_directory_recurs(myList, relativeSdir, absDir);
1653 else if (binding->binding_type == CosNaming::nobject)
1655 std::string objName(bindingName[0].id);
1656 std::string elt = absDir + "/" + objName;
1658 myList.push_back(elt);
1662 binding_iterator->destroy();
1664 if (! relativeSubDir.empty())
1666 _current_context = ref_context;
1670 // ============================================================================
1671 /*! \brief return a stringified reference of root context
1673 * \return a stringified reference of root context
1675 // ============================================================================
1677 char * SALOME_NamingService::getIORaddr()
1679 return _orb->object_to_string(_root_context);
1682 /*! \brief get the orb used by the naming service
1686 CORBA::ORB_ptr SALOME_NamingService::orb()