1 // Copyright (C) 2007-2016 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, or (at your option) any later version.
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
23 // SALOME NamingService : wrapping NamingService services
24 // File : SALOME_NamingService.cxx
25 // Author : Estelle Deville
29 #include "SALOME_NamingService.hxx"
30 #include "ServiceUnreachable.hxx"
32 #include "utilities.h"
40 #define strdup _strdup
43 /*! \class SALOME_NamingService
44 \brief A class to manage the SALOME naming service
48 // ============================================================================
49 /*! \brief Default Constructor without ORB reference.
51 * After Default Constructor, one needs to initialize ORB.
52 * \sa init_orb(CORBA::ORB_ptr orb), SALOME_NamingService(CORBA::ORB_ptr orb)
54 // ============================================================================
56 SALOME_NamingService::SALOME_NamingService()
58 _orb = CORBA::ORB::_nil();
59 _root_context = CosNaming::NamingContext::_nil();
62 // ============================================================================
63 /*! \brief Standard Constructor, with ORB reference.
65 * Initializes the naming service root context
66 * \param orb CORBA::ORB_ptr arguments
68 // ============================================================================
70 SALOME_NamingService::SALOME_NamingService(CORBA::ORB_ptr orb)
72 _orb = CORBA::ORB::_duplicate(orb);
73 _initialize_root_context();
76 // ============================================================================
77 /*! \brief Standard destructor.
79 * The standard destructor does nothing special.
81 // ============================================================================
83 SALOME_NamingService::~SALOME_NamingService()
85 // Problem MESSAGE with singleton: late destruction,
86 // after trace system destruction ?
87 //MESSAGE("SALOME_NamingService destruction");
90 // ============================================================================
91 /*! \brief initializes ORB reference and naming service root context.
93 * Initializes ORB reference and naming service root context.
94 * For use after default constructor.
95 * If param orb is null, the orb is initialized
96 * \param orb CORBA::ORB_ptr arguments
98 // ============================================================================
100 void SALOME_NamingService::init_orb(CORBA::ORB_ptr orb)
102 Utils_Locker lock (&_myMutex);
104 _orb = CORBA::ORB::_duplicate(orb);
108 _orb = CORBA::ORB_init(argc, 0); // Here we make the assumption that the orb has already been initialized
111 _initialize_root_context();
114 // ============================================================================
115 /*! \brief Registers a CORBA object reference under a path.
117 * Registers a CORBA object reference under a path. If the path ends with '/',
118 * only a directory is created.
119 * If the NamingService is out, the exception ServiceUnreachable is thrown.
120 * \param ObjRef CORBA object reference to associate to the path. To create
121 * only a directory, give nil pointer.
122 * \param Path A relative or absolute pathname to store the object reference.
123 * If the pathname begins with a '/', pathname is taken
124 * as an absolute pathname. Else, pathname is taken as a relative
125 * path, to current context. Prefer absolute pathname, relative
126 * pathname are not safe, when SALOME_NamingService object is
127 * shared or use in multithreaded context.
128 * If the path ends with '/', only a directory is created.
129 * \sa Change_Directory(const char* Path),
130 * Create_Directory(const char* Path)
131 * CORBA::Object_ptr Resolve(const char* Path)
133 // ============================================================================
135 void SALOME_NamingService::Register(CORBA::Object_ptr ObjRef,
137 throw(ServiceUnreachable)
139 Utils_Locker lock (&_myMutex);
141 // --- _current_context is replaced to the _root_context
142 // if the Path begins with '/'
145 _current_context = _root_context;
148 // --- the resolution of the directory path has to be done
149 // to place the current_context to the correct node
151 CosNaming::Name context_name;
152 std::vector<std::string> splitPath;
153 int dimension_resultat = _createContextNameDir(Path,
158 CORBA::Boolean not_exist = false;
160 if (dimension_resultat > 0){
161 // A directory is treated (not only an object name)
162 // test if the directory where ObjRef should be recorded already exists
163 // If not, create the new context
166 CORBA::Object_var obj = _current_context->resolve(context_name);
167 _current_context = CosNaming::NamingContext::_narrow(obj);
170 catch (CosNaming::NamingContext::NotFound &){
171 // --- failed to resolve, therefore assume cold start
175 catch (CosNaming::NamingContext::InvalidName &){
176 INFOS("Register() : CosNaming::NamingContext::InvalidName");
179 catch (CosNaming::NamingContext::CannotProceed &){
180 INFOS("Register() : CosNaming::NamingContext::CannotProceed");
183 catch (CORBA::SystemException&){
184 INFOS("Register() : CORBA::SystemException: "
185 << "unable to contact the naming service");
186 throw ServiceUnreachable();
191 context_name.length(1);
192 for (int i = 0 ; i < dimension_resultat ;i++){
193 context_name[0].id = CORBA::string_dup(splitPath[i].c_str());
194 context_name[0].kind = CORBA::string_dup("dir");
195 // SCRUTE(_context_name[0].id);
196 // --- check if the path is created
198 // --- if the context is already created, nothing to do
199 CORBA::Object_var obj = _current_context->resolve(context_name);
200 _current_context = CosNaming::NamingContext::_narrow(obj);
203 catch (CosNaming::NamingContext::NotFound &){
205 // --- the context must be created
206 CosNaming::NamingContext_var temp_context =
207 _current_context->bind_new_context(context_name);
208 _current_context = temp_context;
210 catch (CosNaming::NamingContext::AlreadyBound&){
211 CORBA::Object_var obj = _current_context->resolve(context_name);
212 _current_context = CosNaming::NamingContext::_narrow(obj);
218 catch (CosNaming::NamingContext::AlreadyBound&){
219 INFOS("Register() : CosNaming::NamingContext::AlreadyBound");
222 catch (CosNaming::NamingContext::NotFound& ex){
223 CosNaming::Name n = ex.rest_of_name;
225 if (ex.why == CosNaming::NamingContext::missing_node)
226 INFOS("Register() : " << (char *) n[0].id
227 << " (" << (char *) n[0].kind << ") not found");
229 if (ex.why == CosNaming::NamingContext::not_context)
230 INFOS("Register() : " << (char *) n[0].id
231 << " (" << (char *) n[0].kind
232 << ") is not a context");
234 if (ex.why == CosNaming::NamingContext::not_object)
235 INFOS("Register() : " << (char *) n[0].id
236 << " (" << (char *) n[0].kind
237 << ") is not an object");
240 catch (CosNaming::NamingContext::CannotProceed&){
241 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
244 catch (CosNaming::NamingContext::InvalidName&){
245 INFOS("Register(): CosNaming::NamingContext::InvalidName");
248 catch (CORBA::SystemException&){
249 INFOS("Register():CORBA::SystemException: "
250 << "unable to contact the naming service");
251 throw ServiceUnreachable();
256 // --- The current directory is now the directory where the object should
259 int sizePath = splitPath.size();
260 if (sizePath > dimension_resultat){
261 ASSERT(sizePath == dimension_resultat+1);
262 context_name.length(1);
265 // --- the last element is an object and not a directory
267 context_name[0].id = CORBA::string_dup(splitPath[dimension_resultat].c_str());
268 context_name[0].kind = CORBA::string_dup("object");
269 //SCRUTE(context_name[0].id);
271 _current_context->bind(context_name, ObjRef);
274 catch (CosNaming::NamingContext::NotFound& ex){
275 CosNaming::Name n = ex.rest_of_name;
277 if (ex.why == CosNaming::NamingContext::missing_node)
278 INFOS("Register() : " << (char *) n[0].id
279 << " (" << (char *) n[0].kind << ") not found");
281 if (ex.why == CosNaming::NamingContext::not_context)
282 INFOS("Register() : " << (char *) n[0].id
283 << " (" << (char *) n[0].kind
284 << ") is not a context");
286 if (ex.why == CosNaming::NamingContext::not_object)
287 INFOS("Register() : " << (char *) n[0].id
288 << " (" << (char *) n[0].kind
289 << ") is not an object");
292 catch (CosNaming::NamingContext::CannotProceed&){
293 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
296 catch (CosNaming::NamingContext::InvalidName&){
297 INFOS("Register(): CosNaming::NamingContext::InvalidName");
300 catch (CosNaming::NamingContext::AlreadyBound&){
301 INFOS("Register(): CosNaming::NamingContext::AlreadyBound, "
302 << "object will be rebind");
303 _current_context->rebind(context_name, ObjRef);
306 catch (CORBA::SystemException&){
307 INFOS("!!!Register(): CORBA::SystemException: "
308 << "unable to contact the naming service");
309 throw ServiceUnreachable();
314 // ============================================================================
315 /*! \brief get the CORBA object reference associated to a name.
317 * get the CORBA object reference associated to a complete name with a path.
318 * If the NamingService is out, the exception ServiceUnreachable is thrown
319 * \param Path pathname. If the pathname begins with a '/', pathname is taken
320 * as an absolute pathname. Else, pathname is taken as a relative
321 * path, to current context. Prefer absolute pathname, relative
322 * pathname are not safe, when SALOME_NamingService object is
323 * shared or use in multithreaded context.
324 * \return the object reference if it exists under the pathname,
325 * or nil reference in other cases.
326 * \sa Register(CORBA::Object_ptr ObjRef, const char* Path),
327 * Change_Directory(const char* Path)
329 // ============================================================================
331 CORBA::Object_ptr SALOME_NamingService::Resolve(const char* Path)
332 throw(ServiceUnreachable)
334 Utils_Locker lock (&_myMutex);
336 // --- _current_context is replaced to the _root_context
337 // if the Path begins with '/'
341 _current_context = _root_context;
344 // --- the resolution of the directory path has to be done
345 // to place the current_context to the correct node
347 CosNaming::Name context_name;
348 std::vector<std::string> splitPath;
349 _createContextNameDir(Path,
354 ASSERT(!CORBA::is_nil(_current_context));
356 CORBA::Object_var obj = CORBA::Object::_nil();
360 obj = _current_context->resolve(context_name);
363 catch (CosNaming::NamingContext::NotFound& ex)
365 CosNaming::Name n = ex.rest_of_name;
367 if (ex.why == CosNaming::NamingContext::missing_node)
368 MESSAGE("Resolve() : " << (char *) n[0].id
369 << " (" << (char *) n[0].kind << ") not found");
371 if (ex.why == CosNaming::NamingContext::not_context)
373 << (char *) n[0].id << " (" << (char *) n[0].kind
374 << ") is not a context");
376 if (ex.why == CosNaming::NamingContext::not_object)
377 INFOS("Resolve() : " << (char *) n[0].id
378 << " (" << (char *) n[0].kind
379 << ") is not an object");
382 catch (CosNaming::NamingContext::CannotProceed&)
384 INFOS("Resolve(): CosNaming::NamingContext::CannotProceed");
387 catch (CosNaming::NamingContext::InvalidName&)
389 INFOS("Resolve(): CosNaming::NamingContext::InvalidName");
392 catch (CORBA::SystemException&)
394 INFOS("Resolve():CORBA::SystemException : unable to contact"
395 << "the naming service");
396 throw ServiceUnreachable();
402 // ============================================================================
403 /*! \brief get the CORBA object reference associated to an uncomplete name.
405 * get the CORBA object reference associated to an uncomplete name with a
406 * path. Look for the first occurrence of name*.
407 * If the NamingService is out, the exception ServiceUnreachable is thrown
408 * \param Path pathname under the form "/path/name" (Absolute reference !)
409 * search the fist reference like "/path(.dir)/name*(.kind)"
410 * \return the object reference if found, or nil reference.
411 * \sa Resolve(const char* Path)
413 // ============================================================================
415 CORBA::Object_ptr SALOME_NamingService::ResolveFirst(const char* Path)
416 throw(ServiceUnreachable)
418 Utils_Locker lock (&_myMutex);
420 std::string thePath = Path;
421 std::string basePath = "";
422 std::string name = thePath;
424 std::string::size_type idx = thePath.rfind('/');
426 if (idx != std::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 std::vector<std::string> listElem = list_directory();
445 std::vector<std::string>::iterator its = listElem.begin();
447 while (its != listElem.end())
449 if ((*its).find(name) == 0)
451 return Resolve((*its).c_str());
461 // ============================================================================
462 /*! \brief find a component instance from hostname, containername,
463 * componentName and number of processors.
465 * find a component instance from hostname, containername, componentName and
466 * number of processors.
467 * If the NamingService is out, the exception ServiceUnreachable is thrown.
468 * \param hostname name of the machine on which the component is searched.
469 * \param containerName name of the container in which the component is
471 * \param componentName name of the component we are looking for an existing
473 * \param nbproc in case of multi processor machine, container name is
474 * suffixed with _nbproc.
475 * \return the object reference
477 // ============================================================================
480 SALOME_NamingService::ResolveComponent(const char* hostname,
481 const char* containerName,
482 const char* componentName,
484 throw(ServiceUnreachable)
486 Utils_Locker lock (&_myMutex);
488 std::string name = "/Containers/";
492 if ( strlen(containerName) != 0 )
498 char *newContainerName = new char[strlen(containerName) + 8];
499 sprintf(newContainerName, "%s_%d", containerName, nbproc);
500 name += newContainerName;
501 delete [] newContainerName;
505 name += containerName;
509 name += componentName;
511 return ResolveFirst(name.c_str());
517 std::string basename = name;
518 if (Change_Directory(basename.c_str()))
520 std::vector<std::string> contList = list_subdirs();
522 for (unsigned int ind = 0; ind < contList.size(); ind++)
524 name = contList[ind].c_str();
528 char *str_nbproc = new char[8];
529 sprintf(str_nbproc, "_%d", nbproc);
530 if( strstr(name.c_str(),str_nbproc) == NULL)
531 continue; // check only containers with _%d in name
532 delete [] str_nbproc;
536 name += componentName;
538 CORBA::Object_ptr obj = ResolveFirst(name.c_str());
540 if ( !CORBA::is_nil(obj) )
543 Change_Directory(basename.c_str());
547 return CORBA::Object::_nil();
551 // ============================================================================
552 /*! \brief provide a default container name if empty.
554 * the given container name is returned unchanged, unless it is empty.
555 * \param containerName
556 * \return container name, where empty input is replaced by "FactoryServer",
558 * \sa BuildContainerNameForNS(const char *containerName, const char *hostname)
560 // ============================================================================
562 std::string SALOME_NamingService::ContainerName(const char *containerName)
564 std::string ret,containerNameCpp(containerName);
566 if (containerNameCpp.empty())
567 ret = "FactoryServer";
574 // ============================================================================
575 /*! \brief build a container name, given a ContainerParameters struct.
577 * Build a container name with a ContainerParameters struct. In case of multi
578 * processor machine, container name is suffixed with number of processors.
579 * \param params struct from which we get container name (may be empty) and
580 * number of processors.
581 * \return a container name without the path.
582 * \sa BuildContainerNameForNS(const Engines::ContainerParameters& params,
583 * const char *hostname)
585 // ============================================================================
587 std::string SALOME_NamingService::ContainerName(const Engines::ContainerParameters& params)
593 else if ( params.nb_proc <= 0 )
596 nbproc = params.nb_proc;
598 std::string ret(ContainerName(params.container_name));
602 std::ostringstream suffix;
603 suffix << "_" << nbproc;
610 // ============================================================================
611 /*! \brief build a string representing a container in Naming Service.
613 * Build a string representing the absolute pathname of a container in
614 * SALOME_NamingService. This form gives a suffixed containerName in case of
615 * multi processor machine.
616 * \param containerName name of the container in which the component is
618 * \param hostname name of the host of the container, without domain names.
619 * \return the path under the form /Containers/hostname/containerName
620 * \sa ContainerName(const Engines::MachineParameters& params)
622 // ============================================================================
624 std::string SALOME_NamingService::BuildContainerNameForNS(const char *containerName, const char *hostname)
626 std::string ret("/Containers/");
629 ret += ContainerName(containerName);
634 // ============================================================================
635 /*! \brief build a string representing a container in Naming Service.
637 * Build a string representing the absolute pathname of a container in
638 * SALOME_NamingService.
639 * \param params used as it is, or replaced by FactoryServer if empty.
640 * \param hostname name of the host of the container, without domain names.
641 * \return the path under the form /Containers/hostname/containerName
642 * \sa ContainerName(const char *containerName)
644 // ============================================================================
646 std::string SALOME_NamingService::BuildContainerNameForNS(const Engines::ContainerParameters& params, const char *hostname)
648 std::string ret("/Containers/");
651 ret += ContainerName(params);
656 // ============================================================================
657 /*! \brief search a name in current directory.
659 * Search a name in the current directory. after call, the current directory
660 * is changed to the directory containing the last occurrence of name found.
661 * If no occurrence found (see return value), current directory remains
664 * \param name the name to search.
665 * \return number of occurrences found.
666 * \sa Change_Directory(const char* Path)
668 // ============================================================================
670 int SALOME_NamingService::Find(const char* name)
671 throw(ServiceUnreachable)
673 Utils_Locker lock (&_myMutex);
675 CORBA::Long occurence_number = 0 ;
679 _Find(name, occurence_number);
682 catch (CORBA::SystemException&)
684 INFOS("!!!Find() : CORBA::SystemException : unable to contact"
685 << " the naming service");
686 throw ServiceUnreachable();
689 return occurence_number;
692 // ============================================================================
693 /*! \brief Creates a directory (context_name)
695 * Creates a directory (context_name) relative to the current directory
696 * (current context) or relative to the root directory (root context), if
697 * the path given begins with a '/'.
698 * If the NamingService is out, the exception ServiceUnreachable is thrown.
699 * \param Path A relative or absolute pathname to store the object reference.
700 * If the pathname begins with a '/', pathname is taken
701 * as an absolute pathname. Else, pathname is taken as a relative
702 * path, to current context. Prefer absolute pathname, relative
703 * pathname are not safe, when SALOME_NamingService object is
704 * shared or use in multithreaded context.
705 * \return true if successful
706 * (creation not strictly guaranteed if true, because Register may
707 * catch some specific unlikely exception without throw anything
708 * --- to be corrected ---)
709 * \sa RegisterCORBA::Object_ptr ObjRef, const char* Path)
711 // ============================================================================
713 bool SALOME_NamingService::Create_Directory(const char* Path) throw(ServiceUnreachable)
715 Utils_Locker lock (&_myMutex);
717 std::string path(Path);
719 // --- if path empty, nothing to create, no context change
724 // --- if path ='/', nothing to create, only change to root_context
728 _current_context = _root_context;
732 // --- path must end with '/'
734 if (path[path.length()-1] != '/') path += '/';
736 Register(CORBA::Object::_nil(), path.c_str());
740 // ============================================================================
741 /*! \brief change current directory to the given path
743 * change the current directory to the given path in parameter.
744 * Warning: avoid use when the SALOME_NamingService instance is shared by
745 * several threads (current context may be modified by another thread).
746 * If the path is empty, nothing done return OK.
747 * If Path ="/", the current directory changes to the root directory.
748 * If the NamingService is out, the exception ServiceUnreachable is thrown.
749 * \param Path the new current directory
750 * \return true if the change succeeded
752 // ============================================================================
754 bool SALOME_NamingService::Change_Directory(const char* Path) throw(ServiceUnreachable)
756 Utils_Locker lock (&_myMutex);
758 std::string path(Path);
760 // --- if path empty, nothing to do
765 // --- if path ='/', nothing to resolve, only change to root_context
769 _current_context = _root_context;
773 CosNaming::NamingContext_var current_context = _current_context;
774 bool changeOK = false;
776 // --- replace _current_context with _root_context if Path begins with '/'
779 current_context = _root_context;
781 // --- need to resolve directory path
783 ASSERT(!CORBA::is_nil(current_context));
785 if (path[path.length()-1] != '/') path += '/';
787 CosNaming::Name context_name;
788 std::vector<std::string> splitPath;
789 _createContextNameDir(path.c_str(),
794 // --- Context creation
798 CORBA::Object_var obj = current_context->resolve(context_name);
799 current_context = CosNaming::NamingContext::_narrow(obj);
800 ASSERT(!CORBA::is_nil(current_context));
801 _current_context = current_context;
805 catch (CosNaming::NamingContext::NotFound& ex)
807 CosNaming::Name n = ex.rest_of_name;
809 if (ex.why == CosNaming::NamingContext::missing_node)
810 MESSAGE( "Change_Directory() : " << (char *) n[0].id
811 << " (" << (char *) n[0].kind << ") not found");
812 if (ex.why == CosNaming::NamingContext::not_context)
813 INFOS("Change_Directory() : " << (char *) n[0].id
814 << " (" << (char *) n[0].kind
815 << ") is not a context" );
816 if (ex.why == CosNaming::NamingContext::not_object)
817 INFOS( "Change_Directory() : " << (char *) n[0].id
818 << " (" << (char *) n[0].kind
819 << ") is not an object" );
822 catch (CosNaming::NamingContext::CannotProceed&)
824 INFOS("Change_Directory(): CosNaming::NamingContext::CannotProceed");
827 catch (CosNaming::NamingContext::InvalidName&)
829 INFOS("Change_Directory(): CosNaming::NamingContext::InvalidName");
832 catch (CORBA::SystemException&)
834 INFOS("Change_Directory():CORBA::SystemException : unable to contact"
835 << "the naming service");
836 throw ServiceUnreachable();
842 // ============================================================================
843 /*! \brief get the current directory path
845 * Get the current directory path.
846 * If the NamingService is out, the exception ServiceUnreachable is thrown.
847 * \return the path of the current_context
848 * \sa _current_directory
850 // ============================================================================
852 char *SALOME_NamingService::Current_Directory() throw(ServiceUnreachable)
854 Utils_Locker lock (&_myMutex);
856 CosNaming::NamingContext_var ref_context = _current_context;
858 std::vector<std::string> splitPath;
861 bool notFound = true ;
863 // --- start search from root context
865 _current_context = _root_context ;
869 _current_directory(splitPath, lengthPath, ref_context, notFound );
872 catch (CORBA::SystemException&)
874 INFOS("Current_Directory(): CORBA::SystemException: unable to contact"
875 << " the naming service" )
876 throw ServiceUnreachable();
880 lengthPath = splitPath.size();
881 for (int k = 0 ; k < lengthPath ;k++)
884 path += splitPath[k];
888 _current_context = ref_context ;
890 return strdup(path.c_str());
893 // ============================================================================
894 /*! \brief list recursively all objects in the current context
896 * List and print via trace all directories and objects in the current
897 * context. Trace must be activated: compile option _DEBUG_
898 * If the NamingService is out, the exception ServiceUnreachable is thrown
900 // ============================================================================
902 void SALOME_NamingService::list() throw(ServiceUnreachable)
904 Utils_Locker lock (&_myMutex)
907 CosNaming::BindingList_var binding_list;
908 CosNaming::BindingIterator_var binding_iterator;
909 CosNaming::Binding_var binding ;
911 unsigned long nb = 0 ; // --- only for the BindingIterator use,
912 // to access the bindings
914 CosNaming::NamingContext_var ref_context = _current_context;
916 _current_context->list(nb, binding_list, binding_iterator) ;
918 if (! CORBA::is_nil(binding_iterator))
920 while (binding_iterator->next_one(binding))
922 CosNaming::Name bindingName = binding->binding_name;
924 if (binding->binding_type == CosNaming::ncontext)
928 Change_Directory(bindingName[0].id);
931 catch (ServiceUnreachable&)
933 INFOS( "list(): ServiceUnreachable" )
934 throw ServiceUnreachable();
938 _current_context = ref_context ;
941 else if (binding->binding_type == CosNaming::nobject)
943 MESSAGE( "list(): no Object : " << bindingName[0].id );
947 binding_iterator->destroy();
951 // ============================================================================
952 /*! \brief list all the objects in the current directory.
954 * get a list of all the objects in the current directory, without recursion
955 * on the subdirectories. Only the objects are listed, not the directories.
956 * If the NamingService is out, the exception ServiceUnreachable is thrown.
957 * \return list of strings with objects found.
958 * \sa vector<string> list_directory_recurs()
960 // ============================================================================
962 std::vector<std::string> SALOME_NamingService::list_directory() throw(ServiceUnreachable)
964 Utils_Locker lock (&_myMutex);
965 std::vector<std::string> dirList ;
968 CosNaming::BindingList_var binding_list;
969 CosNaming::BindingIterator_var binding_iterator;
970 CosNaming::Binding_var binding ;
972 unsigned long nb = 0 ; // --- only for the BindingIterator use,
973 // to access the bindings
975 CosNaming::NamingContext_var ref_context = _current_context;
977 _current_context->list(nb, binding_list, binding_iterator);
979 if (binding_iterator->_is_nil())
982 while (binding_iterator->next_one(binding))
984 CosNaming::Name bindingName = binding->binding_name;
986 if (binding->binding_type == CosNaming::nobject)
988 // remove memory leak
989 // dirList.push_back(CORBA::string_dup(bindingName[0].id));
990 dirList.push_back(std::string(bindingName[0].id));
994 // for (unsigned int ind = 0; ind < dirList.size(); ind++)
995 // MESSAGE("list_directory : Object : " << dirList[ind]);
997 binding_iterator->destroy();
1003 // ============================================================================
1004 /*! \brief list all the subdirectories in the current directory.
1006 * get a list of all the subdirectories in the current directory,
1007 * without recursion on the subdirectories.
1008 * Only the subdirectories are listed, not the objects.
1009 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1010 * \return list of strings with directories found.
1011 * \sa vector<string> list_directory()
1013 // ============================================================================
1015 std::vector<std::string> SALOME_NamingService::list_subdirs() throw(ServiceUnreachable)
1017 Utils_Locker lock (&_myMutex);
1018 std::vector<std::string> dirList ;
1021 CosNaming::BindingList_var binding_list;
1022 CosNaming::BindingIterator_var binding_iterator;
1023 CosNaming::Binding_var binding ;
1025 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1026 // to access the bindings
1028 CosNaming::NamingContext_var ref_context = _current_context;
1030 _current_context->list(nb, binding_list, binding_iterator) ;
1032 if (binding_iterator->_is_nil())
1035 while (binding_iterator->next_one(binding))
1037 CosNaming::Name bindingName = binding->binding_name;
1039 if (binding->binding_type == CosNaming::ncontext)
1041 dirList.push_back(bindingName[0].id.in());
1045 // for (unsigned int ind = 0; ind < dirList.size(); ind++)
1046 // MESSAGE("list_directory : Object : " << dirList[ind]);
1048 binding_iterator->destroy();
1053 // ============================================================================
1054 /*! \brief list all the objects in the current directory and subdirectories.
1056 * get a list of all the objects in the current directory, with recursion
1057 * on the subdirectories. Only the objects are listed, not the directories.
1058 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1059 * \return list of strings with objects found.
1060 * \sa vector<string> list_directory()
1062 // ============================================================================
1064 std::vector<std::string> SALOME_NamingService::list_directory_recurs()
1065 throw(ServiceUnreachable)
1067 Utils_Locker lock (&_myMutex);
1069 std::vector<std::string> dirList ;
1071 char* currentDir = Current_Directory();
1073 _list_directory_recurs(dirList, "", currentDir);
1080 // ============================================================================
1081 /*! \brief destroy an entry in naming service.
1083 * Destroy an association Path - Object Reference.
1084 * If the NamingService is out, the exception ServiceUnreachable is thrown
1085 * \param Path object path
1087 // ============================================================================
1089 void SALOME_NamingService::Destroy_Name(const char* Path)
1090 throw(ServiceUnreachable)
1092 Utils_Locker lock (&_myMutex);
1094 std::string path(Path);
1096 // --- if path empty, nothing to do
1101 // --- if path = '/' not applicable, nothing to do
1106 // --- if path begins with '/', set current directory to root context
1109 _current_context = _root_context;
1111 // --- context of the directory containing the object
1113 CosNaming::Name context_name;
1114 std::vector<std::string> splitPath;
1115 int dimension_resultat = _createContextNameDir(path.c_str(),
1122 if (dimension_resultat > 0)
1124 // --- path contains a directory, not only an object name
1125 // switch to the new directory (or return if directory not found)
1129 CORBA::Object_var obj = _current_context->resolve(context_name);
1130 _current_context = CosNaming::NamingContext::_narrow(obj);
1134 catch (CosNaming::NamingContext::NotFound &ex)
1136 // --- failed to resolve
1139 CosNaming::Name n = ex.rest_of_name;
1141 if (ex.why == CosNaming::NamingContext::missing_node)
1142 INFOS( "Destroy_Name(): " << (char *) n[0].id
1143 << " (" << (char *) n[0].kind << ") not found" );
1144 if (ex.why == CosNaming::NamingContext::not_context)
1145 INFOS( "Destroy_Name() : " << (char *) n[0].id
1146 << " (" << (char *) n[0].kind
1147 << ") is not a context" );
1148 if (ex.why == CosNaming::NamingContext::not_object)
1149 INFOS( "Destroy_Name() : " << (char *) n[0].id
1150 << " (" << (char *) n[0].kind
1151 << ") is not an object" );
1154 catch (CosNaming::NamingContext::InvalidName &)
1156 INFOS("Destroy_Name: CosNaming::NamingContext::InvalidName");
1159 catch (CosNaming::NamingContext::CannotProceed &)
1161 INFOS("Destroy_Name: CosNaming::NamingContext::CannotProceed");
1164 catch (CORBA::SystemException&)
1166 INFOS("Destroy_Name : CORBA::SystemException: "
1167 << "unable to contact the naming service");
1168 throw ServiceUnreachable();
1171 if (! exist) return;
1174 ASSERT(!CORBA::is_nil(_current_context));
1176 // --- The current directory is now the directory where the object should
1179 int sizePath = splitPath.size();
1180 if (sizePath > dimension_resultat)
1182 ASSERT(sizePath == dimension_resultat+1);
1183 context_name.length(1);
1187 // --- the last element is an object and not a directory
1189 context_name[0].id =
1190 CORBA::string_dup(splitPath[dimension_resultat].c_str());
1191 context_name[0].kind = CORBA::string_dup("object");
1192 //SCRUTE(context_name[0].id);
1194 _current_context->unbind(context_name);
1195 //MESSAGE("The object " << context_name[0].id << " has been deleted");
1198 catch (CosNaming::NamingContext::NotFound& ex)
1200 CosNaming::Name n = ex.rest_of_name;
1202 if (ex.why == CosNaming::NamingContext::missing_node)
1203 INFOS( "Destroy_Name() : " << (char *) n[0].id
1204 << " (" << (char *) n[0].kind << ") not found" );
1205 if (ex.why == CosNaming::NamingContext::not_context)
1206 INFOS( "Destroy_Name() : " << (char *) n[0].id
1207 << " (" << (char *) n[0].kind
1208 << ") is not a context" );
1209 if (ex.why == CosNaming::NamingContext::not_object)
1210 INFOS( "Destroy_Name() : " << (char *) n[0].id
1211 << " (" << (char *) n[0].kind
1212 << ") is not an object" );
1215 catch (CosNaming::NamingContext::CannotProceed&)
1217 INFOS( "Destroy_Name(): CosNaming::NamingContext::CannotProceed");
1220 catch (CosNaming::NamingContext::InvalidName&)
1222 INFOS( "Destroy_Name(): CosNaming::NamingContext::InvalidName");
1225 catch (CORBA::SystemException&)
1227 INFOS( "Destroy_Name(): CORBA::SystemException: unable to contact"
1228 << " the naming service");
1229 throw ServiceUnreachable();
1234 // ============================================================================
1235 /*! \brief Destroy an empty directory
1237 * Destroy an empty directory in Naming Service.
1238 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1239 * \param Path directory path
1241 // ============================================================================
1243 void SALOME_NamingService::Destroy_Directory(const char* Path) throw(ServiceUnreachable)
1245 Utils_Locker lock (&_myMutex);
1247 std::string path(Path);
1249 // --- if path empty, nothing to do
1254 // --- if path begins with '/', set current directory to root context
1257 _current_context = _root_context;
1259 CosNaming::NamingContext_var ref_context = _current_context;
1261 // --- path must ends with '/' for a directory
1263 if (path[path.size() -1] != '/')
1266 // --- context of the directory
1268 CosNaming::Name context_name;
1269 std::vector<std::string> splitPath;
1270 int dimension_resultat = _createContextNameDir(path.c_str(),
1276 if (dimension_resultat > 0)
1278 // --- path contains a directory, not only an object name
1279 // switch to the new directory (or return if directory not found)
1283 CORBA::Object_var obj = _current_context->resolve(context_name);
1284 _current_context = CosNaming::NamingContext::_narrow(obj);
1288 catch (CosNaming::NamingContext::NotFound &ex)
1290 // --- failed to resolve
1293 CosNaming::Name n = ex.rest_of_name;
1295 if (ex.why == CosNaming::NamingContext::missing_node)
1296 INFOS( "Destroy_Directory(): " << (char *) n[0].id
1297 << " (" << (char *) n[0].kind << ") not found" );
1298 if (ex.why == CosNaming::NamingContext::not_context)
1299 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1300 << " (" << (char *) n[0].kind
1301 << ") is not a context" );
1302 if (ex.why == CosNaming::NamingContext::not_object)
1303 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1304 << " (" << (char *) n[0].kind
1305 << ") is not an object" );
1308 catch (CosNaming::NamingContext::InvalidName &)
1310 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1313 catch (CosNaming::NamingContext::CannotProceed &)
1315 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1318 catch (CORBA::SystemException&)
1320 INFOS("Destroy_Directory : CORBA::SystemException: "
1321 << "unable to contact the naming service");
1322 throw ServiceUnreachable();
1325 if (! exist) return;
1328 ASSERT(!CORBA::is_nil(_current_context));
1330 // --- Context Destruction
1332 bool isContextDestroyed = false;
1335 _current_context->destroy();
1336 isContextDestroyed = true;
1339 catch (CosNaming::NamingContext::NotEmpty&)
1341 INFOS( "Destroy_Directory(): CosNaming::NamingContext::NoEmpty "
1342 << path << " is not empty" );
1345 catch (CORBA::SystemException&)
1347 INFOS( "Destroy_Directory():CORBA::SystemException : "
1348 << "unable to contact the naming service");
1349 throw ServiceUnreachable();
1352 // --- go to the reference directory
1354 _current_context = ref_context ;
1356 ASSERT(!CORBA::is_nil(_current_context));
1358 if (isContextDestroyed)
1362 _current_context->unbind(context_name);
1365 catch (CosNaming::NamingContext::NotFound& ex)
1367 CosNaming::Name n = ex.rest_of_name;
1369 if (ex.why == CosNaming::NamingContext::missing_node)
1370 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1371 << " (" << (char *) n[0].kind << ") not found" );
1372 if (ex.why == CosNaming::NamingContext::not_context)
1373 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1374 << " (" << (char *) n[0].kind
1375 << ") is not a context" );
1376 if (ex.why == CosNaming::NamingContext::not_object)
1377 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1378 << " (" << (char *) n[0].kind
1379 << ") is not an object" );
1382 catch (CosNaming::NamingContext::CannotProceed&)
1384 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1387 catch (CosNaming::NamingContext::InvalidName&)
1389 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1392 catch (CORBA::SystemException&)
1394 INFOS("Destroy_Directory:CORBA::SystemException : unable to contact"
1395 << " the naming service");
1396 throw ServiceUnreachable();
1401 // ============================================================================
1402 /*! \brief Destroy a directory with its contents.
1404 * Destroy the objects associations in a directory, and the directory itself,
1405 * if there is no subdirectories.
1406 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1407 * \param Path the directory path.
1409 // ============================================================================
1411 void SALOME_NamingService::Destroy_FullDirectory(const char* Path) throw(ServiceUnreachable)
1413 //no need to lock here because method calls are threadsafe.
1414 if( Change_Directory(Path) )
1416 std::vector<std::string> contList = list_directory();
1418 for (unsigned int ind = 0; ind < contList.size(); ind++)
1419 Destroy_Name(contList[ind].c_str());
1421 Destroy_Directory(Path);
1425 // ============================================================================
1426 /*! \brief initialize root context (root directory)
1428 * the root context initialisation must be done when the SALOME_NamingService
1429 * instance is created and before any othe call. See constructors.
1431 // ============================================================================
1433 void SALOME_NamingService::_initialize_root_context()
1435 //no lock here because initialization is expected to be done once.
1438 CORBA::Object_var obj = _orb->resolve_initial_references("NameService");
1439 _root_context = CosNaming::NamingContext::_narrow(obj);
1440 _current_context = _root_context ;
1441 ASSERT(!CORBA::is_nil(_root_context));
1444 catch (CORBA::SystemException&)
1446 INFOS("CORBA::SystemException: unable to contact the naming service");
1447 throw ServiceUnreachable();
1452 INFOS("Unknown Exception: unable to contact the naming service");
1453 throw ServiceUnreachable();
1457 // ============================================================================
1458 /*! \brief transform a string path in CosNaming structure.
1460 * Transform a path given as a string in a CosNaming structure.
1461 * \param path a relative or absolute path, with or without an object.
1462 * An absolute path begins with '/'.
1463 * A path without an object ends with '/'.
1464 * \param context_name CosNaming structure to put the path.
1465 * \param splitPath a vector of string with subdirectories and final
1467 * \param onlyDir if true, final object (if any) is omitted
1469 * if false, final object (if any) is included in
1471 * \return dimension of context_name
1473 // ============================================================================
1476 SALOME_NamingService::_createContextNameDir(std::string path,
1477 CosNaming::Name& context_name,
1478 std::vector<std::string>& splitPath,
1484 std::string::size_type begIdx, endIdx;
1485 const std::string delims("/");
1486 splitPath.resize(0);
1487 bool endWithDelim = false;
1489 begIdx = path.find_first_not_of(delims);
1490 while (begIdx != std::string::npos)
1492 endIdx = path.find_first_of(delims, begIdx);
1493 if (endIdx == path.length()-1)
1494 endWithDelim = true;
1495 if (endIdx == std::string::npos)
1496 endIdx = path.length();
1497 int lsub = endIdx - begIdx;
1499 splitPath.push_back(path.substr(begIdx, lsub));
1500 begIdx = path.find_first_not_of(delims, endIdx);
1504 if (onlyDir) // only directory part
1506 dim = splitPath.size()-1; // omit final object
1507 if (endWithDelim) // unless the path ends with a delimiter
1509 endWithDelim = true;
1512 dim = splitPath.size(); // directories and final object
1514 context_name.length(dim);
1515 for (int i=0; i<dim; i++)
1517 // SCRUTE(splitPath[i]);
1518 context_name[i].id = CORBA::string_dup(splitPath[i].c_str());
1519 if (!endWithDelim && (i == dim-1)) // here, the last string is an object
1521 context_name[i].kind = CORBA::string_dup("object");
1522 // MESSAGE("--- " <<splitPath[i] <<".object");
1526 context_name[i].kind = CORBA::string_dup("dir");
1527 // MESSAGE("--- " <<splitPath[i] <<".dir");
1533 // ============================================================================
1534 /*! \brief search a name in current directory.
1536 * Search a name in the current directory. after call, the current directory
1537 * is changed to the directory containing the last occurrence of name found.
1538 * If no occurrence found (see return value), current directory remains
1539 * unchanged. The call is recursive.
1541 * \param name the name to search.
1542 * \param occurence_number number of occurrence already found (incremented)
1544 // ============================================================================
1546 void SALOME_NamingService::_Find(const char* name,
1547 CORBA::Long& occurence_number)
1549 CosNaming::BindingList_var binding_list;
1550 CosNaming::BindingIterator_var binding_iterator;
1551 CosNaming::Binding_var binding;
1553 unsigned long nb = 0 ; // --- only for the use of the BindingIterator,
1554 // to access the bindings
1556 CosNaming::NamingContext_var ref_context = _current_context;
1557 CosNaming::NamingContext_var found_context = _current_context;
1559 _current_context->list(nb, binding_list, binding_iterator) ;
1561 if (! CORBA::is_nil(binding_iterator))
1563 while (binding_iterator->next_one(binding))
1565 CosNaming::Name bindingName = binding->binding_name;
1567 if (binding->binding_type == CosNaming::ncontext)
1569 // --- We work on a directory,
1570 // the search should be done in this directory
1572 Change_Directory(bindingName[0].id);
1573 _Find(name, occurence_number);
1575 // --- We'll go back to the initial context
1577 _current_context = ref_context ;
1580 else if (binding->binding_type == CosNaming::nobject)
1582 // --- We work on an object...
1584 if (!strcmp( bindingName[0].id, name))
1586 //MESSAGE("One occurrence was found");
1589 // --- We keep in memory the directory where
1590 // one occurrence was found
1592 found_context = _current_context ;
1597 binding_iterator->destroy();
1599 // --- We go to the last directory where an occurrence was found
1601 _current_context = found_context;
1603 SCRUTE(occurence_number);
1606 // ============================================================================
1607 /*! \brief find the current directory path.
1609 * Parse the naming service tree to find the current context and give the
1610 * associated directory path (relative to root context).
1612 * \param lengthResult
1613 * \param contextToFind
1616 // ============================================================================
1619 SALOME_NamingService::
1620 _current_directory(std::vector<std::string>& splitPath,
1622 CosNaming::NamingContext_var contextToFind,
1625 CosNaming::BindingList_var binding_list;
1626 CosNaming::BindingIterator_var binding_iterator;
1627 CosNaming::Binding_var binding;
1629 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1630 // to access the bindings
1632 CosNaming::NamingContext_var ref_context = _current_context;
1633 CosNaming::NamingContext_var temp_context = _current_context;
1635 _current_context->list(nb, binding_list, binding_iterator);
1637 if ( !binding_iterator->_is_nil() )
1639 while ((binding_iterator->next_one(binding)) && notFound)
1641 CosNaming::Name bindingName = binding->binding_name;
1643 if (binding->binding_type == CosNaming::ncontext)
1645 // --- directory, search in it
1647 const char* bindingNameid=bindingName[0].id;
1648 splitPath.push_back(bindingNameid);
1651 CORBA::Object_var obj = _current_context->resolve(bindingName);
1652 temp_context = CosNaming::NamingContext::_narrow(obj);
1654 if (temp_context->_is_equivalent(contextToFind))
1656 //MESSAGE("The context is found, we stop the search");
1663 //SCRUTE(bindingName[0].id);
1664 Change_Directory(bindingName[0].id);
1665 _current_directory(splitPath,
1672 // --- go back to the initial context
1674 _current_context = ref_context;
1676 // MESSAGE("Just before the delete of "
1677 // << splitPath[lengthResult-1]);
1678 splitPath.pop_back();
1685 binding_iterator->destroy();
1688 // --- return to the last directory where an occurrence was found
1690 _current_context = ref_context ;
1694 // ============================================================================
1695 /*! \brief list recursively all objects in the given directory and subdirs.
1697 * get a list of all the objects in the current directory, with recursion
1698 * on the subdirectories. Only the objects are listed, not the directories.
1699 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1700 * _current_context must refer to absCurDirectory.
1702 * \param myList The list that will be filled.
1703 * \param relativeSubDir The directory relative to absCurDirectory in which
1704 * the objects are found.
1705 * \param absCurDirectory The current directory, absolute path
1707 // ============================================================================
1709 void SALOME_NamingService::_list_directory_recurs(std::vector<std::string>& myList,
1710 std::string relativeSubDir,
1711 std::string absCurDirectory)
1713 CosNaming::BindingList_var binding_list;
1714 CosNaming::BindingIterator_var binding_iterator;
1715 CosNaming::Binding_var binding ;
1717 unsigned long nb = 0 ; // --- only for thethe use of BindingIterator
1718 // to access the bindings
1722 CosNaming::NamingContext_var ref_context = _current_context;
1724 if (! relativeSubDir.empty())
1726 Change_Directory(relativeSubDir.c_str());
1727 absDir = absCurDirectory + "/" + relativeSubDir;
1731 absDir = absCurDirectory;
1734 _current_context->list(nb, binding_list, binding_iterator) ;
1736 if (! CORBA::is_nil(binding_iterator))
1738 while (binding_iterator->next_one(binding))
1740 CosNaming::Name bindingName = binding->binding_name;
1742 if (binding->binding_type == CosNaming::ncontext)
1744 std::string relativeSdir(bindingName[0].id);
1745 _list_directory_recurs(myList, relativeSdir, absDir);
1748 else if (binding->binding_type == CosNaming::nobject)
1750 std::string objName(bindingName[0].id);
1751 std::string elt = absDir + "/" + objName;
1753 myList.push_back(elt);
1757 binding_iterator->destroy();
1759 if (! relativeSubDir.empty())
1761 _current_context = ref_context;
1765 // ============================================================================
1766 /*! \brief return a stringified reference of root context
1768 * \return a stringified reference of root context
1770 // ============================================================================
1772 char * SALOME_NamingService::getIORaddr()
1774 return _orb->object_to_string(_root_context);
1777 /*! \brief get the orb used by the naming service
1781 CORBA::ORB_ptr SALOME_NamingService::orb()