1 // SALOME NamingService : wrapping NamingService services
3 // Copyright (C) 2003 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.
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
24 // File : SALOME_NamingService.cxx
25 // Author : Estelle Deville
29 #include "SALOME_NamingService.hxx"
30 #include "ServiceUnreachable.hxx"
32 #include "utilities.h"
40 // ============================================================================
41 /*! \brief Default Constructor without ORB reference.
43 * After Default Constructor, one needs to initialize ORB.
44 * \sa init_orb(CORBA::ORB_ptr orb), SALOME_NamingService(CORBA::ORB_ptr orb)
46 // ============================================================================
48 SALOME_NamingService::SALOME_NamingService()
50 MESSAGE("SALOME_NamingService default constructor");
51 _orb = CORBA::ORB::_nil();
52 _root_context = CosNaming::NamingContext::_nil();
55 // ============================================================================
56 /*! \brief Standard Constructor, with ORB reference.
58 * Initializes the naming service root context
59 * \param orb CORBA::ORB_ptr arguments
61 // ============================================================================
63 SALOME_NamingService::SALOME_NamingService(CORBA::ORB_ptr orb)
65 MESSAGE("SALOME_NamingService creation");
67 _initialize_root_context();
70 // ============================================================================
71 /*! \brief Standard destructor.
73 * The standard destructor does nothing special.
75 // ============================================================================
77 SALOME_NamingService::~SALOME_NamingService()
79 // Problem MESSAGE with singleton: late destruction,
80 // after trace system destruction ?
81 //MESSAGE("SALOME_NamingService destruction");
84 // ============================================================================
85 /*! \brief initializes ORB reference and naming service root context.
87 * Initializes ORB reference and naming service root context.
88 * For use after default constructor.
89 * \param orb CORBA::ORB_ptr arguments
91 // ============================================================================
93 void SALOME_NamingService::init_orb(CORBA::ORB_ptr orb)
95 MESSAGE("SALOME_NamingService initialisation");
97 Utils_Locker lock (&_myMutex);
100 _initialize_root_context();
103 // ============================================================================
104 /*! \brief Registers a CORBA object reference under a path.
106 * Registers a CORBA object reference under a path. If the path ends with '/',
107 * only a directory is created.
108 * If the NamingService is out, the exception ServiceUnreachable is thrown.
109 * \param ObjRef CORBA object reference to associate to the path. To create
110 * only a directory, give nil pointer.
111 * \param Path A relative or absolute pathname to store the object reference.
112 * If the pathname begins with a '/', pathname is taken
113 * as an absolute pathname. Else, pathname is taken as a relative
114 * path, to current context. Prefer absolute pathname, relative
115 * pathname are not safe, when SALOME_NamingService object is
116 * shared or use in multithreaded context.
117 * If the path ends with '/', only a directory is created.
118 * \sa Change_Directory(const char* Path),
119 * Create_Directory(const char* Path)
120 * CORBA::Object_ptr Resolve(const char* Path)
122 // ============================================================================
124 void SALOME_NamingService::Register(CORBA::Object_ptr ObjRef,
126 throw(ServiceUnreachable)
128 MESSAGE("BEGIN OF Register: " << Path);
130 Utils_Locker lock (&_myMutex);
132 // --- _current_context is replaced to the _root_context
133 // if the Path begins whith '/'
136 _current_context = _root_context;
139 // --- the resolution of the directory path has to be done
140 // to place the current_context to the correct node
142 CosNaming::Name context_name;
143 vector<string> splitPath;
144 int dimension_resultat = _createContextNameDir(Path,
149 CORBA::Boolean not_exist = false;
151 if (dimension_resultat > 0){
152 // A directory is treated (not only an object name)
153 // test if the directory where ObjRef should be recorded already exists
154 // If not, create the new context
157 CORBA::Object_var obj = _current_context->resolve(context_name);
158 _current_context = CosNaming::NamingContext::_narrow(obj);
161 catch (CosNaming::NamingContext::NotFound &){
162 // --- failed to resolve, therefore assume cold start
166 catch (CosNaming::NamingContext::InvalidName &){
167 INFOS("Register() : CosNaming::NamingContext::InvalidName");
170 catch (CosNaming::NamingContext::CannotProceed &){
171 INFOS("Register() : CosNaming::NamingContext::CannotProceed");
174 catch (CORBA::SystemException&){
175 INFOS("Register() : CORBA::SystemException: "
176 << "unable to contact the naming service");
177 throw ServiceUnreachable();
182 context_name.length(1);
183 for (int i = 0 ; i < dimension_resultat ;i++){
184 context_name[0].id = CORBA::string_dup(splitPath[i].c_str());
185 context_name[0].kind = CORBA::string_dup("dir");
186 // SCRUTE(_context_name[0].id);
187 // --- check if the path is created
189 // --- if the context is already created, nothing to do
190 CORBA::Object_var obj = _current_context->resolve(context_name);
191 _current_context = CosNaming::NamingContext::_narrow(obj);
194 catch (CosNaming::NamingContext::NotFound &){
196 // --- the context must be created
197 CosNaming::NamingContext_var temp_context =
198 _current_context->bind_new_context(context_name);
199 _current_context = temp_context;
201 catch (CosNaming::NamingContext::AlreadyBound&){
202 CORBA::Object_var obj = _current_context->resolve(context_name);
203 _current_context = CosNaming::NamingContext::_narrow(obj);
209 catch (CosNaming::NamingContext::AlreadyBound&){
210 INFOS("Register() : CosNaming::NamingContext::AlreadyBound");
213 catch (CosNaming::NamingContext::NotFound& ex){
214 CosNaming::Name n = ex.rest_of_name;
216 if (ex.why == CosNaming::NamingContext::missing_node)
217 INFOS("Register() : " << (char *) n[0].id
218 << " (" << (char *) n[0].kind << ") not found");
220 if (ex.why == CosNaming::NamingContext::not_context)
221 INFOS("Register() : " << (char *) n[0].id
222 << " (" << (char *) n[0].kind
223 << ") is not a context");
225 if (ex.why == CosNaming::NamingContext::not_object)
226 INFOS("Register() : " << (char *) n[0].id
227 << " (" << (char *) n[0].kind
228 << ") is not an object");
231 catch (CosNaming::NamingContext::CannotProceed&){
232 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
235 catch (CosNaming::NamingContext::InvalidName&){
236 INFOS("Register(): CosNaming::NamingContext::InvalidName");
239 catch (CORBA::SystemException&){
240 INFOS("Register():CORBA::SystemException: "
241 << "unable to contact the naming service");
242 throw ServiceUnreachable();
247 // --- The current directory is now the directory where the object should
250 int sizePath = splitPath.size();
251 if (sizePath > dimension_resultat){
252 ASSERT(sizePath == dimension_resultat+1);
253 context_name.length(1);
256 // --- the last element is an object and not a directory
258 context_name[0].id = CORBA::string_dup(splitPath[dimension_resultat].c_str());
259 context_name[0].kind = CORBA::string_dup("object");
260 //SCRUTE(context_name[0].id);
262 _current_context->bind(context_name, ObjRef);
265 catch (CosNaming::NamingContext::NotFound& ex){
266 CosNaming::Name n = ex.rest_of_name;
268 if (ex.why == CosNaming::NamingContext::missing_node)
269 INFOS("Register() : " << (char *) n[0].id
270 << " (" << (char *) n[0].kind << ") not found");
272 if (ex.why == CosNaming::NamingContext::not_context)
273 INFOS("Register() : " << (char *) n[0].id
274 << " (" << (char *) n[0].kind
275 << ") is not a context");
277 if (ex.why == CosNaming::NamingContext::not_object)
278 INFOS("Register() : " << (char *) n[0].id
279 << " (" << (char *) n[0].kind
280 << ") is not an object");
283 catch (CosNaming::NamingContext::CannotProceed&){
284 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
287 catch (CosNaming::NamingContext::InvalidName&){
288 INFOS("Register(): CosNaming::NamingContext::InvalidName");
291 catch (CosNaming::NamingContext::AlreadyBound&){
292 INFOS("Register(): CosNaming::NamingContext::AlreadyBound, "
293 << "object will be rebind");
294 _current_context->rebind(context_name, ObjRef);
297 catch (CORBA::SystemException&){
298 INFOS("!!!Register(): CORBA::SystemException: "
299 << "unable to contact the naming service");
300 throw ServiceUnreachable();
305 // ============================================================================
306 /*! \brief get the CORBA object reference associated to a name.
308 * get the CORBA object reference associated to a complete name with a path.
309 * If the NamingService is out, the exception ServiceUnreachable is thrown
310 * \param Path pathname. If the pathname begins with a '/', pathname is taken
311 * as an absolute pathname. Else, pathname is taken as a relative
312 * path, to current context. Prefer absolute pathname, relative
313 * pathname are not safe, when SALOME_NamingService object is
314 * shared or use in multithreaded context.
315 * \return the object reference if it exists under the pathname,
316 * or nil reference in other cases.
317 * \sa Register(CORBA::Object_ptr ObjRef, const char* Path),
318 * Change_Directory(const char* Path)
320 // ============================================================================
322 CORBA::Object_ptr SALOME_NamingService::Resolve(const char* Path)
323 throw(ServiceUnreachable)
325 // MESSAGE("BEGIN OF Resolve: " << Path);
327 Utils_Locker lock (&_myMutex);
329 // --- _current_context is replaced to the _root_context
330 // if the Path begins whith '/'
334 _current_context = _root_context;
337 // --- the resolution of the directory path has to be done
338 // to place the current_context to the correct node
340 CosNaming::Name context_name;
341 vector<string> splitPath;
342 int dimension_resultat = _createContextNameDir(Path,
347 ASSERT(!CORBA::is_nil(_current_context));
349 CORBA::Object_var obj = CORBA::Object::_nil();
353 obj = _current_context->resolve(context_name);
356 catch (CosNaming::NamingContext::NotFound& ex)
358 CosNaming::Name n = ex.rest_of_name;
360 if (ex.why == CosNaming::NamingContext::missing_node)
361 MESSAGE("Resolve() : " << (char *) n[0].id
362 << " (" << (char *) n[0].kind << ") not found");
364 if (ex.why == CosNaming::NamingContext::not_context)
366 << (char *) n[0].id << " (" << (char *) n[0].kind
367 << ") is not a context");
369 if (ex.why == CosNaming::NamingContext::not_object)
370 INFOS("Resolve() : " << (char *) n[0].id
371 << " (" << (char *) n[0].kind
372 << ") is not an object");
375 catch (CosNaming::NamingContext::CannotProceed&)
377 INFOS("Resolve(): CosNaming::NamingContext::CannotProceed");
380 catch (CosNaming::NamingContext::InvalidName&)
382 INFOS("Resolve(): CosNaming::NamingContext::InvalidName");
385 catch (CORBA::SystemException&)
387 INFOS("Resolve():CORBA::SystemException : unable to contact"
388 << "the naming service");
389 throw ServiceUnreachable();
395 // ============================================================================
396 /*! \brief get the CORBA object reference associated to an uncomplete name.
398 * get the CORBA object reference associated to an uncomplete name with a
399 * path. Look for the first occurence of name*.
400 * If the NamingService is out, the exception ServiceUnreachable is thrown
401 * \param Path pathname under the form "/path/name" (Absolute reference !)
402 * search the fist reference like "/path(.dir)/name*(.kind)"
403 * \return the object reference if found, or nil reference.
404 * \sa Resolve(const char* Path)
406 // ============================================================================
408 CORBA::Object_ptr SALOME_NamingService::ResolveFirst(const char* Path)
409 throw(ServiceUnreachable)
411 // MESSAGE("ResolveFirst");
413 Utils_Locker lock (&_myMutex);
416 string thePath = Path;
417 string basePath = "";
418 string name = thePath;
420 string::size_type idx = thePath.rfind('/');
422 if (idx != string::npos) // at least one '/' found
424 basePath = thePath.substr(0, idx);
425 name = thePath.substr(idx + 1);
430 CORBA::Object_var obj = CORBA::Object::_nil();
433 if (basePath.empty())
436 isOk = Change_Directory(basePath.c_str());
440 vector<string> listElem = list_directory();
441 vector<string>::iterator its = listElem.begin();
443 while (its != listElem.end())
447 if ((*its).find(name) == 0)
449 return Resolve((*its).c_str());
459 // ============================================================================
460 /*! \brief find a component instance from hostname, containername,
461 * componentName and number of processors.
463 * find a component instance from hostname, containername, componentName and
464 * number of processors.
465 * If the NamingService is out, the exception ServiceUnreachable is thrown.
466 * \param hostname name of the machine on which the component is searched.
467 * \param containerName name of the container in which the component is
469 * \param componentName name of the component we are looking for an existing
471 * \param nbproc in case of multi processor machine, container name is
472 * suffixed with _nbproc.
473 * \return the object reference
475 // ============================================================================
478 SALOME_NamingService::ResolveComponent(const char* hostname,
479 const char* containerName,
480 const char* componentName,
482 throw(ServiceUnreachable)
484 // MESSAGE("ResolveComponent");
486 Utils_Locker lock (&_myMutex);
488 string name = "/Containers/";
492 if ( strlen(containerName) != 0 )
498 char *newContainerName = new char[strlen(containerName) + 8];
499 sprintf(newContainerName, "%s_%d", containerName, nbproc);
500 name += newContainerName;
501 delete [] newContainerName;
505 name += containerName;
509 name += componentName;
511 return ResolveFirst(name.c_str());
517 if (Change_Directory(name.c_str()))
519 vector<string> contList = list_subdirs();
521 for (unsigned int ind = 0; ind < contList.size(); ind++)
523 name = contList[ind].c_str();
527 char *str_nbproc = new char[8];
528 sprintf(str_nbproc, "_%d", nbproc);
529 if( strstr(name.c_str(),str_nbproc) == NULL)
530 continue; // check only containers with _%d in name
531 delete [] str_nbproc;
535 name += componentName;
537 CORBA::Object_ptr obj = ResolveFirst(name.c_str());
539 if ( !CORBA::is_nil(obj) )
544 return CORBA::Object::_nil();
548 // ============================================================================
549 /*! \brief provide a default container name if empty.
551 * the given container name is returned unchanged, unless it is empty.
552 * \param containerName
553 * \return container name, where empty input is replaced by "FactoryServer",
555 * \sa BuildContainerNameForNS(const char *containerName, const char *hostname)
557 // ============================================================================
559 string SALOME_NamingService::ContainerName(const char *containerName)
563 if (strlen(containerName) == 0)
564 ret = "FactoryServer";
571 // ============================================================================
572 /*! \brief build a container name, given a MachineParameters struct.
574 * Build a container name with a MachineParameters struct. In case of multi
575 * processor machine, container name is suffixed with _nbproc. nproc equals
576 * (number of nodes)*(number of processor per nodes).
577 * \param params struct from which we get container name (may be
578 * empty), number of nodes and number of processor
580 * \return a container name without the path.
581 * \sa BuildContainerNameForNS(const Engines::MachineParameters& params,
582 * const char *hostname)
584 // ============================================================================
587 SALOME_NamingService::ContainerName(const Engines::MachineParameters& params)
593 else if ( (params.nb_node <= 0) && (params.nb_proc_per_node <= 0) )
595 else if ( params.nb_node == 0 )
596 nbproc = params.nb_proc_per_node;
597 else if ( params.nb_proc_per_node == 0 )
598 nbproc = params.nb_node;
600 nbproc = params.nb_node * params.nb_proc_per_node;
602 string ret = ContainerName(params.container_name);
606 char *suffix = new char[8];
607 sprintf(suffix, "_%d", nbproc);
614 // ============================================================================
615 /*! \brief build a string representing a container in Naming Service.
617 * Build a string representing the absolute pathname of a container in
618 * SALOME_NamingService. This form gives a suffixed containerName in case of
619 * multi processor machine.
620 * \param containerName name of the container in which the component is
622 * \param hostname name of the host of the container, without domain names.
623 * \return the path under the form /Containers/hostname/containerName
624 * \sa ContainerName(const Engines::MachineParameters& params)
626 // ============================================================================
628 string SALOME_NamingService::BuildContainerNameForNS(const char *containerName,
629 const char *hostname)
631 string ret = "/Containers/";
634 ret += ContainerName(containerName);
639 // ============================================================================
640 /*! \brief build a string representing a container in Naming Service.
642 * Build a string representing the absolute pathname of a container in
643 * SALOME_NamingService.
644 * \param params used as it is, or replaced by FactoryServer if empty.
645 * \param hostname name of the host of the container, without domain names.
646 * \return the path under the form /Containers/hostname/containerName
647 * \sa ContainerName(const char *containerName)
649 // ============================================================================
652 SALOME_NamingService::
653 BuildContainerNameForNS(const Engines::MachineParameters& params,
654 const char *hostname)
656 string ret = "/Containers/";
659 ret += ContainerName(params);
664 // ============================================================================
665 /*! \brief search a name in current directory.
667 * Search a name in the current directory. after call, the current directory
668 * is changed to the directory containing the last occurence of name found.
669 * If no occurence found (see return value), current directory remains
672 * \param name the name to search.
673 * \return number of occurences found.
674 * \sa Change_Directory(const char* Path)
676 // ============================================================================
678 int SALOME_NamingService::Find(const char* name)
679 throw(ServiceUnreachable)
681 MESSAGE("BEGIN OF Find " << name);
683 Utils_Locker lock (&_myMutex);
685 CORBA::Long occurence_number = 0 ;
689 _Find(name, occurence_number);
692 catch (CORBA::SystemException&)
694 INFOS("!!!Find() : CORBA::SystemException : unable to contact"
695 << " the naming service");
696 throw ServiceUnreachable();
699 return occurence_number;
702 // ============================================================================
703 /*! \brief Creates a directory (context_name)
705 * Creates a directory (context_name) relative to the current directory
706 * (current context) or relative to the root directory (root context), if
707 * the path given begins with a '/'.
708 * If the NamingService is out, the exception ServiceUnreachable is thrown.
709 * \param Path A relative or absolute pathname to store the object reference.
710 * If the pathname begins with a '/', pathname is taken
711 * as an absolute pathname. Else, pathname is taken as a relative
712 * path, to current context. Prefer absolute pathname, relative
713 * pathname are not safe, when SALOME_NamingService object is
714 * shared or use in multithreaded context.
715 * \return true if successfull
716 * (creation not strictly garanteed if true, because Register may
717 * catch some specific unlikely exception without throw anything
718 * --- to be corrected ---)
719 * \sa RegisterCORBA::Object_ptr ObjRef, const char* Path)
721 // ============================================================================
723 bool SALOME_NamingService::Create_Directory(const char* Path)
724 throw(ServiceUnreachable)
726 MESSAGE("BEGIN OF Create_Directory");
728 Utils_Locker lock (&_myMutex);
732 // --- if path empty, nothing to create, no context change
737 // --- if path ='/', nothing to create, only change to root_context
741 MESSAGE("Create Directory '/', just change to root_context");
742 _current_context = _root_context;
746 // --- path must end with '/'
748 if (path[path.length()-1] != '/') path += '/';
750 Register(CORBA::Object::_nil(), path.c_str());
754 // ============================================================================
755 /*! \brief change current directory to the given path
757 * change the current directory to the given path in parameter.
758 * Warning: avoid use when the SALOME_NamingService instance is shared by
759 * several threads (current context may be modified by another thread).
760 * If the path is empty, nothing done return OK.
761 * If Path ="/", the current directory changes to the root directory.
762 * If the NamingService is out, the exception ServiceUnreachable is thrown.
763 * \param Path the new current directory
764 * \return true if the change succeeded
766 // ============================================================================
768 bool SALOME_NamingService::Change_Directory(const char* Path)
769 throw(ServiceUnreachable)
771 // MESSAGE("BEGIN OF Change_Directory " << Path);
772 Utils_Locker lock (&_myMutex);
776 // --- if path empty, nothing to do
781 // --- if path ='/', nothing to resolve, only change to root_context
785 // MESSAGE("Change_Directory is called to go to the root_context");
786 _current_context = _root_context;
790 CosNaming::NamingContext_var current_context = _current_context;
791 bool changeOK = false;
793 // --- replace _current_context with _root_context if Path begins whith '/'
796 current_context = _root_context;
798 // --- need to resolve directory path
800 ASSERT(!CORBA::is_nil(current_context));
802 if (path[path.length()-1] != '/') path += '/';
804 CosNaming::Name context_name;
805 vector<string> splitPath;
806 int dimension_resultat = _createContextNameDir(path.c_str(),
811 // --- Context creation
815 CORBA::Object_var obj = current_context->resolve(context_name);
816 current_context = CosNaming::NamingContext::_narrow(obj);
817 ASSERT(!CORBA::is_nil(current_context));
818 _current_context = current_context;
822 catch (CosNaming::NamingContext::NotFound& ex)
824 CosNaming::Name n = ex.rest_of_name;
826 if (ex.why == CosNaming::NamingContext::missing_node)
827 MESSAGE( "Change_Directory() : " << (char *) n[0].id
828 << " (" << (char *) n[0].kind << ") not found");
829 if (ex.why == CosNaming::NamingContext::not_context)
830 INFOS("Change_Directory() : " << (char *) n[0].id
831 << " (" << (char *) n[0].kind
832 << ") is not a context" );
833 if (ex.why == CosNaming::NamingContext::not_object)
834 INFOS( "Change_Directory() : " << (char *) n[0].id
835 << " (" << (char *) n[0].kind
836 << ") is not an object" );
839 catch (CosNaming::NamingContext::CannotProceed&)
841 INFOS("Change_Directory(): CosNaming::NamingContext::CannotProceed");
844 catch (CosNaming::NamingContext::InvalidName&)
846 INFOS("Change_Directory(): CosNaming::NamingContext::InvalidName");
849 catch (CORBA::SystemException&)
851 INFOS("Change_Directory():CORBA::SystemException : unable to contact"
852 << "the naming service");
853 throw ServiceUnreachable();
859 // ============================================================================
860 /*! \brief get the current directory path
862 * Get the current directory path.
863 * If the NamingService is out, the exception ServiceUnreachable is thrown.
864 * \return the path of the current_context
865 * \sa _current_directory
867 // ============================================================================
869 char* SALOME_NamingService::Current_Directory()
870 throw(ServiceUnreachable)
872 MESSAGE("BEGIN OF Current_Directory");
874 Utils_Locker lock (&_myMutex);
876 CosNaming::NamingContext_var ref_context = _current_context;
878 vector<string> splitPath;
881 bool notFound = true ;
883 // --- start search from root context
885 _current_context = _root_context ;
889 _current_directory(splitPath, lengthPath, ref_context, notFound );
892 catch (CORBA::SystemException&)
894 INFOS("Current_Directory(): CORBA::SystemException: unable to contact"
895 << " the naming service" )
896 throw ServiceUnreachable();
900 lengthPath = splitPath.size();
901 for (int k = 0 ; k < lengthPath ;k++)
904 path += splitPath[k];
908 _current_context = ref_context ;
910 return strdup(path.c_str());
913 // ============================================================================
914 /*! \brief list recursively all objects in the current context
916 * List and print via trace all directories and objects in the current
917 * context. Trace must be activated: compile option _DEBUG_
918 * If the NamingService is out, the exception ServiceUnreachable is thrown
920 // ============================================================================
922 void SALOME_NamingService::list()
923 throw(ServiceUnreachable)
925 MESSAGE("Begin of list");
927 Utils_Locker lock (&_myMutex)
930 CosNaming::BindingList_var binding_list;
931 CosNaming::BindingIterator_var binding_iterator;
932 CosNaming::Binding_var binding ;
934 unsigned long nb = 0 ; // --- only for the BindingIterator use,
935 // to access the bindings
937 CosNaming::NamingContext_var ref_context = _current_context;
939 _current_context->list(nb, binding_list, binding_iterator) ;
941 if (! CORBA::is_nil(binding_iterator))
943 while (binding_iterator->next_one(binding))
945 CosNaming::Name bindingName = binding->binding_name;
947 if (binding->binding_type == CosNaming::ncontext)
949 MESSAGE( "Context : " << bindingName[0].id );
953 Change_Directory(bindingName[0].id);
956 catch (ServiceUnreachable&)
958 INFOS( "list(): ServiceUnreachable" )
959 throw ServiceUnreachable();
963 _current_context = ref_context ;
966 else if (binding->binding_type == CosNaming::nobject)
968 MESSAGE( "Object : " << bindingName[0].id );
972 binding_iterator->destroy();
976 // ============================================================================
977 /*! \brief list all the objects in the current directory.
979 * get a list of all the objects in the current directory, without recursion
980 * on the subdirectories. Only the objects are listed, not the directories.
981 * If the NamingService is out, the exception ServiceUnreachable is thrown.
982 * \return list of strings with objects found.
983 * \sa vector<string> list_directory_recurs()
985 // ============================================================================
987 vector<string> SALOME_NamingService::list_directory()
988 throw(ServiceUnreachable)
990 // MESSAGE("list_directory");
991 vector<string> dirList ;
994 CosNaming::BindingList_var binding_list;
995 CosNaming::BindingIterator_var binding_iterator;
996 CosNaming::Binding_var binding ;
998 unsigned long nb = 0 ; // --- only for the BindingIterator use,
999 // to access the bindings
1001 CosNaming::NamingContext_var ref_context = _current_context;
1003 _current_context->list(nb, binding_list, binding_iterator);
1005 if (binding_iterator->_is_nil())
1008 while (binding_iterator->next_one(binding))
1010 CosNaming::Name bindingName = binding->binding_name;
1012 if (binding->binding_type == CosNaming::nobject)
1014 // remove memory leak
1015 // dirList.push_back(CORBA::string_dup(bindingName[0].id));
1016 dirList.push_back(string(bindingName[0].id));
1020 // for (unsigned int ind = 0; ind < dirList.size(); ind++)
1021 // MESSAGE("list_directory : Object : " << dirList[ind]);
1023 binding_iterator->destroy();
1029 // ============================================================================
1030 /*! \brief list all the subdirectories in the current directory.
1032 * get a list of all the subdirectories in the current directory,
1033 * without recursion on the subdirectories.
1034 * Only the subdirectories are listed, not the objects.
1035 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1036 * \return list of strings with directories found.
1037 * \sa vector<string> list_directory()
1039 // ============================================================================
1041 vector<string> SALOME_NamingService::list_subdirs()
1042 throw(ServiceUnreachable)
1044 MESSAGE("list_subdirs");
1045 vector<string> dirList ;
1048 CosNaming::BindingList_var binding_list;
1049 CosNaming::BindingIterator_var binding_iterator;
1050 CosNaming::Binding_var binding ;
1052 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1053 // to access the bindings
1055 CosNaming::NamingContext_var ref_context = _current_context;
1057 _current_context->list(nb, binding_list, binding_iterator) ;
1059 if (binding_iterator->_is_nil())
1062 while (binding_iterator->next_one(binding))
1064 CosNaming::Name bindingName = binding->binding_name;
1066 if (binding->binding_type == CosNaming::ncontext)
1068 dirList.push_back(bindingName[0].id.in());
1072 for (unsigned int ind = 0; ind < dirList.size(); ind++)
1073 MESSAGE("list_directory : Object : " << dirList[ind]);
1075 binding_iterator->destroy();
1080 // ============================================================================
1081 /*! \brief list all the objects in the current directory and subdirectories.
1083 * get a list of all the objects in the current directory, with recursion
1084 * on the subdirectories. Only the objects are listed, not the directories.
1085 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1086 * \return list of strings with objects found.
1087 * \sa vector<string> list_directory()
1089 // ============================================================================
1091 vector<string> SALOME_NamingService::list_directory_recurs()
1092 throw(ServiceUnreachable)
1094 MESSAGE("list_directory_recurs");
1096 Utils_Locker lock (&_myMutex);
1098 vector<string> dirList ;
1100 char* currentDir = Current_Directory();
1102 _list_directory_recurs(dirList, "", currentDir);
1109 // ============================================================================
1110 /*! \brief destroy an entry in naming service.
1112 * Destroy an association Path - Object Reference.
1113 * If the NamingService is out, the exception ServiceUnreachable is thrown
1114 * \param Path object path
1116 // ============================================================================
1118 void SALOME_NamingService::Destroy_Name(const char* Path)
1119 throw(ServiceUnreachable)
1121 MESSAGE("BEGIN OF Destroy_Name " << Path);
1123 Utils_Locker lock (&_myMutex);
1127 // --- if path empty, nothing to do
1132 // --- if path = '/' not applicable, nothing to do
1137 // --- if path begins with '/', set current directory to root context
1140 _current_context = _root_context;
1142 // --- context of the directory containing the object
1144 CosNaming::Name context_name;
1145 vector<string> splitPath;
1146 int dimension_resultat = _createContextNameDir(path.c_str(),
1153 if (dimension_resultat > 0)
1155 // --- path contains a directory, not only an object name
1156 // switch to the new directory (or return if directory not found)
1160 CORBA::Object_var obj = _current_context->resolve(context_name);
1161 _current_context = CosNaming::NamingContext::_narrow(obj);
1165 catch (CosNaming::NamingContext::NotFound &ex)
1167 // --- failed to resolve
1170 CosNaming::Name n = ex.rest_of_name;
1172 if (ex.why == CosNaming::NamingContext::missing_node)
1173 INFOS( "Destroy_Name(): " << (char *) n[0].id
1174 << " (" << (char *) n[0].kind << ") not found" );
1175 if (ex.why == CosNaming::NamingContext::not_context)
1176 INFOS( "Destroy_Name() : " << (char *) n[0].id
1177 << " (" << (char *) n[0].kind
1178 << ") is not a context" );
1179 if (ex.why == CosNaming::NamingContext::not_object)
1180 INFOS( "Destroy_Name() : " << (char *) n[0].id
1181 << " (" << (char *) n[0].kind
1182 << ") is not an object" );
1185 catch (CosNaming::NamingContext::InvalidName &)
1187 INFOS("Destroy_Name: CosNaming::NamingContext::InvalidName");
1190 catch (CosNaming::NamingContext::CannotProceed &)
1192 INFOS("Destroy_Name: CosNaming::NamingContext::CannotProceed");
1195 catch (CORBA::SystemException&)
1197 INFOS("Destroy_Name : CORBA::SystemException: "
1198 << "unable to contact the naming service");
1199 throw ServiceUnreachable();
1202 if (! exist) return;
1205 ASSERT(!CORBA::is_nil(_current_context));
1207 // --- The current directory is now the directory where the object should
1210 int sizePath = splitPath.size();
1211 if (sizePath > dimension_resultat)
1213 ASSERT(sizePath == dimension_resultat+1);
1214 context_name.length(1);
1218 // --- the last element is an object and not a directory
1220 context_name[0].id =
1221 CORBA::string_dup(splitPath[dimension_resultat].c_str());
1222 context_name[0].kind = CORBA::string_dup("object");
1223 SCRUTE(context_name[0].id);
1225 _current_context->unbind(context_name);
1226 MESSAGE("The object " << context_name[0].id << " has been deleted");
1229 catch (CosNaming::NamingContext::NotFound& ex)
1231 CosNaming::Name n = ex.rest_of_name;
1233 if (ex.why == CosNaming::NamingContext::missing_node)
1234 INFOS( "Destroy_Name() : " << (char *) n[0].id
1235 << " (" << (char *) n[0].kind << ") not found" );
1236 if (ex.why == CosNaming::NamingContext::not_context)
1237 INFOS( "Destroy_Name() : " << (char *) n[0].id
1238 << " (" << (char *) n[0].kind
1239 << ") is not a context" );
1240 if (ex.why == CosNaming::NamingContext::not_object)
1241 INFOS( "Destroy_Name() : " << (char *) n[0].id
1242 << " (" << (char *) n[0].kind
1243 << ") is not an object" );
1246 catch (CosNaming::NamingContext::CannotProceed&)
1248 INFOS( "Destroy_Name(): CosNaming::NamingContext::CannotProceed");
1251 catch (CosNaming::NamingContext::InvalidName&)
1253 INFOS( "Destroy_Name(): CosNaming::NamingContext::InvalidName");
1256 catch (CORBA::SystemException&)
1258 INFOS( "Destroy_Name(): CORBA::SystemException: unable to contact"
1259 << " the naming service");
1260 throw ServiceUnreachable();
1265 // ============================================================================
1266 /*! \brief Destroy an empty directory
1268 * Destroy an empty directory in Naming Service.
1269 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1270 * \param Path directory path
1272 // ============================================================================
1274 void SALOME_NamingService::Destroy_Directory(const char* Path)
1275 throw(ServiceUnreachable)
1277 MESSAGE("BEGIN OF Destroy_Directory " << Path);
1279 Utils_Locker lock (&_myMutex);
1283 // --- if path empty, nothing to do
1288 // --- if path begins with '/', set current directory to root context
1291 _current_context = _root_context;
1293 CosNaming::NamingContext_var ref_context = _current_context;
1295 // --- path must ends with '/' for a directory
1297 if (path[path.size() -1] != '/')
1300 // --- context of the directory
1302 CosNaming::Name context_name;
1303 vector<string> splitPath;
1304 int dimension_resultat = _createContextNameDir(path.c_str(),
1310 if (dimension_resultat > 0)
1312 // --- path contains a directory, not only an object name
1313 // switch to the new directory (or return if directory not found)
1317 CORBA::Object_var obj = _current_context->resolve(context_name);
1318 _current_context = CosNaming::NamingContext::_narrow(obj);
1322 catch (CosNaming::NamingContext::NotFound &ex)
1324 // --- failed to resolve
1327 CosNaming::Name n = ex.rest_of_name;
1329 if (ex.why == CosNaming::NamingContext::missing_node)
1330 INFOS( "Destroy_Directory(): " << (char *) n[0].id
1331 << " (" << (char *) n[0].kind << ") not found" );
1332 if (ex.why == CosNaming::NamingContext::not_context)
1333 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1334 << " (" << (char *) n[0].kind
1335 << ") is not a context" );
1336 if (ex.why == CosNaming::NamingContext::not_object)
1337 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1338 << " (" << (char *) n[0].kind
1339 << ") is not an object" );
1342 catch (CosNaming::NamingContext::InvalidName &)
1344 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1347 catch (CosNaming::NamingContext::CannotProceed &)
1349 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1352 catch (CORBA::SystemException&)
1354 INFOS("Destroy_Directory : CORBA::SystemException: "
1355 << "unable to contact the naming service");
1356 throw ServiceUnreachable();
1359 if (! exist) return;
1362 ASSERT(!CORBA::is_nil(_current_context));
1364 // --- Context Destruction
1366 bool isContextDestroyed = false;
1369 _current_context->destroy();
1370 MESSAGE( "The context " << path << " has been deleted" );
1371 isContextDestroyed = true;
1374 catch (CosNaming::NamingContext::NotEmpty&)
1376 INFOS( "Destroy_Directory(): CosNaming::NamingContext::NoEmpty "
1377 << path << " is not empty" );
1380 catch (CORBA::SystemException&)
1382 INFOS( "Destroy_Directory():CORBA::SystemException : "
1383 << "unable to contact the naming service");
1384 throw ServiceUnreachable();
1387 // --- go to the reference directory
1389 _current_context = ref_context ;
1391 ASSERT(!CORBA::is_nil(_current_context));
1393 if (isContextDestroyed)
1397 _current_context->unbind(context_name);
1398 MESSAGE( "The bind to the context "
1399 << context_name[0].id
1400 << " has been deleted" );
1403 catch (CosNaming::NamingContext::NotFound& ex)
1405 CosNaming::Name n = ex.rest_of_name;
1407 if (ex.why == CosNaming::NamingContext::missing_node)
1408 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1409 << " (" << (char *) n[0].kind << ") not found" );
1410 if (ex.why == CosNaming::NamingContext::not_context)
1411 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1412 << " (" << (char *) n[0].kind
1413 << ") is not a context" );
1414 if (ex.why == CosNaming::NamingContext::not_object)
1415 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1416 << " (" << (char *) n[0].kind
1417 << ") is not an object" );
1420 catch (CosNaming::NamingContext::CannotProceed&)
1422 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1425 catch (CosNaming::NamingContext::InvalidName&)
1427 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1430 catch (CORBA::SystemException&)
1432 INFOS("Destroy_Directory:CORBA::SystemException : unable to contact"
1433 << " the naming service");
1434 throw ServiceUnreachable();
1439 // ============================================================================
1440 /*! \brief Destroy a directory with its contents.
1442 * Destroy the objects associations in a directory, and the directory itself,
1443 * if there is no subdirectories.
1444 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1445 * \param Path the directory path.
1447 // ============================================================================
1449 void SALOME_NamingService::Destroy_FullDirectory(const char* Path)
1450 throw(ServiceUnreachable)
1452 MESSAGE("begin of Destroy_FullDirectory " << Path);
1453 if( Change_Directory(Path) )
1455 vector<string> contList = list_directory();
1457 for (unsigned int ind = 0; ind < contList.size(); ind++)
1458 Destroy_Name(contList[ind].c_str());
1460 Destroy_Directory(Path);
1464 // ============================================================================
1465 /*! \brief initialize root context (root directory)
1467 * the root context initialisation must be done when the SALOME_NamingService
1468 * instance is created and before any othe call. See constructors.
1470 // ============================================================================
1472 void SALOME_NamingService::_initialize_root_context()
1474 //MESSAGE("Get the root context");
1478 CORBA::Object_var obj = _orb->resolve_initial_references("NameService");
1479 _root_context = CosNaming::NamingContext::_narrow(obj);
1480 _current_context = _root_context ;
1481 ASSERT(!CORBA::is_nil(_root_context));
1484 catch (CORBA::SystemException&)
1486 INFOS("CORBA::SystemException: unable to contact the naming service");
1487 throw ServiceUnreachable();
1492 INFOS("Unknown Exception: unable to contact the naming service");
1493 throw ServiceUnreachable();
1497 // ============================================================================
1498 /*! \brief transform a string path in CosNaming structure.
1500 * Transform a path given as a string in a CosNaming structure.
1501 * \param path a relative or absolute path, with or without an object.
1502 * An absolute path begins with '/'.
1503 * A path without an object ends with '/'.
1504 * \param context_name CosNaming structure to put the path.
1505 * \param splitPath a vector of string with subdirectories and final
1507 * \param onlyDir if true, final object (if any) is ommited
1509 * if false, final object (if any) is included in
1511 * \return dimension of context_name
1513 // ============================================================================
1516 SALOME_NamingService::_createContextNameDir(string path,
1517 CosNaming::Name& context_name,
1518 vector<string>& splitPath,
1524 string::size_type begIdx, endIdx;
1525 const string delims("/");
1526 splitPath.resize(0);
1527 bool endWithDelim = false;
1529 begIdx = path.find_first_not_of(delims);
1530 while (begIdx != string::npos)
1532 endIdx = path.find_first_of(delims, begIdx);
1533 if (endIdx == path.length()-1)
1534 endWithDelim = true;
1535 if (endIdx == string::npos)
1536 endIdx = path.length();
1537 int lsub = endIdx - begIdx;
1539 splitPath.push_back(path.substr(begIdx, lsub));
1540 begIdx = path.find_first_not_of(delims, endIdx);
1544 if (onlyDir) // only directory part
1546 dim = splitPath.size()-1; // omit final object
1547 if (endWithDelim) // unless the path ends with a delimiter
1549 endWithDelim = true;
1552 dim = splitPath.size(); // directories and final object
1554 context_name.length(dim);
1555 for (int i=0; i<dim; i++)
1557 // SCRUTE(splitPath[i]);
1558 context_name[i].id = CORBA::string_dup(splitPath[i].c_str());
1559 if (!endWithDelim && (i == dim-1)) // here, the last string is an object
1561 context_name[i].kind = CORBA::string_dup("object");
1562 // MESSAGE("--- " <<splitPath[i] <<".object");
1566 context_name[i].kind = CORBA::string_dup("dir");
1567 // MESSAGE("--- " <<splitPath[i] <<".dir");
1573 // ============================================================================
1574 /*! \brief search a name in current directory.
1576 * Search a name in the current directory. after call, the current directory
1577 * is changed to the directory containing the last occurence of name found.
1578 * If no occurence found (see return value), current directory remains
1579 * unchanged. The call is recursive.
1581 * \param name the name to search.
1582 * \param occurence_number number of occurence already found (incremented)
1584 // ============================================================================
1586 void SALOME_NamingService::_Find(const char* name,
1587 CORBA::Long& occurence_number)
1589 MESSAGE("BEGIN OF _Find "<< occurence_number << " " << name);
1591 CosNaming::BindingList_var binding_list;
1592 CosNaming::BindingIterator_var binding_iterator;
1593 CosNaming::Binding_var binding;
1595 unsigned long nb = 0 ; // --- only for the use of the BindingIterator,
1596 // to access the bindings
1598 CosNaming::NamingContext_var ref_context = _current_context;
1599 CosNaming::NamingContext_var found_context = _current_context;
1601 _current_context->list(nb, binding_list, binding_iterator) ;
1603 if (! CORBA::is_nil(binding_iterator))
1605 while (binding_iterator->next_one(binding))
1607 CosNaming::Name bindingName = binding->binding_name;
1609 if (binding->binding_type == CosNaming::ncontext)
1611 // --- We work on a directory,
1612 // the search should be done in this directory
1614 Change_Directory(bindingName[0].id);
1615 _Find(name, occurence_number);
1617 // --- We'll go back to the initial context
1619 _current_context = ref_context ;
1622 else if (binding->binding_type == CosNaming::nobject)
1624 // --- We work on an object...
1626 if (!strcmp( bindingName[0].id, name))
1628 //MESSAGE("One occurence was found");
1631 // --- We keep in memory the directory where
1632 // one occurence was found
1634 found_context = _current_context ;
1639 binding_iterator->destroy();
1641 // --- We go to the last directory where an occurence was found
1643 _current_context = found_context;
1645 SCRUTE(occurence_number);
1648 // ============================================================================
1649 /*! \brief find the current directory path.
1651 * Parse the naming service tree to find the current context and give the
1652 * associated directory path (relative to root context).
1654 * \param lengthResult
1655 * \param contextToFind
1658 // ============================================================================
1661 SALOME_NamingService::
1662 _current_directory(vector<string>& splitPath,
1664 CosNaming::NamingContext_var contextToFind,
1667 MESSAGE("BEGIN OF _current_Directory");
1669 CosNaming::BindingList_var binding_list;
1670 CosNaming::BindingIterator_var binding_iterator;
1671 CosNaming::Binding_var binding;
1673 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1674 // to access the bindings
1676 CosNaming::NamingContext_var ref_context = _current_context;
1677 CosNaming::NamingContext_var temp_context = _current_context;
1679 _current_context->list(nb, binding_list, binding_iterator);
1681 if ( !binding_iterator->_is_nil() )
1683 while ((binding_iterator->next_one(binding)) && notFound)
1685 CosNaming::Name bindingName = binding->binding_name;
1687 if (binding->binding_type == CosNaming::ncontext)
1689 // --- directory, search in it
1691 const char* bindingNameid=bindingName[0].id;
1692 splitPath.push_back(bindingNameid);
1695 CORBA::Object_var obj = _current_context->resolve(bindingName);
1696 temp_context = CosNaming::NamingContext::_narrow(obj);
1698 if (temp_context->_is_equivalent(contextToFind))
1700 MESSAGE("The context is found, we stop the search");
1707 SCRUTE(bindingName[0].id);
1708 Change_Directory(bindingName[0].id);
1709 _current_directory(splitPath,
1716 // --- go back to the initial context
1718 _current_context = ref_context;
1720 MESSAGE("Just before the delete of "
1721 << splitPath[lengthResult-1]);
1722 splitPath.pop_back();
1729 binding_iterator->destroy();
1732 // --- return to the last directory where an occurence was found
1734 _current_context = ref_context ;
1738 // ============================================================================
1739 /*! \brief list recursively all objects in the given directory and subdirs.
1741 * get a list of all the objects in the current directory, with recursion
1742 * on the subdirectories. Only the objects are listed, not the directories.
1743 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1744 * _current_context must refer to absCurDirectory.
1746 * \param myList The list that will be filled.
1747 * \param relativeSubDir The directory relative to absCurDirectory in which
1748 * the objects are found.
1749 * \param absCurDirectory The current directory, absolute path
1751 // ============================================================================
1753 void SALOME_NamingService::_list_directory_recurs(vector<string>& myList,
1754 string relativeSubDir,
1755 string absCurDirectory)
1757 CosNaming::BindingList_var binding_list;
1758 CosNaming::BindingIterator_var binding_iterator;
1759 CosNaming::Binding_var binding ;
1761 unsigned long nb = 0 ; // --- only for thethe use of BindingIterator
1762 // to access the bindings
1766 CosNaming::NamingContext_var ref_context = _current_context;
1768 if (! relativeSubDir.empty())
1770 Change_Directory(relativeSubDir.c_str());
1771 absDir = absCurDirectory + "/" + relativeSubDir;
1775 absDir = absCurDirectory;
1778 _current_context->list(nb, binding_list, binding_iterator) ;
1780 if (! CORBA::is_nil(binding_iterator))
1782 while (binding_iterator->next_one(binding))
1784 CosNaming::Name bindingName = binding->binding_name;
1786 if (binding->binding_type == CosNaming::ncontext)
1788 string relativeSdir(bindingName[0].id);
1789 _list_directory_recurs(myList, relativeSdir, absDir);
1792 else if (binding->binding_type == CosNaming::nobject)
1794 string objName(bindingName[0].id);
1795 string elt = absDir + "/" + objName;
1797 myList.push_back(elt);
1801 binding_iterator->destroy();
1803 if (! relativeSubDir.empty())
1805 _current_context = ref_context;
1809 // ============================================================================
1810 /*! \brief return a stringified reference of root context
1812 * \return a stringified reference of root context
1814 // ============================================================================
1816 char * SALOME_NamingService::getIORaddr()
1818 return _orb->object_to_string(_root_context);