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"
33 #include "utilities.h"
41 #define strdup _strdup
44 /*! \class SALOME_NamingService
45 \brief A class to manage the SALOME naming service
49 // ============================================================================
50 /*! \brief Default Constructor without ORB reference.
52 * After Default Constructor, one needs to initialize ORB.
53 * \sa init_orb(CORBA::ORB_ptr orb), SALOME_NamingService(CORBA::ORB_ptr orb)
55 // ============================================================================
57 SALOME_NamingService::SALOME_NamingService()
59 _orb = CORBA::ORB::_nil();
60 _root_context = CosNaming::NamingContext::_nil();
63 // ============================================================================
64 /*! \brief Standard Constructor, with ORB reference.
66 * Initializes the naming service root context
67 * \param orb CORBA::ORB_ptr arguments
69 // ============================================================================
71 SALOME_NamingService::SALOME_NamingService(CORBA::ORB_ptr orb)
73 _orb = CORBA::ORB::_duplicate(orb);
74 _initialize_root_context();
77 SALOME_NamingService_Abstract *SALOME_NamingService::clone()
79 return new SALOME_NamingService(_orb);
82 // ============================================================================
83 /*! \brief Standard destructor.
85 * The standard destructor does nothing special.
87 // ============================================================================
89 SALOME_NamingService::~SALOME_NamingService()
91 // Problem MESSAGE with singleton: late destruction,
92 // after trace system destruction ?
93 //MESSAGE("SALOME_NamingService destruction");
96 std::vector< std::string > SALOME_NamingService::repr()
98 return std::vector< std::string >();
101 // ============================================================================
102 /*! \brief initializes ORB reference and naming service root context.
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
109 // ============================================================================
111 void SALOME_NamingService::init_orb(CORBA::ORB_ptr orb)
113 Utils_Locker lock (&_myMutex);
115 _orb = CORBA::ORB::_duplicate(orb);
117 _orb = KERNEL::GetRefToORB(); // Here we make the assumption that the orb has already been initialized
119 _initialize_root_context();
122 // ============================================================================
123 /*! \brief Registers a CORBA object reference under a path.
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)
141 // ============================================================================
143 void SALOME_NamingService::Register(CORBA::Object_ptr ObjRef,
147 Utils_Locker lock (&_myMutex);
149 // --- _current_context is replaced to the _root_context
150 // if the Path begins with '/'
153 _current_context = _root_context;
156 // --- the resolution of the directory path has to be done
157 // to place the current_context to the correct node
159 CosNaming::Name context_name;
160 std::vector<std::string> splitPath;
161 int dimension_resultat = _createContextNameDir(Path,
166 CORBA::Boolean not_exist = false;
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
174 CORBA::Object_var obj = _current_context->resolve(context_name);
175 _current_context = CosNaming::NamingContext::_narrow(obj);
178 catch (CosNaming::NamingContext::NotFound &){
179 // --- failed to resolve, therefore assume cold start
183 catch (CosNaming::NamingContext::InvalidName &){
184 INFOS("Register() : CosNaming::NamingContext::InvalidName");
187 catch (CosNaming::NamingContext::CannotProceed &){
188 INFOS("Register() : CosNaming::NamingContext::CannotProceed");
191 catch (CORBA::SystemException&){
192 INFOS("Register() : CORBA::SystemException: "
193 << "unable to contact the naming service");
194 throw ServiceUnreachable();
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
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);
211 catch (CosNaming::NamingContext::NotFound &){
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;
218 catch (CosNaming::NamingContext::AlreadyBound&){
219 CORBA::Object_var obj = _current_context->resolve(context_name);
220 _current_context = CosNaming::NamingContext::_narrow(obj);
226 catch (CosNaming::NamingContext::AlreadyBound&){
227 INFOS("Register() : CosNaming::NamingContext::AlreadyBound");
230 catch (CosNaming::NamingContext::NotFound& ex){
231 CosNaming::Name n = ex.rest_of_name;
233 if (ex.why == CosNaming::NamingContext::missing_node)
234 INFOS("Register() : " << (char *) n[0].id
235 << " (" << (char *) n[0].kind << ") not found");
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");
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");
248 catch (CosNaming::NamingContext::CannotProceed&){
249 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
252 catch (CosNaming::NamingContext::InvalidName&){
253 INFOS("Register(): CosNaming::NamingContext::InvalidName");
256 catch (CORBA::SystemException&){
257 INFOS("Register():CORBA::SystemException: "
258 << "unable to contact the naming service");
259 throw ServiceUnreachable();
264 // --- The current directory is now the directory where the object should
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);
273 // --- the last element is an object and not a directory
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);
279 _current_context->bind(context_name, ObjRef);
282 catch (CosNaming::NamingContext::NotFound& ex){
283 CosNaming::Name n = ex.rest_of_name;
285 if (ex.why == CosNaming::NamingContext::missing_node)
286 INFOS("Register() : " << (char *) n[0].id
287 << " (" << (char *) n[0].kind << ") not found");
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");
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");
300 catch (CosNaming::NamingContext::CannotProceed&){
301 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
304 catch (CosNaming::NamingContext::InvalidName&){
305 INFOS("Register(): CosNaming::NamingContext::InvalidName");
308 catch (CosNaming::NamingContext::AlreadyBound&){
309 INFOS("Register(): CosNaming::NamingContext::AlreadyBound, "
310 << "object will be rebind");
311 _current_context->rebind(context_name, ObjRef);
314 catch (CORBA::SystemException&){
315 INFOS("!!!Register(): CORBA::SystemException: "
316 << "unable to contact the naming service");
317 throw ServiceUnreachable();
322 // ============================================================================
323 /*! \brief get the CORBA object reference associated to a name.
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)
337 // ============================================================================
339 CORBA::Object_ptr SALOME_NamingService::Resolve(const char* Path)
342 Utils_Locker lock (&_myMutex);
344 // --- _current_context is replaced to the _root_context
345 // if the Path begins with '/'
349 _current_context = _root_context;
352 // --- the resolution of the directory path has to be done
353 // to place the current_context to the correct node
355 CosNaming::Name context_name;
356 std::vector<std::string> splitPath;
357 _createContextNameDir(Path,
362 ASSERT(!CORBA::is_nil(_current_context));
364 CORBA::Object_var obj = CORBA::Object::_nil();
368 obj = _current_context->resolve(context_name);
371 catch (CosNaming::NamingContext::NotFound& ex)
373 CosNaming::Name n = ex.rest_of_name;
375 if (ex.why == CosNaming::NamingContext::missing_node)
376 MESSAGE("Resolve() : " << (char *) n[0].id
377 << " (" << (char *) n[0].kind << ") not found");
379 if (ex.why == CosNaming::NamingContext::not_context)
381 << (char *) n[0].id << " (" << (char *) n[0].kind
382 << ") is not a context");
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");
390 catch (CosNaming::NamingContext::CannotProceed&)
392 INFOS("Resolve(): CosNaming::NamingContext::CannotProceed");
395 catch (CosNaming::NamingContext::InvalidName&)
397 INFOS("Resolve(): CosNaming::NamingContext::InvalidName");
400 catch (CORBA::SystemException&)
402 INFOS("Resolve():CORBA::SystemException : unable to contact"
403 << "the naming service");
404 throw ServiceUnreachable();
410 // ============================================================================
411 /*! \brief get the CORBA object reference associated to an incomplete name.
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)
421 // ============================================================================
423 CORBA::Object_ptr SALOME_NamingService::ResolveFirst(const char* Path)
426 Utils_Locker lock (&_myMutex);
428 std::string thePath = Path;
429 std::string basePath = "";
430 std::string name = thePath;
432 std::string::size_type idx = thePath.rfind('/');
434 if (idx != std::string::npos) // at least one '/' found
436 basePath = thePath.substr(0, idx);
437 name = thePath.substr(idx + 1);
442 CORBA::Object_var obj = CORBA::Object::_nil();
445 if (basePath.empty())
448 isOk = Change_Directory(basePath.c_str());
452 std::vector<std::string> listElem = list_directory();
453 std::vector<std::string>::iterator its = listElem.begin();
455 while (its != listElem.end())
457 if ((*its).find(name) == 0)
459 return Resolve((*its).c_str());
469 // ============================================================================
470 /*! \brief find a component instance from hostname, containername,
471 * componentName and number of processors.
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
479 * \param componentName name of the component we are looking for an existing
481 * \param nbproc in case of multi processor machine, container name is
482 * suffixed with _nbproc.
483 * \return the object reference
485 // ============================================================================
488 SALOME_NamingService::ResolveComponent(const char* hostname,
489 const char* containerName,
490 const char* componentName,
494 Utils_Locker lock (&_myMutex);
496 std::string name = "/Containers/";
500 if ( strlen(containerName) != 0 )
506 char *newContainerName = new char[strlen(containerName) + 8];
507 sprintf(newContainerName, "%s_%d", containerName, nbproc);
508 name += newContainerName;
509 delete [] newContainerName;
513 name += containerName;
517 name += componentName;
519 return ResolveFirst(name.c_str());
525 std::string basename = name;
526 if (Change_Directory(basename.c_str()))
528 std::vector<std::string> contList = list_subdirs();
530 for (unsigned int ind = 0; ind < contList.size(); ind++)
532 name = contList[ind].c_str();
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;
544 name += componentName;
546 CORBA::Object_ptr obj = ResolveFirst(name.c_str());
548 if ( !CORBA::is_nil(obj) )
551 Change_Directory(basename.c_str());
555 return CORBA::Object::_nil();
559 // ============================================================================
560 /*! \brief search a name in current directory.
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
567 * \param name the name to search.
568 * \return number of occurrences found.
569 * \sa Change_Directory(const char* Path)
571 // ============================================================================
573 int SALOME_NamingService::Find(const char* name)
576 Utils_Locker lock (&_myMutex);
578 CORBA::Long occurence_number = 0 ;
582 _Find(name, occurence_number);
585 catch (CORBA::SystemException&)
587 INFOS("!!!Find() : CORBA::SystemException : unable to contact"
588 << " the naming service");
589 throw ServiceUnreachable();
592 return occurence_number;
595 // ============================================================================
596 /*! \brief Creates a directory (context_name)
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)
614 // ============================================================================
616 bool SALOME_NamingService::Create_Directory(const char* Path)
618 Utils_Locker lock (&_myMutex);
620 std::string path(Path);
622 // --- if path empty, nothing to create, no context change
627 // --- if path ='/', nothing to create, only change to root_context
631 _current_context = _root_context;
635 // --- path must end with '/'
637 if (path[path.length()-1] != '/') path += '/';
639 Register(CORBA::Object::_nil(), path.c_str());
643 // ============================================================================
644 /*! \brief change current directory to the given path
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
655 // ============================================================================
657 bool SALOME_NamingService::Change_Directory(const char* Path)
659 Utils_Locker lock (&_myMutex);
661 std::string path(Path);
663 // --- if path empty, nothing to do
668 // --- if path ='/', nothing to resolve, only change to root_context
672 _current_context = _root_context;
676 CosNaming::NamingContext_var current_context = _current_context;
677 bool changeOK = false;
679 // --- replace _current_context with _root_context if Path begins with '/'
682 current_context = _root_context;
684 // --- need to resolve directory path
686 ASSERT(!CORBA::is_nil(current_context));
688 if (path[path.length()-1] != '/') path += '/';
690 CosNaming::Name context_name;
691 std::vector<std::string> splitPath;
692 _createContextNameDir(path.c_str(),
697 // --- Context creation
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;
708 catch (CosNaming::NamingContext::NotFound& ex)
710 CosNaming::Name n = ex.rest_of_name;
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" );
725 catch (CosNaming::NamingContext::CannotProceed&)
727 INFOS("Change_Directory(): CosNaming::NamingContext::CannotProceed");
730 catch (CosNaming::NamingContext::InvalidName&)
732 INFOS("Change_Directory(): CosNaming::NamingContext::InvalidName");
735 catch (CORBA::SystemException&)
737 INFOS("Change_Directory():CORBA::SystemException : unable to contact"
738 << "the naming service");
739 throw ServiceUnreachable();
745 // ============================================================================
746 /*! \brief get the current directory path
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
753 // ============================================================================
755 char *SALOME_NamingService::Current_Directory()
757 Utils_Locker lock (&_myMutex);
759 CosNaming::NamingContext_var ref_context = _current_context;
761 std::vector<std::string> splitPath;
764 bool notFound = true ;
766 // --- start search from root context
768 _current_context = _root_context ;
772 _current_directory(splitPath, lengthPath, ref_context, notFound );
775 catch (CORBA::SystemException&)
777 INFOS("Current_Directory(): CORBA::SystemException: unable to contact"
778 << " the naming service" )
779 throw ServiceUnreachable();
783 lengthPath = (int)splitPath.size(); //!< TODO: conversion from size_t to int
784 for (int k = 0 ; k < lengthPath ;k++)
787 path += splitPath[k];
791 _current_context = ref_context ;
793 return strdup(path.c_str());
796 // ============================================================================
797 /*! \brief list recursively all objects in the current context
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
803 // ============================================================================
805 void SALOME_NamingService::list()
807 Utils_Locker lock (&_myMutex)
810 CosNaming::BindingList_var binding_list;
811 CosNaming::BindingIterator_var binding_iterator;
812 CosNaming::Binding_var binding ;
814 unsigned long nb = 0 ; // --- only for the BindingIterator use,
815 // to access the bindings
817 CosNaming::NamingContext_var ref_context = _current_context;
819 _current_context->list(nb, binding_list, binding_iterator) ;
821 if (! CORBA::is_nil(binding_iterator))
823 while (binding_iterator->next_one(binding))
825 CosNaming::Name bindingName = binding->binding_name;
827 if (binding->binding_type == CosNaming::ncontext)
831 Change_Directory(bindingName[0].id);
834 catch (ServiceUnreachable&)
836 INFOS( "list(): ServiceUnreachable" )
837 throw ServiceUnreachable();
841 _current_context = ref_context ;
844 else if (binding->binding_type == CosNaming::nobject)
846 MESSAGE( "list(): no Object : " << bindingName[0].id );
850 binding_iterator->destroy();
854 // ============================================================================
855 /*! \brief list all the objects in the current directory.
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()
863 // ============================================================================
865 std::vector<std::string> SALOME_NamingService::list_directory()
867 Utils_Locker lock (&_myMutex);
868 std::vector<std::string> dirList ;
871 CosNaming::BindingList_var binding_list;
872 CosNaming::BindingIterator_var binding_iterator;
873 CosNaming::Binding_var binding ;
875 unsigned long nb = 0 ; // --- only for the BindingIterator use,
876 // to access the bindings
878 CosNaming::NamingContext_var ref_context = _current_context;
880 _current_context->list(nb, binding_list, binding_iterator);
882 if (binding_iterator->_is_nil())
885 while (binding_iterator->next_one(binding))
887 CosNaming::Name bindingName = binding->binding_name;
889 if (binding->binding_type == CosNaming::nobject)
891 // remove memory leak
892 // dirList.push_back(CORBA::string_dup(bindingName[0].id));
893 dirList.push_back(std::string(bindingName[0].id));
897 // for (unsigned int ind = 0; ind < dirList.size(); ind++)
898 // MESSAGE("list_directory : Object : " << dirList[ind]);
900 binding_iterator->destroy();
906 // ============================================================================
907 /*! \brief list all the subdirectories in the current directory.
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()
916 // ============================================================================
918 std::vector<std::string> SALOME_NamingService::list_subdirs()
920 Utils_Locker lock (&_myMutex);
921 std::vector<std::string> dirList ;
924 CosNaming::BindingList_var binding_list;
925 CosNaming::BindingIterator_var binding_iterator;
926 CosNaming::Binding_var binding ;
928 unsigned long nb = 0 ; // --- only for the BindingIterator use,
929 // to access the bindings
931 CosNaming::NamingContext_var ref_context = _current_context;
933 _current_context->list(nb, binding_list, binding_iterator) ;
935 if (binding_iterator->_is_nil())
938 while (binding_iterator->next_one(binding))
940 CosNaming::Name bindingName = binding->binding_name;
942 if (binding->binding_type == CosNaming::ncontext)
944 dirList.push_back(bindingName[0].id.in());
948 // for (unsigned int ind = 0; ind < dirList.size(); ind++)
949 // MESSAGE("list_directory : Object : " << dirList[ind]);
951 binding_iterator->destroy();
956 // ============================================================================
957 /*! \brief list all the objects in the current directory and subdirectories.
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()
965 // ============================================================================
967 std::vector<std::string> SALOME_NamingService::list_directory_recurs()
970 Utils_Locker lock (&_myMutex);
972 std::vector<std::string> dirList ;
974 char* currentDir = Current_Directory();
976 _list_directory_recurs(dirList, "", currentDir);
983 // ============================================================================
984 /*! \brief destroy an entry in naming service.
986 * Destroy an association Path - Object Reference.
987 * If the NamingService is out, the exception ServiceUnreachable is thrown
988 * \param Path object path
990 // ============================================================================
992 void SALOME_NamingService::Destroy_Name(const char* Path)
995 Utils_Locker lock (&_myMutex);
997 std::string path(Path);
999 // --- if path empty, nothing to do
1004 // --- if path = '/' not applicable, nothing to do
1009 // --- if path begins with '/', set current directory to root context
1012 _current_context = _root_context;
1014 // --- context of the directory containing the object
1016 CosNaming::Name context_name;
1017 std::vector<std::string> splitPath;
1018 int dimension_resultat = _createContextNameDir(path.c_str(),
1025 if (dimension_resultat > 0)
1027 // --- path contains a directory, not only an object name
1028 // switch to the new directory (or return if directory not found)
1032 CORBA::Object_var obj = _current_context->resolve(context_name);
1033 _current_context = CosNaming::NamingContext::_narrow(obj);
1037 catch (CosNaming::NamingContext::NotFound &ex)
1039 // --- failed to resolve
1042 CosNaming::Name n = ex.rest_of_name;
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" );
1057 catch (CosNaming::NamingContext::InvalidName &)
1059 INFOS("Destroy_Name: CosNaming::NamingContext::InvalidName");
1062 catch (CosNaming::NamingContext::CannotProceed &)
1064 INFOS("Destroy_Name: CosNaming::NamingContext::CannotProceed");
1067 catch (CORBA::SystemException&)
1069 INFOS("Destroy_Name : CORBA::SystemException: "
1070 << "unable to contact the naming service");
1071 throw ServiceUnreachable();
1074 if (! exist) return;
1077 ASSERT(!CORBA::is_nil(_current_context));
1079 // --- The current directory is now the directory where the object should
1082 size_t sizePath = splitPath.size();
1083 if (sizePath > (size_t)dimension_resultat)
1085 ASSERT(sizePath == (size_t)dimension_resultat+1);
1086 context_name.length(1);
1090 // --- the last element is an object and not a directory
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);
1097 _current_context->unbind(context_name);
1098 //MESSAGE("The object " << context_name[0].id << " has been deleted");
1101 catch (CosNaming::NamingContext::NotFound& ex)
1103 CosNaming::Name n = ex.rest_of_name;
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" );
1118 catch (CosNaming::NamingContext::CannotProceed&)
1120 INFOS( "Destroy_Name(): CosNaming::NamingContext::CannotProceed");
1123 catch (CosNaming::NamingContext::InvalidName&)
1125 INFOS( "Destroy_Name(): CosNaming::NamingContext::InvalidName");
1128 catch (CORBA::SystemException&)
1130 INFOS( "Destroy_Name(): CORBA::SystemException: unable to contact"
1131 << " the naming service");
1132 throw ServiceUnreachable();
1137 // ============================================================================
1138 /*! \brief Destroy an empty directory
1140 * Destroy an empty directory in Naming Service.
1141 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1142 * \param Path directory path
1144 // ============================================================================
1146 void SALOME_NamingService::Destroy_Directory(const char* Path)
1148 Utils_Locker lock (&_myMutex);
1150 std::string path(Path);
1152 // --- if path empty, nothing to do
1157 // --- if path begins with '/', set current directory to root context
1160 _current_context = _root_context;
1162 CosNaming::NamingContext_var ref_context = _current_context;
1164 // --- path must ends with '/' for a directory
1166 if (path[path.size() -1] != '/')
1169 // --- context of the directory
1171 CosNaming::Name context_name;
1172 std::vector<std::string> splitPath;
1173 int dimension_resultat = _createContextNameDir(path.c_str(),
1179 if (dimension_resultat > 0)
1181 // --- path contains a directory, not only an object name
1182 // switch to the new directory (or return if directory not found)
1186 CORBA::Object_var obj = _current_context->resolve(context_name);
1187 _current_context = CosNaming::NamingContext::_narrow(obj);
1191 catch (CosNaming::NamingContext::NotFound &ex)
1193 // --- failed to resolve
1196 CosNaming::Name n = ex.rest_of_name;
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" );
1211 catch (CosNaming::NamingContext::InvalidName &)
1213 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1216 catch (CosNaming::NamingContext::CannotProceed &)
1218 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1221 catch (CORBA::SystemException&)
1223 INFOS("Destroy_Directory : CORBA::SystemException: "
1224 << "unable to contact the naming service");
1225 throw ServiceUnreachable();
1228 if (! exist) return;
1231 ASSERT(!CORBA::is_nil(_current_context));
1233 // --- Context Destruction
1235 bool isContextDestroyed = false;
1238 _current_context->destroy();
1239 isContextDestroyed = true;
1242 catch (CosNaming::NamingContext::NotEmpty&)
1244 INFOS( "Destroy_Directory(): CosNaming::NamingContext::NoEmpty "
1245 << path << " is not empty" );
1248 catch (CORBA::SystemException&)
1250 INFOS( "Destroy_Directory():CORBA::SystemException : "
1251 << "unable to contact the naming service");
1252 throw ServiceUnreachable();
1255 // --- go to the reference directory
1257 _current_context = ref_context ;
1259 ASSERT(!CORBA::is_nil(_current_context));
1261 if (isContextDestroyed)
1265 _current_context->unbind(context_name);
1268 catch (CosNaming::NamingContext::NotFound& ex)
1270 CosNaming::Name n = ex.rest_of_name;
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" );
1285 catch (CosNaming::NamingContext::CannotProceed&)
1287 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1290 catch (CosNaming::NamingContext::InvalidName&)
1292 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1295 catch (CORBA::SystemException&)
1297 INFOS("Destroy_Directory:CORBA::SystemException : unable to contact"
1298 << " the naming service");
1299 throw ServiceUnreachable();
1304 // ============================================================================
1305 /*! \brief Destroy a directory with its contents.
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.
1312 // ============================================================================
1314 void SALOME_NamingService::Destroy_FullDirectory(const char* Path)
1316 //no need to lock here because method calls are threadsafe.
1317 if( Change_Directory(Path) )
1319 std::vector<std::string> contList = list_directory();
1321 for (unsigned int ind = 0; ind < contList.size(); ind++)
1322 Destroy_Name(contList[ind].c_str());
1324 Destroy_Directory(Path);
1328 // ============================================================================
1329 /*! \brief initialize root context (root directory)
1331 * the root context initialisation must be done when the SALOME_NamingService
1332 * instance is created and before any other call. See constructors.
1334 // ============================================================================
1336 void SALOME_NamingService::_initialize_root_context()
1338 //no lock here because initialization is expected to be done once.
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));
1347 catch (CORBA::SystemException&)
1349 INFOS("CORBA::SystemException: unable to contact the naming service");
1350 throw ServiceUnreachable();
1355 INFOS("Unknown Exception: unable to contact the naming service");
1356 throw ServiceUnreachable();
1360 // ============================================================================
1361 /*! \brief transform a string path in CosNaming structure.
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
1370 * \param onlyDir if true, final object (if any) is omitted
1372 * if false, final object (if any) is included in
1374 * \return dimension of context_name
1376 // ============================================================================
1379 SALOME_NamingService::_createContextNameDir(std::string path,
1380 CosNaming::Name& context_name,
1381 std::vector<std::string>& splitPath,
1387 std::string::size_type begIdx, endIdx;
1388 const std::string delims("/");
1389 splitPath.resize(0);
1390 bool endWithDelim = false;
1392 begIdx = path.find_first_not_of(delims);
1393 while (begIdx != std::string::npos)
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;
1402 splitPath.push_back(path.substr(begIdx, lsub));
1403 begIdx = path.find_first_not_of(delims, endIdx);
1407 if (onlyDir) // only directory part
1409 dim = (int)splitPath.size()-1; // omit final object
1410 if (endWithDelim) // unless the path ends with a delimiter
1412 endWithDelim = true;
1415 dim = (int)splitPath.size(); // directories and final object
1417 context_name.length((CORBA::ULong)dim);
1418 for (int i=0; i<dim; i++)
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
1424 context_name[i].kind = CORBA::string_dup("object");
1425 // MESSAGE("--- " <<splitPath[i] <<".object");
1429 context_name[i].kind = CORBA::string_dup("dir");
1430 // MESSAGE("--- " <<splitPath[i] <<".dir");
1433 return dim; //TODO: return <int> or <size_t>?
1436 // ============================================================================
1437 /*! \brief search a name in current directory.
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.
1444 * \param name the name to search.
1445 * \param occurence_number number of occurrence already found (incremented)
1447 // ============================================================================
1449 void SALOME_NamingService::_Find(const char* name,
1450 CORBA::Long& occurence_number)
1452 CosNaming::BindingList_var binding_list;
1453 CosNaming::BindingIterator_var binding_iterator;
1454 CosNaming::Binding_var binding;
1456 unsigned long nb = 0 ; // --- only for the use of the BindingIterator,
1457 // to access the bindings
1459 CosNaming::NamingContext_var ref_context = _current_context;
1460 CosNaming::NamingContext_var found_context = _current_context;
1462 _current_context->list(nb, binding_list, binding_iterator) ;
1464 if (! CORBA::is_nil(binding_iterator))
1466 while (binding_iterator->next_one(binding))
1468 CosNaming::Name bindingName = binding->binding_name;
1470 if (binding->binding_type == CosNaming::ncontext)
1472 // --- We work on a directory,
1473 // the search should be done in this directory
1475 Change_Directory(bindingName[0].id);
1476 _Find(name, occurence_number);
1478 // --- We'll go back to the initial context
1480 _current_context = ref_context ;
1483 else if (binding->binding_type == CosNaming::nobject)
1485 // --- We work on an object...
1487 if (!strcmp( bindingName[0].id, name))
1489 //MESSAGE("One occurrence was found");
1492 // --- We keep in memory the directory where
1493 // one occurrence was found
1495 found_context = _current_context ;
1500 binding_iterator->destroy();
1502 // --- We go to the last directory where an occurrence was found
1504 _current_context = found_context;
1506 SCRUTE(occurence_number);
1509 // ============================================================================
1510 /*! \brief find the current directory path.
1512 * Parse the naming service tree to find the current context and give the
1513 * associated directory path (relative to root context).
1515 * \param lengthResult
1516 * \param contextToFind
1519 // ============================================================================
1522 SALOME_NamingService::
1523 _current_directory(std::vector<std::string>& splitPath,
1525 CosNaming::NamingContext_var contextToFind,
1528 CosNaming::BindingList_var binding_list;
1529 CosNaming::BindingIterator_var binding_iterator;
1530 CosNaming::Binding_var binding;
1532 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1533 // to access the bindings
1535 CosNaming::NamingContext_var ref_context = _current_context;
1536 CosNaming::NamingContext_var temp_context = _current_context;
1538 _current_context->list(nb, binding_list, binding_iterator);
1540 if ( !binding_iterator->_is_nil() )
1542 while ((binding_iterator->next_one(binding)) && notFound)
1544 CosNaming::Name bindingName = binding->binding_name;
1546 if (binding->binding_type == CosNaming::ncontext)
1548 // --- directory, search in it
1550 const char* bindingNameid=bindingName[0].id;
1551 splitPath.push_back(bindingNameid);
1554 CORBA::Object_var obj = _current_context->resolve(bindingName);
1555 temp_context = CosNaming::NamingContext::_narrow(obj);
1557 if (temp_context->_is_equivalent(contextToFind))
1559 //MESSAGE("The context is found, we stop the search");
1566 //SCRUTE(bindingName[0].id);
1567 Change_Directory(bindingName[0].id);
1568 _current_directory(splitPath,
1575 // --- go back to the initial context
1577 _current_context = ref_context;
1579 // MESSAGE("Just before the delete of "
1580 // << splitPath[lengthResult-1]);
1581 splitPath.pop_back();
1588 binding_iterator->destroy();
1591 // --- return to the last directory where an occurrence was found
1593 _current_context = ref_context ;
1597 // ============================================================================
1598 /*! \brief list recursively all objects in the given directory and subdirs.
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.
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
1610 // ============================================================================
1612 void SALOME_NamingService::_list_directory_recurs(std::vector<std::string>& myList,
1613 std::string relativeSubDir,
1614 std::string absCurDirectory)
1616 CosNaming::BindingList_var binding_list;
1617 CosNaming::BindingIterator_var binding_iterator;
1618 CosNaming::Binding_var binding ;
1620 unsigned long nb = 0 ; // --- only for thethe use of BindingIterator
1621 // to access the bindings
1625 CosNaming::NamingContext_var ref_context = _current_context;
1627 if (! relativeSubDir.empty())
1629 Change_Directory(relativeSubDir.c_str());
1630 absDir = absCurDirectory + "/" + relativeSubDir;
1634 absDir = absCurDirectory;
1637 _current_context->list(nb, binding_list, binding_iterator) ;
1639 if (! CORBA::is_nil(binding_iterator))
1641 while (binding_iterator->next_one(binding))
1643 CosNaming::Name bindingName = binding->binding_name;
1645 if (binding->binding_type == CosNaming::ncontext)
1647 std::string relativeSdir(bindingName[0].id);
1648 _list_directory_recurs(myList, relativeSdir, absDir);
1651 else if (binding->binding_type == CosNaming::nobject)
1653 std::string objName(bindingName[0].id);
1654 std::string elt = absDir + "/" + objName;
1656 myList.push_back(elt);
1660 binding_iterator->destroy();
1662 if (! relativeSubDir.empty())
1664 _current_context = ref_context;
1668 // ============================================================================
1669 /*! \brief return a stringified reference of root context
1671 * \return a stringified reference of root context
1673 // ============================================================================
1675 char * SALOME_NamingService::getIORaddr()
1677 return _orb->object_to_string(_root_context);
1680 /*! \brief get the orb used by the naming service
1684 CORBA::ORB_ptr SALOME_NamingService::orb()