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 SALOME_NamingService *SALOME_NamingService::GetTraditionalNS(SALOME_NamingService_Abstract *ns)
97 SALOME_NamingService *nsc(dynamic_cast<SALOME_NamingService *>(ns));
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);
119 _orb = CORBA::ORB_init(argc, 0); // Here we make the assumption that the orb has already been initialized
122 _initialize_root_context();
125 // ============================================================================
126 /*! \brief Registers a CORBA object reference under a path.
128 * Registers a CORBA object reference under a path. If the path ends with '/',
129 * only a directory is created.
130 * If the NamingService is out, the exception ServiceUnreachable is thrown.
131 * \param ObjRef CORBA object reference to associate to the path. To create
132 * only a directory, give nil pointer.
133 * \param Path A relative or absolute pathname to store the object reference.
134 * If the pathname begins with a '/', pathname is taken
135 * as an absolute pathname. Else, pathname is taken as a relative
136 * path, to current context. Prefer absolute pathname, relative
137 * pathname are not safe, when SALOME_NamingService object is
138 * shared or use in multithreaded context.
139 * If the path ends with '/', only a directory is created.
140 * \sa Change_Directory(const char* Path),
141 * Create_Directory(const char* Path)
142 * CORBA::Object_ptr Resolve(const char* Path)
144 // ============================================================================
146 void SALOME_NamingService::Register(CORBA::Object_ptr ObjRef,
150 Utils_Locker lock (&_myMutex);
152 // --- _current_context is replaced to the _root_context
153 // if the Path begins with '/'
156 _current_context = _root_context;
159 // --- the resolution of the directory path has to be done
160 // to place the current_context to the correct node
162 CosNaming::Name context_name;
163 std::vector<std::string> splitPath;
164 int dimension_resultat = _createContextNameDir(Path,
169 CORBA::Boolean not_exist = false;
171 if (dimension_resultat > 0){
172 // A directory is treated (not only an object name)
173 // test if the directory where ObjRef should be recorded already exists
174 // If not, create the new context
177 CORBA::Object_var obj = _current_context->resolve(context_name);
178 _current_context = CosNaming::NamingContext::_narrow(obj);
181 catch (CosNaming::NamingContext::NotFound &){
182 // --- failed to resolve, therefore assume cold start
186 catch (CosNaming::NamingContext::InvalidName &){
187 INFOS("Register() : CosNaming::NamingContext::InvalidName");
190 catch (CosNaming::NamingContext::CannotProceed &){
191 INFOS("Register() : CosNaming::NamingContext::CannotProceed");
194 catch (CORBA::SystemException&){
195 INFOS("Register() : CORBA::SystemException: "
196 << "unable to contact the naming service");
197 throw ServiceUnreachable();
202 context_name.length(1);
203 for (int i = 0 ; i < dimension_resultat ;i++){
204 context_name[0].id = CORBA::string_dup(splitPath[i].c_str());
205 context_name[0].kind = CORBA::string_dup("dir");
206 // SCRUTE(_context_name[0].id);
207 // --- check if the path is created
209 // --- if the context is already created, nothing to do
210 CORBA::Object_var obj = _current_context->resolve(context_name);
211 _current_context = CosNaming::NamingContext::_narrow(obj);
214 catch (CosNaming::NamingContext::NotFound &){
216 // --- the context must be created
217 CosNaming::NamingContext_var temp_context =
218 _current_context->bind_new_context(context_name);
219 _current_context = temp_context;
221 catch (CosNaming::NamingContext::AlreadyBound&){
222 CORBA::Object_var obj = _current_context->resolve(context_name);
223 _current_context = CosNaming::NamingContext::_narrow(obj);
229 catch (CosNaming::NamingContext::AlreadyBound&){
230 INFOS("Register() : CosNaming::NamingContext::AlreadyBound");
233 catch (CosNaming::NamingContext::NotFound& ex){
234 CosNaming::Name n = ex.rest_of_name;
236 if (ex.why == CosNaming::NamingContext::missing_node)
237 INFOS("Register() : " << (char *) n[0].id
238 << " (" << (char *) n[0].kind << ") not found");
240 if (ex.why == CosNaming::NamingContext::not_context)
241 INFOS("Register() : " << (char *) n[0].id
242 << " (" << (char *) n[0].kind
243 << ") is not a context");
245 if (ex.why == CosNaming::NamingContext::not_object)
246 INFOS("Register() : " << (char *) n[0].id
247 << " (" << (char *) n[0].kind
248 << ") is not an object");
251 catch (CosNaming::NamingContext::CannotProceed&){
252 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
255 catch (CosNaming::NamingContext::InvalidName&){
256 INFOS("Register(): CosNaming::NamingContext::InvalidName");
259 catch (CORBA::SystemException&){
260 INFOS("Register():CORBA::SystemException: "
261 << "unable to contact the naming service");
262 throw ServiceUnreachable();
267 // --- The current directory is now the directory where the object should
270 size_t sizePath = splitPath.size();
271 if (sizePath > (size_t)dimension_resultat){
272 ASSERT(sizePath == (size_t)dimension_resultat+1);
273 context_name.length(1);
276 // --- the last element is an object and not a directory
278 context_name[0].id = CORBA::string_dup(splitPath[dimension_resultat].c_str());
279 context_name[0].kind = CORBA::string_dup("object");
280 //SCRUTE(context_name[0].id);
282 _current_context->bind(context_name, ObjRef);
285 catch (CosNaming::NamingContext::NotFound& ex){
286 CosNaming::Name n = ex.rest_of_name;
288 if (ex.why == CosNaming::NamingContext::missing_node)
289 INFOS("Register() : " << (char *) n[0].id
290 << " (" << (char *) n[0].kind << ") not found");
292 if (ex.why == CosNaming::NamingContext::not_context)
293 INFOS("Register() : " << (char *) n[0].id
294 << " (" << (char *) n[0].kind
295 << ") is not a context");
297 if (ex.why == CosNaming::NamingContext::not_object)
298 INFOS("Register() : " << (char *) n[0].id
299 << " (" << (char *) n[0].kind
300 << ") is not an object");
303 catch (CosNaming::NamingContext::CannotProceed&){
304 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
307 catch (CosNaming::NamingContext::InvalidName&){
308 INFOS("Register(): CosNaming::NamingContext::InvalidName");
311 catch (CosNaming::NamingContext::AlreadyBound&){
312 INFOS("Register(): CosNaming::NamingContext::AlreadyBound, "
313 << "object will be rebind");
314 _current_context->rebind(context_name, ObjRef);
317 catch (CORBA::SystemException&){
318 INFOS("!!!Register(): CORBA::SystemException: "
319 << "unable to contact the naming service");
320 throw ServiceUnreachable();
325 // ============================================================================
326 /*! \brief get the CORBA object reference associated to a name.
328 * get the CORBA object reference associated to a complete name with a path.
329 * If the NamingService is out, the exception ServiceUnreachable is thrown
330 * \param Path pathname. If the pathname begins with a '/', pathname is taken
331 * as an absolute pathname. Else, pathname is taken as a relative
332 * path, to current context. Prefer absolute pathname, relative
333 * pathname are not safe, when SALOME_NamingService object is
334 * shared or use in multithreaded context.
335 * \return the object reference if it exists under the pathname,
336 * or nil reference in other cases.
337 * \sa Register(CORBA::Object_ptr ObjRef, const char* Path),
338 * Change_Directory(const char* Path)
340 // ============================================================================
342 CORBA::Object_ptr SALOME_NamingService::Resolve(const char* Path)
345 Utils_Locker lock (&_myMutex);
347 // --- _current_context is replaced to the _root_context
348 // if the Path begins with '/'
352 _current_context = _root_context;
355 // --- the resolution of the directory path has to be done
356 // to place the current_context to the correct node
358 CosNaming::Name context_name;
359 std::vector<std::string> splitPath;
360 _createContextNameDir(Path,
365 ASSERT(!CORBA::is_nil(_current_context));
367 CORBA::Object_var obj = CORBA::Object::_nil();
371 obj = _current_context->resolve(context_name);
374 catch (CosNaming::NamingContext::NotFound& ex)
376 CosNaming::Name n = ex.rest_of_name;
378 if (ex.why == CosNaming::NamingContext::missing_node)
379 MESSAGE("Resolve() : " << (char *) n[0].id
380 << " (" << (char *) n[0].kind << ") not found");
382 if (ex.why == CosNaming::NamingContext::not_context)
384 << (char *) n[0].id << " (" << (char *) n[0].kind
385 << ") is not a context");
387 if (ex.why == CosNaming::NamingContext::not_object)
388 INFOS("Resolve() : " << (char *) n[0].id
389 << " (" << (char *) n[0].kind
390 << ") is not an object");
393 catch (CosNaming::NamingContext::CannotProceed&)
395 INFOS("Resolve(): CosNaming::NamingContext::CannotProceed");
398 catch (CosNaming::NamingContext::InvalidName&)
400 INFOS("Resolve(): CosNaming::NamingContext::InvalidName");
403 catch (CORBA::SystemException&)
405 INFOS("Resolve():CORBA::SystemException : unable to contact"
406 << "the naming service");
407 throw ServiceUnreachable();
413 // ============================================================================
414 /*! \brief get the CORBA object reference associated to an incomplete name.
416 * get the CORBA object reference associated to an incomplete name with a
417 * path. Look for the first occurrence of name*.
418 * If the NamingService is out, the exception ServiceUnreachable is thrown
419 * \param Path pathname under the form "/path/name" (Absolute reference !)
420 * search the fist reference like "/path(.dir)/name*(.kind)"
421 * \return the object reference if found, or nil reference.
422 * \sa Resolve(const char* Path)
424 // ============================================================================
426 CORBA::Object_ptr SALOME_NamingService::ResolveFirst(const char* Path)
429 Utils_Locker lock (&_myMutex);
431 std::string thePath = Path;
432 std::string basePath = "";
433 std::string name = thePath;
435 std::string::size_type idx = thePath.rfind('/');
437 if (idx != std::string::npos) // at least one '/' found
439 basePath = thePath.substr(0, idx);
440 name = thePath.substr(idx + 1);
445 CORBA::Object_var obj = CORBA::Object::_nil();
448 if (basePath.empty())
451 isOk = Change_Directory(basePath.c_str());
455 std::vector<std::string> listElem = list_directory();
456 std::vector<std::string>::iterator its = listElem.begin();
458 while (its != listElem.end())
460 if ((*its).find(name) == 0)
462 return Resolve((*its).c_str());
472 // ============================================================================
473 /*! \brief find a component instance from hostname, containername,
474 * componentName and number of processors.
476 * find a component instance from hostname, containername, componentName and
477 * number of processors.
478 * If the NamingService is out, the exception ServiceUnreachable is thrown.
479 * \param hostname name of the machine on which the component is searched.
480 * \param containerName name of the container in which the component is
482 * \param componentName name of the component we are looking for an existing
484 * \param nbproc in case of multi processor machine, container name is
485 * suffixed with _nbproc.
486 * \return the object reference
488 // ============================================================================
491 SALOME_NamingService::ResolveComponent(const char* hostname,
492 const char* containerName,
493 const char* componentName,
497 Utils_Locker lock (&_myMutex);
499 std::string name = "/Containers/";
503 if ( strlen(containerName) != 0 )
509 char *newContainerName = new char[strlen(containerName) + 8];
510 sprintf(newContainerName, "%s_%d", containerName, nbproc);
511 name += newContainerName;
512 delete [] newContainerName;
516 name += containerName;
520 name += componentName;
522 return ResolveFirst(name.c_str());
528 std::string basename = name;
529 if (Change_Directory(basename.c_str()))
531 std::vector<std::string> contList = list_subdirs();
533 for (unsigned int ind = 0; ind < contList.size(); ind++)
535 name = contList[ind].c_str();
539 char *str_nbproc = new char[16];
540 sprintf(str_nbproc, "_%d", nbproc);
541 if( strstr(name.c_str(),str_nbproc) == NULL)
542 continue; // check only containers with _%d in name
543 delete [] str_nbproc;
547 name += componentName;
549 CORBA::Object_ptr obj = ResolveFirst(name.c_str());
551 if ( !CORBA::is_nil(obj) )
554 Change_Directory(basename.c_str());
558 return CORBA::Object::_nil();
562 // ============================================================================
563 /*! \brief build a container name, given a ContainerParameters struct.
565 * Build a container name with a ContainerParameters struct. In case of multi
566 * processor machine, container name is suffixed with number of processors.
567 * \param params struct from which we get container name (may be empty) and
568 * number of processors.
569 * \return a container name without the path.
570 * \sa BuildContainerNameForNS(const Engines::ContainerParameters& params,
571 * const char *hostname)
573 // ============================================================================
575 std::string SALOME_NamingService::ContainerName(const Engines::ContainerParameters& params)
581 else if ( params.nb_proc <= 0 )
584 nbproc = params.nb_proc;
586 std::string ret(SALOME_NamingService_Abstract::ContainerName(params.container_name));
590 std::ostringstream suffix;
591 suffix << "_" << nbproc;
598 // ============================================================================
599 /*! \brief build a string representing a container in Naming Service.
601 * Build a string representing the absolute pathname of a container in
602 * SALOME_NamingService.
603 * \param params used as it is, or replaced by FactoryServer if empty.
604 * \param hostname name of the host of the container, without domain names.
605 * \return the path under the form /Containers/hostname/containerName
606 * \sa ContainerName(const char *containerName)
608 // ============================================================================
610 std::string SALOME_NamingService::BuildContainerNameForNS(const Engines::ContainerParameters& params, const char *hostname)
612 std::string ret("/Containers/");
615 ret += ContainerName(params);
620 // ============================================================================
621 /*! \brief search a name in current directory.
623 * Search a name in the current directory. after call, the current directory
624 * is changed to the directory containing the last occurrence of name found.
625 * If no occurrence found (see return value), current directory remains
628 * \param name the name to search.
629 * \return number of occurrences found.
630 * \sa Change_Directory(const char* Path)
632 // ============================================================================
634 int SALOME_NamingService::Find(const char* name)
637 Utils_Locker lock (&_myMutex);
639 CORBA::Long occurence_number = 0 ;
643 _Find(name, occurence_number);
646 catch (CORBA::SystemException&)
648 INFOS("!!!Find() : CORBA::SystemException : unable to contact"
649 << " the naming service");
650 throw ServiceUnreachable();
653 return occurence_number;
656 // ============================================================================
657 /*! \brief Creates a directory (context_name)
659 * Creates a directory (context_name) relative to the current directory
660 * (current context) or relative to the root directory (root context), if
661 * the path given begins with a '/'.
662 * If the NamingService is out, the exception ServiceUnreachable is thrown.
663 * \param Path A relative or absolute pathname to store the object reference.
664 * If the pathname begins with a '/', pathname is taken
665 * as an absolute pathname. Else, pathname is taken as a relative
666 * path, to current context. Prefer absolute pathname, relative
667 * pathname are not safe, when SALOME_NamingService object is
668 * shared or use in multithreaded context.
669 * \return true if successful
670 * (creation not strictly guaranteed if true, because Register may
671 * catch some specific unlikely exception without throw anything
672 * --- to be corrected ---)
673 * \sa RegisterCORBA::Object_ptr ObjRef, const char* Path)
675 // ============================================================================
677 bool SALOME_NamingService::Create_Directory(const char* Path)
679 Utils_Locker lock (&_myMutex);
681 std::string path(Path);
683 // --- if path empty, nothing to create, no context change
688 // --- if path ='/', nothing to create, only change to root_context
692 _current_context = _root_context;
696 // --- path must end with '/'
698 if (path[path.length()-1] != '/') path += '/';
700 Register(CORBA::Object::_nil(), path.c_str());
704 // ============================================================================
705 /*! \brief change current directory to the given path
707 * change the current directory to the given path in parameter.
708 * Warning: avoid use when the SALOME_NamingService instance is shared by
709 * several threads (current context may be modified by another thread).
710 * If the path is empty, nothing done return OK.
711 * If Path ="/", the current directory changes to the root directory.
712 * If the NamingService is out, the exception ServiceUnreachable is thrown.
713 * \param Path the new current directory
714 * \return true if the change succeeded
716 // ============================================================================
718 bool SALOME_NamingService::Change_Directory(const char* Path)
720 Utils_Locker lock (&_myMutex);
722 std::string path(Path);
724 // --- if path empty, nothing to do
729 // --- if path ='/', nothing to resolve, only change to root_context
733 _current_context = _root_context;
737 CosNaming::NamingContext_var current_context = _current_context;
738 bool changeOK = false;
740 // --- replace _current_context with _root_context if Path begins with '/'
743 current_context = _root_context;
745 // --- need to resolve directory path
747 ASSERT(!CORBA::is_nil(current_context));
749 if (path[path.length()-1] != '/') path += '/';
751 CosNaming::Name context_name;
752 std::vector<std::string> splitPath;
753 _createContextNameDir(path.c_str(),
758 // --- Context creation
762 CORBA::Object_var obj = current_context->resolve(context_name);
763 current_context = CosNaming::NamingContext::_narrow(obj);
764 ASSERT(!CORBA::is_nil(current_context));
765 _current_context = current_context;
769 catch (CosNaming::NamingContext::NotFound& ex)
771 CosNaming::Name n = ex.rest_of_name;
773 if (ex.why == CosNaming::NamingContext::missing_node)
774 MESSAGE( "Change_Directory() : " << (char *) n[0].id
775 << " (" << (char *) n[0].kind << ") not found");
776 if (ex.why == CosNaming::NamingContext::not_context)
777 INFOS("Change_Directory() : " << (char *) n[0].id
778 << " (" << (char *) n[0].kind
779 << ") is not a context" );
780 if (ex.why == CosNaming::NamingContext::not_object)
781 INFOS( "Change_Directory() : " << (char *) n[0].id
782 << " (" << (char *) n[0].kind
783 << ") is not an object" );
786 catch (CosNaming::NamingContext::CannotProceed&)
788 INFOS("Change_Directory(): CosNaming::NamingContext::CannotProceed");
791 catch (CosNaming::NamingContext::InvalidName&)
793 INFOS("Change_Directory(): CosNaming::NamingContext::InvalidName");
796 catch (CORBA::SystemException&)
798 INFOS("Change_Directory():CORBA::SystemException : unable to contact"
799 << "the naming service");
800 throw ServiceUnreachable();
806 // ============================================================================
807 /*! \brief get the current directory path
809 * Get the current directory path.
810 * If the NamingService is out, the exception ServiceUnreachable is thrown.
811 * \return the path of the current_context
812 * \sa _current_directory
814 // ============================================================================
816 char *SALOME_NamingService::Current_Directory()
818 Utils_Locker lock (&_myMutex);
820 CosNaming::NamingContext_var ref_context = _current_context;
822 std::vector<std::string> splitPath;
825 bool notFound = true ;
827 // --- start search from root context
829 _current_context = _root_context ;
833 _current_directory(splitPath, lengthPath, ref_context, notFound );
836 catch (CORBA::SystemException&)
838 INFOS("Current_Directory(): CORBA::SystemException: unable to contact"
839 << " the naming service" )
840 throw ServiceUnreachable();
844 lengthPath = (int)splitPath.size(); //!< TODO: conversion from size_t to int
845 for (int k = 0 ; k < lengthPath ;k++)
848 path += splitPath[k];
852 _current_context = ref_context ;
854 return strdup(path.c_str());
857 // ============================================================================
858 /*! \brief list recursively all objects in the current context
860 * List and print via trace all directories and objects in the current
861 * context. Trace must be activated: compile option _DEBUG_
862 * If the NamingService is out, the exception ServiceUnreachable is thrown
864 // ============================================================================
866 void SALOME_NamingService::list()
868 Utils_Locker lock (&_myMutex)
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 (! CORBA::is_nil(binding_iterator))
884 while (binding_iterator->next_one(binding))
886 CosNaming::Name bindingName = binding->binding_name;
888 if (binding->binding_type == CosNaming::ncontext)
892 Change_Directory(bindingName[0].id);
895 catch (ServiceUnreachable&)
897 INFOS( "list(): ServiceUnreachable" )
898 throw ServiceUnreachable();
902 _current_context = ref_context ;
905 else if (binding->binding_type == CosNaming::nobject)
907 MESSAGE( "list(): no Object : " << bindingName[0].id );
911 binding_iterator->destroy();
915 // ============================================================================
916 /*! \brief list all the objects in the current directory.
918 * get a list of all the objects in the current directory, without recursion
919 * on the subdirectories. Only the objects are listed, not the directories.
920 * If the NamingService is out, the exception ServiceUnreachable is thrown.
921 * \return list of strings with objects found.
922 * \sa vector<string> list_directory_recurs()
924 // ============================================================================
926 std::vector<std::string> SALOME_NamingService::list_directory()
928 Utils_Locker lock (&_myMutex);
929 std::vector<std::string> dirList ;
932 CosNaming::BindingList_var binding_list;
933 CosNaming::BindingIterator_var binding_iterator;
934 CosNaming::Binding_var binding ;
936 unsigned long nb = 0 ; // --- only for the BindingIterator use,
937 // to access the bindings
939 CosNaming::NamingContext_var ref_context = _current_context;
941 _current_context->list(nb, binding_list, binding_iterator);
943 if (binding_iterator->_is_nil())
946 while (binding_iterator->next_one(binding))
948 CosNaming::Name bindingName = binding->binding_name;
950 if (binding->binding_type == CosNaming::nobject)
952 // remove memory leak
953 // dirList.push_back(CORBA::string_dup(bindingName[0].id));
954 dirList.push_back(std::string(bindingName[0].id));
958 // for (unsigned int ind = 0; ind < dirList.size(); ind++)
959 // MESSAGE("list_directory : Object : " << dirList[ind]);
961 binding_iterator->destroy();
967 // ============================================================================
968 /*! \brief list all the subdirectories in the current directory.
970 * get a list of all the subdirectories in the current directory,
971 * without recursion on the subdirectories.
972 * Only the subdirectories are listed, not the objects.
973 * If the NamingService is out, the exception ServiceUnreachable is thrown.
974 * \return list of strings with directories found.
975 * \sa vector<string> list_directory()
977 // ============================================================================
979 std::vector<std::string> SALOME_NamingService::list_subdirs()
981 Utils_Locker lock (&_myMutex);
982 std::vector<std::string> dirList ;
985 CosNaming::BindingList_var binding_list;
986 CosNaming::BindingIterator_var binding_iterator;
987 CosNaming::Binding_var binding ;
989 unsigned long nb = 0 ; // --- only for the BindingIterator use,
990 // to access the bindings
992 CosNaming::NamingContext_var ref_context = _current_context;
994 _current_context->list(nb, binding_list, binding_iterator) ;
996 if (binding_iterator->_is_nil())
999 while (binding_iterator->next_one(binding))
1001 CosNaming::Name bindingName = binding->binding_name;
1003 if (binding->binding_type == CosNaming::ncontext)
1005 dirList.push_back(bindingName[0].id.in());
1009 // for (unsigned int ind = 0; ind < dirList.size(); ind++)
1010 // MESSAGE("list_directory : Object : " << dirList[ind]);
1012 binding_iterator->destroy();
1017 // ============================================================================
1018 /*! \brief list all the objects in the current directory and subdirectories.
1020 * get a list of all the objects in the current directory, with recursion
1021 * on the subdirectories. Only the objects are listed, not the directories.
1022 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1023 * \return list of strings with objects found.
1024 * \sa vector<string> list_directory()
1026 // ============================================================================
1028 std::vector<std::string> SALOME_NamingService::list_directory_recurs()
1031 Utils_Locker lock (&_myMutex);
1033 std::vector<std::string> dirList ;
1035 char* currentDir = Current_Directory();
1037 _list_directory_recurs(dirList, "", currentDir);
1044 // ============================================================================
1045 /*! \brief destroy an entry in naming service.
1047 * Destroy an association Path - Object Reference.
1048 * If the NamingService is out, the exception ServiceUnreachable is thrown
1049 * \param Path object path
1051 // ============================================================================
1053 void SALOME_NamingService::Destroy_Name(const char* Path)
1056 Utils_Locker lock (&_myMutex);
1058 std::string path(Path);
1060 // --- if path empty, nothing to do
1065 // --- if path = '/' not applicable, nothing to do
1070 // --- if path begins with '/', set current directory to root context
1073 _current_context = _root_context;
1075 // --- context of the directory containing the object
1077 CosNaming::Name context_name;
1078 std::vector<std::string> splitPath;
1079 int dimension_resultat = _createContextNameDir(path.c_str(),
1086 if (dimension_resultat > 0)
1088 // --- path contains a directory, not only an object name
1089 // switch to the new directory (or return if directory not found)
1093 CORBA::Object_var obj = _current_context->resolve(context_name);
1094 _current_context = CosNaming::NamingContext::_narrow(obj);
1098 catch (CosNaming::NamingContext::NotFound &ex)
1100 // --- failed to resolve
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::InvalidName &)
1120 INFOS("Destroy_Name: CosNaming::NamingContext::InvalidName");
1123 catch (CosNaming::NamingContext::CannotProceed &)
1125 INFOS("Destroy_Name: CosNaming::NamingContext::CannotProceed");
1128 catch (CORBA::SystemException&)
1130 INFOS("Destroy_Name : CORBA::SystemException: "
1131 << "unable to contact the naming service");
1132 throw ServiceUnreachable();
1135 if (! exist) return;
1138 ASSERT(!CORBA::is_nil(_current_context));
1140 // --- The current directory is now the directory where the object should
1143 size_t sizePath = splitPath.size();
1144 if (sizePath > (size_t)dimension_resultat)
1146 ASSERT(sizePath == (size_t)dimension_resultat+1);
1147 context_name.length(1);
1151 // --- the last element is an object and not a directory
1153 context_name[0].id =
1154 CORBA::string_dup(splitPath[dimension_resultat].c_str());
1155 context_name[0].kind = CORBA::string_dup("object");
1156 //SCRUTE(context_name[0].id);
1158 _current_context->unbind(context_name);
1159 //MESSAGE("The object " << context_name[0].id << " has been deleted");
1162 catch (CosNaming::NamingContext::NotFound& ex)
1164 CosNaming::Name n = ex.rest_of_name;
1166 if (ex.why == CosNaming::NamingContext::missing_node)
1167 INFOS( "Destroy_Name() : " << (char *) n[0].id
1168 << " (" << (char *) n[0].kind << ") not found" );
1169 if (ex.why == CosNaming::NamingContext::not_context)
1170 INFOS( "Destroy_Name() : " << (char *) n[0].id
1171 << " (" << (char *) n[0].kind
1172 << ") is not a context" );
1173 if (ex.why == CosNaming::NamingContext::not_object)
1174 INFOS( "Destroy_Name() : " << (char *) n[0].id
1175 << " (" << (char *) n[0].kind
1176 << ") is not an object" );
1179 catch (CosNaming::NamingContext::CannotProceed&)
1181 INFOS( "Destroy_Name(): CosNaming::NamingContext::CannotProceed");
1184 catch (CosNaming::NamingContext::InvalidName&)
1186 INFOS( "Destroy_Name(): CosNaming::NamingContext::InvalidName");
1189 catch (CORBA::SystemException&)
1191 INFOS( "Destroy_Name(): CORBA::SystemException: unable to contact"
1192 << " the naming service");
1193 throw ServiceUnreachable();
1198 // ============================================================================
1199 /*! \brief Destroy an empty directory
1201 * Destroy an empty directory in Naming Service.
1202 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1203 * \param Path directory path
1205 // ============================================================================
1207 void SALOME_NamingService::Destroy_Directory(const char* Path)
1209 Utils_Locker lock (&_myMutex);
1211 std::string path(Path);
1213 // --- if path empty, nothing to do
1218 // --- if path begins with '/', set current directory to root context
1221 _current_context = _root_context;
1223 CosNaming::NamingContext_var ref_context = _current_context;
1225 // --- path must ends with '/' for a directory
1227 if (path[path.size() -1] != '/')
1230 // --- context of the directory
1232 CosNaming::Name context_name;
1233 std::vector<std::string> splitPath;
1234 int dimension_resultat = _createContextNameDir(path.c_str(),
1240 if (dimension_resultat > 0)
1242 // --- path contains a directory, not only an object name
1243 // switch to the new directory (or return if directory not found)
1247 CORBA::Object_var obj = _current_context->resolve(context_name);
1248 _current_context = CosNaming::NamingContext::_narrow(obj);
1252 catch (CosNaming::NamingContext::NotFound &ex)
1254 // --- failed to resolve
1257 CosNaming::Name n = ex.rest_of_name;
1259 if (ex.why == CosNaming::NamingContext::missing_node)
1260 INFOS( "Destroy_Directory(): " << (char *) n[0].id
1261 << " (" << (char *) n[0].kind << ") not found" );
1262 if (ex.why == CosNaming::NamingContext::not_context)
1263 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1264 << " (" << (char *) n[0].kind
1265 << ") is not a context" );
1266 if (ex.why == CosNaming::NamingContext::not_object)
1267 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1268 << " (" << (char *) n[0].kind
1269 << ") is not an object" );
1272 catch (CosNaming::NamingContext::InvalidName &)
1274 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1277 catch (CosNaming::NamingContext::CannotProceed &)
1279 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1282 catch (CORBA::SystemException&)
1284 INFOS("Destroy_Directory : CORBA::SystemException: "
1285 << "unable to contact the naming service");
1286 throw ServiceUnreachable();
1289 if (! exist) return;
1292 ASSERT(!CORBA::is_nil(_current_context));
1294 // --- Context Destruction
1296 bool isContextDestroyed = false;
1299 _current_context->destroy();
1300 isContextDestroyed = true;
1303 catch (CosNaming::NamingContext::NotEmpty&)
1305 INFOS( "Destroy_Directory(): CosNaming::NamingContext::NoEmpty "
1306 << path << " is not empty" );
1309 catch (CORBA::SystemException&)
1311 INFOS( "Destroy_Directory():CORBA::SystemException : "
1312 << "unable to contact the naming service");
1313 throw ServiceUnreachable();
1316 // --- go to the reference directory
1318 _current_context = ref_context ;
1320 ASSERT(!CORBA::is_nil(_current_context));
1322 if (isContextDestroyed)
1326 _current_context->unbind(context_name);
1329 catch (CosNaming::NamingContext::NotFound& ex)
1331 CosNaming::Name n = ex.rest_of_name;
1333 if (ex.why == CosNaming::NamingContext::missing_node)
1334 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1335 << " (" << (char *) n[0].kind << ") not found" );
1336 if (ex.why == CosNaming::NamingContext::not_context)
1337 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1338 << " (" << (char *) n[0].kind
1339 << ") is not a context" );
1340 if (ex.why == CosNaming::NamingContext::not_object)
1341 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1342 << " (" << (char *) n[0].kind
1343 << ") is not an object" );
1346 catch (CosNaming::NamingContext::CannotProceed&)
1348 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1351 catch (CosNaming::NamingContext::InvalidName&)
1353 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1356 catch (CORBA::SystemException&)
1358 INFOS("Destroy_Directory:CORBA::SystemException : unable to contact"
1359 << " the naming service");
1360 throw ServiceUnreachable();
1365 // ============================================================================
1366 /*! \brief Destroy a directory with its contents.
1368 * Destroy the objects associations in a directory, and the directory itself,
1369 * if there is no subdirectories.
1370 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1371 * \param Path the directory path.
1373 // ============================================================================
1375 void SALOME_NamingService::Destroy_FullDirectory(const char* Path)
1377 //no need to lock here because method calls are threadsafe.
1378 if( Change_Directory(Path) )
1380 std::vector<std::string> contList = list_directory();
1382 for (unsigned int ind = 0; ind < contList.size(); ind++)
1383 Destroy_Name(contList[ind].c_str());
1385 Destroy_Directory(Path);
1389 // ============================================================================
1390 /*! \brief initialize root context (root directory)
1392 * the root context initialisation must be done when the SALOME_NamingService
1393 * instance is created and before any other call. See constructors.
1395 // ============================================================================
1397 void SALOME_NamingService::_initialize_root_context()
1399 //no lock here because initialization is expected to be done once.
1402 CORBA::Object_var obj = _orb->resolve_initial_references("NameService");
1403 _root_context = CosNaming::NamingContext::_narrow(obj);
1404 _current_context = _root_context ;
1405 ASSERT(!CORBA::is_nil(_root_context));
1408 catch (CORBA::SystemException&)
1410 INFOS("CORBA::SystemException: unable to contact the naming service");
1411 throw ServiceUnreachable();
1416 INFOS("Unknown Exception: unable to contact the naming service");
1417 throw ServiceUnreachable();
1421 // ============================================================================
1422 /*! \brief transform a string path in CosNaming structure.
1424 * Transform a path given as a string in a CosNaming structure.
1425 * \param path a relative or absolute path, with or without an object.
1426 * An absolute path begins with '/'.
1427 * A path without an object ends with '/'.
1428 * \param context_name CosNaming structure to put the path.
1429 * \param splitPath a vector of string with subdirectories and final
1431 * \param onlyDir if true, final object (if any) is omitted
1433 * if false, final object (if any) is included in
1435 * \return dimension of context_name
1437 // ============================================================================
1440 SALOME_NamingService::_createContextNameDir(std::string path,
1441 CosNaming::Name& context_name,
1442 std::vector<std::string>& splitPath,
1448 std::string::size_type begIdx, endIdx;
1449 const std::string delims("/");
1450 splitPath.resize(0);
1451 bool endWithDelim = false;
1453 begIdx = path.find_first_not_of(delims);
1454 while (begIdx != std::string::npos)
1456 endIdx = path.find_first_of(delims, begIdx);
1457 if (endIdx == path.length()-1)
1458 endWithDelim = true;
1459 if (endIdx == std::string::npos)
1460 endIdx = path.length();
1461 size_t lsub = endIdx - begIdx;
1463 splitPath.push_back(path.substr(begIdx, lsub));
1464 begIdx = path.find_first_not_of(delims, endIdx);
1468 if (onlyDir) // only directory part
1470 dim = (int)splitPath.size()-1; // omit final object
1471 if (endWithDelim) // unless the path ends with a delimiter
1473 endWithDelim = true;
1476 dim = (int)splitPath.size(); // directories and final object
1478 context_name.length((CORBA::ULong)dim);
1479 for (int i=0; i<dim; i++)
1481 // SCRUTE(splitPath[i]);
1482 context_name[i].id = CORBA::string_dup(splitPath[i].c_str());
1483 if (!endWithDelim && (i == dim-1)) // here, the last string is an object
1485 context_name[i].kind = CORBA::string_dup("object");
1486 // MESSAGE("--- " <<splitPath[i] <<".object");
1490 context_name[i].kind = CORBA::string_dup("dir");
1491 // MESSAGE("--- " <<splitPath[i] <<".dir");
1494 return dim; //TODO: return <int> or <size_t>?
1497 // ============================================================================
1498 /*! \brief search a name in current directory.
1500 * Search a name in the current directory. after call, the current directory
1501 * is changed to the directory containing the last occurrence of name found.
1502 * If no occurrence found (see return value), current directory remains
1503 * unchanged. The call is recursive.
1505 * \param name the name to search.
1506 * \param occurence_number number of occurrence already found (incremented)
1508 // ============================================================================
1510 void SALOME_NamingService::_Find(const char* name,
1511 CORBA::Long& occurence_number)
1513 CosNaming::BindingList_var binding_list;
1514 CosNaming::BindingIterator_var binding_iterator;
1515 CosNaming::Binding_var binding;
1517 unsigned long nb = 0 ; // --- only for the use of the BindingIterator,
1518 // to access the bindings
1520 CosNaming::NamingContext_var ref_context = _current_context;
1521 CosNaming::NamingContext_var found_context = _current_context;
1523 _current_context->list(nb, binding_list, binding_iterator) ;
1525 if (! CORBA::is_nil(binding_iterator))
1527 while (binding_iterator->next_one(binding))
1529 CosNaming::Name bindingName = binding->binding_name;
1531 if (binding->binding_type == CosNaming::ncontext)
1533 // --- We work on a directory,
1534 // the search should be done in this directory
1536 Change_Directory(bindingName[0].id);
1537 _Find(name, occurence_number);
1539 // --- We'll go back to the initial context
1541 _current_context = ref_context ;
1544 else if (binding->binding_type == CosNaming::nobject)
1546 // --- We work on an object...
1548 if (!strcmp( bindingName[0].id, name))
1550 //MESSAGE("One occurrence was found");
1553 // --- We keep in memory the directory where
1554 // one occurrence was found
1556 found_context = _current_context ;
1561 binding_iterator->destroy();
1563 // --- We go to the last directory where an occurrence was found
1565 _current_context = found_context;
1567 SCRUTE(occurence_number);
1570 // ============================================================================
1571 /*! \brief find the current directory path.
1573 * Parse the naming service tree to find the current context and give the
1574 * associated directory path (relative to root context).
1576 * \param lengthResult
1577 * \param contextToFind
1580 // ============================================================================
1583 SALOME_NamingService::
1584 _current_directory(std::vector<std::string>& splitPath,
1586 CosNaming::NamingContext_var contextToFind,
1589 CosNaming::BindingList_var binding_list;
1590 CosNaming::BindingIterator_var binding_iterator;
1591 CosNaming::Binding_var binding;
1593 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1594 // to access the bindings
1596 CosNaming::NamingContext_var ref_context = _current_context;
1597 CosNaming::NamingContext_var temp_context = _current_context;
1599 _current_context->list(nb, binding_list, binding_iterator);
1601 if ( !binding_iterator->_is_nil() )
1603 while ((binding_iterator->next_one(binding)) && notFound)
1605 CosNaming::Name bindingName = binding->binding_name;
1607 if (binding->binding_type == CosNaming::ncontext)
1609 // --- directory, search in it
1611 const char* bindingNameid=bindingName[0].id;
1612 splitPath.push_back(bindingNameid);
1615 CORBA::Object_var obj = _current_context->resolve(bindingName);
1616 temp_context = CosNaming::NamingContext::_narrow(obj);
1618 if (temp_context->_is_equivalent(contextToFind))
1620 //MESSAGE("The context is found, we stop the search");
1627 //SCRUTE(bindingName[0].id);
1628 Change_Directory(bindingName[0].id);
1629 _current_directory(splitPath,
1636 // --- go back to the initial context
1638 _current_context = ref_context;
1640 // MESSAGE("Just before the delete of "
1641 // << splitPath[lengthResult-1]);
1642 splitPath.pop_back();
1649 binding_iterator->destroy();
1652 // --- return to the last directory where an occurrence was found
1654 _current_context = ref_context ;
1658 // ============================================================================
1659 /*! \brief list recursively all objects in the given directory and subdirs.
1661 * get a list of all the objects in the current directory, with recursion
1662 * on the subdirectories. Only the objects are listed, not the directories.
1663 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1664 * _current_context must refer to absCurDirectory.
1666 * \param myList The list that will be filled.
1667 * \param relativeSubDir The directory relative to absCurDirectory in which
1668 * the objects are found.
1669 * \param absCurDirectory The current directory, absolute path
1671 // ============================================================================
1673 void SALOME_NamingService::_list_directory_recurs(std::vector<std::string>& myList,
1674 std::string relativeSubDir,
1675 std::string absCurDirectory)
1677 CosNaming::BindingList_var binding_list;
1678 CosNaming::BindingIterator_var binding_iterator;
1679 CosNaming::Binding_var binding ;
1681 unsigned long nb = 0 ; // --- only for thethe use of BindingIterator
1682 // to access the bindings
1686 CosNaming::NamingContext_var ref_context = _current_context;
1688 if (! relativeSubDir.empty())
1690 Change_Directory(relativeSubDir.c_str());
1691 absDir = absCurDirectory + "/" + relativeSubDir;
1695 absDir = absCurDirectory;
1698 _current_context->list(nb, binding_list, binding_iterator) ;
1700 if (! CORBA::is_nil(binding_iterator))
1702 while (binding_iterator->next_one(binding))
1704 CosNaming::Name bindingName = binding->binding_name;
1706 if (binding->binding_type == CosNaming::ncontext)
1708 std::string relativeSdir(bindingName[0].id);
1709 _list_directory_recurs(myList, relativeSdir, absDir);
1712 else if (binding->binding_type == CosNaming::nobject)
1714 std::string objName(bindingName[0].id);
1715 std::string elt = absDir + "/" + objName;
1717 myList.push_back(elt);
1721 binding_iterator->destroy();
1723 if (! relativeSubDir.empty())
1725 _current_context = ref_context;
1729 // ============================================================================
1730 /*! \brief return a stringified reference of root context
1732 * \return a stringified reference of root context
1734 // ============================================================================
1736 char * SALOME_NamingService::getIORaddr()
1738 return _orb->object_to_string(_root_context);
1741 /*! \brief get the orb used by the naming service
1745 CORBA::ORB_ptr SALOME_NamingService::orb()