1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
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
22 // SALOME NamingService : wrapping NamingService services
23 // File : SALOME_NamingService.cxx
24 // Author : Estelle Deville
28 #include "SALOME_NamingService.hxx"
29 #include "ServiceUnreachable.hxx"
31 #include "utilities.h"
39 /*! \class SALOME_NamingService
40 \brief A class to manage the SALOME naming service
44 // ============================================================================
45 /*! \brief Default Constructor without ORB reference.
47 * After Default Constructor, one needs to initialize ORB.
48 * \sa init_orb(CORBA::ORB_ptr orb), SALOME_NamingService(CORBA::ORB_ptr orb)
50 // ============================================================================
52 SALOME_NamingService::SALOME_NamingService()
54 MESSAGE("SALOME_NamingService default constructor");
55 _orb = CORBA::ORB::_nil();
56 _root_context = CosNaming::NamingContext::_nil();
59 // ============================================================================
60 /*! \brief Standard Constructor, with ORB reference.
62 * Initializes the naming service root context
63 * \param orb CORBA::ORB_ptr arguments
65 // ============================================================================
67 SALOME_NamingService::SALOME_NamingService(CORBA::ORB_ptr orb)
69 MESSAGE("SALOME_NamingService creation");
71 _initialize_root_context();
74 // ============================================================================
75 /*! \brief Standard destructor.
77 * The standard destructor does nothing special.
79 // ============================================================================
81 SALOME_NamingService::~SALOME_NamingService()
83 // Problem MESSAGE with singleton: late destruction,
84 // after trace system destruction ?
85 //MESSAGE("SALOME_NamingService destruction");
88 // ============================================================================
89 /*! \brief initializes ORB reference and naming service root context.
91 * Initializes ORB reference and naming service root context.
92 * For use after default constructor.
93 * \param orb CORBA::ORB_ptr arguments
95 // ============================================================================
97 void SALOME_NamingService::init_orb(CORBA::ORB_ptr orb)
99 MESSAGE("SALOME_NamingService initialisation");
101 Utils_Locker lock (&_myMutex);
104 _initialize_root_context();
107 // ============================================================================
108 /*! \brief Registers a CORBA object reference under a path.
110 * Registers a CORBA object reference under a path. If the path ends with '/',
111 * only a directory is created.
112 * If the NamingService is out, the exception ServiceUnreachable is thrown.
113 * \param ObjRef CORBA object reference to associate to the path. To create
114 * only a directory, give nil pointer.
115 * \param Path A relative or absolute pathname to store the object reference.
116 * If the pathname begins with a '/', pathname is taken
117 * as an absolute pathname. Else, pathname is taken as a relative
118 * path, to current context. Prefer absolute pathname, relative
119 * pathname are not safe, when SALOME_NamingService object is
120 * shared or use in multithreaded context.
121 * If the path ends with '/', only a directory is created.
122 * \sa Change_Directory(const char* Path),
123 * Create_Directory(const char* Path)
124 * CORBA::Object_ptr Resolve(const char* Path)
126 // ============================================================================
128 void SALOME_NamingService::Register(CORBA::Object_ptr ObjRef,
130 throw(ServiceUnreachable)
132 MESSAGE("BEGIN OF Register: " << Path);
134 Utils_Locker lock (&_myMutex);
136 // --- _current_context is replaced to the _root_context
137 // if the Path begins whith '/'
140 _current_context = _root_context;
143 // --- the resolution of the directory path has to be done
144 // to place the current_context to the correct node
146 CosNaming::Name context_name;
147 vector<string> splitPath;
148 int dimension_resultat = _createContextNameDir(Path,
153 CORBA::Boolean not_exist = false;
155 if (dimension_resultat > 0){
156 // A directory is treated (not only an object name)
157 // test if the directory where ObjRef should be recorded already exists
158 // If not, create the new context
161 CORBA::Object_var obj = _current_context->resolve(context_name);
162 _current_context = CosNaming::NamingContext::_narrow(obj);
165 catch (CosNaming::NamingContext::NotFound &){
166 // --- failed to resolve, therefore assume cold start
170 catch (CosNaming::NamingContext::InvalidName &){
171 INFOS("Register() : CosNaming::NamingContext::InvalidName");
174 catch (CosNaming::NamingContext::CannotProceed &){
175 INFOS("Register() : CosNaming::NamingContext::CannotProceed");
178 catch (CORBA::SystemException&){
179 INFOS("Register() : CORBA::SystemException: "
180 << "unable to contact the naming service");
181 throw ServiceUnreachable();
186 context_name.length(1);
187 for (int i = 0 ; i < dimension_resultat ;i++){
188 context_name[0].id = CORBA::string_dup(splitPath[i].c_str());
189 context_name[0].kind = CORBA::string_dup("dir");
190 // SCRUTE(_context_name[0].id);
191 // --- check if the path is created
193 // --- if the context is already created, nothing to do
194 CORBA::Object_var obj = _current_context->resolve(context_name);
195 _current_context = CosNaming::NamingContext::_narrow(obj);
198 catch (CosNaming::NamingContext::NotFound &){
200 // --- the context must be created
201 CosNaming::NamingContext_var temp_context =
202 _current_context->bind_new_context(context_name);
203 _current_context = temp_context;
205 catch (CosNaming::NamingContext::AlreadyBound&){
206 CORBA::Object_var obj = _current_context->resolve(context_name);
207 _current_context = CosNaming::NamingContext::_narrow(obj);
213 catch (CosNaming::NamingContext::AlreadyBound&){
214 INFOS("Register() : CosNaming::NamingContext::AlreadyBound");
217 catch (CosNaming::NamingContext::NotFound& ex){
218 CosNaming::Name n = ex.rest_of_name;
220 if (ex.why == CosNaming::NamingContext::missing_node)
221 INFOS("Register() : " << (char *) n[0].id
222 << " (" << (char *) n[0].kind << ") not found");
224 if (ex.why == CosNaming::NamingContext::not_context)
225 INFOS("Register() : " << (char *) n[0].id
226 << " (" << (char *) n[0].kind
227 << ") is not a context");
229 if (ex.why == CosNaming::NamingContext::not_object)
230 INFOS("Register() : " << (char *) n[0].id
231 << " (" << (char *) n[0].kind
232 << ") is not an object");
235 catch (CosNaming::NamingContext::CannotProceed&){
236 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
239 catch (CosNaming::NamingContext::InvalidName&){
240 INFOS("Register(): CosNaming::NamingContext::InvalidName");
243 catch (CORBA::SystemException&){
244 INFOS("Register():CORBA::SystemException: "
245 << "unable to contact the naming service");
246 throw ServiceUnreachable();
251 // --- The current directory is now the directory where the object should
254 int sizePath = splitPath.size();
255 if (sizePath > dimension_resultat){
256 ASSERT(sizePath == dimension_resultat+1);
257 context_name.length(1);
260 // --- the last element is an object and not a directory
262 context_name[0].id = CORBA::string_dup(splitPath[dimension_resultat].c_str());
263 context_name[0].kind = CORBA::string_dup("object");
264 //SCRUTE(context_name[0].id);
266 _current_context->bind(context_name, ObjRef);
269 catch (CosNaming::NamingContext::NotFound& ex){
270 CosNaming::Name n = ex.rest_of_name;
272 if (ex.why == CosNaming::NamingContext::missing_node)
273 INFOS("Register() : " << (char *) n[0].id
274 << " (" << (char *) n[0].kind << ") not found");
276 if (ex.why == CosNaming::NamingContext::not_context)
277 INFOS("Register() : " << (char *) n[0].id
278 << " (" << (char *) n[0].kind
279 << ") is not a context");
281 if (ex.why == CosNaming::NamingContext::not_object)
282 INFOS("Register() : " << (char *) n[0].id
283 << " (" << (char *) n[0].kind
284 << ") is not an object");
287 catch (CosNaming::NamingContext::CannotProceed&){
288 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
291 catch (CosNaming::NamingContext::InvalidName&){
292 INFOS("Register(): CosNaming::NamingContext::InvalidName");
295 catch (CosNaming::NamingContext::AlreadyBound&){
296 INFOS("Register(): CosNaming::NamingContext::AlreadyBound, "
297 << "object will be rebind");
298 _current_context->rebind(context_name, ObjRef);
301 catch (CORBA::SystemException&){
302 INFOS("!!!Register(): CORBA::SystemException: "
303 << "unable to contact the naming service");
304 throw ServiceUnreachable();
309 // ============================================================================
310 /*! \brief get the CORBA object reference associated to a name.
312 * get the CORBA object reference associated to a complete name with a path.
313 * If the NamingService is out, the exception ServiceUnreachable is thrown
314 * \param Path pathname. If the pathname begins with a '/', pathname is taken
315 * as an absolute pathname. Else, pathname is taken as a relative
316 * path, to current context. Prefer absolute pathname, relative
317 * pathname are not safe, when SALOME_NamingService object is
318 * shared or use in multithreaded context.
319 * \return the object reference if it exists under the pathname,
320 * or nil reference in other cases.
321 * \sa Register(CORBA::Object_ptr ObjRef, const char* Path),
322 * Change_Directory(const char* Path)
324 // ============================================================================
326 CORBA::Object_ptr SALOME_NamingService::Resolve(const char* Path)
327 throw(ServiceUnreachable)
329 // MESSAGE("BEGIN OF Resolve: " << Path);
331 Utils_Locker lock (&_myMutex);
333 // --- _current_context is replaced to the _root_context
334 // if the Path begins whith '/'
338 _current_context = _root_context;
341 // --- the resolution of the directory path has to be done
342 // to place the current_context to the correct node
344 CosNaming::Name context_name;
345 vector<string> splitPath;
346 _createContextNameDir(Path,
351 ASSERT(!CORBA::is_nil(_current_context));
353 CORBA::Object_var obj = CORBA::Object::_nil();
357 obj = _current_context->resolve(context_name);
360 catch (CosNaming::NamingContext::NotFound& ex)
362 CosNaming::Name n = ex.rest_of_name;
364 if (ex.why == CosNaming::NamingContext::missing_node)
365 MESSAGE("Resolve() : " << (char *) n[0].id
366 << " (" << (char *) n[0].kind << ") not found");
368 if (ex.why == CosNaming::NamingContext::not_context)
370 << (char *) n[0].id << " (" << (char *) n[0].kind
371 << ") is not a context");
373 if (ex.why == CosNaming::NamingContext::not_object)
374 INFOS("Resolve() : " << (char *) n[0].id
375 << " (" << (char *) n[0].kind
376 << ") is not an object");
379 catch (CosNaming::NamingContext::CannotProceed&)
381 INFOS("Resolve(): CosNaming::NamingContext::CannotProceed");
384 catch (CosNaming::NamingContext::InvalidName&)
386 INFOS("Resolve(): CosNaming::NamingContext::InvalidName");
389 catch (CORBA::SystemException&)
391 INFOS("Resolve():CORBA::SystemException : unable to contact"
392 << "the naming service");
393 throw ServiceUnreachable();
399 // ============================================================================
400 /*! \brief get the CORBA object reference associated to an uncomplete name.
402 * get the CORBA object reference associated to an uncomplete name with a
403 * path. Look for the first occurence of name*.
404 * If the NamingService is out, the exception ServiceUnreachable is thrown
405 * \param Path pathname under the form "/path/name" (Absolute reference !)
406 * search the fist reference like "/path(.dir)/name*(.kind)"
407 * \return the object reference if found, or nil reference.
408 * \sa Resolve(const char* Path)
410 // ============================================================================
412 CORBA::Object_ptr SALOME_NamingService::ResolveFirst(const char* Path)
413 throw(ServiceUnreachable)
415 // MESSAGE("ResolveFirst");
417 Utils_Locker lock (&_myMutex);
420 string thePath = Path;
421 string basePath = "";
422 string name = thePath;
424 string::size_type idx = thePath.rfind('/');
426 if (idx != string::npos) // at least one '/' found
428 basePath = thePath.substr(0, idx);
429 name = thePath.substr(idx + 1);
434 CORBA::Object_var obj = CORBA::Object::_nil();
437 if (basePath.empty())
440 isOk = Change_Directory(basePath.c_str());
444 vector<string> listElem = list_directory();
445 vector<string>::iterator its = listElem.begin();
447 while (its != listElem.end())
451 if ((*its).find(name) == 0)
453 return Resolve((*its).c_str());
463 // ============================================================================
464 /*! \brief find a component instance from hostname, containername,
465 * componentName and number of processors.
467 * find a component instance from hostname, containername, componentName and
468 * number of processors.
469 * If the NamingService is out, the exception ServiceUnreachable is thrown.
470 * \param hostname name of the machine on which the component is searched.
471 * \param containerName name of the container in which the component is
473 * \param componentName name of the component we are looking for an existing
475 * \param nbproc in case of multi processor machine, container name is
476 * suffixed with _nbproc.
477 * \return the object reference
479 // ============================================================================
482 SALOME_NamingService::ResolveComponent(const char* hostname,
483 const char* containerName,
484 const char* componentName,
486 throw(ServiceUnreachable)
488 // MESSAGE("ResolveComponent");
490 Utils_Locker lock (&_myMutex);
492 string name = "/Containers/";
496 if ( strlen(containerName) != 0 )
502 char *newContainerName = new char[strlen(containerName) + 8];
503 sprintf(newContainerName, "%s_%d", containerName, nbproc);
504 name += newContainerName;
505 delete [] newContainerName;
509 name += containerName;
513 name += componentName;
515 return ResolveFirst(name.c_str());
521 string basename = name;
522 if (Change_Directory(basename.c_str()))
524 vector<string> contList = list_subdirs();
526 for (unsigned int ind = 0; ind < contList.size(); ind++)
528 name = contList[ind].c_str();
532 char *str_nbproc = new char[8];
533 sprintf(str_nbproc, "_%d", nbproc);
534 if( strstr(name.c_str(),str_nbproc) == NULL)
535 continue; // check only containers with _%d in name
536 delete [] str_nbproc;
540 name += componentName;
542 CORBA::Object_ptr obj = ResolveFirst(name.c_str());
544 if ( !CORBA::is_nil(obj) )
547 Change_Directory(basename.c_str());
551 return CORBA::Object::_nil();
555 // ============================================================================
556 /*! \brief provide a default container name if empty.
558 * the given container name is returned unchanged, unless it is empty.
559 * \param containerName
560 * \return container name, where empty input is replaced by "FactoryServer",
562 * \sa BuildContainerNameForNS(const char *containerName, const char *hostname)
564 // ============================================================================
566 string SALOME_NamingService::ContainerName(const char *containerName)
570 if (strlen(containerName) == 0)
571 ret = "FactoryServer";
578 // ============================================================================
579 /*! \brief build a container name, given a MachineParameters struct.
581 * Build a container name with a MachineParameters struct. In case of multi
582 * processor machine, container name is suffixed with _nbproc. nproc equals
583 * (number of nodes)*(number of processor per nodes).
584 * \param params struct from which we get container name (may be
585 * empty), number of nodes and number of processor
587 * \return a container name without the path.
588 * \sa BuildContainerNameForNS(const Engines::MachineParameters& params,
589 * const char *hostname)
591 // ============================================================================
594 SALOME_NamingService::ContainerName(const Engines::MachineParameters& params)
600 else if ( (params.nb_node <= 0) && (params.nb_proc_per_node <= 0) )
602 else if ( params.nb_node == 0 )
603 nbproc = params.nb_proc_per_node;
604 else if ( params.nb_proc_per_node == 0 )
605 nbproc = params.nb_node;
607 nbproc = params.nb_node * params.nb_proc_per_node;
609 string ret = ContainerName(params.container_name);
613 char *suffix = new char[8];
614 sprintf(suffix, "_%d", nbproc);
621 // ============================================================================
622 /*! \brief build a string representing a container in Naming Service.
624 * Build a string representing the absolute pathname of a container in
625 * SALOME_NamingService. This form gives a suffixed containerName in case of
626 * multi processor machine.
627 * \param containerName name of the container in which the component is
629 * \param hostname name of the host of the container, without domain names.
630 * \return the path under the form /Containers/hostname/containerName
631 * \sa ContainerName(const Engines::MachineParameters& params)
633 // ============================================================================
635 string SALOME_NamingService::BuildContainerNameForNS(const char *containerName,
636 const char *hostname)
638 string ret = "/Containers/";
641 ret += ContainerName(containerName);
646 // ============================================================================
647 /*! \brief build a string representing a container in Naming Service.
649 * Build a string representing the absolute pathname of a container in
650 * SALOME_NamingService.
651 * \param params used as it is, or replaced by FactoryServer if empty.
652 * \param hostname name of the host of the container, without domain names.
653 * \return the path under the form /Containers/hostname/containerName
654 * \sa ContainerName(const char *containerName)
656 // ============================================================================
659 SALOME_NamingService::
660 BuildContainerNameForNS(const Engines::MachineParameters& params,
661 const char *hostname)
663 string ret = "/Containers/";
666 ret += ContainerName(params);
671 // ============================================================================
672 /*! \brief search a name in current directory.
674 * Search a name in the current directory. after call, the current directory
675 * is changed to the directory containing the last occurence of name found.
676 * If no occurence found (see return value), current directory remains
679 * \param name the name to search.
680 * \return number of occurences found.
681 * \sa Change_Directory(const char* Path)
683 // ============================================================================
685 int SALOME_NamingService::Find(const char* name)
686 throw(ServiceUnreachable)
688 MESSAGE("BEGIN OF Find " << name);
690 Utils_Locker lock (&_myMutex);
692 CORBA::Long occurence_number = 0 ;
696 _Find(name, occurence_number);
699 catch (CORBA::SystemException&)
701 INFOS("!!!Find() : CORBA::SystemException : unable to contact"
702 << " the naming service");
703 throw ServiceUnreachable();
706 return occurence_number;
709 // ============================================================================
710 /*! \brief Creates a directory (context_name)
712 * Creates a directory (context_name) relative to the current directory
713 * (current context) or relative to the root directory (root context), if
714 * the path given begins with a '/'.
715 * If the NamingService is out, the exception ServiceUnreachable is thrown.
716 * \param Path A relative or absolute pathname to store the object reference.
717 * If the pathname begins with a '/', pathname is taken
718 * as an absolute pathname. Else, pathname is taken as a relative
719 * path, to current context. Prefer absolute pathname, relative
720 * pathname are not safe, when SALOME_NamingService object is
721 * shared or use in multithreaded context.
722 * \return true if successfull
723 * (creation not strictly garanteed if true, because Register may
724 * catch some specific unlikely exception without throw anything
725 * --- to be corrected ---)
726 * \sa RegisterCORBA::Object_ptr ObjRef, const char* Path)
728 // ============================================================================
730 bool SALOME_NamingService::Create_Directory(const char* Path)
731 throw(ServiceUnreachable)
733 MESSAGE("BEGIN OF Create_Directory");
735 Utils_Locker lock (&_myMutex);
739 // --- if path empty, nothing to create, no context change
744 // --- if path ='/', nothing to create, only change to root_context
748 MESSAGE("Create Directory '/', just change to root_context");
749 _current_context = _root_context;
753 // --- path must end with '/'
755 if (path[path.length()-1] != '/') path += '/';
757 Register(CORBA::Object::_nil(), path.c_str());
761 // ============================================================================
762 /*! \brief change current directory to the given path
764 * change the current directory to the given path in parameter.
765 * Warning: avoid use when the SALOME_NamingService instance is shared by
766 * several threads (current context may be modified by another thread).
767 * If the path is empty, nothing done return OK.
768 * If Path ="/", the current directory changes to the root directory.
769 * If the NamingService is out, the exception ServiceUnreachable is thrown.
770 * \param Path the new current directory
771 * \return true if the change succeeded
773 // ============================================================================
775 bool SALOME_NamingService::Change_Directory(const char* Path)
776 throw(ServiceUnreachable)
778 // MESSAGE("BEGIN OF Change_Directory " << Path);
779 Utils_Locker lock (&_myMutex);
783 // --- if path empty, nothing to do
788 // --- if path ='/', nothing to resolve, only change to root_context
792 // MESSAGE("Change_Directory is called to go to the root_context");
793 _current_context = _root_context;
797 CosNaming::NamingContext_var current_context = _current_context;
798 bool changeOK = false;
800 // --- replace _current_context with _root_context if Path begins whith '/'
803 current_context = _root_context;
805 // --- need to resolve directory path
807 ASSERT(!CORBA::is_nil(current_context));
809 if (path[path.length()-1] != '/') path += '/';
811 CosNaming::Name context_name;
812 vector<string> splitPath;
813 _createContextNameDir(path.c_str(),
818 // --- Context creation
822 CORBA::Object_var obj = current_context->resolve(context_name);
823 current_context = CosNaming::NamingContext::_narrow(obj);
824 ASSERT(!CORBA::is_nil(current_context));
825 _current_context = current_context;
829 catch (CosNaming::NamingContext::NotFound& ex)
831 CosNaming::Name n = ex.rest_of_name;
833 if (ex.why == CosNaming::NamingContext::missing_node)
834 MESSAGE( "Change_Directory() : " << (char *) n[0].id
835 << " (" << (char *) n[0].kind << ") not found");
836 if (ex.why == CosNaming::NamingContext::not_context)
837 INFOS("Change_Directory() : " << (char *) n[0].id
838 << " (" << (char *) n[0].kind
839 << ") is not a context" );
840 if (ex.why == CosNaming::NamingContext::not_object)
841 INFOS( "Change_Directory() : " << (char *) n[0].id
842 << " (" << (char *) n[0].kind
843 << ") is not an object" );
846 catch (CosNaming::NamingContext::CannotProceed&)
848 INFOS("Change_Directory(): CosNaming::NamingContext::CannotProceed");
851 catch (CosNaming::NamingContext::InvalidName&)
853 INFOS("Change_Directory(): CosNaming::NamingContext::InvalidName");
856 catch (CORBA::SystemException&)
858 INFOS("Change_Directory():CORBA::SystemException : unable to contact"
859 << "the naming service");
860 throw ServiceUnreachable();
866 // ============================================================================
867 /*! \brief get the current directory path
869 * Get the current directory path.
870 * If the NamingService is out, the exception ServiceUnreachable is thrown.
871 * \return the path of the current_context
872 * \sa _current_directory
874 // ============================================================================
876 char* SALOME_NamingService::Current_Directory()
877 throw(ServiceUnreachable)
879 MESSAGE("BEGIN OF Current_Directory");
881 Utils_Locker lock (&_myMutex);
883 CosNaming::NamingContext_var ref_context = _current_context;
885 vector<string> splitPath;
888 bool notFound = true ;
890 // --- start search from root context
892 _current_context = _root_context ;
896 _current_directory(splitPath, lengthPath, ref_context, notFound );
899 catch (CORBA::SystemException&)
901 INFOS("Current_Directory(): CORBA::SystemException: unable to contact"
902 << " the naming service" )
903 throw ServiceUnreachable();
907 lengthPath = splitPath.size();
908 for (int k = 0 ; k < lengthPath ;k++)
911 path += splitPath[k];
915 _current_context = ref_context ;
917 return strdup(path.c_str());
920 // ============================================================================
921 /*! \brief list recursively all objects in the current context
923 * List and print via trace all directories and objects in the current
924 * context. Trace must be activated: compile option _DEBUG_
925 * If the NamingService is out, the exception ServiceUnreachable is thrown
927 // ============================================================================
929 void SALOME_NamingService::list()
930 throw(ServiceUnreachable)
932 MESSAGE("Begin of list");
934 Utils_Locker lock (&_myMutex)
937 CosNaming::BindingList_var binding_list;
938 CosNaming::BindingIterator_var binding_iterator;
939 CosNaming::Binding_var binding ;
941 unsigned long nb = 0 ; // --- only for the BindingIterator use,
942 // to access the bindings
944 CosNaming::NamingContext_var ref_context = _current_context;
946 _current_context->list(nb, binding_list, binding_iterator) ;
948 if (! CORBA::is_nil(binding_iterator))
950 while (binding_iterator->next_one(binding))
952 CosNaming::Name bindingName = binding->binding_name;
954 if (binding->binding_type == CosNaming::ncontext)
956 MESSAGE( "Context : " << bindingName[0].id );
960 Change_Directory(bindingName[0].id);
963 catch (ServiceUnreachable&)
965 INFOS( "list(): ServiceUnreachable" )
966 throw ServiceUnreachable();
970 _current_context = ref_context ;
973 else if (binding->binding_type == CosNaming::nobject)
975 MESSAGE( "Object : " << bindingName[0].id );
979 binding_iterator->destroy();
983 // ============================================================================
984 /*! \brief list all the objects in the current directory.
986 * get a list of all the objects in the current directory, without recursion
987 * on the subdirectories. Only the objects are listed, not the directories.
988 * If the NamingService is out, the exception ServiceUnreachable is thrown.
989 * \return list of strings with objects found.
990 * \sa vector<string> list_directory_recurs()
992 // ============================================================================
994 vector<string> SALOME_NamingService::list_directory()
995 throw(ServiceUnreachable)
997 // MESSAGE("list_directory");
998 vector<string> dirList ;
1001 CosNaming::BindingList_var binding_list;
1002 CosNaming::BindingIterator_var binding_iterator;
1003 CosNaming::Binding_var binding ;
1005 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1006 // to access the bindings
1008 CosNaming::NamingContext_var ref_context = _current_context;
1010 _current_context->list(nb, binding_list, binding_iterator);
1012 if (binding_iterator->_is_nil())
1015 while (binding_iterator->next_one(binding))
1017 CosNaming::Name bindingName = binding->binding_name;
1019 if (binding->binding_type == CosNaming::nobject)
1021 // remove memory leak
1022 // dirList.push_back(CORBA::string_dup(bindingName[0].id));
1023 dirList.push_back(string(bindingName[0].id));
1027 // for (unsigned int ind = 0; ind < dirList.size(); ind++)
1028 // MESSAGE("list_directory : Object : " << dirList[ind]);
1030 binding_iterator->destroy();
1036 // ============================================================================
1037 /*! \brief list all the subdirectories in the current directory.
1039 * get a list of all the subdirectories in the current directory,
1040 * without recursion on the subdirectories.
1041 * Only the subdirectories are listed, not the objects.
1042 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1043 * \return list of strings with directories found.
1044 * \sa vector<string> list_directory()
1046 // ============================================================================
1048 vector<string> SALOME_NamingService::list_subdirs()
1049 throw(ServiceUnreachable)
1051 MESSAGE("list_subdirs");
1052 vector<string> dirList ;
1055 CosNaming::BindingList_var binding_list;
1056 CosNaming::BindingIterator_var binding_iterator;
1057 CosNaming::Binding_var binding ;
1059 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1060 // to access the bindings
1062 CosNaming::NamingContext_var ref_context = _current_context;
1064 _current_context->list(nb, binding_list, binding_iterator) ;
1066 if (binding_iterator->_is_nil())
1069 while (binding_iterator->next_one(binding))
1071 CosNaming::Name bindingName = binding->binding_name;
1073 if (binding->binding_type == CosNaming::ncontext)
1075 dirList.push_back(bindingName[0].id.in());
1079 for (unsigned int ind = 0; ind < dirList.size(); ind++)
1080 MESSAGE("list_directory : Object : " << dirList[ind]);
1082 binding_iterator->destroy();
1087 // ============================================================================
1088 /*! \brief list all the objects in the current directory and subdirectories.
1090 * get a list of all the objects in the current directory, with recursion
1091 * on the subdirectories. Only the objects are listed, not the directories.
1092 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1093 * \return list of strings with objects found.
1094 * \sa vector<string> list_directory()
1096 // ============================================================================
1098 vector<string> SALOME_NamingService::list_directory_recurs()
1099 throw(ServiceUnreachable)
1101 MESSAGE("list_directory_recurs");
1103 Utils_Locker lock (&_myMutex);
1105 vector<string> dirList ;
1107 char* currentDir = Current_Directory();
1109 _list_directory_recurs(dirList, "", currentDir);
1116 // ============================================================================
1117 /*! \brief destroy an entry in naming service.
1119 * Destroy an association Path - Object Reference.
1120 * If the NamingService is out, the exception ServiceUnreachable is thrown
1121 * \param Path object path
1123 // ============================================================================
1125 void SALOME_NamingService::Destroy_Name(const char* Path)
1126 throw(ServiceUnreachable)
1128 MESSAGE("BEGIN OF Destroy_Name " << Path);
1130 Utils_Locker lock (&_myMutex);
1134 // --- if path empty, nothing to do
1139 // --- if path = '/' not applicable, nothing to do
1144 // --- if path begins with '/', set current directory to root context
1147 _current_context = _root_context;
1149 // --- context of the directory containing the object
1151 CosNaming::Name context_name;
1152 vector<string> splitPath;
1153 int dimension_resultat = _createContextNameDir(path.c_str(),
1160 if (dimension_resultat > 0)
1162 // --- path contains a directory, not only an object name
1163 // switch to the new directory (or return if directory not found)
1167 CORBA::Object_var obj = _current_context->resolve(context_name);
1168 _current_context = CosNaming::NamingContext::_narrow(obj);
1172 catch (CosNaming::NamingContext::NotFound &ex)
1174 // --- failed to resolve
1177 CosNaming::Name n = ex.rest_of_name;
1179 if (ex.why == CosNaming::NamingContext::missing_node)
1180 INFOS( "Destroy_Name(): " << (char *) n[0].id
1181 << " (" << (char *) n[0].kind << ") not found" );
1182 if (ex.why == CosNaming::NamingContext::not_context)
1183 INFOS( "Destroy_Name() : " << (char *) n[0].id
1184 << " (" << (char *) n[0].kind
1185 << ") is not a context" );
1186 if (ex.why == CosNaming::NamingContext::not_object)
1187 INFOS( "Destroy_Name() : " << (char *) n[0].id
1188 << " (" << (char *) n[0].kind
1189 << ") is not an object" );
1192 catch (CosNaming::NamingContext::InvalidName &)
1194 INFOS("Destroy_Name: CosNaming::NamingContext::InvalidName");
1197 catch (CosNaming::NamingContext::CannotProceed &)
1199 INFOS("Destroy_Name: CosNaming::NamingContext::CannotProceed");
1202 catch (CORBA::SystemException&)
1204 INFOS("Destroy_Name : CORBA::SystemException: "
1205 << "unable to contact the naming service");
1206 throw ServiceUnreachable();
1209 if (! exist) return;
1212 ASSERT(!CORBA::is_nil(_current_context));
1214 // --- The current directory is now the directory where the object should
1217 int sizePath = splitPath.size();
1218 if (sizePath > dimension_resultat)
1220 ASSERT(sizePath == dimension_resultat+1);
1221 context_name.length(1);
1225 // --- the last element is an object and not a directory
1227 context_name[0].id =
1228 CORBA::string_dup(splitPath[dimension_resultat].c_str());
1229 context_name[0].kind = CORBA::string_dup("object");
1230 SCRUTE(context_name[0].id);
1232 _current_context->unbind(context_name);
1233 MESSAGE("The object " << context_name[0].id << " has been deleted");
1236 catch (CosNaming::NamingContext::NotFound& ex)
1238 CosNaming::Name n = ex.rest_of_name;
1240 if (ex.why == CosNaming::NamingContext::missing_node)
1241 INFOS( "Destroy_Name() : " << (char *) n[0].id
1242 << " (" << (char *) n[0].kind << ") not found" );
1243 if (ex.why == CosNaming::NamingContext::not_context)
1244 INFOS( "Destroy_Name() : " << (char *) n[0].id
1245 << " (" << (char *) n[0].kind
1246 << ") is not a context" );
1247 if (ex.why == CosNaming::NamingContext::not_object)
1248 INFOS( "Destroy_Name() : " << (char *) n[0].id
1249 << " (" << (char *) n[0].kind
1250 << ") is not an object" );
1253 catch (CosNaming::NamingContext::CannotProceed&)
1255 INFOS( "Destroy_Name(): CosNaming::NamingContext::CannotProceed");
1258 catch (CosNaming::NamingContext::InvalidName&)
1260 INFOS( "Destroy_Name(): CosNaming::NamingContext::InvalidName");
1263 catch (CORBA::SystemException&)
1265 INFOS( "Destroy_Name(): CORBA::SystemException: unable to contact"
1266 << " the naming service");
1267 throw ServiceUnreachable();
1272 // ============================================================================
1273 /*! \brief Destroy an empty directory
1275 * Destroy an empty directory in Naming Service.
1276 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1277 * \param Path directory path
1279 // ============================================================================
1281 void SALOME_NamingService::Destroy_Directory(const char* Path)
1282 throw(ServiceUnreachable)
1284 MESSAGE("BEGIN OF Destroy_Directory " << Path);
1286 Utils_Locker lock (&_myMutex);
1290 // --- if path empty, nothing to do
1295 // --- if path begins with '/', set current directory to root context
1298 _current_context = _root_context;
1300 CosNaming::NamingContext_var ref_context = _current_context;
1302 // --- path must ends with '/' for a directory
1304 if (path[path.size() -1] != '/')
1307 // --- context of the directory
1309 CosNaming::Name context_name;
1310 vector<string> splitPath;
1311 int dimension_resultat = _createContextNameDir(path.c_str(),
1317 if (dimension_resultat > 0)
1319 // --- path contains a directory, not only an object name
1320 // switch to the new directory (or return if directory not found)
1324 CORBA::Object_var obj = _current_context->resolve(context_name);
1325 _current_context = CosNaming::NamingContext::_narrow(obj);
1329 catch (CosNaming::NamingContext::NotFound &ex)
1331 // --- failed to resolve
1334 CosNaming::Name n = ex.rest_of_name;
1336 if (ex.why == CosNaming::NamingContext::missing_node)
1337 INFOS( "Destroy_Directory(): " << (char *) n[0].id
1338 << " (" << (char *) n[0].kind << ") not found" );
1339 if (ex.why == CosNaming::NamingContext::not_context)
1340 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1341 << " (" << (char *) n[0].kind
1342 << ") is not a context" );
1343 if (ex.why == CosNaming::NamingContext::not_object)
1344 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1345 << " (" << (char *) n[0].kind
1346 << ") is not an object" );
1349 catch (CosNaming::NamingContext::InvalidName &)
1351 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1354 catch (CosNaming::NamingContext::CannotProceed &)
1356 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1359 catch (CORBA::SystemException&)
1361 INFOS("Destroy_Directory : CORBA::SystemException: "
1362 << "unable to contact the naming service");
1363 throw ServiceUnreachable();
1366 if (! exist) return;
1369 ASSERT(!CORBA::is_nil(_current_context));
1371 // --- Context Destruction
1373 bool isContextDestroyed = false;
1376 _current_context->destroy();
1377 MESSAGE( "The context " << path << " has been deleted" );
1378 isContextDestroyed = true;
1381 catch (CosNaming::NamingContext::NotEmpty&)
1383 INFOS( "Destroy_Directory(): CosNaming::NamingContext::NoEmpty "
1384 << path << " is not empty" );
1387 catch (CORBA::SystemException&)
1389 INFOS( "Destroy_Directory():CORBA::SystemException : "
1390 << "unable to contact the naming service");
1391 throw ServiceUnreachable();
1394 // --- go to the reference directory
1396 _current_context = ref_context ;
1398 ASSERT(!CORBA::is_nil(_current_context));
1400 if (isContextDestroyed)
1404 _current_context->unbind(context_name);
1405 MESSAGE( "The bind to the context "
1406 << context_name[0].id
1407 << " has been deleted" );
1410 catch (CosNaming::NamingContext::NotFound& ex)
1412 CosNaming::Name n = ex.rest_of_name;
1414 if (ex.why == CosNaming::NamingContext::missing_node)
1415 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1416 << " (" << (char *) n[0].kind << ") not found" );
1417 if (ex.why == CosNaming::NamingContext::not_context)
1418 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1419 << " (" << (char *) n[0].kind
1420 << ") is not a context" );
1421 if (ex.why == CosNaming::NamingContext::not_object)
1422 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1423 << " (" << (char *) n[0].kind
1424 << ") is not an object" );
1427 catch (CosNaming::NamingContext::CannotProceed&)
1429 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1432 catch (CosNaming::NamingContext::InvalidName&)
1434 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1437 catch (CORBA::SystemException&)
1439 INFOS("Destroy_Directory:CORBA::SystemException : unable to contact"
1440 << " the naming service");
1441 throw ServiceUnreachable();
1446 // ============================================================================
1447 /*! \brief Destroy a directory with its contents.
1449 * Destroy the objects associations in a directory, and the directory itself,
1450 * if there is no subdirectories.
1451 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1452 * \param Path the directory path.
1454 // ============================================================================
1456 void SALOME_NamingService::Destroy_FullDirectory(const char* Path)
1457 throw(ServiceUnreachable)
1459 MESSAGE("begin of Destroy_FullDirectory " << Path);
1460 if( Change_Directory(Path) )
1462 vector<string> contList = list_directory();
1464 for (unsigned int ind = 0; ind < contList.size(); ind++)
1465 Destroy_Name(contList[ind].c_str());
1467 Destroy_Directory(Path);
1471 // ============================================================================
1472 /*! \brief initialize root context (root directory)
1474 * the root context initialisation must be done when the SALOME_NamingService
1475 * instance is created and before any othe call. See constructors.
1477 // ============================================================================
1479 void SALOME_NamingService::_initialize_root_context()
1481 //MESSAGE("Get the root context");
1485 CORBA::Object_var obj = _orb->resolve_initial_references("NameService");
1486 _root_context = CosNaming::NamingContext::_narrow(obj);
1487 _current_context = _root_context ;
1488 ASSERT(!CORBA::is_nil(_root_context));
1491 catch (CORBA::SystemException&)
1493 INFOS("CORBA::SystemException: unable to contact the naming service");
1494 throw ServiceUnreachable();
1499 INFOS("Unknown Exception: unable to contact the naming service");
1500 throw ServiceUnreachable();
1504 // ============================================================================
1505 /*! \brief transform a string path in CosNaming structure.
1507 * Transform a path given as a string in a CosNaming structure.
1508 * \param path a relative or absolute path, with or without an object.
1509 * An absolute path begins with '/'.
1510 * A path without an object ends with '/'.
1511 * \param context_name CosNaming structure to put the path.
1512 * \param splitPath a vector of string with subdirectories and final
1514 * \param onlyDir if true, final object (if any) is ommited
1516 * if false, final object (if any) is included in
1518 * \return dimension of context_name
1520 // ============================================================================
1523 SALOME_NamingService::_createContextNameDir(string path,
1524 CosNaming::Name& context_name,
1525 vector<string>& splitPath,
1531 string::size_type begIdx, endIdx;
1532 const string delims("/");
1533 splitPath.resize(0);
1534 bool endWithDelim = false;
1536 begIdx = path.find_first_not_of(delims);
1537 while (begIdx != string::npos)
1539 endIdx = path.find_first_of(delims, begIdx);
1540 if (endIdx == path.length()-1)
1541 endWithDelim = true;
1542 if (endIdx == string::npos)
1543 endIdx = path.length();
1544 int lsub = endIdx - begIdx;
1546 splitPath.push_back(path.substr(begIdx, lsub));
1547 begIdx = path.find_first_not_of(delims, endIdx);
1551 if (onlyDir) // only directory part
1553 dim = splitPath.size()-1; // omit final object
1554 if (endWithDelim) // unless the path ends with a delimiter
1556 endWithDelim = true;
1559 dim = splitPath.size(); // directories and final object
1561 context_name.length(dim);
1562 for (int i=0; i<dim; i++)
1564 // SCRUTE(splitPath[i]);
1565 context_name[i].id = CORBA::string_dup(splitPath[i].c_str());
1566 if (!endWithDelim && (i == dim-1)) // here, the last string is an object
1568 context_name[i].kind = CORBA::string_dup("object");
1569 // MESSAGE("--- " <<splitPath[i] <<".object");
1573 context_name[i].kind = CORBA::string_dup("dir");
1574 // MESSAGE("--- " <<splitPath[i] <<".dir");
1580 // ============================================================================
1581 /*! \brief search a name in current directory.
1583 * Search a name in the current directory. after call, the current directory
1584 * is changed to the directory containing the last occurence of name found.
1585 * If no occurence found (see return value), current directory remains
1586 * unchanged. The call is recursive.
1588 * \param name the name to search.
1589 * \param occurence_number number of occurence already found (incremented)
1591 // ============================================================================
1593 void SALOME_NamingService::_Find(const char* name,
1594 CORBA::Long& occurence_number)
1596 MESSAGE("BEGIN OF _Find "<< occurence_number << " " << name);
1598 CosNaming::BindingList_var binding_list;
1599 CosNaming::BindingIterator_var binding_iterator;
1600 CosNaming::Binding_var binding;
1602 unsigned long nb = 0 ; // --- only for the use of the BindingIterator,
1603 // to access the bindings
1605 CosNaming::NamingContext_var ref_context = _current_context;
1606 CosNaming::NamingContext_var found_context = _current_context;
1608 _current_context->list(nb, binding_list, binding_iterator) ;
1610 if (! CORBA::is_nil(binding_iterator))
1612 while (binding_iterator->next_one(binding))
1614 CosNaming::Name bindingName = binding->binding_name;
1616 if (binding->binding_type == CosNaming::ncontext)
1618 // --- We work on a directory,
1619 // the search should be done in this directory
1621 Change_Directory(bindingName[0].id);
1622 _Find(name, occurence_number);
1624 // --- We'll go back to the initial context
1626 _current_context = ref_context ;
1629 else if (binding->binding_type == CosNaming::nobject)
1631 // --- We work on an object...
1633 if (!strcmp( bindingName[0].id, name))
1635 //MESSAGE("One occurence was found");
1638 // --- We keep in memory the directory where
1639 // one occurence was found
1641 found_context = _current_context ;
1646 binding_iterator->destroy();
1648 // --- We go to the last directory where an occurence was found
1650 _current_context = found_context;
1652 SCRUTE(occurence_number);
1655 // ============================================================================
1656 /*! \brief find the current directory path.
1658 * Parse the naming service tree to find the current context and give the
1659 * associated directory path (relative to root context).
1661 * \param lengthResult
1662 * \param contextToFind
1665 // ============================================================================
1668 SALOME_NamingService::
1669 _current_directory(vector<string>& splitPath,
1671 CosNaming::NamingContext_var contextToFind,
1674 MESSAGE("BEGIN OF _current_Directory");
1676 CosNaming::BindingList_var binding_list;
1677 CosNaming::BindingIterator_var binding_iterator;
1678 CosNaming::Binding_var binding;
1680 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1681 // to access the bindings
1683 CosNaming::NamingContext_var ref_context = _current_context;
1684 CosNaming::NamingContext_var temp_context = _current_context;
1686 _current_context->list(nb, binding_list, binding_iterator);
1688 if ( !binding_iterator->_is_nil() )
1690 while ((binding_iterator->next_one(binding)) && notFound)
1692 CosNaming::Name bindingName = binding->binding_name;
1694 if (binding->binding_type == CosNaming::ncontext)
1696 // --- directory, search in it
1698 const char* bindingNameid=bindingName[0].id;
1699 splitPath.push_back(bindingNameid);
1702 CORBA::Object_var obj = _current_context->resolve(bindingName);
1703 temp_context = CosNaming::NamingContext::_narrow(obj);
1705 if (temp_context->_is_equivalent(contextToFind))
1707 MESSAGE("The context is found, we stop the search");
1714 SCRUTE(bindingName[0].id);
1715 Change_Directory(bindingName[0].id);
1716 _current_directory(splitPath,
1723 // --- go back to the initial context
1725 _current_context = ref_context;
1727 MESSAGE("Just before the delete of "
1728 << splitPath[lengthResult-1]);
1729 splitPath.pop_back();
1736 binding_iterator->destroy();
1739 // --- return to the last directory where an occurence was found
1741 _current_context = ref_context ;
1745 // ============================================================================
1746 /*! \brief list recursively all objects in the given directory and subdirs.
1748 * get a list of all the objects in the current directory, with recursion
1749 * on the subdirectories. Only the objects are listed, not the directories.
1750 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1751 * _current_context must refer to absCurDirectory.
1753 * \param myList The list that will be filled.
1754 * \param relativeSubDir The directory relative to absCurDirectory in which
1755 * the objects are found.
1756 * \param absCurDirectory The current directory, absolute path
1758 // ============================================================================
1760 void SALOME_NamingService::_list_directory_recurs(vector<string>& myList,
1761 string relativeSubDir,
1762 string absCurDirectory)
1764 CosNaming::BindingList_var binding_list;
1765 CosNaming::BindingIterator_var binding_iterator;
1766 CosNaming::Binding_var binding ;
1768 unsigned long nb = 0 ; // --- only for thethe use of BindingIterator
1769 // to access the bindings
1773 CosNaming::NamingContext_var ref_context = _current_context;
1775 if (! relativeSubDir.empty())
1777 Change_Directory(relativeSubDir.c_str());
1778 absDir = absCurDirectory + "/" + relativeSubDir;
1782 absDir = absCurDirectory;
1785 _current_context->list(nb, binding_list, binding_iterator) ;
1787 if (! CORBA::is_nil(binding_iterator))
1789 while (binding_iterator->next_one(binding))
1791 CosNaming::Name bindingName = binding->binding_name;
1793 if (binding->binding_type == CosNaming::ncontext)
1795 string relativeSdir(bindingName[0].id);
1796 _list_directory_recurs(myList, relativeSdir, absDir);
1799 else if (binding->binding_type == CosNaming::nobject)
1801 string objName(bindingName[0].id);
1802 string elt = absDir + "/" + objName;
1804 myList.push_back(elt);
1808 binding_iterator->destroy();
1810 if (! relativeSubDir.empty())
1812 _current_context = ref_context;
1816 // ============================================================================
1817 /*! \brief return a stringified reference of root context
1819 * \return a stringified reference of root context
1821 // ============================================================================
1823 char * SALOME_NamingService::getIORaddr()
1825 return _orb->object_to_string(_root_context);