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 '/'
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_var 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 MESSAGE("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_var 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 containerName name of the container in which the component is
644 * \param hostname name of the host of the container, without domain names.
645 * \return the path under the form /Containers/hostname/containerName
646 * \sa ContainerName(const Engines::MachineParameters& params)
648 // ============================================================================
650 string SALOME_NamingService::BuildContainerNameForNS(const char *containerName,
651 const char *hostname)
653 string ret = "/Containers/";
656 ret += ContainerName(containerName);
661 // ============================================================================
662 /*! \brief build a string representing a container in Naming Service.
664 * Build a string representing the absolute pathname of a container in
665 * SALOME_NamingService.
666 * \param params used as it is, or replaced by FactoryServer if empty.
667 * \param hostname name of the host of the container, without domain names.
668 * \return the path under the form /Containers/hostname/containerName
669 * \sa ContainerName(const char *containerName)
671 // ============================================================================
674 SALOME_NamingService::
675 BuildContainerNameForNS(const Engines::MachineParameters& params,
676 const char *hostname)
678 string ret = "/Containers/";
681 ret += ContainerName(params);
686 // ============================================================================
687 /*! \brief search a name in current directory.
689 * Search a name in the current directory. after call, the current directory
690 * is changed to the directory containing the last occurence of name found.
691 * If no occurence found (see return value), current directory remains
694 * \param name the name to search.
695 * \return number of occurences found.
696 * \sa Change_Directory(const char* Path)
698 // ============================================================================
700 int SALOME_NamingService::Find(const char* name)
701 throw(ServiceUnreachable)
703 MESSAGE("BEGIN OF Find " << name);
705 Utils_Locker lock (&_myMutex);
707 CORBA::Long occurence_number = 0 ;
711 _Find(name, occurence_number);
714 catch (CORBA::SystemException&)
716 INFOS("!!!Find() : CORBA::SystemException : unable to contact"
717 << " the naming service");
718 throw ServiceUnreachable();
721 return occurence_number;
724 // ============================================================================
725 /*! \brief Creates a directory (context_name)
727 * Creates a directory (context_name) relative to the current directory
728 * (current context) or relative to the root directory (root context), if
729 * the path given begins with a '/'.
730 * If the NamingService is out, the exception ServiceUnreachable is thrown.
731 * \param Path A relative or absolute pathname to store the object reference.
732 * If the pathname begins with a '/', pathname is taken
733 * as an absolute pathname. Else, pathname is taken as a relative
734 * path, to current context. Prefer absolute pathname, relative
735 * pathname are not safe, when SALOME_NamingService object is
736 * shared or use in multithreaded context.
737 * \return true if successfull
738 * (creation not strictly garanteed if true, because Register may
739 * catch some specific unlikely exception without throw anything
740 * --- to be corrected ---)
741 * \sa RegisterCORBA::Object_ptr ObjRef, const char* Path)
743 // ============================================================================
745 bool SALOME_NamingService::Create_Directory(const char* Path)
746 throw(ServiceUnreachable)
748 MESSAGE("BEGIN OF Create_Directory");
750 Utils_Locker lock (&_myMutex);
754 // --- if path empty, nothing to create, no context change
759 // --- if path ='/', nothing to create, only change to root_context
763 MESSAGE("Create Directory '/', just change to root_context");
764 _current_context = _root_context;
768 // --- path must end with '/'
770 if (path[path.length()-1] != '/') path += '/';
772 Register(CORBA::Object::_nil(), path.c_str());
776 // ============================================================================
777 /*! \brief change current directory to the given path
779 * change the current directory to the given path in parameter.
780 * Warning: avoid use when the SALOME_NamingService instance is shared by
781 * several threads (current context may be modified by another thread).
782 * If the path is empty, nothing done return OK.
783 * If Path ="/", the current directory changes to the root directory.
784 * If the NamingService is out, the exception ServiceUnreachable is thrown.
785 * \param Path the new current directory
786 * \return true if the change succeeded
788 // ============================================================================
790 bool SALOME_NamingService::Change_Directory(const char* Path)
791 throw(ServiceUnreachable)
793 // MESSAGE("BEGIN OF Change_Directory " << Path);
794 Utils_Locker lock (&_myMutex);
798 // --- if path empty, nothing to do
803 // --- if path ='/', nothing to resolve, only change to root_context
807 // MESSAGE("Change_Directory is called to go to the root_context");
808 _current_context = _root_context;
812 CosNaming::NamingContext_var current_context = _current_context;
813 bool changeOK = false;
815 // --- replace _current_context with _root_context if Path begins whith '/'
818 current_context = _root_context;
820 // --- need to resolve directory path
822 ASSERT(!CORBA::is_nil(current_context));
824 if (path[path.length()-1] != '/') path += '/';
826 CosNaming::Name context_name;
827 vector<string> splitPath;
828 int dimension_resultat = _createContextNameDir(path.c_str(),
833 // --- Context creation
837 CORBA::Object_var obj = current_context->resolve(context_name);
838 current_context = CosNaming::NamingContext::_narrow(obj);
839 ASSERT(!CORBA::is_nil(current_context));
840 _current_context = current_context;
844 catch (CosNaming::NamingContext::NotFound& ex)
846 CosNaming::Name n = ex.rest_of_name;
848 if (ex.why == CosNaming::NamingContext::missing_node)
849 MESSAGE( "Change_Directory() : " << (char *) n[0].id
850 << " (" << (char *) n[0].kind << ") not found");
851 if (ex.why == CosNaming::NamingContext::not_context)
852 INFOS("Change_Directory() : " << (char *) n[0].id
853 << " (" << (char *) n[0].kind
854 << ") is not a context" );
855 if (ex.why == CosNaming::NamingContext::not_object)
856 INFOS( "Change_Directory() : " << (char *) n[0].id
857 << " (" << (char *) n[0].kind
858 << ") is not an object" );
861 catch (CosNaming::NamingContext::CannotProceed&)
863 INFOS("Change_Directory(): CosNaming::NamingContext::CannotProceed");
866 catch (CosNaming::NamingContext::InvalidName&)
868 INFOS("Change_Directory(): CosNaming::NamingContext::InvalidName");
871 catch (CORBA::SystemException&)
873 INFOS("Change_Directory():CORBA::SystemException : unable to contact"
874 << "the naming service");
875 throw ServiceUnreachable();
881 // ============================================================================
882 /*! \brief get the current directory path
884 * Get the current directory path.
885 * If the NamingService is out, the exception ServiceUnreachable is thrown.
886 * \return the path of the current_context
887 * \sa _current_directory
889 // ============================================================================
891 char* SALOME_NamingService::Current_Directory()
892 throw(ServiceUnreachable)
894 MESSAGE("BEGIN OF Current_Directory");
896 Utils_Locker lock (&_myMutex);
898 CosNaming::NamingContext_var ref_context = _current_context;
900 vector<string> splitPath;
903 bool notFound = true ;
905 // --- start search from root context
907 _current_context = _root_context ;
911 _current_directory(splitPath, lengthPath, ref_context, notFound );
914 catch (CORBA::SystemException&)
916 INFOS("Current_Directory(): CORBA::SystemException: unable to contact"
917 << " the naming service" )
918 throw ServiceUnreachable();
922 lengthPath = splitPath.size();
923 for (int k = 0 ; k < lengthPath ;k++)
926 path += splitPath[k];
930 _current_context = ref_context ;
932 return strdup(path.c_str());
935 // ============================================================================
936 /*! \brief list recursively all objects in the current context
938 * List and print via trace all directories and objects in the current
939 * context. Trace must be activated: compile option _DEBUG_
940 * If the NamingService is out, the exception ServiceUnreachable is thrown
942 // ============================================================================
944 void SALOME_NamingService::list()
945 throw(ServiceUnreachable)
947 MESSAGE("Begin of list");
949 Utils_Locker lock (&_myMutex)
952 CosNaming::BindingList_var binding_list;
953 CosNaming::BindingIterator_var binding_iterator;
954 CosNaming::Binding_var binding ;
956 unsigned long nb = 0 ; // --- only for the BindingIterator use,
957 // to access the bindings
959 CosNaming::NamingContext_var ref_context = _current_context;
961 _current_context->list(nb, binding_list, binding_iterator) ;
963 if (! CORBA::is_nil(binding_iterator))
965 while (binding_iterator->next_one(binding))
967 CosNaming::Name bindingName = binding->binding_name;
969 if (binding->binding_type == CosNaming::ncontext)
971 MESSAGE( "Context : " << bindingName[0].id );
975 Change_Directory(bindingName[0].id);
978 catch (ServiceUnreachable&)
980 INFOS( "list(): ServiceUnreachable" )
981 throw ServiceUnreachable();
985 _current_context = ref_context ;
988 else if (binding->binding_type == CosNaming::nobject)
990 MESSAGE( "Object : " << bindingName[0].id );
994 binding_iterator->destroy();
998 // ============================================================================
999 /*! \brief list all the objects in the current directory.
1001 * get a list of all the objects in the current directory, without recursion
1002 * on the subdirectories. Only the objects are listed, not the directories.
1003 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1004 * \return list of strings with objects found.
1005 * \sa vector<string> list_directory_recurs()
1007 // ============================================================================
1009 vector<string> SALOME_NamingService::list_directory()
1010 throw(ServiceUnreachable)
1012 // MESSAGE("list_directory");
1013 vector<string> dirList ;
1016 CosNaming::BindingList_var binding_list;
1017 CosNaming::BindingIterator_var binding_iterator;
1018 CosNaming::Binding_var binding ;
1020 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1021 // to access the bindings
1023 CosNaming::NamingContext_var ref_context = _current_context;
1025 _current_context->list(nb, binding_list, binding_iterator);
1027 if (binding_iterator->_is_nil())
1030 while (binding_iterator->next_one(binding))
1032 CosNaming::Name bindingName = binding->binding_name;
1034 if (binding->binding_type == CosNaming::nobject)
1036 // remove memory leak
1037 // dirList.push_back(CORBA::string_dup(bindingName[0].id));
1038 dirList.push_back(string(bindingName[0].id));
1042 // for (unsigned int ind = 0; ind < dirList.size(); ind++)
1043 // MESSAGE("list_directory : Object : " << dirList[ind]);
1045 binding_iterator->destroy();
1051 // ============================================================================
1052 /*! \brief list all the subdirectories in the current directory.
1054 * get a list of all the subdirectories in the current directory,
1055 * without recursion on the subdirectories.
1056 * Only the subdirectories are listed, not the objects.
1057 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1058 * \return list of strings with directories found.
1059 * \sa vector<string> list_directory()
1061 // ============================================================================
1063 vector<string> SALOME_NamingService::list_subdirs()
1064 throw(ServiceUnreachable)
1066 MESSAGE("list_subdirs");
1067 vector<string> dirList ;
1070 CosNaming::BindingList_var binding_list;
1071 CosNaming::BindingIterator_var binding_iterator;
1072 CosNaming::Binding_var binding ;
1074 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1075 // to access the bindings
1077 CosNaming::NamingContext_var ref_context = _current_context;
1079 _current_context->list(nb, binding_list, binding_iterator) ;
1081 if (binding_iterator->_is_nil())
1084 while (binding_iterator->next_one(binding))
1086 CosNaming::Name bindingName = binding->binding_name;
1088 if (binding->binding_type == CosNaming::ncontext)
1090 dirList.push_back(CORBA::string_dup(bindingName[0].id));
1094 for (unsigned int ind = 0; ind < dirList.size(); ind++)
1095 MESSAGE("list_directory : Object : " << dirList[ind]);
1097 binding_iterator->destroy();
1102 // ============================================================================
1103 /*! \brief list all the objects in the current directory and subdirectories.
1105 * get a list of all the objects in the current directory, with recursion
1106 * on the subdirectories. Only the objects are listed, not the directories.
1107 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1108 * \return list of strings with objects found.
1109 * \sa vector<string> list_directory()
1111 // ============================================================================
1113 vector<string> SALOME_NamingService::list_directory_recurs()
1114 throw(ServiceUnreachable)
1116 MESSAGE("list_directory_recurs");
1118 Utils_Locker lock (&_myMutex);
1120 vector<string> dirList ;
1122 string currentDir = Current_Directory();
1124 _list_directory_recurs(dirList, "", currentDir);
1129 // ============================================================================
1130 /*! \brief destroy an entry in naming service.
1132 * Destroy an association Path - Object Reference.
1133 * If the NamingService is out, the exception ServiceUnreachable is thrown
1134 * \param Path object path
1136 // ============================================================================
1138 void SALOME_NamingService::Destroy_Name(const char* Path)
1139 throw(ServiceUnreachable)
1141 MESSAGE("BEGIN OF Destroy_Name " << Path);
1143 Utils_Locker lock (&_myMutex);
1147 // --- if path empty, nothing to do
1152 // --- if path = '/' not applicable, nothing to do
1157 // --- if path begins with '/', set current directory to root context
1160 _current_context = _root_context;
1162 // --- context of the directory containing the object
1164 CosNaming::Name context_name;
1165 vector<string> splitPath;
1166 int dimension_resultat = _createContextNameDir(path.c_str(),
1173 if (dimension_resultat > 0)
1175 // --- path contains a directory, not only an object name
1176 // switch to the new directory (or return if directory not found)
1180 CORBA::Object_var obj = _current_context->resolve(context_name);
1181 _current_context = CosNaming::NamingContext::_narrow(obj);
1185 catch (CosNaming::NamingContext::NotFound &ex)
1187 // --- failed to resolve
1190 CosNaming::Name n = ex.rest_of_name;
1192 if (ex.why == CosNaming::NamingContext::missing_node)
1193 INFOS( "Destroy_Name(): " << (char *) n[0].id
1194 << " (" << (char *) n[0].kind << ") not found" );
1195 if (ex.why == CosNaming::NamingContext::not_context)
1196 INFOS( "Destroy_Name() : " << (char *) n[0].id
1197 << " (" << (char *) n[0].kind
1198 << ") is not a context" );
1199 if (ex.why == CosNaming::NamingContext::not_object)
1200 INFOS( "Destroy_Name() : " << (char *) n[0].id
1201 << " (" << (char *) n[0].kind
1202 << ") is not an object" );
1205 catch (CosNaming::NamingContext::InvalidName &)
1207 INFOS("Destroy_Name: CosNaming::NamingContext::InvalidName");
1210 catch (CosNaming::NamingContext::CannotProceed &)
1212 INFOS("Destroy_Name: CosNaming::NamingContext::CannotProceed");
1215 catch (CORBA::SystemException&)
1217 INFOS("Destroy_Name : CORBA::SystemException: "
1218 << "unable to contact the naming service");
1219 throw ServiceUnreachable();
1222 if (! exist) return;
1225 ASSERT(!CORBA::is_nil(_current_context));
1227 // --- The current directory is now the directory where the object should
1230 int sizePath = splitPath.size();
1231 if (sizePath > dimension_resultat)
1233 ASSERT(sizePath == dimension_resultat+1);
1234 context_name.length(1);
1238 // --- the last element is an object and not a directory
1240 context_name[0].id =
1241 CORBA::string_dup(splitPath[dimension_resultat].c_str());
1242 context_name[0].kind = CORBA::string_dup("object");
1243 SCRUTE(context_name[0].id);
1245 _current_context->unbind(context_name);
1246 MESSAGE("The object " << context_name[0].id << " has been deleted");
1249 catch (CosNaming::NamingContext::NotFound& ex)
1251 CosNaming::Name n = ex.rest_of_name;
1253 if (ex.why == CosNaming::NamingContext::missing_node)
1254 INFOS( "Destroy_Name() : " << (char *) n[0].id
1255 << " (" << (char *) n[0].kind << ") not found" );
1256 if (ex.why == CosNaming::NamingContext::not_context)
1257 INFOS( "Destroy_Name() : " << (char *) n[0].id
1258 << " (" << (char *) n[0].kind
1259 << ") is not a context" );
1260 if (ex.why == CosNaming::NamingContext::not_object)
1261 INFOS( "Destroy_Name() : " << (char *) n[0].id
1262 << " (" << (char *) n[0].kind
1263 << ") is not an object" );
1266 catch (CosNaming::NamingContext::CannotProceed&)
1268 INFOS( "Destroy_Name(): CosNaming::NamingContext::CannotProceed");
1271 catch (CosNaming::NamingContext::InvalidName&)
1273 INFOS( "Destroy_Name(): CosNaming::NamingContext::InvalidName");
1276 catch (CORBA::SystemException&)
1278 INFOS( "Destroy_Name(): CORBA::SystemException: unable to contact"
1279 << " the naming service");
1280 throw ServiceUnreachable();
1285 // ============================================================================
1286 /*! \brief Destroy an empty directory
1288 * Destroy an empty directory in Naming Service.
1289 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1290 * \param Path directory path
1292 // ============================================================================
1294 void SALOME_NamingService::Destroy_Directory(const char* Path)
1295 throw(ServiceUnreachable)
1297 MESSAGE("BEGIN OF Destroy_Directory " << Path);
1299 Utils_Locker lock (&_myMutex);
1303 // --- if path empty, nothing to do
1308 // --- if path begins with '/', set current directory to root context
1311 _current_context = _root_context;
1313 CosNaming::NamingContext_var ref_context = _current_context;
1315 // --- path must ends with '/' for a directory
1317 if (path[path.size() -1] != '/')
1320 // --- context of the directory
1322 CosNaming::Name context_name;
1323 vector<string> splitPath;
1324 int dimension_resultat = _createContextNameDir(path.c_str(),
1330 if (dimension_resultat > 0)
1332 // --- path contains a directory, not only an object name
1333 // switch to the new directory (or return if directory not found)
1337 CORBA::Object_var obj = _current_context->resolve(context_name);
1338 _current_context = CosNaming::NamingContext::_narrow(obj);
1342 catch (CosNaming::NamingContext::NotFound &ex)
1344 // --- failed to resolve
1347 CosNaming::Name n = ex.rest_of_name;
1349 if (ex.why == CosNaming::NamingContext::missing_node)
1350 INFOS( "Destroy_Directory(): " << (char *) n[0].id
1351 << " (" << (char *) n[0].kind << ") not found" );
1352 if (ex.why == CosNaming::NamingContext::not_context)
1353 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1354 << " (" << (char *) n[0].kind
1355 << ") is not a context" );
1356 if (ex.why == CosNaming::NamingContext::not_object)
1357 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1358 << " (" << (char *) n[0].kind
1359 << ") is not an object" );
1362 catch (CosNaming::NamingContext::InvalidName &)
1364 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1367 catch (CosNaming::NamingContext::CannotProceed &)
1369 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1372 catch (CORBA::SystemException&)
1374 INFOS("Destroy_Directory : CORBA::SystemException: "
1375 << "unable to contact the naming service");
1376 throw ServiceUnreachable();
1379 if (! exist) return;
1382 ASSERT(!CORBA::is_nil(_current_context));
1384 // --- Context Destruction
1386 bool isContextDestroyed = false;
1389 _current_context->destroy();
1390 MESSAGE( "The context " << path << " has been deleted" );
1391 isContextDestroyed = true;
1394 catch (CosNaming::NamingContext::NotEmpty&)
1396 INFOS( "Destroy_Directory(): CosNaming::NamingContext::NoEmpty "
1397 << path << " is not empty" );
1400 catch (CORBA::SystemException&)
1402 INFOS( "Destroy_Directory():CORBA::SystemException : "
1403 << "unable to contact the naming service");
1404 throw ServiceUnreachable();
1407 // --- go to the reference directory
1409 _current_context = ref_context ;
1411 ASSERT(!CORBA::is_nil(_current_context));
1413 if (isContextDestroyed)
1417 _current_context->unbind(context_name);
1418 MESSAGE( "The bind to the context "
1419 << context_name[0].id
1420 << " has been deleted" );
1423 catch (CosNaming::NamingContext::NotFound& ex)
1425 CosNaming::Name n = ex.rest_of_name;
1427 if (ex.why == CosNaming::NamingContext::missing_node)
1428 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1429 << " (" << (char *) n[0].kind << ") not found" );
1430 if (ex.why == CosNaming::NamingContext::not_context)
1431 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1432 << " (" << (char *) n[0].kind
1433 << ") is not a context" );
1434 if (ex.why == CosNaming::NamingContext::not_object)
1435 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1436 << " (" << (char *) n[0].kind
1437 << ") is not an object" );
1440 catch (CosNaming::NamingContext::CannotProceed&)
1442 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1445 catch (CosNaming::NamingContext::InvalidName&)
1447 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1450 catch (CORBA::SystemException&)
1452 INFOS("Destroy_Directory:CORBA::SystemException : unable to contact"
1453 << " the naming service");
1454 throw ServiceUnreachable();
1459 // ============================================================================
1460 /*! \brief Destroy a directory with its contents.
1462 * Destroy the objects associations in a directory, and the directory itself,
1463 * if there is no subdirectories.
1464 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1465 * \param Path the directory path.
1467 // ============================================================================
1469 void SALOME_NamingService::Destroy_FullDirectory(const char* Path)
1470 throw(ServiceUnreachable)
1472 MESSAGE("begin of Destroy_FullDirectory " << Path);
1473 if( Change_Directory(Path) )
1475 vector<string> contList = list_directory();
1477 for (unsigned int ind = 0; ind < contList.size(); ind++)
1478 Destroy_Name(contList[ind].c_str());
1480 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 * _current_context must refer to absCurDirectory.
1765 * \param myList The list that will be filled.
1766 * \param relativeSubDir The directory relative to absCurDirectory in which
1767 * the objects are found.
1768 * \param absCurDirectory The current directory, absolute path
1770 // ============================================================================
1772 void SALOME_NamingService::_list_directory_recurs(vector<string>& myList,
1773 string relativeSubDir,
1774 string absCurDirectory)
1776 CosNaming::BindingList_var binding_list;
1777 CosNaming::BindingIterator_var binding_iterator;
1778 CosNaming::Binding_var binding ;
1780 unsigned long nb = 0 ; // --- only for thethe use of BindingIterator
1781 // to access the bindings
1785 CosNaming::NamingContext_var ref_context = _current_context;
1787 if (! relativeSubDir.empty())
1789 Change_Directory(relativeSubDir.c_str());
1790 absDir = absCurDirectory + "/" + relativeSubDir;
1794 absDir = absCurDirectory;
1797 _current_context->list(nb, binding_list, binding_iterator) ;
1799 if (! CORBA::is_nil(binding_iterator))
1801 while (binding_iterator->next_one(binding))
1803 CosNaming::Name bindingName = binding->binding_name;
1805 if (binding->binding_type == CosNaming::ncontext)
1807 string relativeSdir(bindingName[0].id);
1808 _list_directory_recurs(myList, relativeSdir, absDir);
1811 else if (binding->binding_type == CosNaming::nobject)
1813 string objName(bindingName[0].id);
1814 string elt = absDir + "/" + objName;
1816 myList.push_back(elt);
1820 binding_iterator->destroy();
1822 if (! relativeSubDir.empty())
1824 _current_context = ref_context;
1828 // ============================================================================
1829 /*! \brief return a stringified reference of root context
1831 * \return a stringified reference of root context
1833 // ============================================================================
1835 char * SALOME_NamingService::getIORaddr()
1837 return _orb->object_to_string(_root_context);