1 // Copyright (C) 2007-2014 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 MESSAGE("SALOME_NamingService default constructor");
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 MESSAGE("SALOME_NamingService creation");
74 _orb = CORBA::ORB::_duplicate(orb);
75 _initialize_root_context();
78 // ============================================================================
79 /*! \brief Standard destructor.
81 * The standard destructor does nothing special.
83 // ============================================================================
85 SALOME_NamingService::~SALOME_NamingService()
87 // Problem MESSAGE with singleton: late destruction,
88 // after trace system destruction ?
89 //MESSAGE("SALOME_NamingService destruction");
92 // ============================================================================
93 /*! \brief initializes ORB reference and naming service root context.
95 * Initializes ORB reference and naming service root context.
96 * For use after default constructor.
97 * If param orb is null, the orb is initialized
98 * \param orb CORBA::ORB_ptr arguments
100 // ============================================================================
102 void SALOME_NamingService::init_orb(CORBA::ORB_ptr orb)
104 MESSAGE("SALOME_NamingService initialisation");
106 Utils_Locker lock (&_myMutex);
108 _orb = CORBA::ORB::_duplicate(orb);
112 _orb = CORBA::ORB_init(argc, 0); // Here we make the assumption that the orb has already been initialized
115 _initialize_root_context();
118 // ============================================================================
119 /*! \brief Registers a CORBA object reference under a path.
121 * Registers a CORBA object reference under a path. If the path ends with '/',
122 * only a directory is created.
123 * If the NamingService is out, the exception ServiceUnreachable is thrown.
124 * \param ObjRef CORBA object reference to associate to the path. To create
125 * only a directory, give nil pointer.
126 * \param Path A relative or absolute pathname to store the object reference.
127 * If the pathname begins with a '/', pathname is taken
128 * as an absolute pathname. Else, pathname is taken as a relative
129 * path, to current context. Prefer absolute pathname, relative
130 * pathname are not safe, when SALOME_NamingService object is
131 * shared or use in multithreaded context.
132 * If the path ends with '/', only a directory is created.
133 * \sa Change_Directory(const char* Path),
134 * Create_Directory(const char* Path)
135 * CORBA::Object_ptr Resolve(const char* Path)
137 // ============================================================================
139 void SALOME_NamingService::Register(CORBA::Object_ptr ObjRef,
141 throw(ServiceUnreachable)
143 MESSAGE("BEGIN OF Register: " << Path);
145 Utils_Locker lock (&_myMutex);
147 // --- _current_context is replaced to the _root_context
148 // if the Path begins whith '/'
151 _current_context = _root_context;
154 // --- the resolution of the directory path has to be done
155 // to place the current_context to the correct node
157 CosNaming::Name context_name;
158 std::vector<std::string> splitPath;
159 int dimension_resultat = _createContextNameDir(Path,
164 CORBA::Boolean not_exist = false;
166 if (dimension_resultat > 0){
167 // A directory is treated (not only an object name)
168 // test if the directory where ObjRef should be recorded already exists
169 // If not, create the new context
172 CORBA::Object_var obj = _current_context->resolve(context_name);
173 _current_context = CosNaming::NamingContext::_narrow(obj);
176 catch (CosNaming::NamingContext::NotFound &){
177 // --- failed to resolve, therefore assume cold start
181 catch (CosNaming::NamingContext::InvalidName &){
182 INFOS("Register() : CosNaming::NamingContext::InvalidName");
185 catch (CosNaming::NamingContext::CannotProceed &){
186 INFOS("Register() : CosNaming::NamingContext::CannotProceed");
189 catch (CORBA::SystemException&){
190 INFOS("Register() : CORBA::SystemException: "
191 << "unable to contact the naming service");
192 throw ServiceUnreachable();
197 context_name.length(1);
198 for (int i = 0 ; i < dimension_resultat ;i++){
199 context_name[0].id = CORBA::string_dup(splitPath[i].c_str());
200 context_name[0].kind = CORBA::string_dup("dir");
201 // SCRUTE(_context_name[0].id);
202 // --- check if the path is created
204 // --- if the context is already created, nothing to do
205 CORBA::Object_var obj = _current_context->resolve(context_name);
206 _current_context = CosNaming::NamingContext::_narrow(obj);
209 catch (CosNaming::NamingContext::NotFound &){
211 // --- the context must be created
212 CosNaming::NamingContext_var temp_context =
213 _current_context->bind_new_context(context_name);
214 _current_context = temp_context;
216 catch (CosNaming::NamingContext::AlreadyBound&){
217 CORBA::Object_var obj = _current_context->resolve(context_name);
218 _current_context = CosNaming::NamingContext::_narrow(obj);
224 catch (CosNaming::NamingContext::AlreadyBound&){
225 INFOS("Register() : CosNaming::NamingContext::AlreadyBound");
228 catch (CosNaming::NamingContext::NotFound& ex){
229 CosNaming::Name n = ex.rest_of_name;
231 if (ex.why == CosNaming::NamingContext::missing_node)
232 INFOS("Register() : " << (char *) n[0].id
233 << " (" << (char *) n[0].kind << ") not found");
235 if (ex.why == CosNaming::NamingContext::not_context)
236 INFOS("Register() : " << (char *) n[0].id
237 << " (" << (char *) n[0].kind
238 << ") is not a context");
240 if (ex.why == CosNaming::NamingContext::not_object)
241 INFOS("Register() : " << (char *) n[0].id
242 << " (" << (char *) n[0].kind
243 << ") is not an object");
246 catch (CosNaming::NamingContext::CannotProceed&){
247 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
250 catch (CosNaming::NamingContext::InvalidName&){
251 INFOS("Register(): CosNaming::NamingContext::InvalidName");
254 catch (CORBA::SystemException&){
255 INFOS("Register():CORBA::SystemException: "
256 << "unable to contact the naming service");
257 throw ServiceUnreachable();
262 // --- The current directory is now the directory where the object should
265 int sizePath = splitPath.size();
266 if (sizePath > dimension_resultat){
267 ASSERT(sizePath == dimension_resultat+1);
268 context_name.length(1);
271 // --- the last element is an object and not a directory
273 context_name[0].id = CORBA::string_dup(splitPath[dimension_resultat].c_str());
274 context_name[0].kind = CORBA::string_dup("object");
275 //SCRUTE(context_name[0].id);
277 _current_context->bind(context_name, ObjRef);
280 catch (CosNaming::NamingContext::NotFound& ex){
281 CosNaming::Name n = ex.rest_of_name;
283 if (ex.why == CosNaming::NamingContext::missing_node)
284 INFOS("Register() : " << (char *) n[0].id
285 << " (" << (char *) n[0].kind << ") not found");
287 if (ex.why == CosNaming::NamingContext::not_context)
288 INFOS("Register() : " << (char *) n[0].id
289 << " (" << (char *) n[0].kind
290 << ") is not a context");
292 if (ex.why == CosNaming::NamingContext::not_object)
293 INFOS("Register() : " << (char *) n[0].id
294 << " (" << (char *) n[0].kind
295 << ") is not an object");
298 catch (CosNaming::NamingContext::CannotProceed&){
299 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
302 catch (CosNaming::NamingContext::InvalidName&){
303 INFOS("Register(): CosNaming::NamingContext::InvalidName");
306 catch (CosNaming::NamingContext::AlreadyBound&){
307 INFOS("Register(): CosNaming::NamingContext::AlreadyBound, "
308 << "object will be rebind");
309 _current_context->rebind(context_name, ObjRef);
312 catch (CORBA::SystemException&){
313 INFOS("!!!Register(): CORBA::SystemException: "
314 << "unable to contact the naming service");
315 throw ServiceUnreachable();
320 // ============================================================================
321 /*! \brief get the CORBA object reference associated to a name.
323 * get the CORBA object reference associated to a complete name with a path.
324 * If the NamingService is out, the exception ServiceUnreachable is thrown
325 * \param Path pathname. If the pathname begins with a '/', pathname is taken
326 * as an absolute pathname. Else, pathname is taken as a relative
327 * path, to current context. Prefer absolute pathname, relative
328 * pathname are not safe, when SALOME_NamingService object is
329 * shared or use in multithreaded context.
330 * \return the object reference if it exists under the pathname,
331 * or nil reference in other cases.
332 * \sa Register(CORBA::Object_ptr ObjRef, const char* Path),
333 * Change_Directory(const char* Path)
335 // ============================================================================
337 CORBA::Object_ptr SALOME_NamingService::Resolve(const char* Path)
338 throw(ServiceUnreachable)
340 // MESSAGE("BEGIN OF Resolve: " << Path);
342 Utils_Locker lock (&_myMutex);
344 // --- _current_context is replaced to the _root_context
345 // if the Path begins whith '/'
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 uncomplete name.
413 * get the CORBA object reference associated to an uncomplete name with a
414 * path. Look for the first occurence 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)
424 throw(ServiceUnreachable)
426 // MESSAGE("ResolveFirst");
428 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())
462 if ((*its).find(name) == 0)
464 return Resolve((*its).c_str());
474 // ============================================================================
475 /*! \brief find a component instance from hostname, containername,
476 * componentName and number of processors.
478 * find a component instance from hostname, containername, componentName and
479 * number of processors.
480 * If the NamingService is out, the exception ServiceUnreachable is thrown.
481 * \param hostname name of the machine on which the component is searched.
482 * \param containerName name of the container in which the component is
484 * \param componentName name of the component we are looking for an existing
486 * \param nbproc in case of multi processor machine, container name is
487 * suffixed with _nbproc.
488 * \return the object reference
490 // ============================================================================
493 SALOME_NamingService::ResolveComponent(const char* hostname,
494 const char* containerName,
495 const char* componentName,
497 throw(ServiceUnreachable)
499 // MESSAGE("ResolveComponent");
501 Utils_Locker lock (&_myMutex);
503 std::string name = "/Containers/";
507 if ( strlen(containerName) != 0 )
513 char *newContainerName = new char[strlen(containerName) + 8];
514 sprintf(newContainerName, "%s_%d", containerName, nbproc);
515 name += newContainerName;
516 delete [] newContainerName;
520 name += containerName;
524 name += componentName;
526 return ResolveFirst(name.c_str());
532 std::string basename = name;
533 if (Change_Directory(basename.c_str()))
535 std::vector<std::string> contList = list_subdirs();
537 for (unsigned int ind = 0; ind < contList.size(); ind++)
539 name = contList[ind].c_str();
543 char *str_nbproc = new char[8];
544 sprintf(str_nbproc, "_%d", nbproc);
545 if( strstr(name.c_str(),str_nbproc) == NULL)
546 continue; // check only containers with _%d in name
547 delete [] str_nbproc;
551 name += componentName;
553 CORBA::Object_ptr obj = ResolveFirst(name.c_str());
555 if ( !CORBA::is_nil(obj) )
558 Change_Directory(basename.c_str());
562 return CORBA::Object::_nil();
566 // ============================================================================
567 /*! \brief provide a default container name if empty.
569 * the given container name is returned unchanged, unless it is empty.
570 * \param containerName
571 * \return container name, where empty input is replaced by "FactoryServer",
573 * \sa BuildContainerNameForNS(const char *containerName, const char *hostname)
575 // ============================================================================
577 std::string SALOME_NamingService::ContainerName(const char *containerName)
579 std::string ret,containerNameCpp(containerName);
581 if (containerNameCpp.empty())
582 ret = "FactoryServer";
589 // ============================================================================
590 /*! \brief build a container name, given a ContainerParameters struct.
592 * Build a container name with a ContainerParameters struct. In case of multi
593 * processor machine, container name is suffixed with number of processors.
594 * \param params struct from which we get container name (may be empty) and
595 * number of processors.
596 * \return a container name without the path.
597 * \sa BuildContainerNameForNS(const Engines::ContainerParameters& params,
598 * const char *hostname)
600 // ============================================================================
602 std::string SALOME_NamingService::ContainerName(const Engines::ContainerParameters& params)
608 else if ( params.nb_proc <= 0 )
611 nbproc = params.nb_proc;
613 std::string ret(ContainerName(params.container_name));
617 std::ostringstream suffix;
618 suffix << "_" << nbproc;
625 // ============================================================================
626 /*! \brief build a string representing a container in Naming Service.
628 * Build a string representing the absolute pathname of a container in
629 * SALOME_NamingService. This form gives a suffixed containerName in case of
630 * multi processor machine.
631 * \param containerName name of the container in which the component is
633 * \param hostname name of the host of the container, without domain names.
634 * \return the path under the form /Containers/hostname/containerName
635 * \sa ContainerName(const Engines::MachineParameters& params)
637 // ============================================================================
639 std::string SALOME_NamingService::BuildContainerNameForNS(const char *containerName, const char *hostname)
641 std::string ret("/Containers/");
644 ret += ContainerName(containerName);
649 // ============================================================================
650 /*! \brief build a string representing a container in Naming Service.
652 * Build a string representing the absolute pathname of a container in
653 * SALOME_NamingService.
654 * \param params used as it is, or replaced by FactoryServer if empty.
655 * \param hostname name of the host of the container, without domain names.
656 * \return the path under the form /Containers/hostname/containerName
657 * \sa ContainerName(const char *containerName)
659 // ============================================================================
661 std::string SALOME_NamingService::BuildContainerNameForNS(const Engines::ContainerParameters& params, const char *hostname)
663 std::string ret("/Containers/");
666 ret += ContainerName(params);
671 // ============================================================================
672 /*! \brief search a name in current directory.
674 * Search a name in the current directory. after call, the current directory
675 * is changed to the directory containing the last occurence of name found.
676 * If no occurence found (see return value), current directory remains
679 * \param name the name to search.
680 * \return number of occurences found.
681 * \sa Change_Directory(const char* Path)
683 // ============================================================================
685 int SALOME_NamingService::Find(const char* name)
686 throw(ServiceUnreachable)
688 MESSAGE("BEGIN OF Find " << name);
690 Utils_Locker lock (&_myMutex);
692 CORBA::Long occurence_number = 0 ;
696 _Find(name, occurence_number);
699 catch (CORBA::SystemException&)
701 INFOS("!!!Find() : CORBA::SystemException : unable to contact"
702 << " the naming service");
703 throw ServiceUnreachable();
706 return occurence_number;
709 // ============================================================================
710 /*! \brief Creates a directory (context_name)
712 * Creates a directory (context_name) relative to the current directory
713 * (current context) or relative to the root directory (root context), if
714 * the path given begins with a '/'.
715 * If the NamingService is out, the exception ServiceUnreachable is thrown.
716 * \param Path A relative or absolute pathname to store the object reference.
717 * If the pathname begins with a '/', pathname is taken
718 * as an absolute pathname. Else, pathname is taken as a relative
719 * path, to current context. Prefer absolute pathname, relative
720 * pathname are not safe, when SALOME_NamingService object is
721 * shared or use in multithreaded context.
722 * \return true if successfull
723 * (creation not strictly garanteed if true, because Register may
724 * catch some specific unlikely exception without throw anything
725 * --- to be corrected ---)
726 * \sa RegisterCORBA::Object_ptr ObjRef, const char* Path)
728 // ============================================================================
730 bool SALOME_NamingService::Create_Directory(const char* Path) throw(ServiceUnreachable)
732 MESSAGE("BEGIN OF Create_Directory");
734 Utils_Locker lock (&_myMutex);
736 std::string path(Path);
738 // --- if path empty, nothing to create, no context change
743 // --- if path ='/', nothing to create, only change to root_context
747 MESSAGE("Create Directory '/', just change to root_context");
748 _current_context = _root_context;
752 // --- path must end with '/'
754 if (path[path.length()-1] != '/') path += '/';
756 Register(CORBA::Object::_nil(), path.c_str());
760 // ============================================================================
761 /*! \brief change current directory to the given path
763 * change the current directory to the given path in parameter.
764 * Warning: avoid use when the SALOME_NamingService instance is shared by
765 * several threads (current context may be modified by another thread).
766 * If the path is empty, nothing done return OK.
767 * If Path ="/", the current directory changes to the root directory.
768 * If the NamingService is out, the exception ServiceUnreachable is thrown.
769 * \param Path the new current directory
770 * \return true if the change succeeded
772 // ============================================================================
774 bool SALOME_NamingService::Change_Directory(const char* Path) throw(ServiceUnreachable)
776 // MESSAGE("BEGIN OF Change_Directory " << Path);
777 Utils_Locker lock (&_myMutex);
779 std::string path(Path);
781 // --- if path empty, nothing to do
786 // --- if path ='/', nothing to resolve, only change to root_context
790 // MESSAGE("Change_Directory is called to go to the root_context");
791 _current_context = _root_context;
795 CosNaming::NamingContext_var current_context = _current_context;
796 bool changeOK = false;
798 // --- replace _current_context with _root_context if Path begins whith '/'
801 current_context = _root_context;
803 // --- need to resolve directory path
805 ASSERT(!CORBA::is_nil(current_context));
807 if (path[path.length()-1] != '/') path += '/';
809 CosNaming::Name context_name;
810 std::vector<std::string> splitPath;
811 _createContextNameDir(path.c_str(),
816 // --- Context creation
820 CORBA::Object_var obj = current_context->resolve(context_name);
821 current_context = CosNaming::NamingContext::_narrow(obj);
822 ASSERT(!CORBA::is_nil(current_context));
823 _current_context = current_context;
827 catch (CosNaming::NamingContext::NotFound& ex)
829 CosNaming::Name n = ex.rest_of_name;
831 if (ex.why == CosNaming::NamingContext::missing_node)
832 MESSAGE( "Change_Directory() : " << (char *) n[0].id
833 << " (" << (char *) n[0].kind << ") not found");
834 if (ex.why == CosNaming::NamingContext::not_context)
835 INFOS("Change_Directory() : " << (char *) n[0].id
836 << " (" << (char *) n[0].kind
837 << ") is not a context" );
838 if (ex.why == CosNaming::NamingContext::not_object)
839 INFOS( "Change_Directory() : " << (char *) n[0].id
840 << " (" << (char *) n[0].kind
841 << ") is not an object" );
844 catch (CosNaming::NamingContext::CannotProceed&)
846 INFOS("Change_Directory(): CosNaming::NamingContext::CannotProceed");
849 catch (CosNaming::NamingContext::InvalidName&)
851 INFOS("Change_Directory(): CosNaming::NamingContext::InvalidName");
854 catch (CORBA::SystemException&)
856 INFOS("Change_Directory():CORBA::SystemException : unable to contact"
857 << "the naming service");
858 throw ServiceUnreachable();
864 // ============================================================================
865 /*! \brief get the current directory path
867 * Get the current directory path.
868 * If the NamingService is out, the exception ServiceUnreachable is thrown.
869 * \return the path of the current_context
870 * \sa _current_directory
872 // ============================================================================
874 char *SALOME_NamingService::Current_Directory() throw(ServiceUnreachable)
876 MESSAGE("BEGIN OF Current_Directory");
878 Utils_Locker lock (&_myMutex);
880 CosNaming::NamingContext_var ref_context = _current_context;
882 std::vector<std::string> splitPath;
885 bool notFound = true ;
887 // --- start search from root context
889 _current_context = _root_context ;
893 _current_directory(splitPath, lengthPath, ref_context, notFound );
896 catch (CORBA::SystemException&)
898 INFOS("Current_Directory(): CORBA::SystemException: unable to contact"
899 << " the naming service" )
900 throw ServiceUnreachable();
904 lengthPath = splitPath.size();
905 for (int k = 0 ; k < lengthPath ;k++)
908 path += splitPath[k];
912 _current_context = ref_context ;
914 return strdup(path.c_str());
917 // ============================================================================
918 /*! \brief list recursively all objects in the current context
920 * List and print via trace all directories and objects in the current
921 * context. Trace must be activated: compile option _DEBUG_
922 * If the NamingService is out, the exception ServiceUnreachable is thrown
924 // ============================================================================
926 void SALOME_NamingService::list() throw(ServiceUnreachable)
928 MESSAGE("Begin of list");
930 Utils_Locker lock (&_myMutex)
933 CosNaming::BindingList_var binding_list;
934 CosNaming::BindingIterator_var binding_iterator;
935 CosNaming::Binding_var binding ;
937 unsigned long nb = 0 ; // --- only for the BindingIterator use,
938 // to access the bindings
940 CosNaming::NamingContext_var ref_context = _current_context;
942 _current_context->list(nb, binding_list, binding_iterator) ;
944 if (! CORBA::is_nil(binding_iterator))
946 while (binding_iterator->next_one(binding))
948 CosNaming::Name bindingName = binding->binding_name;
950 if (binding->binding_type == CosNaming::ncontext)
952 MESSAGE( "Context : " << bindingName[0].id );
956 Change_Directory(bindingName[0].id);
959 catch (ServiceUnreachable&)
961 INFOS( "list(): ServiceUnreachable" )
962 throw ServiceUnreachable();
966 _current_context = ref_context ;
969 else if (binding->binding_type == CosNaming::nobject)
971 MESSAGE( "Object : " << bindingName[0].id );
975 binding_iterator->destroy();
979 // ============================================================================
980 /*! \brief list all the objects in the current directory.
982 * get a list of all the objects in the current directory, without recursion
983 * on the subdirectories. Only the objects are listed, not the directories.
984 * If the NamingService is out, the exception ServiceUnreachable is thrown.
985 * \return list of strings with objects found.
986 * \sa vector<string> list_directory_recurs()
988 // ============================================================================
990 std::vector<std::string> SALOME_NamingService::list_directory() throw(ServiceUnreachable)
992 // MESSAGE("list_directory");
993 Utils_Locker lock (&_myMutex);
994 std::vector<std::string> dirList ;
997 CosNaming::BindingList_var binding_list;
998 CosNaming::BindingIterator_var binding_iterator;
999 CosNaming::Binding_var binding ;
1001 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1002 // to access the bindings
1004 CosNaming::NamingContext_var ref_context = _current_context;
1006 _current_context->list(nb, binding_list, binding_iterator);
1008 if (binding_iterator->_is_nil())
1011 while (binding_iterator->next_one(binding))
1013 CosNaming::Name bindingName = binding->binding_name;
1015 if (binding->binding_type == CosNaming::nobject)
1017 // remove memory leak
1018 // dirList.push_back(CORBA::string_dup(bindingName[0].id));
1019 dirList.push_back(std::string(bindingName[0].id));
1023 // for (unsigned int ind = 0; ind < dirList.size(); ind++)
1024 // MESSAGE("list_directory : Object : " << dirList[ind]);
1026 binding_iterator->destroy();
1032 // ============================================================================
1033 /*! \brief list all the subdirectories in the current directory.
1035 * get a list of all the subdirectories in the current directory,
1036 * without recursion on the subdirectories.
1037 * Only the subdirectories are listed, not the objects.
1038 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1039 * \return list of strings with directories found.
1040 * \sa vector<string> list_directory()
1042 // ============================================================================
1044 std::vector<std::string> SALOME_NamingService::list_subdirs() throw(ServiceUnreachable)
1046 MESSAGE("list_subdirs");
1047 Utils_Locker lock (&_myMutex);
1048 std::vector<std::string> dirList ;
1051 CosNaming::BindingList_var binding_list;
1052 CosNaming::BindingIterator_var binding_iterator;
1053 CosNaming::Binding_var binding ;
1055 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1056 // to access the bindings
1058 CosNaming::NamingContext_var ref_context = _current_context;
1060 _current_context->list(nb, binding_list, binding_iterator) ;
1062 if (binding_iterator->_is_nil())
1065 while (binding_iterator->next_one(binding))
1067 CosNaming::Name bindingName = binding->binding_name;
1069 if (binding->binding_type == CosNaming::ncontext)
1071 dirList.push_back(bindingName[0].id.in());
1075 for (unsigned int ind = 0; ind < dirList.size(); ind++)
1076 MESSAGE("list_directory : Object : " << dirList[ind]);
1078 binding_iterator->destroy();
1083 // ============================================================================
1084 /*! \brief list all the objects in the current directory and subdirectories.
1086 * get a list of all the objects in the current directory, with recursion
1087 * on the subdirectories. Only the objects are listed, not the directories.
1088 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1089 * \return list of strings with objects found.
1090 * \sa vector<string> list_directory()
1092 // ============================================================================
1094 std::vector<std::string> SALOME_NamingService::list_directory_recurs()
1095 throw(ServiceUnreachable)
1097 MESSAGE("list_directory_recurs");
1099 Utils_Locker lock (&_myMutex);
1101 std::vector<std::string> dirList ;
1103 char* currentDir = Current_Directory();
1105 _list_directory_recurs(dirList, "", currentDir);
1112 // ============================================================================
1113 /*! \brief destroy an entry in naming service.
1115 * Destroy an association Path - Object Reference.
1116 * If the NamingService is out, the exception ServiceUnreachable is thrown
1117 * \param Path object path
1119 // ============================================================================
1121 void SALOME_NamingService::Destroy_Name(const char* Path)
1122 throw(ServiceUnreachable)
1124 MESSAGE("BEGIN OF Destroy_Name " << Path);
1126 Utils_Locker lock (&_myMutex);
1128 std::string path(Path);
1130 // --- if path empty, nothing to do
1135 // --- if path = '/' not applicable, nothing to do
1140 // --- if path begins with '/', set current directory to root context
1143 _current_context = _root_context;
1145 // --- context of the directory containing the object
1147 CosNaming::Name context_name;
1148 std::vector<std::string> splitPath;
1149 int dimension_resultat = _createContextNameDir(path.c_str(),
1156 if (dimension_resultat > 0)
1158 // --- path contains a directory, not only an object name
1159 // switch to the new directory (or return if directory not found)
1163 CORBA::Object_var obj = _current_context->resolve(context_name);
1164 _current_context = CosNaming::NamingContext::_narrow(obj);
1168 catch (CosNaming::NamingContext::NotFound &ex)
1170 // --- failed to resolve
1173 CosNaming::Name n = ex.rest_of_name;
1175 if (ex.why == CosNaming::NamingContext::missing_node)
1176 INFOS( "Destroy_Name(): " << (char *) n[0].id
1177 << " (" << (char *) n[0].kind << ") not found" );
1178 if (ex.why == CosNaming::NamingContext::not_context)
1179 INFOS( "Destroy_Name() : " << (char *) n[0].id
1180 << " (" << (char *) n[0].kind
1181 << ") is not a context" );
1182 if (ex.why == CosNaming::NamingContext::not_object)
1183 INFOS( "Destroy_Name() : " << (char *) n[0].id
1184 << " (" << (char *) n[0].kind
1185 << ") is not an object" );
1188 catch (CosNaming::NamingContext::InvalidName &)
1190 INFOS("Destroy_Name: CosNaming::NamingContext::InvalidName");
1193 catch (CosNaming::NamingContext::CannotProceed &)
1195 INFOS("Destroy_Name: CosNaming::NamingContext::CannotProceed");
1198 catch (CORBA::SystemException&)
1200 INFOS("Destroy_Name : CORBA::SystemException: "
1201 << "unable to contact the naming service");
1202 throw ServiceUnreachable();
1205 if (! exist) return;
1208 ASSERT(!CORBA::is_nil(_current_context));
1210 // --- The current directory is now the directory where the object should
1213 int sizePath = splitPath.size();
1214 if (sizePath > dimension_resultat)
1216 ASSERT(sizePath == dimension_resultat+1);
1217 context_name.length(1);
1221 // --- the last element is an object and not a directory
1223 context_name[0].id =
1224 CORBA::string_dup(splitPath[dimension_resultat].c_str());
1225 context_name[0].kind = CORBA::string_dup("object");
1226 SCRUTE(context_name[0].id);
1228 _current_context->unbind(context_name);
1229 MESSAGE("The object " << context_name[0].id << " has been deleted");
1232 catch (CosNaming::NamingContext::NotFound& ex)
1234 CosNaming::Name n = ex.rest_of_name;
1236 if (ex.why == CosNaming::NamingContext::missing_node)
1237 INFOS( "Destroy_Name() : " << (char *) n[0].id
1238 << " (" << (char *) n[0].kind << ") not found" );
1239 if (ex.why == CosNaming::NamingContext::not_context)
1240 INFOS( "Destroy_Name() : " << (char *) n[0].id
1241 << " (" << (char *) n[0].kind
1242 << ") is not a context" );
1243 if (ex.why == CosNaming::NamingContext::not_object)
1244 INFOS( "Destroy_Name() : " << (char *) n[0].id
1245 << " (" << (char *) n[0].kind
1246 << ") is not an object" );
1249 catch (CosNaming::NamingContext::CannotProceed&)
1251 INFOS( "Destroy_Name(): CosNaming::NamingContext::CannotProceed");
1254 catch (CosNaming::NamingContext::InvalidName&)
1256 INFOS( "Destroy_Name(): CosNaming::NamingContext::InvalidName");
1259 catch (CORBA::SystemException&)
1261 INFOS( "Destroy_Name(): CORBA::SystemException: unable to contact"
1262 << " the naming service");
1263 throw ServiceUnreachable();
1268 // ============================================================================
1269 /*! \brief Destroy an empty directory
1271 * Destroy an empty directory in Naming Service.
1272 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1273 * \param Path directory path
1275 // ============================================================================
1277 void SALOME_NamingService::Destroy_Directory(const char* Path) throw(ServiceUnreachable)
1279 MESSAGE("BEGIN OF Destroy_Directory " << Path);
1281 Utils_Locker lock (&_myMutex);
1283 std::string path(Path);
1285 // --- if path empty, nothing to do
1290 // --- if path begins with '/', set current directory to root context
1293 _current_context = _root_context;
1295 CosNaming::NamingContext_var ref_context = _current_context;
1297 // --- path must ends with '/' for a directory
1299 if (path[path.size() -1] != '/')
1302 // --- context of the directory
1304 CosNaming::Name context_name;
1305 std::vector<std::string> splitPath;
1306 int dimension_resultat = _createContextNameDir(path.c_str(),
1312 if (dimension_resultat > 0)
1314 // --- path contains a directory, not only an object name
1315 // switch to the new directory (or return if directory not found)
1319 CORBA::Object_var obj = _current_context->resolve(context_name);
1320 _current_context = CosNaming::NamingContext::_narrow(obj);
1324 catch (CosNaming::NamingContext::NotFound &ex)
1326 // --- failed to resolve
1329 CosNaming::Name n = ex.rest_of_name;
1331 if (ex.why == CosNaming::NamingContext::missing_node)
1332 INFOS( "Destroy_Directory(): " << (char *) n[0].id
1333 << " (" << (char *) n[0].kind << ") not found" );
1334 if (ex.why == CosNaming::NamingContext::not_context)
1335 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1336 << " (" << (char *) n[0].kind
1337 << ") is not a context" );
1338 if (ex.why == CosNaming::NamingContext::not_object)
1339 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1340 << " (" << (char *) n[0].kind
1341 << ") is not an object" );
1344 catch (CosNaming::NamingContext::InvalidName &)
1346 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1349 catch (CosNaming::NamingContext::CannotProceed &)
1351 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1354 catch (CORBA::SystemException&)
1356 INFOS("Destroy_Directory : CORBA::SystemException: "
1357 << "unable to contact the naming service");
1358 throw ServiceUnreachable();
1361 if (! exist) return;
1364 ASSERT(!CORBA::is_nil(_current_context));
1366 // --- Context Destruction
1368 bool isContextDestroyed = false;
1371 _current_context->destroy();
1372 MESSAGE( "The context " << path << " has been deleted" );
1373 isContextDestroyed = true;
1376 catch (CosNaming::NamingContext::NotEmpty&)
1378 INFOS( "Destroy_Directory(): CosNaming::NamingContext::NoEmpty "
1379 << path << " is not empty" );
1382 catch (CORBA::SystemException&)
1384 INFOS( "Destroy_Directory():CORBA::SystemException : "
1385 << "unable to contact the naming service");
1386 throw ServiceUnreachable();
1389 // --- go to the reference directory
1391 _current_context = ref_context ;
1393 ASSERT(!CORBA::is_nil(_current_context));
1395 if (isContextDestroyed)
1399 _current_context->unbind(context_name);
1400 MESSAGE( "The bind to the context "
1401 << context_name[0].id
1402 << " has been deleted" );
1405 catch (CosNaming::NamingContext::NotFound& ex)
1407 CosNaming::Name n = ex.rest_of_name;
1409 if (ex.why == CosNaming::NamingContext::missing_node)
1410 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1411 << " (" << (char *) n[0].kind << ") not found" );
1412 if (ex.why == CosNaming::NamingContext::not_context)
1413 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1414 << " (" << (char *) n[0].kind
1415 << ") is not a context" );
1416 if (ex.why == CosNaming::NamingContext::not_object)
1417 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1418 << " (" << (char *) n[0].kind
1419 << ") is not an object" );
1422 catch (CosNaming::NamingContext::CannotProceed&)
1424 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1427 catch (CosNaming::NamingContext::InvalidName&)
1429 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1432 catch (CORBA::SystemException&)
1434 INFOS("Destroy_Directory:CORBA::SystemException : unable to contact"
1435 << " the naming service");
1436 throw ServiceUnreachable();
1441 // ============================================================================
1442 /*! \brief Destroy a directory with its contents.
1444 * Destroy the objects associations in a directory, and the directory itself,
1445 * if there is no subdirectories.
1446 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1447 * \param Path the directory path.
1449 // ============================================================================
1451 void SALOME_NamingService::Destroy_FullDirectory(const char* Path) throw(ServiceUnreachable)
1453 MESSAGE("begin of Destroy_FullDirectory " << Path);
1454 //no need to lock here because method calls are threadsafe.
1455 if( Change_Directory(Path) )
1457 std::vector<std::string> contList = list_directory();
1459 for (unsigned int ind = 0; ind < contList.size(); ind++)
1460 Destroy_Name(contList[ind].c_str());
1462 Destroy_Directory(Path);
1466 // ============================================================================
1467 /*! \brief initialize root context (root directory)
1469 * the root context initialisation must be done when the SALOME_NamingService
1470 * instance is created and before any othe call. See constructors.
1472 // ============================================================================
1474 void SALOME_NamingService::_initialize_root_context()
1476 //MESSAGE("Get the root context");
1477 //no lock here because initialization is expected to be done once.
1480 CORBA::Object_var obj = _orb->resolve_initial_references("NameService");
1481 _root_context = CosNaming::NamingContext::_narrow(obj);
1482 _current_context = _root_context ;
1483 ASSERT(!CORBA::is_nil(_root_context));
1486 catch (CORBA::SystemException&)
1488 INFOS("CORBA::SystemException: unable to contact the naming service");
1489 throw ServiceUnreachable();
1494 INFOS("Unknown Exception: unable to contact the naming service");
1495 throw ServiceUnreachable();
1499 // ============================================================================
1500 /*! \brief transform a string path in CosNaming structure.
1502 * Transform a path given as a string in a CosNaming structure.
1503 * \param path a relative or absolute path, with or without an object.
1504 * An absolute path begins with '/'.
1505 * A path without an object ends with '/'.
1506 * \param context_name CosNaming structure to put the path.
1507 * \param splitPath a vector of string with subdirectories and final
1509 * \param onlyDir if true, final object (if any) is ommited
1511 * if false, final object (if any) is included in
1513 * \return dimension of context_name
1515 // ============================================================================
1518 SALOME_NamingService::_createContextNameDir(std::string path,
1519 CosNaming::Name& context_name,
1520 std::vector<std::string>& splitPath,
1526 std::string::size_type begIdx, endIdx;
1527 const std::string delims("/");
1528 splitPath.resize(0);
1529 bool endWithDelim = false;
1531 begIdx = path.find_first_not_of(delims);
1532 while (begIdx != std::string::npos)
1534 endIdx = path.find_first_of(delims, begIdx);
1535 if (endIdx == path.length()-1)
1536 endWithDelim = true;
1537 if (endIdx == std::string::npos)
1538 endIdx = path.length();
1539 int lsub = endIdx - begIdx;
1541 splitPath.push_back(path.substr(begIdx, lsub));
1542 begIdx = path.find_first_not_of(delims, endIdx);
1546 if (onlyDir) // only directory part
1548 dim = splitPath.size()-1; // omit final object
1549 if (endWithDelim) // unless the path ends with a delimiter
1551 endWithDelim = true;
1554 dim = splitPath.size(); // directories and final object
1556 context_name.length(dim);
1557 for (int i=0; i<dim; i++)
1559 // SCRUTE(splitPath[i]);
1560 context_name[i].id = CORBA::string_dup(splitPath[i].c_str());
1561 if (!endWithDelim && (i == dim-1)) // here, the last string is an object
1563 context_name[i].kind = CORBA::string_dup("object");
1564 // MESSAGE("--- " <<splitPath[i] <<".object");
1568 context_name[i].kind = CORBA::string_dup("dir");
1569 // MESSAGE("--- " <<splitPath[i] <<".dir");
1575 // ============================================================================
1576 /*! \brief search a name in current directory.
1578 * Search a name in the current directory. after call, the current directory
1579 * is changed to the directory containing the last occurence of name found.
1580 * If no occurence found (see return value), current directory remains
1581 * unchanged. The call is recursive.
1583 * \param name the name to search.
1584 * \param occurence_number number of occurence already found (incremented)
1586 // ============================================================================
1588 void SALOME_NamingService::_Find(const char* name,
1589 CORBA::Long& occurence_number)
1591 MESSAGE("BEGIN OF _Find "<< occurence_number << " " << name);
1593 CosNaming::BindingList_var binding_list;
1594 CosNaming::BindingIterator_var binding_iterator;
1595 CosNaming::Binding_var binding;
1597 unsigned long nb = 0 ; // --- only for the use of the BindingIterator,
1598 // to access the bindings
1600 CosNaming::NamingContext_var ref_context = _current_context;
1601 CosNaming::NamingContext_var found_context = _current_context;
1603 _current_context->list(nb, binding_list, binding_iterator) ;
1605 if (! CORBA::is_nil(binding_iterator))
1607 while (binding_iterator->next_one(binding))
1609 CosNaming::Name bindingName = binding->binding_name;
1611 if (binding->binding_type == CosNaming::ncontext)
1613 // --- We work on a directory,
1614 // the search should be done in this directory
1616 Change_Directory(bindingName[0].id);
1617 _Find(name, occurence_number);
1619 // --- We'll go back to the initial context
1621 _current_context = ref_context ;
1624 else if (binding->binding_type == CosNaming::nobject)
1626 // --- We work on an object...
1628 if (!strcmp( bindingName[0].id, name))
1630 //MESSAGE("One occurence was found");
1633 // --- We keep in memory the directory where
1634 // one occurence was found
1636 found_context = _current_context ;
1641 binding_iterator->destroy();
1643 // --- We go to the last directory where an occurence was found
1645 _current_context = found_context;
1647 SCRUTE(occurence_number);
1650 // ============================================================================
1651 /*! \brief find the current directory path.
1653 * Parse the naming service tree to find the current context and give the
1654 * associated directory path (relative to root context).
1656 * \param lengthResult
1657 * \param contextToFind
1660 // ============================================================================
1663 SALOME_NamingService::
1664 _current_directory(std::vector<std::string>& splitPath,
1666 CosNaming::NamingContext_var contextToFind,
1669 MESSAGE("BEGIN OF _current_Directory");
1671 CosNaming::BindingList_var binding_list;
1672 CosNaming::BindingIterator_var binding_iterator;
1673 CosNaming::Binding_var binding;
1675 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1676 // to access the bindings
1678 CosNaming::NamingContext_var ref_context = _current_context;
1679 CosNaming::NamingContext_var temp_context = _current_context;
1681 _current_context->list(nb, binding_list, binding_iterator);
1683 if ( !binding_iterator->_is_nil() )
1685 while ((binding_iterator->next_one(binding)) && notFound)
1687 CosNaming::Name bindingName = binding->binding_name;
1689 if (binding->binding_type == CosNaming::ncontext)
1691 // --- directory, search in it
1693 const char* bindingNameid=bindingName[0].id;
1694 splitPath.push_back(bindingNameid);
1697 CORBA::Object_var obj = _current_context->resolve(bindingName);
1698 temp_context = CosNaming::NamingContext::_narrow(obj);
1700 if (temp_context->_is_equivalent(contextToFind))
1702 MESSAGE("The context is found, we stop the search");
1709 SCRUTE(bindingName[0].id);
1710 Change_Directory(bindingName[0].id);
1711 _current_directory(splitPath,
1718 // --- go back to the initial context
1720 _current_context = ref_context;
1722 MESSAGE("Just before the delete of "
1723 << splitPath[lengthResult-1]);
1724 splitPath.pop_back();
1731 binding_iterator->destroy();
1734 // --- return to the last directory where an occurence was found
1736 _current_context = ref_context ;
1740 // ============================================================================
1741 /*! \brief list recursively all objects in the given directory and subdirs.
1743 * get a list of all the objects in the current directory, with recursion
1744 * on the subdirectories. Only the objects are listed, not the directories.
1745 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1746 * _current_context must refer to absCurDirectory.
1748 * \param myList The list that will be filled.
1749 * \param relativeSubDir The directory relative to absCurDirectory in which
1750 * the objects are found.
1751 * \param absCurDirectory The current directory, absolute path
1753 // ============================================================================
1755 void SALOME_NamingService::_list_directory_recurs(std::vector<std::string>& myList,
1756 std::string relativeSubDir,
1757 std::string absCurDirectory)
1759 CosNaming::BindingList_var binding_list;
1760 CosNaming::BindingIterator_var binding_iterator;
1761 CosNaming::Binding_var binding ;
1763 unsigned long nb = 0 ; // --- only for thethe use of BindingIterator
1764 // to access the bindings
1768 CosNaming::NamingContext_var ref_context = _current_context;
1770 if (! relativeSubDir.empty())
1772 Change_Directory(relativeSubDir.c_str());
1773 absDir = absCurDirectory + "/" + relativeSubDir;
1777 absDir = absCurDirectory;
1780 _current_context->list(nb, binding_list, binding_iterator) ;
1782 if (! CORBA::is_nil(binding_iterator))
1784 while (binding_iterator->next_one(binding))
1786 CosNaming::Name bindingName = binding->binding_name;
1788 if (binding->binding_type == CosNaming::ncontext)
1790 std::string relativeSdir(bindingName[0].id);
1791 _list_directory_recurs(myList, relativeSdir, absDir);
1794 else if (binding->binding_type == CosNaming::nobject)
1796 std::string objName(bindingName[0].id);
1797 std::string elt = absDir + "/" + objName;
1799 myList.push_back(elt);
1803 binding_iterator->destroy();
1805 if (! relativeSubDir.empty())
1807 _current_context = ref_context;
1811 // ============================================================================
1812 /*! \brief return a stringified reference of root context
1814 * \return a stringified reference of root context
1816 // ============================================================================
1818 char * SALOME_NamingService::getIORaddr()
1820 return _orb->object_to_string(_root_context);
1823 /*! \brief get the orb used by the naming service
1827 CORBA::ORB_ptr SALOME_NamingService::orb()