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 // ============================================================================
40 /*! \brief Default Constructor without ORB reference.
42 * After Default Constructor, one needs to initialize ORB.
43 * \sa init_orb(CORBA::ORB_ptr orb), SALOME_NamingService(CORBA::ORB_ptr orb)
45 // ============================================================================
47 SALOME_NamingService::SALOME_NamingService()
49 MESSAGE("SALOME_NamingService default constructor");
50 _orb = CORBA::ORB::_nil();
51 _root_context = CosNaming::NamingContext::_nil();
54 // ============================================================================
55 /*! \brief Standard Constructor, with ORB reference.
57 * Initializes the naming service root context
58 * \param orb CORBA::ORB_ptr arguments
60 // ============================================================================
62 SALOME_NamingService::SALOME_NamingService(CORBA::ORB_ptr orb)
64 MESSAGE("SALOME_NamingService creation");
66 _initialize_root_context();
69 // ============================================================================
70 /*! \brief Standard destructor.
72 * The standard destructor does nothing special.
74 // ============================================================================
76 SALOME_NamingService::~SALOME_NamingService()
78 // Problem MESSAGE with singleton: late destruction,
79 // after trace system destruction ?
80 //MESSAGE("SALOME_NamingService destruction");
83 // ============================================================================
84 /*! \brief initializes ORB reference and naming service root context.
86 * Initializes ORB reference and naming service root context.
87 * For use after default constructor.
88 * \param orb CORBA::ORB_ptr arguments
90 // ============================================================================
92 void SALOME_NamingService::init_orb(CORBA::ORB_ptr orb)
94 MESSAGE("SALOME_NamingService initialisation");
96 Utils_Locker lock (&_myMutex);
99 _initialize_root_context();
102 // ============================================================================
103 /*! \brief Registers a CORBA object reference under a path.
105 * Registers a CORBA object reference under a path. If the path ends with '/',
106 * only a directory is created.
107 * If the NamingService is out, the exception ServiceUnreachable is thrown.
108 * \param ObjRef CORBA object reference to associate to the path. To create
109 * only a directory, give nil pointer.
110 * \param Path A relative or absolute pathname to store the object reference.
111 * If the pathname begins with a '/', pathname is taken
112 * as an absolute pathname. Else, pathname is taken as a relative
113 * path, to current context. Prefer absolute pathname, relative
114 * pathname are not safe, when SALOME_NamingService object is
115 * shared or use in multithreaded context.
116 * If the path ends with '/', only a directory is created.
117 * \sa Change_Directory(const char* Path),
118 * Create_Directory(const char* Path)
119 * CORBA::Object_ptr Resolve(const char* Path)
121 // ============================================================================
123 void SALOME_NamingService::Register(CORBA::Object_ptr ObjRef,
125 throw(ServiceUnreachable)
127 MESSAGE("BEGIN OF Register: " << Path);
129 Utils_Locker lock (&_myMutex);
131 // --- _current_context is replaced to the _root_context
132 // if the Path begins whith '/'
135 _current_context = _root_context;
138 // --- the resolution of the directory path has to be done
139 // to place the current_context to the correct node
141 CosNaming::Name context_name;
142 vector<string> splitPath;
143 int dimension_resultat = _createContextNameDir(Path,
148 CORBA::Boolean not_exist = false;
150 if (dimension_resultat > 0){
151 // A directory is treated (not only an object name)
152 // test if the directory where ObjRef should be recorded already exists
153 // If not, create the new context
156 CORBA::Object_var obj = _current_context->resolve(context_name);
157 _current_context = CosNaming::NamingContext::_narrow(obj);
160 catch (CosNaming::NamingContext::NotFound &){
161 // --- failed to resolve, therefore assume cold start
165 catch (CosNaming::NamingContext::InvalidName &){
166 INFOS("Register() : CosNaming::NamingContext::InvalidName");
169 catch (CosNaming::NamingContext::CannotProceed &){
170 INFOS("Register() : CosNaming::NamingContext::CannotProceed");
173 catch (CORBA::SystemException&){
174 INFOS("Register() : CORBA::SystemException: "
175 << "unable to contact the naming service");
176 throw ServiceUnreachable();
181 context_name.length(1);
182 for (int i = 0 ; i < dimension_resultat ;i++){
183 context_name[0].id = CORBA::string_dup(splitPath[i].c_str());
184 context_name[0].kind = CORBA::string_dup("dir");
185 // SCRUTE(_context_name[0].id);
186 // --- check if the path is created
188 // --- if the context is already created, nothing to do
189 CORBA::Object_var obj = _current_context->resolve(context_name);
190 _current_context = CosNaming::NamingContext::_narrow(obj);
193 catch (CosNaming::NamingContext::NotFound &){
195 // --- the context must be created
196 CosNaming::NamingContext_var temp_context =
197 _current_context->bind_new_context(context_name);
198 _current_context = temp_context;
200 catch (CosNaming::NamingContext::AlreadyBound&){
201 CORBA::Object_var obj = _current_context->resolve(context_name);
202 _current_context = CosNaming::NamingContext::_narrow(obj);
208 catch (CosNaming::NamingContext::AlreadyBound&){
209 INFOS("Register() : CosNaming::NamingContext::AlreadyBound");
212 catch (CosNaming::NamingContext::NotFound& ex){
213 CosNaming::Name n = ex.rest_of_name;
215 if (ex.why == CosNaming::NamingContext::missing_node)
216 INFOS("Register() : " << (char *) n[0].id
217 << " (" << (char *) n[0].kind << ") not found");
219 if (ex.why == CosNaming::NamingContext::not_context)
220 INFOS("Register() : " << (char *) n[0].id
221 << " (" << (char *) n[0].kind
222 << ") is not a context");
224 if (ex.why == CosNaming::NamingContext::not_object)
225 INFOS("Register() : " << (char *) n[0].id
226 << " (" << (char *) n[0].kind
227 << ") is not an object");
230 catch (CosNaming::NamingContext::CannotProceed&){
231 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
234 catch (CosNaming::NamingContext::InvalidName&){
235 INFOS("Register(): CosNaming::NamingContext::InvalidName");
238 catch (CORBA::SystemException&){
239 INFOS("Register():CORBA::SystemException: "
240 << "unable to contact the naming service");
241 throw ServiceUnreachable();
246 // --- The current directory is now the directory where the object should
249 int sizePath = splitPath.size();
250 if (sizePath > dimension_resultat){
251 ASSERT(sizePath == dimension_resultat+1);
252 context_name.length(1);
255 // --- the last element is an object and not a directory
257 context_name[0].id = CORBA::string_dup(splitPath[dimension_resultat].c_str());
258 context_name[0].kind = CORBA::string_dup("object");
259 //SCRUTE(context_name[0].id);
261 _current_context->bind(context_name, ObjRef);
264 catch (CosNaming::NamingContext::NotFound& ex){
265 CosNaming::Name n = ex.rest_of_name;
267 if (ex.why == CosNaming::NamingContext::missing_node)
268 INFOS("Register() : " << (char *) n[0].id
269 << " (" << (char *) n[0].kind << ") not found");
271 if (ex.why == CosNaming::NamingContext::not_context)
272 INFOS("Register() : " << (char *) n[0].id
273 << " (" << (char *) n[0].kind
274 << ") is not a context");
276 if (ex.why == CosNaming::NamingContext::not_object)
277 INFOS("Register() : " << (char *) n[0].id
278 << " (" << (char *) n[0].kind
279 << ") is not an object");
282 catch (CosNaming::NamingContext::CannotProceed&){
283 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
286 catch (CosNaming::NamingContext::InvalidName&){
287 INFOS("Register(): CosNaming::NamingContext::InvalidName");
290 catch (CosNaming::NamingContext::AlreadyBound&){
291 INFOS("Register(): CosNaming::NamingContext::AlreadyBound, "
292 << "object will be rebind");
293 _current_context->rebind(context_name, ObjRef);
296 catch (CORBA::SystemException&){
297 INFOS("!!!Register(): CORBA::SystemException: "
298 << "unable to contact the naming service");
299 throw ServiceUnreachable();
304 // ============================================================================
305 /*! \brief get the CORBA object reference associated to a name.
307 * get the CORBA object reference associated to a complete name with a path.
308 * If the NamingService is out, the exception ServiceUnreachable is thrown
309 * \param Path pathname. If the pathname begins with a '/', pathname is taken
310 * as an absolute pathname. Else, pathname is taken as a relative
311 * path, to current context. Prefer absolute pathname, relative
312 * pathname are not safe, when SALOME_NamingService object is
313 * shared or use in multithreaded context.
314 * \return the object reference if it exists under the pathname,
315 * or nil reference in other cases.
316 * \sa Register(CORBA::Object_ptr ObjRef, const char* Path),
317 * Change_Directory(const char* Path)
319 // ============================================================================
321 CORBA::Object_ptr SALOME_NamingService::Resolve(const char* Path)
322 throw(ServiceUnreachable)
324 // MESSAGE("BEGIN OF Resolve: " << Path);
326 Utils_Locker lock (&_myMutex);
328 // --- _current_context is replaced to the _root_context
329 // if the Path begins whith '/'
333 _current_context = _root_context;
336 // --- the resolution of the directory path has to be done
337 // to place the current_context to the correct node
339 CosNaming::Name context_name;
340 vector<string> splitPath;
341 _createContextNameDir(Path,
346 ASSERT(!CORBA::is_nil(_current_context));
348 CORBA::Object_var obj = CORBA::Object::_nil();
352 obj = _current_context->resolve(context_name);
355 catch (CosNaming::NamingContext::NotFound& ex)
357 CosNaming::Name n = ex.rest_of_name;
359 if (ex.why == CosNaming::NamingContext::missing_node)
360 MESSAGE("Resolve() : " << (char *) n[0].id
361 << " (" << (char *) n[0].kind << ") not found");
363 if (ex.why == CosNaming::NamingContext::not_context)
365 << (char *) n[0].id << " (" << (char *) n[0].kind
366 << ") is not a context");
368 if (ex.why == CosNaming::NamingContext::not_object)
369 INFOS("Resolve() : " << (char *) n[0].id
370 << " (" << (char *) n[0].kind
371 << ") is not an object");
374 catch (CosNaming::NamingContext::CannotProceed&)
376 INFOS("Resolve(): CosNaming::NamingContext::CannotProceed");
379 catch (CosNaming::NamingContext::InvalidName&)
381 INFOS("Resolve(): CosNaming::NamingContext::InvalidName");
384 catch (CORBA::SystemException&)
386 INFOS("Resolve():CORBA::SystemException : unable to contact"
387 << "the naming service");
388 throw ServiceUnreachable();
394 // ============================================================================
395 /*! \brief get the CORBA object reference associated to an uncomplete name.
397 * get the CORBA object reference associated to an uncomplete name with a
398 * path. Look for the first occurence of name*.
399 * If the NamingService is out, the exception ServiceUnreachable is thrown
400 * \param Path pathname under the form "/path/name" (Absolute reference !)
401 * search the fist reference like "/path(.dir)/name*(.kind)"
402 * \return the object reference if found, or nil reference.
403 * \sa Resolve(const char* Path)
405 // ============================================================================
407 CORBA::Object_ptr SALOME_NamingService::ResolveFirst(const char* Path)
408 throw(ServiceUnreachable)
410 // MESSAGE("ResolveFirst");
412 Utils_Locker lock (&_myMutex);
415 string thePath = Path;
416 string basePath = "";
417 string name = thePath;
419 string::size_type idx = thePath.rfind('/');
421 if (idx != string::npos) // at least one '/' found
423 basePath = thePath.substr(0, idx);
424 name = thePath.substr(idx + 1);
429 CORBA::Object_var obj = CORBA::Object::_nil();
432 if (basePath.empty())
435 isOk = Change_Directory(basePath.c_str());
439 vector<string> listElem = list_directory();
440 vector<string>::iterator its = listElem.begin();
442 while (its != listElem.end())
446 if ((*its).find(name) == 0)
448 return Resolve((*its).c_str());
458 // ============================================================================
459 /*! \brief find a component instance from hostname, containername,
460 * componentName and number of processors.
462 * find a component instance from hostname, containername, componentName and
463 * number of processors.
464 * If the NamingService is out, the exception ServiceUnreachable is thrown.
465 * \param hostname name of the machine on which the component is searched.
466 * \param containerName name of the container in which the component is
468 * \param componentName name of the component we are looking for an existing
470 * \param nbproc in case of multi processor machine, container name is
471 * suffixed with _nbproc.
472 * \return the object reference
474 // ============================================================================
477 SALOME_NamingService::ResolveComponent(const char* hostname,
478 const char* containerName,
479 const char* componentName,
481 throw(ServiceUnreachable)
483 // MESSAGE("ResolveComponent");
485 Utils_Locker lock (&_myMutex);
487 string name = "/Containers/";
491 if ( strlen(containerName) != 0 )
497 char *newContainerName = new char[strlen(containerName) + 8];
498 sprintf(newContainerName, "%s_%d", containerName, nbproc);
499 name += newContainerName;
500 delete [] newContainerName;
504 name += containerName;
508 name += componentName;
510 return ResolveFirst(name.c_str());
516 if (Change_Directory(name.c_str()))
518 vector<string> contList = list_subdirs();
520 for (unsigned int ind = 0; ind < contList.size(); ind++)
522 name = contList[ind].c_str();
526 char *str_nbproc = new char[8];
527 sprintf(str_nbproc, "_%d", nbproc);
528 if( strstr(name.c_str(),str_nbproc) == NULL)
529 continue; // check only containers with _%d in name
530 delete [] str_nbproc;
534 name += componentName;
536 CORBA::Object_ptr obj = ResolveFirst(name.c_str());
538 if ( !CORBA::is_nil(obj) )
543 return CORBA::Object::_nil();
547 // ============================================================================
548 /*! \brief provide a default container name if empty.
550 * the given container name is returned unchanged, unless it is empty.
551 * \param containerName
552 * \return container name, where empty input is replaced by "FactoryServer",
554 * \sa BuildContainerNameForNS(const char *containerName, const char *hostname)
556 // ============================================================================
558 string SALOME_NamingService::ContainerName(const char *containerName)
562 if (strlen(containerName) == 0)
563 ret = "FactoryServer";
570 // ============================================================================
571 /*! \brief build a container name, given a MachineParameters struct.
573 * Build a container name with a MachineParameters struct. In case of multi
574 * processor machine, container name is suffixed with _nbproc. nproc equals
575 * (number of nodes)*(number of processor per nodes).
576 * \param params struct from which we get container name (may be
577 * empty), number of nodes and number of processor
579 * \return a container name without the path.
580 * \sa BuildContainerNameForNS(const Engines::MachineParameters& params,
581 * const char *hostname)
583 // ============================================================================
586 SALOME_NamingService::ContainerName(const Engines::MachineParameters& params)
592 else if ( (params.nb_node <= 0) && (params.nb_proc_per_node <= 0) )
594 else if ( params.nb_node == 0 )
595 nbproc = params.nb_proc_per_node;
596 else if ( params.nb_proc_per_node == 0 )
597 nbproc = params.nb_node;
599 nbproc = params.nb_node * params.nb_proc_per_node;
601 string ret = ContainerName(params.container_name);
605 char *suffix = new char[8];
606 sprintf(suffix, "_%d", nbproc);
613 // ============================================================================
614 /*! \brief build a string representing a container in Naming Service.
616 * Build a string representing the absolute pathname of a container in
617 * SALOME_NamingService. This form gives a suffixed containerName in case of
618 * multi processor machine.
619 * \param containerName name of the container in which the component is
621 * \param hostname name of the host of the container, without domain names.
622 * \return the path under the form /Containers/hostname/containerName
623 * \sa ContainerName(const Engines::MachineParameters& params)
625 // ============================================================================
627 string SALOME_NamingService::BuildContainerNameForNS(const char *containerName,
628 const char *hostname)
630 string ret = "/Containers/";
633 ret += ContainerName(containerName);
638 // ============================================================================
639 /*! \brief build a string representing a container in Naming Service.
641 * Build a string representing the absolute pathname of a container in
642 * SALOME_NamingService.
643 * \param params used as it is, or replaced by FactoryServer if empty.
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 char *containerName)
648 // ============================================================================
651 SALOME_NamingService::
652 BuildContainerNameForNS(const Engines::MachineParameters& params,
653 const char *hostname)
655 string ret = "/Containers/";
658 ret += ContainerName(params);
663 // ============================================================================
664 /*! \brief search a name in current directory.
666 * Search a name in the current directory. after call, the current directory
667 * is changed to the directory containing the last occurence of name found.
668 * If no occurence found (see return value), current directory remains
671 * \param name the name to search.
672 * \return number of occurences found.
673 * \sa Change_Directory(const char* Path)
675 // ============================================================================
677 int SALOME_NamingService::Find(const char* name)
678 throw(ServiceUnreachable)
680 MESSAGE("BEGIN OF Find " << name);
682 Utils_Locker lock (&_myMutex);
684 CORBA::Long occurence_number = 0 ;
688 _Find(name, occurence_number);
691 catch (CORBA::SystemException&)
693 INFOS("!!!Find() : CORBA::SystemException : unable to contact"
694 << " the naming service");
695 throw ServiceUnreachable();
698 return occurence_number;
701 // ============================================================================
702 /*! \brief Creates a directory (context_name)
704 * Creates a directory (context_name) relative to the current directory
705 * (current context) or relative to the root directory (root context), if
706 * the path given begins with a '/'.
707 * If the NamingService is out, the exception ServiceUnreachable is thrown.
708 * \param Path A relative or absolute pathname to store the object reference.
709 * If the pathname begins with a '/', pathname is taken
710 * as an absolute pathname. Else, pathname is taken as a relative
711 * path, to current context. Prefer absolute pathname, relative
712 * pathname are not safe, when SALOME_NamingService object is
713 * shared or use in multithreaded context.
714 * \return true if successfull
715 * (creation not strictly garanteed if true, because Register may
716 * catch some specific unlikely exception without throw anything
717 * --- to be corrected ---)
718 * \sa RegisterCORBA::Object_ptr ObjRef, const char* Path)
720 // ============================================================================
722 bool SALOME_NamingService::Create_Directory(const char* Path)
723 throw(ServiceUnreachable)
725 MESSAGE("BEGIN OF Create_Directory");
727 Utils_Locker lock (&_myMutex);
731 // --- if path empty, nothing to create, no context change
736 // --- if path ='/', nothing to create, only change to root_context
740 MESSAGE("Create Directory '/', just change to root_context");
741 _current_context = _root_context;
745 // --- path must end with '/'
747 if (path[path.length()-1] != '/') path += '/';
749 Register(CORBA::Object::_nil(), path.c_str());
753 // ============================================================================
754 /*! \brief change current directory to the given path
756 * change the current directory to the given path in parameter.
757 * Warning: avoid use when the SALOME_NamingService instance is shared by
758 * several threads (current context may be modified by another thread).
759 * If the path is empty, nothing done return OK.
760 * If Path ="/", the current directory changes to the root directory.
761 * If the NamingService is out, the exception ServiceUnreachable is thrown.
762 * \param Path the new current directory
763 * \return true if the change succeeded
765 // ============================================================================
767 bool SALOME_NamingService::Change_Directory(const char* Path)
768 throw(ServiceUnreachable)
770 // MESSAGE("BEGIN OF Change_Directory " << Path);
771 Utils_Locker lock (&_myMutex);
775 // --- if path empty, nothing to do
780 // --- if path ='/', nothing to resolve, only change to root_context
784 // MESSAGE("Change_Directory is called to go to the root_context");
785 _current_context = _root_context;
789 CosNaming::NamingContext_var current_context = _current_context;
790 bool changeOK = false;
792 // --- replace _current_context with _root_context if Path begins whith '/'
795 current_context = _root_context;
797 // --- need to resolve directory path
799 ASSERT(!CORBA::is_nil(current_context));
801 if (path[path.length()-1] != '/') path += '/';
803 CosNaming::Name context_name;
804 vector<string> splitPath;
805 _createContextNameDir(path.c_str(),
810 // --- Context creation
814 CORBA::Object_var obj = current_context->resolve(context_name);
815 current_context = CosNaming::NamingContext::_narrow(obj);
816 ASSERT(!CORBA::is_nil(current_context));
817 _current_context = current_context;
821 catch (CosNaming::NamingContext::NotFound& ex)
823 CosNaming::Name n = ex.rest_of_name;
825 if (ex.why == CosNaming::NamingContext::missing_node)
826 MESSAGE( "Change_Directory() : " << (char *) n[0].id
827 << " (" << (char *) n[0].kind << ") not found");
828 if (ex.why == CosNaming::NamingContext::not_context)
829 INFOS("Change_Directory() : " << (char *) n[0].id
830 << " (" << (char *) n[0].kind
831 << ") is not a context" );
832 if (ex.why == CosNaming::NamingContext::not_object)
833 INFOS( "Change_Directory() : " << (char *) n[0].id
834 << " (" << (char *) n[0].kind
835 << ") is not an object" );
838 catch (CosNaming::NamingContext::CannotProceed&)
840 INFOS("Change_Directory(): CosNaming::NamingContext::CannotProceed");
843 catch (CosNaming::NamingContext::InvalidName&)
845 INFOS("Change_Directory(): CosNaming::NamingContext::InvalidName");
848 catch (CORBA::SystemException&)
850 INFOS("Change_Directory():CORBA::SystemException : unable to contact"
851 << "the naming service");
852 throw ServiceUnreachable();
858 // ============================================================================
859 /*! \brief get the current directory path
861 * Get the current directory path.
862 * If the NamingService is out, the exception ServiceUnreachable is thrown.
863 * \return the path of the current_context
864 * \sa _current_directory
866 // ============================================================================
868 char* SALOME_NamingService::Current_Directory()
869 throw(ServiceUnreachable)
871 MESSAGE("BEGIN OF Current_Directory");
873 Utils_Locker lock (&_myMutex);
875 CosNaming::NamingContext_var ref_context = _current_context;
877 vector<string> splitPath;
880 bool notFound = true ;
882 // --- start search from root context
884 _current_context = _root_context ;
888 _current_directory(splitPath, lengthPath, ref_context, notFound );
891 catch (CORBA::SystemException&)
893 INFOS("Current_Directory(): CORBA::SystemException: unable to contact"
894 << " the naming service" )
895 throw ServiceUnreachable();
899 lengthPath = splitPath.size();
900 for (int k = 0 ; k < lengthPath ;k++)
903 path += splitPath[k];
907 _current_context = ref_context ;
909 return strdup(path.c_str());
912 // ============================================================================
913 /*! \brief list recursively all objects in the current context
915 * List and print via trace all directories and objects in the current
916 * context. Trace must be activated: compile option _DEBUG_
917 * If the NamingService is out, the exception ServiceUnreachable is thrown
919 // ============================================================================
921 void SALOME_NamingService::list()
922 throw(ServiceUnreachable)
924 MESSAGE("Begin of list");
926 Utils_Locker lock (&_myMutex)
929 CosNaming::BindingList_var binding_list;
930 CosNaming::BindingIterator_var binding_iterator;
931 CosNaming::Binding_var binding ;
933 unsigned long nb = 0 ; // --- only for the BindingIterator use,
934 // to access the bindings
936 CosNaming::NamingContext_var ref_context = _current_context;
938 _current_context->list(nb, binding_list, binding_iterator) ;
940 if (! CORBA::is_nil(binding_iterator))
942 while (binding_iterator->next_one(binding))
944 CosNaming::Name bindingName = binding->binding_name;
946 if (binding->binding_type == CosNaming::ncontext)
948 MESSAGE( "Context : " << bindingName[0].id );
952 Change_Directory(bindingName[0].id);
955 catch (ServiceUnreachable&)
957 INFOS( "list(): ServiceUnreachable" )
958 throw ServiceUnreachable();
962 _current_context = ref_context ;
965 else if (binding->binding_type == CosNaming::nobject)
967 MESSAGE( "Object : " << bindingName[0].id );
971 binding_iterator->destroy();
975 // ============================================================================
976 /*! \brief list all the objects in the current directory.
978 * get a list of all the objects in the current directory, without recursion
979 * on the subdirectories. Only the objects are listed, not the directories.
980 * If the NamingService is out, the exception ServiceUnreachable is thrown.
981 * \return list of strings with objects found.
982 * \sa vector<string> list_directory_recurs()
984 // ============================================================================
986 vector<string> SALOME_NamingService::list_directory()
987 throw(ServiceUnreachable)
989 // MESSAGE("list_directory");
990 vector<string> dirList ;
993 CosNaming::BindingList_var binding_list;
994 CosNaming::BindingIterator_var binding_iterator;
995 CosNaming::Binding_var binding ;
997 unsigned long nb = 0 ; // --- only for the BindingIterator use,
998 // to access the bindings
1000 CosNaming::NamingContext_var ref_context = _current_context;
1002 _current_context->list(nb, binding_list, binding_iterator);
1004 if (binding_iterator->_is_nil())
1007 while (binding_iterator->next_one(binding))
1009 CosNaming::Name bindingName = binding->binding_name;
1011 if (binding->binding_type == CosNaming::nobject)
1013 // remove memory leak
1014 // dirList.push_back(CORBA::string_dup(bindingName[0].id));
1015 dirList.push_back(string(bindingName[0].id));
1019 // for (unsigned int ind = 0; ind < dirList.size(); ind++)
1020 // MESSAGE("list_directory : Object : " << dirList[ind]);
1022 binding_iterator->destroy();
1028 // ============================================================================
1029 /*! \brief list all the subdirectories in the current directory.
1031 * get a list of all the subdirectories in the current directory,
1032 * without recursion on the subdirectories.
1033 * Only the subdirectories are listed, not the objects.
1034 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1035 * \return list of strings with directories found.
1036 * \sa vector<string> list_directory()
1038 // ============================================================================
1040 vector<string> SALOME_NamingService::list_subdirs()
1041 throw(ServiceUnreachable)
1043 MESSAGE("list_subdirs");
1044 vector<string> dirList ;
1047 CosNaming::BindingList_var binding_list;
1048 CosNaming::BindingIterator_var binding_iterator;
1049 CosNaming::Binding_var binding ;
1051 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1052 // to access the bindings
1054 CosNaming::NamingContext_var ref_context = _current_context;
1056 _current_context->list(nb, binding_list, binding_iterator) ;
1058 if (binding_iterator->_is_nil())
1061 while (binding_iterator->next_one(binding))
1063 CosNaming::Name bindingName = binding->binding_name;
1065 if (binding->binding_type == CosNaming::ncontext)
1067 dirList.push_back(bindingName[0].id.in());
1071 for (unsigned int ind = 0; ind < dirList.size(); ind++)
1072 MESSAGE("list_directory : Object : " << dirList[ind]);
1074 binding_iterator->destroy();
1079 // ============================================================================
1080 /*! \brief list all the objects in the current directory and subdirectories.
1082 * get a list of all the objects in the current directory, with recursion
1083 * on the subdirectories. Only the objects are listed, not the directories.
1084 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1085 * \return list of strings with objects found.
1086 * \sa vector<string> list_directory()
1088 // ============================================================================
1090 vector<string> SALOME_NamingService::list_directory_recurs()
1091 throw(ServiceUnreachable)
1093 MESSAGE("list_directory_recurs");
1095 Utils_Locker lock (&_myMutex);
1097 vector<string> dirList ;
1099 char* currentDir = Current_Directory();
1101 _list_directory_recurs(dirList, "", currentDir);
1108 // ============================================================================
1109 /*! \brief destroy an entry in naming service.
1111 * Destroy an association Path - Object Reference.
1112 * If the NamingService is out, the exception ServiceUnreachable is thrown
1113 * \param Path object path
1115 // ============================================================================
1117 void SALOME_NamingService::Destroy_Name(const char* Path)
1118 throw(ServiceUnreachable)
1120 MESSAGE("BEGIN OF Destroy_Name " << Path);
1122 Utils_Locker lock (&_myMutex);
1126 // --- if path empty, nothing to do
1131 // --- if path = '/' not applicable, nothing to do
1136 // --- if path begins with '/', set current directory to root context
1139 _current_context = _root_context;
1141 // --- context of the directory containing the object
1143 CosNaming::Name context_name;
1144 vector<string> splitPath;
1145 int dimension_resultat = _createContextNameDir(path.c_str(),
1152 if (dimension_resultat > 0)
1154 // --- path contains a directory, not only an object name
1155 // switch to the new directory (or return if directory not found)
1159 CORBA::Object_var obj = _current_context->resolve(context_name);
1160 _current_context = CosNaming::NamingContext::_narrow(obj);
1164 catch (CosNaming::NamingContext::NotFound &ex)
1166 // --- failed to resolve
1169 CosNaming::Name n = ex.rest_of_name;
1171 if (ex.why == CosNaming::NamingContext::missing_node)
1172 INFOS( "Destroy_Name(): " << (char *) n[0].id
1173 << " (" << (char *) n[0].kind << ") not found" );
1174 if (ex.why == CosNaming::NamingContext::not_context)
1175 INFOS( "Destroy_Name() : " << (char *) n[0].id
1176 << " (" << (char *) n[0].kind
1177 << ") is not a context" );
1178 if (ex.why == CosNaming::NamingContext::not_object)
1179 INFOS( "Destroy_Name() : " << (char *) n[0].id
1180 << " (" << (char *) n[0].kind
1181 << ") is not an object" );
1184 catch (CosNaming::NamingContext::InvalidName &)
1186 INFOS("Destroy_Name: CosNaming::NamingContext::InvalidName");
1189 catch (CosNaming::NamingContext::CannotProceed &)
1191 INFOS("Destroy_Name: CosNaming::NamingContext::CannotProceed");
1194 catch (CORBA::SystemException&)
1196 INFOS("Destroy_Name : CORBA::SystemException: "
1197 << "unable to contact the naming service");
1198 throw ServiceUnreachable();
1201 if (! exist) return;
1204 ASSERT(!CORBA::is_nil(_current_context));
1206 // --- The current directory is now the directory where the object should
1209 int sizePath = splitPath.size();
1210 if (sizePath > dimension_resultat)
1212 ASSERT(sizePath == dimension_resultat+1);
1213 context_name.length(1);
1217 // --- the last element is an object and not a directory
1219 context_name[0].id =
1220 CORBA::string_dup(splitPath[dimension_resultat].c_str());
1221 context_name[0].kind = CORBA::string_dup("object");
1222 SCRUTE(context_name[0].id);
1224 _current_context->unbind(context_name);
1225 MESSAGE("The object " << context_name[0].id << " has been deleted");
1228 catch (CosNaming::NamingContext::NotFound& ex)
1230 CosNaming::Name n = ex.rest_of_name;
1232 if (ex.why == CosNaming::NamingContext::missing_node)
1233 INFOS( "Destroy_Name() : " << (char *) n[0].id
1234 << " (" << (char *) n[0].kind << ") not found" );
1235 if (ex.why == CosNaming::NamingContext::not_context)
1236 INFOS( "Destroy_Name() : " << (char *) n[0].id
1237 << " (" << (char *) n[0].kind
1238 << ") is not a context" );
1239 if (ex.why == CosNaming::NamingContext::not_object)
1240 INFOS( "Destroy_Name() : " << (char *) n[0].id
1241 << " (" << (char *) n[0].kind
1242 << ") is not an object" );
1245 catch (CosNaming::NamingContext::CannotProceed&)
1247 INFOS( "Destroy_Name(): CosNaming::NamingContext::CannotProceed");
1250 catch (CosNaming::NamingContext::InvalidName&)
1252 INFOS( "Destroy_Name(): CosNaming::NamingContext::InvalidName");
1255 catch (CORBA::SystemException&)
1257 INFOS( "Destroy_Name(): CORBA::SystemException: unable to contact"
1258 << " the naming service");
1259 throw ServiceUnreachable();
1264 // ============================================================================
1265 /*! \brief Destroy an empty directory
1267 * Destroy an empty directory in Naming Service.
1268 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1269 * \param Path directory path
1271 // ============================================================================
1273 void SALOME_NamingService::Destroy_Directory(const char* Path)
1274 throw(ServiceUnreachable)
1276 MESSAGE("BEGIN OF Destroy_Directory " << Path);
1278 Utils_Locker lock (&_myMutex);
1282 // --- if path empty, nothing to do
1287 // --- if path begins with '/', set current directory to root context
1290 _current_context = _root_context;
1292 CosNaming::NamingContext_var ref_context = _current_context;
1294 // --- path must ends with '/' for a directory
1296 if (path[path.size() -1] != '/')
1299 // --- context of the directory
1301 CosNaming::Name context_name;
1302 vector<string> splitPath;
1303 int dimension_resultat = _createContextNameDir(path.c_str(),
1309 if (dimension_resultat > 0)
1311 // --- path contains a directory, not only an object name
1312 // switch to the new directory (or return if directory not found)
1316 CORBA::Object_var obj = _current_context->resolve(context_name);
1317 _current_context = CosNaming::NamingContext::_narrow(obj);
1321 catch (CosNaming::NamingContext::NotFound &ex)
1323 // --- failed to resolve
1326 CosNaming::Name n = ex.rest_of_name;
1328 if (ex.why == CosNaming::NamingContext::missing_node)
1329 INFOS( "Destroy_Directory(): " << (char *) n[0].id
1330 << " (" << (char *) n[0].kind << ") not found" );
1331 if (ex.why == CosNaming::NamingContext::not_context)
1332 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1333 << " (" << (char *) n[0].kind
1334 << ") is not a context" );
1335 if (ex.why == CosNaming::NamingContext::not_object)
1336 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1337 << " (" << (char *) n[0].kind
1338 << ") is not an object" );
1341 catch (CosNaming::NamingContext::InvalidName &)
1343 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1346 catch (CosNaming::NamingContext::CannotProceed &)
1348 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1351 catch (CORBA::SystemException&)
1353 INFOS("Destroy_Directory : CORBA::SystemException: "
1354 << "unable to contact the naming service");
1355 throw ServiceUnreachable();
1358 if (! exist) return;
1361 ASSERT(!CORBA::is_nil(_current_context));
1363 // --- Context Destruction
1365 bool isContextDestroyed = false;
1368 _current_context->destroy();
1369 MESSAGE( "The context " << path << " has been deleted" );
1370 isContextDestroyed = true;
1373 catch (CosNaming::NamingContext::NotEmpty&)
1375 INFOS( "Destroy_Directory(): CosNaming::NamingContext::NoEmpty "
1376 << path << " is not empty" );
1379 catch (CORBA::SystemException&)
1381 INFOS( "Destroy_Directory():CORBA::SystemException : "
1382 << "unable to contact the naming service");
1383 throw ServiceUnreachable();
1386 // --- go to the reference directory
1388 _current_context = ref_context ;
1390 ASSERT(!CORBA::is_nil(_current_context));
1392 if (isContextDestroyed)
1396 _current_context->unbind(context_name);
1397 MESSAGE( "The bind to the context "
1398 << context_name[0].id
1399 << " has been deleted" );
1402 catch (CosNaming::NamingContext::NotFound& ex)
1404 CosNaming::Name n = ex.rest_of_name;
1406 if (ex.why == CosNaming::NamingContext::missing_node)
1407 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1408 << " (" << (char *) n[0].kind << ") not found" );
1409 if (ex.why == CosNaming::NamingContext::not_context)
1410 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1411 << " (" << (char *) n[0].kind
1412 << ") is not a context" );
1413 if (ex.why == CosNaming::NamingContext::not_object)
1414 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1415 << " (" << (char *) n[0].kind
1416 << ") is not an object" );
1419 catch (CosNaming::NamingContext::CannotProceed&)
1421 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1424 catch (CosNaming::NamingContext::InvalidName&)
1426 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1429 catch (CORBA::SystemException&)
1431 INFOS("Destroy_Directory:CORBA::SystemException : unable to contact"
1432 << " the naming service");
1433 throw ServiceUnreachable();
1438 // ============================================================================
1439 /*! \brief Destroy a directory with its contents.
1441 * Destroy the objects associations in a directory, and the directory itself,
1442 * if there is no subdirectories.
1443 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1444 * \param Path the directory path.
1446 // ============================================================================
1448 void SALOME_NamingService::Destroy_FullDirectory(const char* Path)
1449 throw(ServiceUnreachable)
1451 MESSAGE("begin of Destroy_FullDirectory " << Path);
1452 if( Change_Directory(Path) )
1454 vector<string> contList = list_directory();
1456 for (unsigned int ind = 0; ind < contList.size(); ind++)
1457 Destroy_Name(contList[ind].c_str());
1459 Destroy_Directory(Path);
1463 // ============================================================================
1464 /*! \brief initialize root context (root directory)
1466 * the root context initialisation must be done when the SALOME_NamingService
1467 * instance is created and before any othe call. See constructors.
1469 // ============================================================================
1471 void SALOME_NamingService::_initialize_root_context()
1473 //MESSAGE("Get the root context");
1477 CORBA::Object_var obj = _orb->resolve_initial_references("NameService");
1478 _root_context = CosNaming::NamingContext::_narrow(obj);
1479 _current_context = _root_context ;
1480 ASSERT(!CORBA::is_nil(_root_context));
1483 catch (CORBA::SystemException&)
1485 INFOS("CORBA::SystemException: unable to contact the naming service");
1486 throw ServiceUnreachable();
1491 INFOS("Unknown Exception: unable to contact the naming service");
1492 throw ServiceUnreachable();
1496 // ============================================================================
1497 /*! \brief transform a string path in CosNaming structure.
1499 * Transform a path given as a string in a CosNaming structure.
1500 * \param path a relative or absolute path, with or without an object.
1501 * An absolute path begins with '/'.
1502 * A path without an object ends with '/'.
1503 * \param context_name CosNaming structure to put the path.
1504 * \param splitPath a vector of string with subdirectories and final
1506 * \param onlyDir if true, final object (if any) is ommited
1508 * if false, final object (if any) is included in
1510 * \return dimension of context_name
1512 // ============================================================================
1515 SALOME_NamingService::_createContextNameDir(string path,
1516 CosNaming::Name& context_name,
1517 vector<string>& splitPath,
1523 string::size_type begIdx, endIdx;
1524 const string delims("/");
1525 splitPath.resize(0);
1526 bool endWithDelim = false;
1528 begIdx = path.find_first_not_of(delims);
1529 while (begIdx != string::npos)
1531 endIdx = path.find_first_of(delims, begIdx);
1532 if (endIdx == path.length()-1)
1533 endWithDelim = true;
1534 if (endIdx == string::npos)
1535 endIdx = path.length();
1536 int lsub = endIdx - begIdx;
1538 splitPath.push_back(path.substr(begIdx, lsub));
1539 begIdx = path.find_first_not_of(delims, endIdx);
1543 if (onlyDir) // only directory part
1545 dim = splitPath.size()-1; // omit final object
1546 if (endWithDelim) // unless the path ends with a delimiter
1548 endWithDelim = true;
1551 dim = splitPath.size(); // directories and final object
1553 context_name.length(dim);
1554 for (int i=0; i<dim; i++)
1556 // SCRUTE(splitPath[i]);
1557 context_name[i].id = CORBA::string_dup(splitPath[i].c_str());
1558 if (!endWithDelim && (i == dim-1)) // here, the last string is an object
1560 context_name[i].kind = CORBA::string_dup("object");
1561 // MESSAGE("--- " <<splitPath[i] <<".object");
1565 context_name[i].kind = CORBA::string_dup("dir");
1566 // MESSAGE("--- " <<splitPath[i] <<".dir");
1572 // ============================================================================
1573 /*! \brief search a name in current directory.
1575 * Search a name in the current directory. after call, the current directory
1576 * is changed to the directory containing the last occurence of name found.
1577 * If no occurence found (see return value), current directory remains
1578 * unchanged. The call is recursive.
1580 * \param name the name to search.
1581 * \param occurence_number number of occurence already found (incremented)
1583 // ============================================================================
1585 void SALOME_NamingService::_Find(const char* name,
1586 CORBA::Long& occurence_number)
1588 MESSAGE("BEGIN OF _Find "<< occurence_number << " " << name);
1590 CosNaming::BindingList_var binding_list;
1591 CosNaming::BindingIterator_var binding_iterator;
1592 CosNaming::Binding_var binding;
1594 unsigned long nb = 0 ; // --- only for the use of the BindingIterator,
1595 // to access the bindings
1597 CosNaming::NamingContext_var ref_context = _current_context;
1598 CosNaming::NamingContext_var found_context = _current_context;
1600 _current_context->list(nb, binding_list, binding_iterator) ;
1602 if (! CORBA::is_nil(binding_iterator))
1604 while (binding_iterator->next_one(binding))
1606 CosNaming::Name bindingName = binding->binding_name;
1608 if (binding->binding_type == CosNaming::ncontext)
1610 // --- We work on a directory,
1611 // the search should be done in this directory
1613 Change_Directory(bindingName[0].id);
1614 _Find(name, occurence_number);
1616 // --- We'll go back to the initial context
1618 _current_context = ref_context ;
1621 else if (binding->binding_type == CosNaming::nobject)
1623 // --- We work on an object...
1625 if (!strcmp( bindingName[0].id, name))
1627 //MESSAGE("One occurence was found");
1630 // --- We keep in memory the directory where
1631 // one occurence was found
1633 found_context = _current_context ;
1638 binding_iterator->destroy();
1640 // --- We go to the last directory where an occurence was found
1642 _current_context = found_context;
1644 SCRUTE(occurence_number);
1647 // ============================================================================
1648 /*! \brief find the current directory path.
1650 * Parse the naming service tree to find the current context and give the
1651 * associated directory path (relative to root context).
1653 * \param lengthResult
1654 * \param contextToFind
1657 // ============================================================================
1660 SALOME_NamingService::
1661 _current_directory(vector<string>& splitPath,
1663 CosNaming::NamingContext_var contextToFind,
1666 MESSAGE("BEGIN OF _current_Directory");
1668 CosNaming::BindingList_var binding_list;
1669 CosNaming::BindingIterator_var binding_iterator;
1670 CosNaming::Binding_var binding;
1672 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1673 // to access the bindings
1675 CosNaming::NamingContext_var ref_context = _current_context;
1676 CosNaming::NamingContext_var temp_context = _current_context;
1678 _current_context->list(nb, binding_list, binding_iterator);
1680 if ( !binding_iterator->_is_nil() )
1682 while ((binding_iterator->next_one(binding)) && notFound)
1684 CosNaming::Name bindingName = binding->binding_name;
1686 if (binding->binding_type == CosNaming::ncontext)
1688 // --- directory, search in it
1690 const char* bindingNameid=bindingName[0].id;
1691 splitPath.push_back(bindingNameid);
1694 CORBA::Object_var obj = _current_context->resolve(bindingName);
1695 temp_context = CosNaming::NamingContext::_narrow(obj);
1697 if (temp_context->_is_equivalent(contextToFind))
1699 MESSAGE("The context is found, we stop the search");
1706 SCRUTE(bindingName[0].id);
1707 Change_Directory(bindingName[0].id);
1708 _current_directory(splitPath,
1715 // --- go back to the initial context
1717 _current_context = ref_context;
1719 MESSAGE("Just before the delete of "
1720 << splitPath[lengthResult-1]);
1721 splitPath.pop_back();
1728 binding_iterator->destroy();
1731 // --- return to the last directory where an occurence was found
1733 _current_context = ref_context ;
1737 // ============================================================================
1738 /*! \brief list recursively all objects in the given directory and subdirs.
1740 * get a list of all the objects in the current directory, with recursion
1741 * on the subdirectories. Only the objects are listed, not the directories.
1742 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1743 * _current_context must refer to absCurDirectory.
1745 * \param myList The list that will be filled.
1746 * \param relativeSubDir The directory relative to absCurDirectory in which
1747 * the objects are found.
1748 * \param absCurDirectory The current directory, absolute path
1750 // ============================================================================
1752 void SALOME_NamingService::_list_directory_recurs(vector<string>& myList,
1753 string relativeSubDir,
1754 string absCurDirectory)
1756 CosNaming::BindingList_var binding_list;
1757 CosNaming::BindingIterator_var binding_iterator;
1758 CosNaming::Binding_var binding ;
1760 unsigned long nb = 0 ; // --- only for thethe use of BindingIterator
1761 // to access the bindings
1765 CosNaming::NamingContext_var ref_context = _current_context;
1767 if (! relativeSubDir.empty())
1769 Change_Directory(relativeSubDir.c_str());
1770 absDir = absCurDirectory + "/" + relativeSubDir;
1774 absDir = absCurDirectory;
1777 _current_context->list(nb, binding_list, binding_iterator) ;
1779 if (! CORBA::is_nil(binding_iterator))
1781 while (binding_iterator->next_one(binding))
1783 CosNaming::Name bindingName = binding->binding_name;
1785 if (binding->binding_type == CosNaming::ncontext)
1787 string relativeSdir(bindingName[0].id);
1788 _list_directory_recurs(myList, relativeSdir, absDir);
1791 else if (binding->binding_type == CosNaming::nobject)
1793 string objName(bindingName[0].id);
1794 string elt = absDir + "/" + objName;
1796 myList.push_back(elt);
1800 binding_iterator->destroy();
1802 if (! relativeSubDir.empty())
1804 _current_context = ref_context;
1808 // ============================================================================
1809 /*! \brief return a stringified reference of root context
1811 * \return a stringified reference of root context
1813 // ============================================================================
1815 char * SALOME_NamingService::getIORaddr()
1817 return _orb->object_to_string(_root_context);