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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
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 '/'
137 _current_context = _root_context;
140 // --- the resolution of the directory path has to be done
141 // to place the current_context to the correct node
143 CosNaming::Name context_name;
144 vector<string> splitPath;
145 int dimension_resultat = _createContextNameDir(Path,
150 CORBA::Boolean not_exist = false;
152 if (dimension_resultat > 0)
154 // A directory is treated (not only an object name)
155 // test if the directory where ObjRef should be recorded already exists
156 // If not, create the new context
160 CORBA::Object_var obj = _current_context->resolve(context_name);
161 _current_context = CosNaming::NamingContext::_narrow(obj);
164 catch (CosNaming::NamingContext::NotFound &)
166 // --- failed to resolve, therefore assume cold start
170 catch (CosNaming::NamingContext::InvalidName &)
172 INFOS("Register() : CosNaming::NamingContext::InvalidName");
175 catch (CosNaming::NamingContext::CannotProceed &)
177 INFOS("Register() : CosNaming::NamingContext::CannotProceed");
180 catch (CORBA::SystemException&)
182 INFOS("Register() : CORBA::SystemException: "
183 << "unable to contact the naming service");
184 throw ServiceUnreachable();
191 context_name.length(1);
192 for (int i = 0 ; i < dimension_resultat ;i++)
195 CORBA::string_dup(splitPath[i].c_str());
196 context_name[0].kind = CORBA::string_dup("dir");
197 // SCRUTE(_context_name[0].id);
198 // --- check if the path is created
201 // --- if the context is already created, nothing to do
202 CORBA::Object_var obj =
203 _current_context->resolve(context_name);
205 CosNaming::NamingContext::_narrow(obj);
208 catch (CosNaming::NamingContext::NotFound &)
210 // --- the context must be created
211 CosNaming::NamingContext_var temp_context =
212 _current_context->bind_new_context(context_name);
213 _current_context = temp_context;
218 catch (CosNaming::NamingContext::AlreadyBound&)
220 INFOS("Register() : CosNaming::NamingContext::AlreadyBound");
223 catch (CosNaming::NamingContext::NotFound& ex)
225 CosNaming::Name n = ex.rest_of_name;
227 if (ex.why == CosNaming::NamingContext::missing_node)
228 INFOS("Register() : " << (char *) n[0].id
229 << " (" << (char *) n[0].kind << ") not found");
231 if (ex.why == CosNaming::NamingContext::not_context)
232 INFOS("Register() : " << (char *) n[0].id
233 << " (" << (char *) n[0].kind
234 << ") is not a context");
236 if (ex.why == CosNaming::NamingContext::not_object)
237 INFOS("Register() : " << (char *) n[0].id
238 << " (" << (char *) n[0].kind
239 << ") is not an object");
242 catch (CosNaming::NamingContext::CannotProceed&)
244 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
247 catch (CosNaming::NamingContext::InvalidName&)
249 INFOS("Register(): CosNaming::NamingContext::InvalidName");
252 catch (CORBA::SystemException&)
254 INFOS("Register():CORBA::SystemException: "
255 << "unable to contact the naming service");
256 throw ServiceUnreachable();
261 // --- The current directory is now the directory where the object should
264 int sizePath = splitPath.size();
265 if (sizePath > dimension_resultat)
267 ASSERT(sizePath == dimension_resultat+1);
268 context_name.length(1);
272 // --- the last element is an object and not a directory
275 CORBA::string_dup(splitPath[dimension_resultat].c_str());
276 context_name[0].kind = CORBA::string_dup("object");
277 //SCRUTE(context_name[0].id);
279 _current_context->bind(context_name, ObjRef);
282 catch (CosNaming::NamingContext::NotFound& ex)
284 CosNaming::Name n = ex.rest_of_name;
286 if (ex.why == CosNaming::NamingContext::missing_node)
287 INFOS("Register() : " << (char *) n[0].id
288 << " (" << (char *) n[0].kind << ") not found");
290 if (ex.why == CosNaming::NamingContext::not_context)
291 INFOS("Register() : " << (char *) n[0].id
292 << " (" << (char *) n[0].kind
293 << ") is not a context");
295 if (ex.why == CosNaming::NamingContext::not_object)
296 INFOS("Register() : " << (char *) n[0].id
297 << " (" << (char *) n[0].kind
298 << ") is not an object");
301 catch (CosNaming::NamingContext::CannotProceed&)
303 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
306 catch (CosNaming::NamingContext::InvalidName&)
308 INFOS("Register(): CosNaming::NamingContext::InvalidName");
311 catch (CosNaming::NamingContext::AlreadyBound&)
313 INFOS("Register(): CosNaming::NamingContext::AlreadyBound, "
314 << "object will be rebind");
315 _current_context->rebind(context_name, ObjRef);
318 catch (CORBA::SystemException&)
320 INFOS("!!!Register(): CORBA::SystemException: "
321 << "unable to contact the naming service");
322 throw ServiceUnreachable();
327 // ============================================================================
328 /*! \brief get the CORBA object reference associated to a name.
330 * get the CORBA object reference associated to a complete name with a path.
331 * If the NamingService is out, the exception ServiceUnreachable is thrown
332 * \param Path pathname. If the pathname begins with a '/', pathname is taken
333 * as an absolute pathname. Else, pathname is taken as a relative
334 * path, to current context. Prefer absolute pathname, relative
335 * pathname are not safe, when SALOME_NamingService object is
336 * shared or use in multithreaded context.
337 * \return the object reference if it exists under the pathname,
338 * or nil reference in other cases.
339 * \sa Register(CORBA::Object_ptr ObjRef, const char* Path),
340 * Change_Directory(const char* Path)
342 // ============================================================================
344 CORBA::Object_ptr SALOME_NamingService::Resolve(const char* Path)
345 throw(ServiceUnreachable)
347 MESSAGE("BEGIN OF Resolve: " << Path);
349 Utils_Locker lock (&_myMutex);
351 // --- _current_context is replaced to the _root_context
352 // if the Path begins whith '/'
356 _current_context = _root_context;
359 // --- the resolution of the directory path has to be done
360 // to place the current_context to the correct node
362 CosNaming::Name context_name;
363 vector<string> splitPath;
364 int dimension_resultat = _createContextNameDir(Path,
369 ASSERT(!CORBA::is_nil(_current_context));
371 CORBA::Object_ptr obj = CORBA::Object::_nil();
375 obj = _current_context->resolve(context_name);
378 catch (CosNaming::NamingContext::NotFound& ex)
380 CosNaming::Name n = ex.rest_of_name;
382 if (ex.why == CosNaming::NamingContext::missing_node)
383 INFOS("Resolve() : " << (char *) n[0].id
384 << " (" << (char *) n[0].kind << ") not found");
386 if (ex.why == CosNaming::NamingContext::not_context)
388 << (char *) n[0].id << " (" << (char *) n[0].kind
389 << ") is not a context");
391 if (ex.why == CosNaming::NamingContext::not_object)
392 INFOS("Resolve() : " << (char *) n[0].id
393 << " (" << (char *) n[0].kind
394 << ") is not an object");
397 catch (CosNaming::NamingContext::CannotProceed&)
399 INFOS("Resolve(): CosNaming::NamingContext::CannotProceed");
402 catch (CosNaming::NamingContext::InvalidName&)
404 INFOS("Resolve(): CosNaming::NamingContext::InvalidName");
407 catch (CORBA::SystemException&)
409 INFOS("Resolve():CORBA::SystemException : unable to contact"
410 << "the naming service");
411 throw ServiceUnreachable();
417 // ============================================================================
418 /*! \brief get the CORBA object reference associated to an uncomplete name.
420 * get the CORBA object reference associated to an uncomplete name with a
421 * path. Look for the first occurence of name*.
422 * If the NamingService is out, the exception ServiceUnreachable is thrown
423 * \param Path pathname under the form "/path/name" (Absolute reference !)
424 * search the fist reference like "/path(.dir)/name*(.kind)"
425 * \return the object reference if found, or nil reference.
426 * \sa Resolve(const char* Path)
428 // ============================================================================
430 CORBA::Object_ptr SALOME_NamingService::ResolveFirst(const char* Path)
431 throw(ServiceUnreachable)
433 MESSAGE("ResolveFirst");
435 Utils_Locker lock (&_myMutex);
438 string thePath = Path;
439 string basePath = "";
440 string name = thePath;
442 string::size_type idx = thePath.rfind('/');
444 if (idx != string::npos) // at least one '/' found
446 basePath = thePath.substr(0, idx);
447 name = thePath.substr(idx + 1);
452 CORBA::Object_ptr obj = CORBA::Object::_nil();
455 if (basePath.empty())
458 isOk = Change_Directory(basePath.c_str());
462 vector<string> listElem = list_directory();
463 vector<string>::iterator its = listElem.begin();
465 while (its != listElem.end())
469 if ((*its).find(name) == 0)
471 return Resolve((*its).c_str());
481 // ============================================================================
482 /*! \brief find a component instance from hostname, containername,
483 * componentName and number of processors.
485 * find a component instance from hostname, containername, componentName and
486 * number of processors.
487 * If the NamingService is out, the exception ServiceUnreachable is thrown.
488 * \param hostname name of the machine on which the component is searched.
489 * \param containername name of the container in which the component is
491 * \param componentname name of the component we are looking for an existing
493 * \param nbproc in case of multi processor machine, container name is
494 * suffixed with _nbproc.
495 * \return the object reference
497 // ============================================================================
500 SALOME_NamingService::ResolveComponent(const char* hostname,
501 const char* containerName,
502 const char* componentName,
504 throw(ServiceUnreachable)
506 MESSAGE("ResolveComponent");
508 Utils_Locker lock (&_myMutex);
510 string name = "/Containers/";
514 if ( strlen(containerName) != 0 )
520 char *newContainerName = new char[strlen(containerName) + 8];
521 sprintf(newContainerName, "%s_%d", containerName, nbproc);
522 name += newContainerName;
523 delete [] newContainerName;
527 name += containerName;
531 name += componentName;
533 return ResolveFirst(name.c_str());
539 if (Change_Directory(name.c_str()))
541 vector<string> contList = list_subdirs();
543 for (unsigned int ind = 0; ind < contList.size(); ind++)
545 name = contList[ind].c_str();
549 char *str_nbproc = new char[8];
550 sprintf(str_nbproc, "_%d", nbproc);
551 if( strstr(name.c_str(),str_nbproc) == NULL)
552 continue; // check only containers with _%d in name
553 delete [] str_nbproc;
557 name += componentName;
559 CORBA::Object_ptr obj = ResolveFirst(name.c_str());
561 if ( !CORBA::is_nil(obj) )
566 return CORBA::Object::_nil();
570 // ============================================================================
571 /*! \brief provide a default container name if empty.
573 * the given container name is returned unchanged, unless it is empty.
574 * \param containerName
575 * \return container name, where empty input is replaced by "FactoryServer",
577 * \sa BuildContainerNameForNS(const char *containerName, const char *hostname)
579 // ============================================================================
581 string SALOME_NamingService::ContainerName(const char *containerName)
585 if (strlen(containerName) == 0)
586 ret = "FactoryServer";
593 // ============================================================================
594 /*! \brief build a container name, given a MachineParameters struct.
596 * Build a container name with a MachineParameters struct. In case of multi
597 * processor machine, container name is suffixed with _nbproc. nproc equals
598 * (number of nodes)*(number of processor per nodes).
599 * \param params struct from which we get container name (may be
600 * empty), number of nodes and number of processor
602 * \return a container name without the path.
603 * \sa BuildContainerNameForNS(const Engines::MachineParameters& params,
604 * const char *hostname)
606 // ============================================================================
609 SALOME_NamingService::ContainerName(const Engines::MachineParameters& params)
615 else if ( (params.nb_node <= 0) && (params.nb_proc_per_node <= 0) )
617 else if ( params.nb_node == 0 )
618 nbproc = params.nb_proc_per_node;
619 else if ( params.nb_proc_per_node == 0 )
620 nbproc = params.nb_node;
622 nbproc = params.nb_node * params.nb_proc_per_node;
624 string ret = ContainerName(params.container_name);
628 char *suffix = new char[8];
629 sprintf(suffix, "_%d", nbproc);
636 // ============================================================================
637 /*! \brief build a string representing a container in Naming Service.
639 * Build a string representing the absolute pathname of a container in
640 * SALOME_NamingService. This form gives a suffixed containerName in case of
641 * multi processor machine.
642 * \param params struct from which we get container name (may be
643 * empty), number of nodes and number of processor
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 Engines::MachineParameters& params)
649 // ============================================================================
651 string SALOME_NamingService::BuildContainerNameForNS(const char *containerName,
652 const char *hostname)
654 string ret = "/Containers/";
657 ret += ContainerName(containerName);
662 // ============================================================================
663 /*! \brief build a string representing a container in Naming Service.
665 * Build a string representing the absolute pathname of a container in
666 * SALOME_NamingService.
667 * /param params used as it is, or replaced by FactoryServer if empty.
668 * /param hostname name of the host of the container, without domain names.
669 * /return the path under the form /Containers/hostname/containerName
670 * /sa ContainerName(const char *containerName)
672 // ============================================================================
675 SALOME_NamingService::
676 BuildContainerNameForNS(const Engines::MachineParameters& params,
677 const char *hostname)
679 string ret = "/Containers/";
682 ret += ContainerName(params);
687 // ============================================================================
688 /*! \brief search a name in current directory.
690 * Search a name in the current directory. after call, the current directory
691 * is changed to the directory containing the last occurence of name found.
692 * If no occurence found (see return value), current directory remains
695 * \param name the name to search.
696 * \return number of occurences found.
697 * \sa Change_Directory(const char* Path)
699 // ============================================================================
701 int SALOME_NamingService::Find(const char* name)
702 throw(ServiceUnreachable)
704 MESSAGE("BEGIN OF Find " << name);
706 Utils_Locker lock (&_myMutex);
708 CORBA::Long occurence_number = 0 ;
712 _Find(name, occurence_number);
715 catch (CORBA::SystemException&)
717 INFOS("!!!Find() : CORBA::SystemException : unable to contact"
718 << " the naming service");
719 throw ServiceUnreachable();
722 return occurence_number;
725 // ============================================================================
726 /*! \brief Creates a directory (context_name)
728 * Creates a directory (context_name) relative to the current directory
729 * (current context) or relative to the root directory (root context), if
730 * the path given begins with a '/'.
731 * If the NamingService is out, the exception ServiceUnreachable is thrown.
732 * \param Path A relative or absolute pathname to store the object reference.
733 * If the pathname begins with a '/', pathname is taken
734 * as an absolute pathname. Else, pathname is taken as a relative
735 * path, to current context. Prefer absolute pathname, relative
736 * pathname are not safe, when SALOME_NamingService object is
737 * shared or use in multithreaded context.
738 * \return true if successfull
739 * (creation not strictly garanteed if true, because Register may
740 * catch some specific unlikely exception without throw anything
741 * --- to be corrected ---)
742 * \sa RegisterCORBA::Object_ptr ObjRef, const char* Path)
744 // ============================================================================
746 bool SALOME_NamingService::Create_Directory(const char* Path)
747 throw(ServiceUnreachable)
749 MESSAGE("BEGIN OF Create_Directory");
751 Utils_Locker lock (&_myMutex);
755 // --- if path empty, nothing to create, no context change
760 // --- if path ='/', nothing to create, only change to root_context
764 MESSAGE("Create Directory '/', just change to root_context");
765 _current_context = _root_context;
769 // --- path must end with '/'
771 if (path[path.length()-1] != '/') path += '/';
773 Register(CORBA::Object::_nil(), path.c_str());
777 // ============================================================================
778 /*! \brief change current directory to the given path
780 * change the current directory to the given path in parameter.
781 * Warning: avoid use when the SALOME_NamingService instance is shared by
782 * several threads (current context may be modified by another thread).
783 * If the path is empty, nothing done return OK.
784 * If Path ="/", the current directory changes to the root directory.
785 * If the NamingService is out, the exception ServiceUnreachable is thrown.
786 * \param Path the new current directory
787 * \return true if the change succeeded
789 // ============================================================================
791 bool SALOME_NamingService::Change_Directory(const char* Path)
792 throw(ServiceUnreachable)
794 MESSAGE("BEGIN OF Change_Directory " << Path);
795 Utils_Locker lock (&_myMutex);
799 // --- if path empty, nothing to do
804 // --- if path ='/', nothing to resolve, only change to root_context
808 MESSAGE("Change_Directory is called to go to the root_context");
809 _current_context = _root_context;
813 CosNaming::NamingContext_var current_context = _current_context;
814 bool changeOK = false;
816 // --- replace _current_context with _root_context if Path begins whith '/'
819 current_context = _root_context;
821 // --- need to resolve directory path
823 ASSERT(!CORBA::is_nil(current_context));
825 if (path[path.length()-1] != '/') path += '/';
827 CosNaming::Name context_name;
828 vector<string> splitPath;
829 int dimension_resultat = _createContextNameDir(path.c_str(),
834 // --- Context creation
838 CORBA::Object_var obj = current_context->resolve(context_name);
839 current_context = CosNaming::NamingContext::_narrow(obj);
840 ASSERT(!CORBA::is_nil(current_context));
841 _current_context = current_context;
845 catch (CosNaming::NamingContext::NotFound& ex)
847 CosNaming::Name n = ex.rest_of_name;
849 if (ex.why == CosNaming::NamingContext::missing_node)
850 INFOS( "Change_Directory() : " << (char *) n[0].id
851 << " (" << (char *) n[0].kind << ") not found");
852 if (ex.why == CosNaming::NamingContext::not_context)
853 INFOS("Change_Directory() : " << (char *) n[0].id
854 << " (" << (char *) n[0].kind
855 << ") is not a context" );
856 if (ex.why == CosNaming::NamingContext::not_object)
857 INFOS( "Change_Directory() : " << (char *) n[0].id
858 << " (" << (char *) n[0].kind
859 << ") is not an object" );
862 catch (CosNaming::NamingContext::CannotProceed&)
864 INFOS("Change_Directory(): CosNaming::NamingContext::CannotProceed");
867 catch (CosNaming::NamingContext::InvalidName&)
869 INFOS("Change_Directory(): CosNaming::NamingContext::InvalidName");
872 catch (CORBA::SystemException&)
874 INFOS("Change_Directory():CORBA::SystemException : unable to contact"
875 << "the naming service");
876 throw ServiceUnreachable();
882 // ============================================================================
883 /*! \brief get the current directory path
885 * Get the current directory path.
886 * If the NamingService is out, the exception ServiceUnreachable is thrown.
887 * \return the path of the current_context
888 * \sa _current_directory
890 // ============================================================================
892 char* SALOME_NamingService::Current_Directory()
893 throw(ServiceUnreachable)
895 MESSAGE("BEGIN OF Current_Directory");
897 Utils_Locker lock (&_myMutex);
899 CosNaming::NamingContext_var ref_context = _current_context;
901 vector<string> splitPath;
904 bool notFound = true ;
906 // --- start search from root context
908 _current_context = _root_context ;
912 _current_directory(splitPath, lengthPath, ref_context, notFound );
915 catch (CORBA::SystemException&)
917 INFOS("Current_Directory(): CORBA::SystemException: unable to contact"
918 << " the naming service" )
919 throw ServiceUnreachable();
923 lengthPath = splitPath.size();
924 for (int k = 0 ; k < lengthPath ;k++)
927 path += splitPath[k];
931 _current_context = ref_context ;
933 return strdup(path.c_str());
936 // ============================================================================
937 /*! \brief list recursively all objects in the current context
939 * List and print via trace all directories and objects in the current
940 * context. Trace must be activated: compile option _DEBUG_
941 * If the NamingService is out, the exception ServiceUnreachable is thrown
943 // ============================================================================
945 void SALOME_NamingService::list()
946 throw(ServiceUnreachable)
948 MESSAGE("Begin of list");
950 Utils_Locker lock (&_myMutex)
953 CosNaming::BindingList_var binding_list;
954 CosNaming::BindingIterator_var binding_iterator;
955 CosNaming::Binding_var binding ;
957 unsigned long nb = 0 ; // --- only for the BindingIterator use,
958 // to access the bindings
960 CosNaming::NamingContext_var ref_context = _current_context;
962 _current_context->list(nb, binding_list, binding_iterator) ;
964 if (! CORBA::is_nil(binding_iterator))
966 while (binding_iterator->next_one(binding))
968 CosNaming::Name bindingName = binding->binding_name;
970 if (binding->binding_type == CosNaming::ncontext)
972 MESSAGE( "Context : " << bindingName[0].id );
976 Change_Directory(bindingName[0].id);
979 catch (ServiceUnreachable&)
981 INFOS( "list(): ServiceUnreachable" )
982 throw ServiceUnreachable();
986 _current_context = ref_context ;
989 else if (binding->binding_type == CosNaming::nobject)
991 MESSAGE( "Object : " << bindingName[0].id );
995 binding_iterator->destroy();
999 // ============================================================================
1000 /*! \brief list all the objects in the current directory.
1002 * get a list of all the objects in the current directory, without recursion
1003 * on the subdirectories. Only the objects are listed, not the directories.
1004 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1005 * \return list of strings with objects found.
1006 * \sa vector<string> list_directory_recurs()
1008 // ============================================================================
1010 vector<string> SALOME_NamingService::list_directory()
1011 throw(ServiceUnreachable)
1013 MESSAGE("list_directory");
1014 vector<string> dirList ;
1017 CosNaming::BindingList_var binding_list;
1018 CosNaming::BindingIterator_var binding_iterator;
1019 CosNaming::Binding_var binding ;
1021 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1022 // to access the bindings
1024 CosNaming::NamingContext_var ref_context = _current_context;
1026 _current_context->list(nb, binding_list, binding_iterator);
1028 if (binding_iterator->_is_nil())
1031 while (binding_iterator->next_one(binding))
1033 CosNaming::Name bindingName = binding->binding_name;
1035 if (binding->binding_type == CosNaming::nobject)
1037 dirList.push_back(CORBA::string_dup(bindingName[0].id));
1041 for (unsigned int ind = 0; ind < dirList.size(); ind++)
1042 MESSAGE("list_directory : Object : " << dirList[ind]);
1044 binding_iterator->destroy();
1050 // ============================================================================
1051 /*! \brief list all the subdirectories in the current directory.
1053 * get a list of all the subdirectories in the current directory,
1054 * without recursion on the subdirectories.
1055 * Only the subdirectories are listed, not the objects.
1056 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1057 * \return list of strings with directories found.
1058 * \sa vector<string> list_directory()
1060 // ============================================================================
1062 vector<string> SALOME_NamingService::list_subdirs()
1063 throw(ServiceUnreachable)
1065 MESSAGE("list_subdirs");
1066 vector<string> dirList ;
1069 CosNaming::BindingList_var binding_list;
1070 CosNaming::BindingIterator_var binding_iterator;
1071 CosNaming::Binding_var binding ;
1073 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1074 // to access the bindings
1076 CosNaming::NamingContext_var ref_context = _current_context;
1078 _current_context->list(nb, binding_list, binding_iterator) ;
1080 if (binding_iterator->_is_nil())
1083 while (binding_iterator->next_one(binding))
1085 CosNaming::Name bindingName = binding->binding_name;
1087 if (binding->binding_type == CosNaming::ncontext)
1089 dirList.push_back(CORBA::string_dup(bindingName[0].id));
1093 for (unsigned int ind = 0; ind < dirList.size(); ind++)
1094 MESSAGE("list_directory : Object : " << dirList[ind]);
1096 binding_iterator->destroy();
1101 // ============================================================================
1102 /*! \brief list all the objects in the current directory and subdirectories.
1104 * get a list of all the objects in the current directory, with recursion
1105 * on the subdirectories. Only the objects are listed, not the directories.
1106 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1107 * \return list of strings with objects found.
1108 * \sa vector<string> list_directory()
1110 // ============================================================================
1112 vector<string> SALOME_NamingService::list_directory_recurs()
1113 throw(ServiceUnreachable)
1115 MESSAGE("list_directory_recurs");
1117 Utils_Locker lock (&_myMutex);
1119 vector<string> dirList ;
1121 string currentDir = Current_Directory();
1123 _list_directory_recurs(dirList, "", currentDir);
1128 // ============================================================================
1129 /*! \brief destroy an entry in naming service.
1131 * Destroy an association Path - Object Reference.
1132 * If the NamingService is out, the exception ServiceUnreachable is thrown
1133 * \param Path object path
1135 // ============================================================================
1137 void SALOME_NamingService::Destroy_Name(const char* Path)
1138 throw(ServiceUnreachable)
1140 MESSAGE("BEGIN OF Destroy_Name " << Path);
1142 Utils_Locker lock (&_myMutex);
1146 // --- if path empty, nothing to do
1151 // --- if path = '/' not applicable, nothing to do
1156 // --- if path begins with '/', set current directory to root context
1159 _current_context = _root_context;
1161 // --- context of the directory containing the object
1163 CosNaming::Name context_name;
1164 vector<string> splitPath;
1165 int dimension_resultat = _createContextNameDir(path.c_str(),
1172 if (dimension_resultat > 0)
1174 // --- path contains a directory, not only an object name
1175 // switch to the new directory (or return if directory not found)
1179 CORBA::Object_var obj = _current_context->resolve(context_name);
1180 _current_context = CosNaming::NamingContext::_narrow(obj);
1184 catch (CosNaming::NamingContext::NotFound &ex)
1186 // --- failed to resolve
1189 CosNaming::Name n = ex.rest_of_name;
1191 if (ex.why == CosNaming::NamingContext::missing_node)
1192 INFOS( "Destroy_Name(): " << (char *) n[0].id
1193 << " (" << (char *) n[0].kind << ") not found" );
1194 if (ex.why == CosNaming::NamingContext::not_context)
1195 INFOS( "Destroy_Name() : " << (char *) n[0].id
1196 << " (" << (char *) n[0].kind
1197 << ") is not a context" );
1198 if (ex.why == CosNaming::NamingContext::not_object)
1199 INFOS( "Destroy_Name() : " << (char *) n[0].id
1200 << " (" << (char *) n[0].kind
1201 << ") is not an object" );
1204 catch (CosNaming::NamingContext::InvalidName &)
1206 INFOS("Destroy_Name: CosNaming::NamingContext::InvalidName");
1209 catch (CosNaming::NamingContext::CannotProceed &)
1211 INFOS("Destroy_Name: CosNaming::NamingContext::CannotProceed");
1214 catch (CORBA::SystemException&)
1216 INFOS("Destroy_Name : CORBA::SystemException: "
1217 << "unable to contact the naming service");
1218 throw ServiceUnreachable();
1221 if (! exist) return;
1224 ASSERT(!CORBA::is_nil(_current_context));
1226 // --- The current directory is now the directory where the object should
1229 int sizePath = splitPath.size();
1230 if (sizePath > dimension_resultat)
1232 ASSERT(sizePath == dimension_resultat+1);
1233 context_name.length(1);
1237 // --- the last element is an object and not a directory
1239 context_name[0].id =
1240 CORBA::string_dup(splitPath[dimension_resultat].c_str());
1241 context_name[0].kind = CORBA::string_dup("object");
1242 SCRUTE(context_name[0].id);
1244 _current_context->unbind(context_name);
1245 MESSAGE("The object " << context_name[0].id << " has been deleted");
1248 catch (CosNaming::NamingContext::NotFound& ex)
1250 CosNaming::Name n = ex.rest_of_name;
1252 if (ex.why == CosNaming::NamingContext::missing_node)
1253 INFOS( "Destroy_Name() : " << (char *) n[0].id
1254 << " (" << (char *) n[0].kind << ") not found" );
1255 if (ex.why == CosNaming::NamingContext::not_context)
1256 INFOS( "Destroy_Name() : " << (char *) n[0].id
1257 << " (" << (char *) n[0].kind
1258 << ") is not a context" );
1259 if (ex.why == CosNaming::NamingContext::not_object)
1260 INFOS( "Destroy_Name() : " << (char *) n[0].id
1261 << " (" << (char *) n[0].kind
1262 << ") is not an object" );
1265 catch (CosNaming::NamingContext::CannotProceed&)
1267 INFOS( "Destroy_Name(): CosNaming::NamingContext::CannotProceed");
1270 catch (CosNaming::NamingContext::InvalidName&)
1272 INFOS( "Destroy_Name(): CosNaming::NamingContext::InvalidName");
1275 catch (CORBA::SystemException&)
1277 INFOS( "Destroy_Name(): CORBA::SystemException: unable to contact"
1278 << " the naming service");
1279 throw ServiceUnreachable();
1284 // ============================================================================
1285 /*! \brief Destroy an empty directory
1287 * Destroy an empty directory in Naming Service.
1288 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1289 * \param Path directory path
1291 // ============================================================================
1293 void SALOME_NamingService::Destroy_Directory(const char* Path)
1294 throw(ServiceUnreachable)
1296 MESSAGE("BEGIN OF Destroy_Directory" << Path);
1298 Utils_Locker lock (&_myMutex);
1302 // --- if path empty, nothing to do
1307 // --- if path begins with '/', set current directory to root context
1310 _current_context = _root_context;
1312 CosNaming::NamingContext_var ref_context = _current_context;
1314 // --- path must ends with '/' for a directory
1316 if (path[path.size() -1] != '/')
1319 // --- context of the directory
1321 CosNaming::Name context_name;
1322 vector<string> splitPath;
1323 int dimension_resultat = _createContextNameDir(path.c_str(),
1329 if (dimension_resultat > 0)
1331 // --- path contains a directory, not only an object name
1332 // switch to the new directory (or return if directory not found)
1336 CORBA::Object_var obj = _current_context->resolve(context_name);
1337 _current_context = CosNaming::NamingContext::_narrow(obj);
1341 catch (CosNaming::NamingContext::NotFound &ex)
1343 // --- failed to resolve
1346 CosNaming::Name n = ex.rest_of_name;
1348 if (ex.why == CosNaming::NamingContext::missing_node)
1349 INFOS( "Destroy_Directory(): " << (char *) n[0].id
1350 << " (" << (char *) n[0].kind << ") not found" );
1351 if (ex.why == CosNaming::NamingContext::not_context)
1352 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1353 << " (" << (char *) n[0].kind
1354 << ") is not a context" );
1355 if (ex.why == CosNaming::NamingContext::not_object)
1356 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1357 << " (" << (char *) n[0].kind
1358 << ") is not an object" );
1361 catch (CosNaming::NamingContext::InvalidName &)
1363 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1366 catch (CosNaming::NamingContext::CannotProceed &)
1368 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1371 catch (CORBA::SystemException&)
1373 INFOS("Destroy_Directory : CORBA::SystemException: "
1374 << "unable to contact the naming service");
1375 throw ServiceUnreachable();
1378 if (! exist) return;
1381 ASSERT(!CORBA::is_nil(_current_context));
1383 // --- Context Destruction
1385 bool isContextDestroyed = false;
1388 _current_context->destroy();
1389 MESSAGE( "The context " << path << " has been deleted" );
1390 isContextDestroyed = true;
1393 catch (CosNaming::NamingContext::NotEmpty&)
1395 INFOS( "Destroy_Directory(): CosNaming::NamingContext::NoEmpty "
1396 << path << " is not empty" );
1399 catch (CORBA::SystemException&)
1401 INFOS( "Destroy_Directory():CORBA::SystemException : "
1402 << "unable to contact the naming service");
1403 throw ServiceUnreachable();
1406 // --- go to the reference directory
1408 _current_context = ref_context ;
1410 ASSERT(!CORBA::is_nil(_current_context));
1412 if (isContextDestroyed)
1416 _current_context->unbind(context_name);
1417 MESSAGE( "The bind to the context "
1418 << context_name[0].id
1419 << " has been deleted" );
1422 catch (CosNaming::NamingContext::NotFound& ex)
1424 CosNaming::Name n = ex.rest_of_name;
1426 if (ex.why == CosNaming::NamingContext::missing_node)
1427 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1428 << " (" << (char *) n[0].kind << ") not found" );
1429 if (ex.why == CosNaming::NamingContext::not_context)
1430 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1431 << " (" << (char *) n[0].kind
1432 << ") is not a context" );
1433 if (ex.why == CosNaming::NamingContext::not_object)
1434 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1435 << " (" << (char *) n[0].kind
1436 << ") is not an object" );
1439 catch (CosNaming::NamingContext::CannotProceed&)
1441 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1444 catch (CosNaming::NamingContext::InvalidName&)
1446 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1449 catch (CORBA::SystemException&)
1451 INFOS("Destroy_Directory:CORBA::SystemException : unable to contact"
1452 << " the naming service");
1453 throw ServiceUnreachable();
1458 // ============================================================================
1459 /*! \brief Destroy a directory with its contents.
1461 * Destroy the objects associations in a directory, and the directory itself,
1462 * if there is no subdirectories.
1463 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1464 * \param Path the directory path.
1466 // ============================================================================
1468 void SALOME_NamingService::Destroy_FullDirectory(const char* Path)
1469 throw(ServiceUnreachable)
1471 if( Change_Directory(Path) )
1473 vector<string> contList = list_directory();
1475 for (unsigned int ind = 0; ind < contList.size(); ind++)
1476 Destroy_Name(contList[ind].c_str());
1478 Destroy_Directory(Path);
1484 // ============================================================================
1485 /*! \brief initialize root context (root directory)
1487 * the root context initialisation must be done when the SALOME_NamingService
1488 * instance is created and before any othe call. See constructors.
1490 // ============================================================================
1492 void SALOME_NamingService::_initialize_root_context()
1494 //MESSAGE("Get the root context");
1498 CORBA::Object_var obj = _orb->resolve_initial_references("NameService");
1499 _root_context = CosNaming::NamingContext::_narrow(obj);
1500 _current_context = _root_context ;
1501 ASSERT(!CORBA::is_nil(_root_context));
1504 catch (CORBA::SystemException&)
1506 INFOS("CORBA::SystemException: unable to contact the naming service");
1507 throw ServiceUnreachable();
1512 INFOS("Unknown Exception: unable to contact the naming service");
1513 throw ServiceUnreachable();
1517 // ============================================================================
1518 /*! \brief transform a string path in CosNaming structure.
1520 * Transform a path given as a string in a CosNaming structure.
1521 * \param path a relative or absolute path, with or without an object.
1522 * An absolute path begins with '/'.
1523 * A path without an object ends with '/'.
1524 * \param context_name CosNaming structure to put the path.
1525 * \param splitPath a vector of string with subdirectories and final
1527 * \param onlyDir if true, final object (if any) is ommited
1529 * if false, final object (if any) is included in
1531 * \return dimension of context_name
1533 // ============================================================================
1536 SALOME_NamingService::_createContextNameDir(string path,
1537 CosNaming::Name& context_name,
1538 vector<string>& splitPath,
1544 string::size_type begIdx, endIdx;
1545 const string delims("/");
1546 splitPath.resize(0);
1547 bool endWithDelim = false;
1549 begIdx = path.find_first_not_of(delims);
1550 while (begIdx != string::npos)
1552 endIdx = path.find_first_of(delims, begIdx);
1553 if (endIdx == path.length()-1)
1554 endWithDelim = true;
1555 if (endIdx == string::npos)
1556 endIdx = path.length();
1557 int lsub = endIdx - begIdx;
1559 splitPath.push_back(path.substr(begIdx, lsub));
1560 begIdx = path.find_first_not_of(delims, endIdx);
1564 if (onlyDir) // only directory part
1566 dim = splitPath.size()-1; // omit final object
1567 if (endWithDelim) // unless the path ends with a delimiter
1569 endWithDelim = true;
1572 dim = splitPath.size(); // directories and final object
1574 context_name.length(dim);
1575 for (int i=0; i<dim; i++)
1577 SCRUTE(splitPath[i]);
1578 context_name[i].id = CORBA::string_dup(splitPath[i].c_str());
1579 if (!endWithDelim && (i == dim-1)) // here, the last string is an object
1581 context_name[i].kind = CORBA::string_dup("object");
1582 MESSAGE("--- " <<splitPath[i] <<".object");
1586 context_name[i].kind = CORBA::string_dup("dir");
1587 MESSAGE("--- " <<splitPath[i] <<".dir");
1593 // ============================================================================
1594 /*! \brief search a name in current directory.
1596 * Search a name in the current directory. after call, the current directory
1597 * is changed to the directory containing the last occurence of name found.
1598 * If no occurence found (see return value), current directory remains
1599 * unchanged. The call is recursive.
1601 * \param name the name to search.
1602 * \param occurence_number number of occurence already found (incremented)
1604 // ============================================================================
1606 void SALOME_NamingService::_Find(const char* name,
1607 CORBA::Long& occurence_number)
1609 MESSAGE("BEGIN OF _Find "<< occurence_number << " " << name);
1611 CosNaming::BindingList_var binding_list;
1612 CosNaming::BindingIterator_var binding_iterator;
1613 CosNaming::Binding_var binding;
1615 unsigned long nb = 0 ; // --- only for the use of the BindingIterator,
1616 // to access the bindings
1618 CosNaming::NamingContext_var ref_context = _current_context;
1619 CosNaming::NamingContext_var found_context = _current_context;
1621 _current_context->list(nb, binding_list, binding_iterator) ;
1623 if (! CORBA::is_nil(binding_iterator))
1625 while (binding_iterator->next_one(binding))
1627 CosNaming::Name bindingName = binding->binding_name;
1629 if (binding->binding_type == CosNaming::ncontext)
1631 // --- We work on a directory,
1632 // the search should be done in this directory
1634 Change_Directory(bindingName[0].id);
1635 _Find(name, occurence_number);
1637 // --- We'll go back to the initial context
1639 _current_context = ref_context ;
1642 else if (binding->binding_type == CosNaming::nobject)
1644 // --- We work on an object...
1646 if (!strcmp( bindingName[0].id, name))
1648 //MESSAGE("One occurence was found");
1651 // --- We keep in memory the directory where
1652 // one occurence was found
1654 found_context = _current_context ;
1659 binding_iterator->destroy();
1661 // --- We go to the last directory where an occurence was found
1663 _current_context = found_context;
1665 SCRUTE(occurence_number);
1668 // ============================================================================
1669 /*! \brief find the current directory path.
1671 * Parse the naming service tree to find the current context and give the
1672 * associated directory path (relative to root context).
1674 * \param lengthResult
1675 * \param contextToFind
1678 // ============================================================================
1681 SALOME_NamingService::
1682 _current_directory(vector<string>& splitPath,
1684 CosNaming::NamingContext_var contextToFind,
1687 MESSAGE("BEGIN OF _current_Directory");
1689 CosNaming::BindingList_var binding_list;
1690 CosNaming::BindingIterator_var binding_iterator;
1691 CosNaming::Binding_var binding;
1693 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1694 // to access the bindings
1696 CosNaming::NamingContext_var ref_context = _current_context;
1697 CosNaming::NamingContext_var temp_context = _current_context;
1699 _current_context->list(nb, binding_list, binding_iterator);
1701 if ( !binding_iterator->_is_nil() )
1703 while ((binding_iterator->next_one(binding)) && notFound)
1705 CosNaming::Name bindingName = binding->binding_name;
1707 if (binding->binding_type == CosNaming::ncontext)
1709 // --- directory, search in it
1711 splitPath.push_back(CORBA::string_dup(bindingName[0].id));
1714 CORBA::Object_var obj = _current_context->resolve(bindingName);
1715 temp_context = CosNaming::NamingContext::_narrow(obj);
1717 if (temp_context->_is_equivalent(contextToFind))
1719 MESSAGE("The context is found, we stop the search");
1726 SCRUTE(bindingName[0].id);
1727 Change_Directory(bindingName[0].id);
1728 _current_directory(splitPath,
1735 // --- go back to the initial context
1737 _current_context = ref_context;
1739 MESSAGE("Just before the delete of "
1740 << splitPath[lengthResult-1]);
1741 splitPath.pop_back();
1748 binding_iterator->destroy();
1751 // --- return to the last directory where an occurence was found
1753 _current_context = ref_context ;
1757 // ============================================================================
1758 /*! \brief list recursively all objects in the given directory and subdirs.
1760 * get a list of all the objects in the current directory, with recursion
1761 * on the subdirectories. Only the objects are listed, not the directories.
1762 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1763 * \param myList the list of objects
1765 Function :_list_directory_recurs.
1766 * Purpose : method to list recursively all the objects contained in the tree of absCurDirectory/relativeSubDir.
1767 * \param myList The list that will be filled.
1768 * \param relativeSubDir The directory from absCurDirectory in which the objects are found.
1769 * \param absCurDirectory The directory in ABSOLUTE form.
1770 * _current_context must refer to absCurDirectory.
1772 // ============================================================================
1774 void SALOME_NamingService::_list_directory_recurs(vector<string>& myList,
1775 string relativeSubDir,
1776 string absCurDirectory)
1778 CosNaming::BindingList_var binding_list;
1779 CosNaming::BindingIterator_var binding_iterator;
1780 CosNaming::Binding_var binding ;
1782 unsigned long nb = 0 ; // --- only for thethe use of BindingIterator
1783 // to access the bindings
1787 CosNaming::NamingContext_var ref_context = _current_context;
1789 if (! relativeSubDir.empty())
1791 Change_Directory(relativeSubDir.c_str());
1792 absDir = absCurDirectory + "/" + relativeSubDir;
1796 absDir = absCurDirectory;
1799 _current_context->list(nb, binding_list, binding_iterator) ;
1801 if (! CORBA::is_nil(binding_iterator))
1803 while (binding_iterator->next_one(binding))
1805 CosNaming::Name bindingName = binding->binding_name;
1807 if (binding->binding_type == CosNaming::ncontext)
1809 string relativeSdir(bindingName[0].id);
1810 _list_directory_recurs(myList, relativeSdir, absDir);
1813 else if (binding->binding_type == CosNaming::nobject)
1815 string objName(bindingName[0].id);
1816 string elt = absDir + "/" + objName;
1818 myList.push_back(elt);
1822 binding_iterator->destroy();
1824 if (! relativeSubDir.empty())
1826 _current_context = ref_context;
1830 // ============================================================================
1831 /*! \brief return a stringified reference of root context
1833 * \return a stringified reference of root context
1835 // ============================================================================
1837 char * SALOME_NamingService::getIORaddr()
1839 return _orb->object_to_string(_root_context);