1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // SALOME NamingService : wrapping NamingService services
23 // File : SALOME_NamingService.cxx
24 // Author : Estelle Deville
28 #include "SALOME_NamingService.hxx"
29 #include "ServiceUnreachable.hxx"
31 #include "utilities.h"
39 /*! \class SALOME_NamingService
40 \brief A class to manage the SALOME naming service
44 // ============================================================================
45 /*! \brief Default Constructor without ORB reference.
47 * After Default Constructor, one needs to initialize ORB.
48 * \sa init_orb(CORBA::ORB_ptr orb), SALOME_NamingService(CORBA::ORB_ptr orb)
50 // ============================================================================
52 SALOME_NamingService::SALOME_NamingService()
54 MESSAGE("SALOME_NamingService default constructor");
55 _orb = CORBA::ORB::_nil();
56 _root_context = CosNaming::NamingContext::_nil();
59 // ============================================================================
60 /*! \brief Standard Constructor, with ORB reference.
62 * Initializes the naming service root context
63 * \param orb CORBA::ORB_ptr arguments
65 // ============================================================================
67 SALOME_NamingService::SALOME_NamingService(CORBA::ORB_ptr orb)
69 MESSAGE("SALOME_NamingService creation");
70 _orb = CORBA::ORB::_duplicate(orb);
71 _initialize_root_context();
74 // ============================================================================
75 /*! \brief Standard destructor.
77 * The standard destructor does nothing special.
79 // ============================================================================
81 SALOME_NamingService::~SALOME_NamingService()
83 // Problem MESSAGE with singleton: late destruction,
84 // after trace system destruction ?
85 //MESSAGE("SALOME_NamingService destruction");
88 // ============================================================================
89 /*! \brief initializes ORB reference and naming service root context.
91 * Initializes ORB reference and naming service root context.
92 * For use after default constructor.
93 * If param orb is null, the orb is initialized
94 * \param orb CORBA::ORB_ptr arguments
96 // ============================================================================
98 void SALOME_NamingService::init_orb(CORBA::ORB_ptr orb)
100 MESSAGE("SALOME_NamingService initialisation");
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 MESSAGE("BEGIN OF Register: " << Path);
141 Utils_Locker lock (&_myMutex);
143 // --- _current_context is replaced to the _root_context
144 // if the Path begins whith '/'
147 _current_context = _root_context;
150 // --- the resolution of the directory path has to be done
151 // to place the current_context to the correct node
153 CosNaming::Name context_name;
154 vector<string> splitPath;
155 int dimension_resultat = _createContextNameDir(Path,
160 CORBA::Boolean not_exist = false;
162 if (dimension_resultat > 0){
163 // A directory is treated (not only an object name)
164 // test if the directory where ObjRef should be recorded already exists
165 // If not, create the new context
168 CORBA::Object_var obj = _current_context->resolve(context_name);
169 _current_context = CosNaming::NamingContext::_narrow(obj);
172 catch (CosNaming::NamingContext::NotFound &){
173 // --- failed to resolve, therefore assume cold start
177 catch (CosNaming::NamingContext::InvalidName &){
178 INFOS("Register() : CosNaming::NamingContext::InvalidName");
181 catch (CosNaming::NamingContext::CannotProceed &){
182 INFOS("Register() : CosNaming::NamingContext::CannotProceed");
185 catch (CORBA::SystemException&){
186 INFOS("Register() : CORBA::SystemException: "
187 << "unable to contact the naming service");
188 throw ServiceUnreachable();
193 context_name.length(1);
194 for (int i = 0 ; i < dimension_resultat ;i++){
195 context_name[0].id = CORBA::string_dup(splitPath[i].c_str());
196 context_name[0].kind = CORBA::string_dup("dir");
197 // SCRUTE(_context_name[0].id);
198 // --- check if the path is created
200 // --- if the context is already created, nothing to do
201 CORBA::Object_var obj = _current_context->resolve(context_name);
202 _current_context = CosNaming::NamingContext::_narrow(obj);
205 catch (CosNaming::NamingContext::NotFound &){
207 // --- the context must be created
208 CosNaming::NamingContext_var temp_context =
209 _current_context->bind_new_context(context_name);
210 _current_context = temp_context;
212 catch (CosNaming::NamingContext::AlreadyBound&){
213 CORBA::Object_var obj = _current_context->resolve(context_name);
214 _current_context = CosNaming::NamingContext::_narrow(obj);
220 catch (CosNaming::NamingContext::AlreadyBound&){
221 INFOS("Register() : CosNaming::NamingContext::AlreadyBound");
224 catch (CosNaming::NamingContext::NotFound& ex){
225 CosNaming::Name n = ex.rest_of_name;
227 if (ex.why == CosNaming::NamingContext::missing_node)
228 INFOS("Register() : " << (char *) n[0].id
229 << " (" << (char *) n[0].kind << ") not found");
231 if (ex.why == CosNaming::NamingContext::not_context)
232 INFOS("Register() : " << (char *) n[0].id
233 << " (" << (char *) n[0].kind
234 << ") is not a context");
236 if (ex.why == CosNaming::NamingContext::not_object)
237 INFOS("Register() : " << (char *) n[0].id
238 << " (" << (char *) n[0].kind
239 << ") is not an object");
242 catch (CosNaming::NamingContext::CannotProceed&){
243 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
246 catch (CosNaming::NamingContext::InvalidName&){
247 INFOS("Register(): CosNaming::NamingContext::InvalidName");
250 catch (CORBA::SystemException&){
251 INFOS("Register():CORBA::SystemException: "
252 << "unable to contact the naming service");
253 throw ServiceUnreachable();
258 // --- The current directory is now the directory where the object should
261 int sizePath = splitPath.size();
262 if (sizePath > dimension_resultat){
263 ASSERT(sizePath == dimension_resultat+1);
264 context_name.length(1);
267 // --- the last element is an object and not a directory
269 context_name[0].id = CORBA::string_dup(splitPath[dimension_resultat].c_str());
270 context_name[0].kind = CORBA::string_dup("object");
271 //SCRUTE(context_name[0].id);
273 _current_context->bind(context_name, ObjRef);
276 catch (CosNaming::NamingContext::NotFound& ex){
277 CosNaming::Name n = ex.rest_of_name;
279 if (ex.why == CosNaming::NamingContext::missing_node)
280 INFOS("Register() : " << (char *) n[0].id
281 << " (" << (char *) n[0].kind << ") not found");
283 if (ex.why == CosNaming::NamingContext::not_context)
284 INFOS("Register() : " << (char *) n[0].id
285 << " (" << (char *) n[0].kind
286 << ") is not a context");
288 if (ex.why == CosNaming::NamingContext::not_object)
289 INFOS("Register() : " << (char *) n[0].id
290 << " (" << (char *) n[0].kind
291 << ") is not an object");
294 catch (CosNaming::NamingContext::CannotProceed&){
295 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
298 catch (CosNaming::NamingContext::InvalidName&){
299 INFOS("Register(): CosNaming::NamingContext::InvalidName");
302 catch (CosNaming::NamingContext::AlreadyBound&){
303 INFOS("Register(): CosNaming::NamingContext::AlreadyBound, "
304 << "object will be rebind");
305 _current_context->rebind(context_name, ObjRef);
308 catch (CORBA::SystemException&){
309 INFOS("!!!Register(): CORBA::SystemException: "
310 << "unable to contact the naming service");
311 throw ServiceUnreachable();
316 // ============================================================================
317 /*! \brief get the CORBA object reference associated to a name.
319 * get the CORBA object reference associated to a complete name with a path.
320 * If the NamingService is out, the exception ServiceUnreachable is thrown
321 * \param Path pathname. If the pathname begins with a '/', pathname is taken
322 * as an absolute pathname. Else, pathname is taken as a relative
323 * path, to current context. Prefer absolute pathname, relative
324 * pathname are not safe, when SALOME_NamingService object is
325 * shared or use in multithreaded context.
326 * \return the object reference if it exists under the pathname,
327 * or nil reference in other cases.
328 * \sa Register(CORBA::Object_ptr ObjRef, const char* Path),
329 * Change_Directory(const char* Path)
331 // ============================================================================
333 CORBA::Object_ptr SALOME_NamingService::Resolve(const char* Path)
334 throw(ServiceUnreachable)
336 // MESSAGE("BEGIN OF Resolve: " << Path);
338 Utils_Locker lock (&_myMutex);
340 // --- _current_context is replaced to the _root_context
341 // if the Path begins whith '/'
345 _current_context = _root_context;
348 // --- the resolution of the directory path has to be done
349 // to place the current_context to the correct node
351 CosNaming::Name context_name;
352 vector<string> splitPath;
353 _createContextNameDir(Path,
358 ASSERT(!CORBA::is_nil(_current_context));
360 CORBA::Object_var obj = CORBA::Object::_nil();
364 obj = _current_context->resolve(context_name);
367 catch (CosNaming::NamingContext::NotFound& ex)
369 CosNaming::Name n = ex.rest_of_name;
371 if (ex.why == CosNaming::NamingContext::missing_node)
372 MESSAGE("Resolve() : " << (char *) n[0].id
373 << " (" << (char *) n[0].kind << ") not found");
375 if (ex.why == CosNaming::NamingContext::not_context)
377 << (char *) n[0].id << " (" << (char *) n[0].kind
378 << ") is not a context");
380 if (ex.why == CosNaming::NamingContext::not_object)
381 INFOS("Resolve() : " << (char *) n[0].id
382 << " (" << (char *) n[0].kind
383 << ") is not an object");
386 catch (CosNaming::NamingContext::CannotProceed&)
388 INFOS("Resolve(): CosNaming::NamingContext::CannotProceed");
391 catch (CosNaming::NamingContext::InvalidName&)
393 INFOS("Resolve(): CosNaming::NamingContext::InvalidName");
396 catch (CORBA::SystemException&)
398 INFOS("Resolve():CORBA::SystemException : unable to contact"
399 << "the naming service");
400 throw ServiceUnreachable();
406 // ============================================================================
407 /*! \brief get the CORBA object reference associated to an uncomplete name.
409 * get the CORBA object reference associated to an uncomplete name with a
410 * path. Look for the first occurence of name*.
411 * If the NamingService is out, the exception ServiceUnreachable is thrown
412 * \param Path pathname under the form "/path/name" (Absolute reference !)
413 * search the fist reference like "/path(.dir)/name*(.kind)"
414 * \return the object reference if found, or nil reference.
415 * \sa Resolve(const char* Path)
417 // ============================================================================
419 CORBA::Object_ptr SALOME_NamingService::ResolveFirst(const char* Path)
420 throw(ServiceUnreachable)
422 // MESSAGE("ResolveFirst");
424 Utils_Locker lock (&_myMutex);
427 string thePath = Path;
428 string basePath = "";
429 string name = thePath;
431 string::size_type idx = thePath.rfind('/');
433 if (idx != string::npos) // at least one '/' found
435 basePath = thePath.substr(0, idx);
436 name = thePath.substr(idx + 1);
441 CORBA::Object_var obj = CORBA::Object::_nil();
444 if (basePath.empty())
447 isOk = Change_Directory(basePath.c_str());
451 vector<string> listElem = list_directory();
452 vector<string>::iterator its = listElem.begin();
454 while (its != listElem.end())
458 if ((*its).find(name) == 0)
460 return Resolve((*its).c_str());
470 // ============================================================================
471 /*! \brief find a component instance from hostname, containername,
472 * componentName and number of processors.
474 * find a component instance from hostname, containername, componentName and
475 * number of processors.
476 * If the NamingService is out, the exception ServiceUnreachable is thrown.
477 * \param hostname name of the machine on which the component is searched.
478 * \param containerName name of the container in which the component is
480 * \param componentName name of the component we are looking for an existing
482 * \param nbproc in case of multi processor machine, container name is
483 * suffixed with _nbproc.
484 * \return the object reference
486 // ============================================================================
489 SALOME_NamingService::ResolveComponent(const char* hostname,
490 const char* containerName,
491 const char* componentName,
493 throw(ServiceUnreachable)
495 // MESSAGE("ResolveComponent");
497 Utils_Locker lock (&_myMutex);
499 string name = "/Containers/";
503 if ( strlen(containerName) != 0 )
509 char *newContainerName = new char[strlen(containerName) + 8];
510 sprintf(newContainerName, "%s_%d", containerName, nbproc);
511 name += newContainerName;
512 delete [] newContainerName;
516 name += containerName;
520 name += componentName;
522 return ResolveFirst(name.c_str());
528 string basename = name;
529 if (Change_Directory(basename.c_str()))
531 vector<string> contList = list_subdirs();
533 for (unsigned int ind = 0; ind < contList.size(); ind++)
535 name = contList[ind].c_str();
539 char *str_nbproc = new char[8];
540 sprintf(str_nbproc, "_%d", nbproc);
541 if( strstr(name.c_str(),str_nbproc) == NULL)
542 continue; // check only containers with _%d in name
543 delete [] str_nbproc;
547 name += componentName;
549 CORBA::Object_ptr obj = ResolveFirst(name.c_str());
551 if ( !CORBA::is_nil(obj) )
554 Change_Directory(basename.c_str());
558 return CORBA::Object::_nil();
562 // ============================================================================
563 /*! \brief provide a default container name if empty.
565 * the given container name is returned unchanged, unless it is empty.
566 * \param containerName
567 * \return container name, where empty input is replaced by "FactoryServer",
569 * \sa BuildContainerNameForNS(const char *containerName, const char *hostname)
571 // ============================================================================
573 string SALOME_NamingService::ContainerName(const char *containerName)
577 if (strlen(containerName) == 0)
578 ret = "FactoryServer";
585 // ============================================================================
586 /*! \brief build a container name, given a MachineParameters struct.
588 * Build a container name with a MachineParameters struct. In case of multi
589 * processor machine, container name is suffixed with _nbproc. nproc equals
590 * (number of nodes)*(number of processor per nodes).
591 * \param params struct from which we get container name (may be
592 * empty), number of nodes and number of processor
594 * \return a container name without the path.
595 * \sa BuildContainerNameForNS(const Engines::MachineParameters& params,
596 * const char *hostname)
598 // ============================================================================
601 SALOME_NamingService::ContainerName(const Engines::MachineParameters& params)
607 else if ( (params.nb_node <= 0) && (params.nb_proc_per_node <= 0) )
609 else if ( params.nb_node == 0 )
610 nbproc = params.nb_proc_per_node;
611 else if ( params.nb_proc_per_node == 0 )
612 nbproc = params.nb_node;
614 nbproc = params.nb_node * params.nb_proc_per_node;
616 string ret = ContainerName(params.container_name);
620 char *suffix = new char[8];
621 sprintf(suffix, "_%d", nbproc);
628 // ============================================================================
629 /*! \brief build a string representing a container in Naming Service.
631 * Build a string representing the absolute pathname of a container in
632 * SALOME_NamingService. This form gives a suffixed containerName in case of
633 * multi processor machine.
634 * \param containerName name of the container in which the component is
636 * \param hostname name of the host of the container, without domain names.
637 * \return the path under the form /Containers/hostname/containerName
638 * \sa ContainerName(const Engines::MachineParameters& params)
640 // ============================================================================
642 string SALOME_NamingService::BuildContainerNameForNS(const char *containerName,
643 const char *hostname)
645 string ret = "/Containers/";
648 ret += ContainerName(containerName);
653 // ============================================================================
654 /*! \brief build a string representing a container in Naming Service.
656 * Build a string representing the absolute pathname of a container in
657 * SALOME_NamingService.
658 * \param params used as it is, or replaced by FactoryServer if empty.
659 * \param hostname name of the host of the container, without domain names.
660 * \return the path under the form /Containers/hostname/containerName
661 * \sa ContainerName(const char *containerName)
663 // ============================================================================
666 SALOME_NamingService::
667 BuildContainerNameForNS(const Engines::MachineParameters& params,
668 const char *hostname)
670 string ret = "/Containers/";
673 ret += ContainerName(params);
678 // ============================================================================
679 /*! \brief search a name in current directory.
681 * Search a name in the current directory. after call, the current directory
682 * is changed to the directory containing the last occurence of name found.
683 * If no occurence found (see return value), current directory remains
686 * \param name the name to search.
687 * \return number of occurences found.
688 * \sa Change_Directory(const char* Path)
690 // ============================================================================
692 int SALOME_NamingService::Find(const char* name)
693 throw(ServiceUnreachable)
695 MESSAGE("BEGIN OF Find " << name);
697 Utils_Locker lock (&_myMutex);
699 CORBA::Long occurence_number = 0 ;
703 _Find(name, occurence_number);
706 catch (CORBA::SystemException&)
708 INFOS("!!!Find() : CORBA::SystemException : unable to contact"
709 << " the naming service");
710 throw ServiceUnreachable();
713 return occurence_number;
716 // ============================================================================
717 /*! \brief Creates a directory (context_name)
719 * Creates a directory (context_name) relative to the current directory
720 * (current context) or relative to the root directory (root context), if
721 * the path given begins with a '/'.
722 * If the NamingService is out, the exception ServiceUnreachable is thrown.
723 * \param Path A relative or absolute pathname to store the object reference.
724 * If the pathname begins with a '/', pathname is taken
725 * as an absolute pathname. Else, pathname is taken as a relative
726 * path, to current context. Prefer absolute pathname, relative
727 * pathname are not safe, when SALOME_NamingService object is
728 * shared or use in multithreaded context.
729 * \return true if successfull
730 * (creation not strictly garanteed if true, because Register may
731 * catch some specific unlikely exception without throw anything
732 * --- to be corrected ---)
733 * \sa RegisterCORBA::Object_ptr ObjRef, const char* Path)
735 // ============================================================================
737 bool SALOME_NamingService::Create_Directory(const char* Path)
738 throw(ServiceUnreachable)
740 MESSAGE("BEGIN OF Create_Directory");
742 Utils_Locker lock (&_myMutex);
746 // --- if path empty, nothing to create, no context change
751 // --- if path ='/', nothing to create, only change to root_context
755 MESSAGE("Create Directory '/', just change to root_context");
756 _current_context = _root_context;
760 // --- path must end with '/'
762 if (path[path.length()-1] != '/') path += '/';
764 Register(CORBA::Object::_nil(), path.c_str());
768 // ============================================================================
769 /*! \brief change current directory to the given path
771 * change the current directory to the given path in parameter.
772 * Warning: avoid use when the SALOME_NamingService instance is shared by
773 * several threads (current context may be modified by another thread).
774 * If the path is empty, nothing done return OK.
775 * If Path ="/", the current directory changes to the root directory.
776 * If the NamingService is out, the exception ServiceUnreachable is thrown.
777 * \param Path the new current directory
778 * \return true if the change succeeded
780 // ============================================================================
782 bool SALOME_NamingService::Change_Directory(const char* Path)
783 throw(ServiceUnreachable)
785 // MESSAGE("BEGIN OF Change_Directory " << Path);
786 Utils_Locker lock (&_myMutex);
790 // --- if path empty, nothing to do
795 // --- if path ='/', nothing to resolve, only change to root_context
799 // MESSAGE("Change_Directory is called to go to the root_context");
800 _current_context = _root_context;
804 CosNaming::NamingContext_var current_context = _current_context;
805 bool changeOK = false;
807 // --- replace _current_context with _root_context if Path begins whith '/'
810 current_context = _root_context;
812 // --- need to resolve directory path
814 ASSERT(!CORBA::is_nil(current_context));
816 if (path[path.length()-1] != '/') path += '/';
818 CosNaming::Name context_name;
819 vector<string> splitPath;
820 _createContextNameDir(path.c_str(),
825 // --- Context creation
829 CORBA::Object_var obj = current_context->resolve(context_name);
830 current_context = CosNaming::NamingContext::_narrow(obj);
831 ASSERT(!CORBA::is_nil(current_context));
832 _current_context = current_context;
836 catch (CosNaming::NamingContext::NotFound& ex)
838 CosNaming::Name n = ex.rest_of_name;
840 if (ex.why == CosNaming::NamingContext::missing_node)
841 MESSAGE( "Change_Directory() : " << (char *) n[0].id
842 << " (" << (char *) n[0].kind << ") not found");
843 if (ex.why == CosNaming::NamingContext::not_context)
844 INFOS("Change_Directory() : " << (char *) n[0].id
845 << " (" << (char *) n[0].kind
846 << ") is not a context" );
847 if (ex.why == CosNaming::NamingContext::not_object)
848 INFOS( "Change_Directory() : " << (char *) n[0].id
849 << " (" << (char *) n[0].kind
850 << ") is not an object" );
853 catch (CosNaming::NamingContext::CannotProceed&)
855 INFOS("Change_Directory(): CosNaming::NamingContext::CannotProceed");
858 catch (CosNaming::NamingContext::InvalidName&)
860 INFOS("Change_Directory(): CosNaming::NamingContext::InvalidName");
863 catch (CORBA::SystemException&)
865 INFOS("Change_Directory():CORBA::SystemException : unable to contact"
866 << "the naming service");
867 throw ServiceUnreachable();
873 // ============================================================================
874 /*! \brief get the current directory path
876 * Get the current directory path.
877 * If the NamingService is out, the exception ServiceUnreachable is thrown.
878 * \return the path of the current_context
879 * \sa _current_directory
881 // ============================================================================
883 char* SALOME_NamingService::Current_Directory()
884 throw(ServiceUnreachable)
886 MESSAGE("BEGIN OF Current_Directory");
888 Utils_Locker lock (&_myMutex);
890 CosNaming::NamingContext_var ref_context = _current_context;
892 vector<string> splitPath;
895 bool notFound = true ;
897 // --- start search from root context
899 _current_context = _root_context ;
903 _current_directory(splitPath, lengthPath, ref_context, notFound );
906 catch (CORBA::SystemException&)
908 INFOS("Current_Directory(): CORBA::SystemException: unable to contact"
909 << " the naming service" )
910 throw ServiceUnreachable();
914 lengthPath = splitPath.size();
915 for (int k = 0 ; k < lengthPath ;k++)
918 path += splitPath[k];
922 _current_context = ref_context ;
924 return strdup(path.c_str());
927 // ============================================================================
928 /*! \brief list recursively all objects in the current context
930 * List and print via trace all directories and objects in the current
931 * context. Trace must be activated: compile option _DEBUG_
932 * If the NamingService is out, the exception ServiceUnreachable is thrown
934 // ============================================================================
936 void SALOME_NamingService::list()
937 throw(ServiceUnreachable)
939 MESSAGE("Begin of list");
941 Utils_Locker lock (&_myMutex)
944 CosNaming::BindingList_var binding_list;
945 CosNaming::BindingIterator_var binding_iterator;
946 CosNaming::Binding_var binding ;
948 unsigned long nb = 0 ; // --- only for the BindingIterator use,
949 // to access the bindings
951 CosNaming::NamingContext_var ref_context = _current_context;
953 _current_context->list(nb, binding_list, binding_iterator) ;
955 if (! CORBA::is_nil(binding_iterator))
957 while (binding_iterator->next_one(binding))
959 CosNaming::Name bindingName = binding->binding_name;
961 if (binding->binding_type == CosNaming::ncontext)
963 MESSAGE( "Context : " << bindingName[0].id );
967 Change_Directory(bindingName[0].id);
970 catch (ServiceUnreachable&)
972 INFOS( "list(): ServiceUnreachable" )
973 throw ServiceUnreachable();
977 _current_context = ref_context ;
980 else if (binding->binding_type == CosNaming::nobject)
982 MESSAGE( "Object : " << bindingName[0].id );
986 binding_iterator->destroy();
990 // ============================================================================
991 /*! \brief list all the objects in the current directory.
993 * get a list of all the objects in the current directory, without recursion
994 * on the subdirectories. Only the objects are listed, not the directories.
995 * If the NamingService is out, the exception ServiceUnreachable is thrown.
996 * \return list of strings with objects found.
997 * \sa vector<string> list_directory_recurs()
999 // ============================================================================
1001 vector<string> SALOME_NamingService::list_directory()
1002 throw(ServiceUnreachable)
1004 // MESSAGE("list_directory");
1005 vector<string> dirList ;
1008 CosNaming::BindingList_var binding_list;
1009 CosNaming::BindingIterator_var binding_iterator;
1010 CosNaming::Binding_var binding ;
1012 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1013 // to access the bindings
1015 CosNaming::NamingContext_var ref_context = _current_context;
1017 _current_context->list(nb, binding_list, binding_iterator);
1019 if (binding_iterator->_is_nil())
1022 while (binding_iterator->next_one(binding))
1024 CosNaming::Name bindingName = binding->binding_name;
1026 if (binding->binding_type == CosNaming::nobject)
1028 // remove memory leak
1029 // dirList.push_back(CORBA::string_dup(bindingName[0].id));
1030 dirList.push_back(string(bindingName[0].id));
1034 // for (unsigned int ind = 0; ind < dirList.size(); ind++)
1035 // MESSAGE("list_directory : Object : " << dirList[ind]);
1037 binding_iterator->destroy();
1043 // ============================================================================
1044 /*! \brief list all the subdirectories in the current directory.
1046 * get a list of all the subdirectories in the current directory,
1047 * without recursion on the subdirectories.
1048 * Only the subdirectories are listed, not the objects.
1049 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1050 * \return list of strings with directories found.
1051 * \sa vector<string> list_directory()
1053 // ============================================================================
1055 vector<string> SALOME_NamingService::list_subdirs()
1056 throw(ServiceUnreachable)
1058 MESSAGE("list_subdirs");
1059 vector<string> dirList ;
1062 CosNaming::BindingList_var binding_list;
1063 CosNaming::BindingIterator_var binding_iterator;
1064 CosNaming::Binding_var binding ;
1066 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1067 // to access the bindings
1069 CosNaming::NamingContext_var ref_context = _current_context;
1071 _current_context->list(nb, binding_list, binding_iterator) ;
1073 if (binding_iterator->_is_nil())
1076 while (binding_iterator->next_one(binding))
1078 CosNaming::Name bindingName = binding->binding_name;
1080 if (binding->binding_type == CosNaming::ncontext)
1082 dirList.push_back(bindingName[0].id.in());
1086 for (unsigned int ind = 0; ind < dirList.size(); ind++)
1087 MESSAGE("list_directory : Object : " << dirList[ind]);
1089 binding_iterator->destroy();
1094 // ============================================================================
1095 /*! \brief list all the objects in the current directory and subdirectories.
1097 * get a list of all the objects in the current directory, with recursion
1098 * on the subdirectories. Only the objects are listed, not the directories.
1099 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1100 * \return list of strings with objects found.
1101 * \sa vector<string> list_directory()
1103 // ============================================================================
1105 vector<string> SALOME_NamingService::list_directory_recurs()
1106 throw(ServiceUnreachable)
1108 MESSAGE("list_directory_recurs");
1110 Utils_Locker lock (&_myMutex);
1112 vector<string> dirList ;
1114 char* currentDir = Current_Directory();
1116 _list_directory_recurs(dirList, "", currentDir);
1123 // ============================================================================
1124 /*! \brief destroy an entry in naming service.
1126 * Destroy an association Path - Object Reference.
1127 * If the NamingService is out, the exception ServiceUnreachable is thrown
1128 * \param Path object path
1130 // ============================================================================
1132 void SALOME_NamingService::Destroy_Name(const char* Path)
1133 throw(ServiceUnreachable)
1135 MESSAGE("BEGIN OF Destroy_Name " << Path);
1137 Utils_Locker lock (&_myMutex);
1141 // --- if path empty, nothing to do
1146 // --- if path = '/' not applicable, nothing to do
1151 // --- if path begins with '/', set current directory to root context
1154 _current_context = _root_context;
1156 // --- context of the directory containing the object
1158 CosNaming::Name context_name;
1159 vector<string> splitPath;
1160 int dimension_resultat = _createContextNameDir(path.c_str(),
1167 if (dimension_resultat > 0)
1169 // --- path contains a directory, not only an object name
1170 // switch to the new directory (or return if directory not found)
1174 CORBA::Object_var obj = _current_context->resolve(context_name);
1175 _current_context = CosNaming::NamingContext::_narrow(obj);
1179 catch (CosNaming::NamingContext::NotFound &ex)
1181 // --- failed to resolve
1184 CosNaming::Name n = ex.rest_of_name;
1186 if (ex.why == CosNaming::NamingContext::missing_node)
1187 INFOS( "Destroy_Name(): " << (char *) n[0].id
1188 << " (" << (char *) n[0].kind << ") not found" );
1189 if (ex.why == CosNaming::NamingContext::not_context)
1190 INFOS( "Destroy_Name() : " << (char *) n[0].id
1191 << " (" << (char *) n[0].kind
1192 << ") is not a context" );
1193 if (ex.why == CosNaming::NamingContext::not_object)
1194 INFOS( "Destroy_Name() : " << (char *) n[0].id
1195 << " (" << (char *) n[0].kind
1196 << ") is not an object" );
1199 catch (CosNaming::NamingContext::InvalidName &)
1201 INFOS("Destroy_Name: CosNaming::NamingContext::InvalidName");
1204 catch (CosNaming::NamingContext::CannotProceed &)
1206 INFOS("Destroy_Name: CosNaming::NamingContext::CannotProceed");
1209 catch (CORBA::SystemException&)
1211 INFOS("Destroy_Name : CORBA::SystemException: "
1212 << "unable to contact the naming service");
1213 throw ServiceUnreachable();
1216 if (! exist) return;
1219 ASSERT(!CORBA::is_nil(_current_context));
1221 // --- The current directory is now the directory where the object should
1224 int sizePath = splitPath.size();
1225 if (sizePath > dimension_resultat)
1227 ASSERT(sizePath == dimension_resultat+1);
1228 context_name.length(1);
1232 // --- the last element is an object and not a directory
1234 context_name[0].id =
1235 CORBA::string_dup(splitPath[dimension_resultat].c_str());
1236 context_name[0].kind = CORBA::string_dup("object");
1237 SCRUTE(context_name[0].id);
1239 _current_context->unbind(context_name);
1240 MESSAGE("The object " << context_name[0].id << " has been deleted");
1243 catch (CosNaming::NamingContext::NotFound& ex)
1245 CosNaming::Name n = ex.rest_of_name;
1247 if (ex.why == CosNaming::NamingContext::missing_node)
1248 INFOS( "Destroy_Name() : " << (char *) n[0].id
1249 << " (" << (char *) n[0].kind << ") not found" );
1250 if (ex.why == CosNaming::NamingContext::not_context)
1251 INFOS( "Destroy_Name() : " << (char *) n[0].id
1252 << " (" << (char *) n[0].kind
1253 << ") is not a context" );
1254 if (ex.why == CosNaming::NamingContext::not_object)
1255 INFOS( "Destroy_Name() : " << (char *) n[0].id
1256 << " (" << (char *) n[0].kind
1257 << ") is not an object" );
1260 catch (CosNaming::NamingContext::CannotProceed&)
1262 INFOS( "Destroy_Name(): CosNaming::NamingContext::CannotProceed");
1265 catch (CosNaming::NamingContext::InvalidName&)
1267 INFOS( "Destroy_Name(): CosNaming::NamingContext::InvalidName");
1270 catch (CORBA::SystemException&)
1272 INFOS( "Destroy_Name(): CORBA::SystemException: unable to contact"
1273 << " the naming service");
1274 throw ServiceUnreachable();
1279 // ============================================================================
1280 /*! \brief Destroy an empty directory
1282 * Destroy an empty directory in Naming Service.
1283 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1284 * \param Path directory path
1286 // ============================================================================
1288 void SALOME_NamingService::Destroy_Directory(const char* Path)
1289 throw(ServiceUnreachable)
1291 MESSAGE("BEGIN OF Destroy_Directory " << Path);
1293 Utils_Locker lock (&_myMutex);
1297 // --- if path empty, nothing to do
1302 // --- if path begins with '/', set current directory to root context
1305 _current_context = _root_context;
1307 CosNaming::NamingContext_var ref_context = _current_context;
1309 // --- path must ends with '/' for a directory
1311 if (path[path.size() -1] != '/')
1314 // --- context of the directory
1316 CosNaming::Name context_name;
1317 vector<string> splitPath;
1318 int dimension_resultat = _createContextNameDir(path.c_str(),
1324 if (dimension_resultat > 0)
1326 // --- path contains a directory, not only an object name
1327 // switch to the new directory (or return if directory not found)
1331 CORBA::Object_var obj = _current_context->resolve(context_name);
1332 _current_context = CosNaming::NamingContext::_narrow(obj);
1336 catch (CosNaming::NamingContext::NotFound &ex)
1338 // --- failed to resolve
1341 CosNaming::Name n = ex.rest_of_name;
1343 if (ex.why == CosNaming::NamingContext::missing_node)
1344 INFOS( "Destroy_Directory(): " << (char *) n[0].id
1345 << " (" << (char *) n[0].kind << ") not found" );
1346 if (ex.why == CosNaming::NamingContext::not_context)
1347 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1348 << " (" << (char *) n[0].kind
1349 << ") is not a context" );
1350 if (ex.why == CosNaming::NamingContext::not_object)
1351 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1352 << " (" << (char *) n[0].kind
1353 << ") is not an object" );
1356 catch (CosNaming::NamingContext::InvalidName &)
1358 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1361 catch (CosNaming::NamingContext::CannotProceed &)
1363 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1366 catch (CORBA::SystemException&)
1368 INFOS("Destroy_Directory : CORBA::SystemException: "
1369 << "unable to contact the naming service");
1370 throw ServiceUnreachable();
1373 if (! exist) return;
1376 ASSERT(!CORBA::is_nil(_current_context));
1378 // --- Context Destruction
1380 bool isContextDestroyed = false;
1383 _current_context->destroy();
1384 MESSAGE( "The context " << path << " has been deleted" );
1385 isContextDestroyed = true;
1388 catch (CosNaming::NamingContext::NotEmpty&)
1390 INFOS( "Destroy_Directory(): CosNaming::NamingContext::NoEmpty "
1391 << path << " is not empty" );
1394 catch (CORBA::SystemException&)
1396 INFOS( "Destroy_Directory():CORBA::SystemException : "
1397 << "unable to contact the naming service");
1398 throw ServiceUnreachable();
1401 // --- go to the reference directory
1403 _current_context = ref_context ;
1405 ASSERT(!CORBA::is_nil(_current_context));
1407 if (isContextDestroyed)
1411 _current_context->unbind(context_name);
1412 MESSAGE( "The bind to the context "
1413 << context_name[0].id
1414 << " has been deleted" );
1417 catch (CosNaming::NamingContext::NotFound& ex)
1419 CosNaming::Name n = ex.rest_of_name;
1421 if (ex.why == CosNaming::NamingContext::missing_node)
1422 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1423 << " (" << (char *) n[0].kind << ") not found" );
1424 if (ex.why == CosNaming::NamingContext::not_context)
1425 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1426 << " (" << (char *) n[0].kind
1427 << ") is not a context" );
1428 if (ex.why == CosNaming::NamingContext::not_object)
1429 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1430 << " (" << (char *) n[0].kind
1431 << ") is not an object" );
1434 catch (CosNaming::NamingContext::CannotProceed&)
1436 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1439 catch (CosNaming::NamingContext::InvalidName&)
1441 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1444 catch (CORBA::SystemException&)
1446 INFOS("Destroy_Directory:CORBA::SystemException : unable to contact"
1447 << " the naming service");
1448 throw ServiceUnreachable();
1453 // ============================================================================
1454 /*! \brief Destroy a directory with its contents.
1456 * Destroy the objects associations in a directory, and the directory itself,
1457 * if there is no subdirectories.
1458 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1459 * \param Path the directory path.
1461 // ============================================================================
1463 void SALOME_NamingService::Destroy_FullDirectory(const char* Path)
1464 throw(ServiceUnreachable)
1466 MESSAGE("begin of Destroy_FullDirectory " << Path);
1467 if( Change_Directory(Path) )
1469 vector<string> contList = list_directory();
1471 for (unsigned int ind = 0; ind < contList.size(); ind++)
1472 Destroy_Name(contList[ind].c_str());
1474 Destroy_Directory(Path);
1478 // ============================================================================
1479 /*! \brief initialize root context (root directory)
1481 * the root context initialisation must be done when the SALOME_NamingService
1482 * instance is created and before any othe call. See constructors.
1484 // ============================================================================
1486 void SALOME_NamingService::_initialize_root_context()
1488 //MESSAGE("Get the root context");
1492 CORBA::Object_var obj = _orb->resolve_initial_references("NameService");
1493 _root_context = CosNaming::NamingContext::_narrow(obj);
1494 _current_context = _root_context ;
1495 ASSERT(!CORBA::is_nil(_root_context));
1498 catch (CORBA::SystemException&)
1500 INFOS("CORBA::SystemException: unable to contact the naming service");
1501 throw ServiceUnreachable();
1506 INFOS("Unknown Exception: unable to contact the naming service");
1507 throw ServiceUnreachable();
1511 // ============================================================================
1512 /*! \brief transform a string path in CosNaming structure.
1514 * Transform a path given as a string in a CosNaming structure.
1515 * \param path a relative or absolute path, with or without an object.
1516 * An absolute path begins with '/'.
1517 * A path without an object ends with '/'.
1518 * \param context_name CosNaming structure to put the path.
1519 * \param splitPath a vector of string with subdirectories and final
1521 * \param onlyDir if true, final object (if any) is ommited
1523 * if false, final object (if any) is included in
1525 * \return dimension of context_name
1527 // ============================================================================
1530 SALOME_NamingService::_createContextNameDir(string path,
1531 CosNaming::Name& context_name,
1532 vector<string>& splitPath,
1538 string::size_type begIdx, endIdx;
1539 const string delims("/");
1540 splitPath.resize(0);
1541 bool endWithDelim = false;
1543 begIdx = path.find_first_not_of(delims);
1544 while (begIdx != string::npos)
1546 endIdx = path.find_first_of(delims, begIdx);
1547 if (endIdx == path.length()-1)
1548 endWithDelim = true;
1549 if (endIdx == string::npos)
1550 endIdx = path.length();
1551 int lsub = endIdx - begIdx;
1553 splitPath.push_back(path.substr(begIdx, lsub));
1554 begIdx = path.find_first_not_of(delims, endIdx);
1558 if (onlyDir) // only directory part
1560 dim = splitPath.size()-1; // omit final object
1561 if (endWithDelim) // unless the path ends with a delimiter
1563 endWithDelim = true;
1566 dim = splitPath.size(); // directories and final object
1568 context_name.length(dim);
1569 for (int i=0; i<dim; i++)
1571 // SCRUTE(splitPath[i]);
1572 context_name[i].id = CORBA::string_dup(splitPath[i].c_str());
1573 if (!endWithDelim && (i == dim-1)) // here, the last string is an object
1575 context_name[i].kind = CORBA::string_dup("object");
1576 // MESSAGE("--- " <<splitPath[i] <<".object");
1580 context_name[i].kind = CORBA::string_dup("dir");
1581 // MESSAGE("--- " <<splitPath[i] <<".dir");
1587 // ============================================================================
1588 /*! \brief search a name in current directory.
1590 * Search a name in the current directory. after call, the current directory
1591 * is changed to the directory containing the last occurence of name found.
1592 * If no occurence found (see return value), current directory remains
1593 * unchanged. The call is recursive.
1595 * \param name the name to search.
1596 * \param occurence_number number of occurence already found (incremented)
1598 // ============================================================================
1600 void SALOME_NamingService::_Find(const char* name,
1601 CORBA::Long& occurence_number)
1603 MESSAGE("BEGIN OF _Find "<< occurence_number << " " << name);
1605 CosNaming::BindingList_var binding_list;
1606 CosNaming::BindingIterator_var binding_iterator;
1607 CosNaming::Binding_var binding;
1609 unsigned long nb = 0 ; // --- only for the use of the BindingIterator,
1610 // to access the bindings
1612 CosNaming::NamingContext_var ref_context = _current_context;
1613 CosNaming::NamingContext_var found_context = _current_context;
1615 _current_context->list(nb, binding_list, binding_iterator) ;
1617 if (! CORBA::is_nil(binding_iterator))
1619 while (binding_iterator->next_one(binding))
1621 CosNaming::Name bindingName = binding->binding_name;
1623 if (binding->binding_type == CosNaming::ncontext)
1625 // --- We work on a directory,
1626 // the search should be done in this directory
1628 Change_Directory(bindingName[0].id);
1629 _Find(name, occurence_number);
1631 // --- We'll go back to the initial context
1633 _current_context = ref_context ;
1636 else if (binding->binding_type == CosNaming::nobject)
1638 // --- We work on an object...
1640 if (!strcmp( bindingName[0].id, name))
1642 //MESSAGE("One occurence was found");
1645 // --- We keep in memory the directory where
1646 // one occurence was found
1648 found_context = _current_context ;
1653 binding_iterator->destroy();
1655 // --- We go to the last directory where an occurence was found
1657 _current_context = found_context;
1659 SCRUTE(occurence_number);
1662 // ============================================================================
1663 /*! \brief find the current directory path.
1665 * Parse the naming service tree to find the current context and give the
1666 * associated directory path (relative to root context).
1668 * \param lengthResult
1669 * \param contextToFind
1672 // ============================================================================
1675 SALOME_NamingService::
1676 _current_directory(vector<string>& splitPath,
1678 CosNaming::NamingContext_var contextToFind,
1681 MESSAGE("BEGIN OF _current_Directory");
1683 CosNaming::BindingList_var binding_list;
1684 CosNaming::BindingIterator_var binding_iterator;
1685 CosNaming::Binding_var binding;
1687 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1688 // to access the bindings
1690 CosNaming::NamingContext_var ref_context = _current_context;
1691 CosNaming::NamingContext_var temp_context = _current_context;
1693 _current_context->list(nb, binding_list, binding_iterator);
1695 if ( !binding_iterator->_is_nil() )
1697 while ((binding_iterator->next_one(binding)) && notFound)
1699 CosNaming::Name bindingName = binding->binding_name;
1701 if (binding->binding_type == CosNaming::ncontext)
1703 // --- directory, search in it
1705 const char* bindingNameid=bindingName[0].id;
1706 splitPath.push_back(bindingNameid);
1709 CORBA::Object_var obj = _current_context->resolve(bindingName);
1710 temp_context = CosNaming::NamingContext::_narrow(obj);
1712 if (temp_context->_is_equivalent(contextToFind))
1714 MESSAGE("The context is found, we stop the search");
1721 SCRUTE(bindingName[0].id);
1722 Change_Directory(bindingName[0].id);
1723 _current_directory(splitPath,
1730 // --- go back to the initial context
1732 _current_context = ref_context;
1734 MESSAGE("Just before the delete of "
1735 << splitPath[lengthResult-1]);
1736 splitPath.pop_back();
1743 binding_iterator->destroy();
1746 // --- return to the last directory where an occurence was found
1748 _current_context = ref_context ;
1752 // ============================================================================
1753 /*! \brief list recursively all objects in the given directory and subdirs.
1755 * get a list of all the objects in the current directory, with recursion
1756 * on the subdirectories. Only the objects are listed, not the directories.
1757 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1758 * _current_context must refer to absCurDirectory.
1760 * \param myList The list that will be filled.
1761 * \param relativeSubDir The directory relative to absCurDirectory in which
1762 * the objects are found.
1763 * \param absCurDirectory The current directory, absolute path
1765 // ============================================================================
1767 void SALOME_NamingService::_list_directory_recurs(vector<string>& myList,
1768 string relativeSubDir,
1769 string absCurDirectory)
1771 CosNaming::BindingList_var binding_list;
1772 CosNaming::BindingIterator_var binding_iterator;
1773 CosNaming::Binding_var binding ;
1775 unsigned long nb = 0 ; // --- only for thethe use of BindingIterator
1776 // to access the bindings
1780 CosNaming::NamingContext_var ref_context = _current_context;
1782 if (! relativeSubDir.empty())
1784 Change_Directory(relativeSubDir.c_str());
1785 absDir = absCurDirectory + "/" + relativeSubDir;
1789 absDir = absCurDirectory;
1792 _current_context->list(nb, binding_list, binding_iterator) ;
1794 if (! CORBA::is_nil(binding_iterator))
1796 while (binding_iterator->next_one(binding))
1798 CosNaming::Name bindingName = binding->binding_name;
1800 if (binding->binding_type == CosNaming::ncontext)
1802 string relativeSdir(bindingName[0].id);
1803 _list_directory_recurs(myList, relativeSdir, absDir);
1806 else if (binding->binding_type == CosNaming::nobject)
1808 string objName(bindingName[0].id);
1809 string elt = absDir + "/" + objName;
1811 myList.push_back(elt);
1815 binding_iterator->destroy();
1817 if (! relativeSubDir.empty())
1819 _current_context = ref_context;
1823 // ============================================================================
1824 /*! \brief return a stringified reference of root context
1826 * \return a stringified reference of root context
1828 // ============================================================================
1830 char * SALOME_NamingService::getIORaddr()
1832 return _orb->object_to_string(_root_context);
1835 /*! \brief get the orb used by the naming service
1839 CORBA::ORB_ptr SALOME_NamingService::orb()