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"
40 /*! \class SALOME_NamingService
41 \brief A class to manage the SALOME naming service
45 // ============================================================================
46 /*! \brief Default Constructor without ORB reference.
48 * After Default Constructor, one needs to initialize ORB.
49 * \sa init_orb(CORBA::ORB_ptr orb), SALOME_NamingService(CORBA::ORB_ptr orb)
51 // ============================================================================
53 SALOME_NamingService::SALOME_NamingService()
55 MESSAGE("SALOME_NamingService default constructor");
56 _orb = CORBA::ORB::_nil();
57 _root_context = CosNaming::NamingContext::_nil();
60 // ============================================================================
61 /*! \brief Standard Constructor, with ORB reference.
63 * Initializes the naming service root context
64 * \param orb CORBA::ORB_ptr arguments
66 // ============================================================================
68 SALOME_NamingService::SALOME_NamingService(CORBA::ORB_ptr orb)
70 MESSAGE("SALOME_NamingService creation");
71 _orb = CORBA::ORB::_duplicate(orb);
72 _initialize_root_context();
75 // ============================================================================
76 /*! \brief Standard destructor.
78 * The standard destructor does nothing special.
80 // ============================================================================
82 SALOME_NamingService::~SALOME_NamingService()
84 // Problem MESSAGE with singleton: late destruction,
85 // after trace system destruction ?
86 //MESSAGE("SALOME_NamingService destruction");
89 // ============================================================================
90 /*! \brief initializes ORB reference and naming service root context.
92 * Initializes ORB reference and naming service root context.
93 * For use after default constructor.
94 * If param orb is null, the orb is initialized
95 * \param orb CORBA::ORB_ptr arguments
97 // ============================================================================
99 void SALOME_NamingService::init_orb(CORBA::ORB_ptr orb)
101 MESSAGE("SALOME_NamingService initialisation");
103 Utils_Locker lock (&_myMutex);
105 _orb = CORBA::ORB::_duplicate(orb);
109 _orb = CORBA::ORB_init(argc, 0); // Here we make the assumption that the orb has already been initialized
112 _initialize_root_context();
115 // ============================================================================
116 /*! \brief Registers a CORBA object reference under a path.
118 * Registers a CORBA object reference under a path. If the path ends with '/',
119 * only a directory is created.
120 * If the NamingService is out, the exception ServiceUnreachable is thrown.
121 * \param ObjRef CORBA object reference to associate to the path. To create
122 * only a directory, give nil pointer.
123 * \param Path A relative or absolute pathname to store the object reference.
124 * If the pathname begins with a '/', pathname is taken
125 * as an absolute pathname. Else, pathname is taken as a relative
126 * path, to current context. Prefer absolute pathname, relative
127 * pathname are not safe, when SALOME_NamingService object is
128 * shared or use in multithreaded context.
129 * If the path ends with '/', only a directory is created.
130 * \sa Change_Directory(const char* Path),
131 * Create_Directory(const char* Path)
132 * CORBA::Object_ptr Resolve(const char* Path)
134 // ============================================================================
136 void SALOME_NamingService::Register(CORBA::Object_ptr ObjRef,
138 throw(ServiceUnreachable)
140 MESSAGE("BEGIN OF Register: " << Path);
142 Utils_Locker lock (&_myMutex);
144 // --- _current_context is replaced to the _root_context
145 // if the Path begins whith '/'
148 _current_context = _root_context;
151 // --- the resolution of the directory path has to be done
152 // to place the current_context to the correct node
154 CosNaming::Name context_name;
155 vector<string> splitPath;
156 int dimension_resultat = _createContextNameDir(Path,
161 CORBA::Boolean not_exist = false;
163 if (dimension_resultat > 0){
164 // A directory is treated (not only an object name)
165 // test if the directory where ObjRef should be recorded already exists
166 // If not, create the new context
169 CORBA::Object_var obj = _current_context->resolve(context_name);
170 _current_context = CosNaming::NamingContext::_narrow(obj);
173 catch (CosNaming::NamingContext::NotFound &){
174 // --- failed to resolve, therefore assume cold start
178 catch (CosNaming::NamingContext::InvalidName &){
179 INFOS("Register() : CosNaming::NamingContext::InvalidName");
182 catch (CosNaming::NamingContext::CannotProceed &){
183 INFOS("Register() : CosNaming::NamingContext::CannotProceed");
186 catch (CORBA::SystemException&){
187 INFOS("Register() : CORBA::SystemException: "
188 << "unable to contact the naming service");
189 throw ServiceUnreachable();
194 context_name.length(1);
195 for (int i = 0 ; i < dimension_resultat ;i++){
196 context_name[0].id = CORBA::string_dup(splitPath[i].c_str());
197 context_name[0].kind = CORBA::string_dup("dir");
198 // SCRUTE(_context_name[0].id);
199 // --- check if the path is created
201 // --- if the context is already created, nothing to do
202 CORBA::Object_var obj = _current_context->resolve(context_name);
203 _current_context = CosNaming::NamingContext::_narrow(obj);
206 catch (CosNaming::NamingContext::NotFound &){
208 // --- the context must be created
209 CosNaming::NamingContext_var temp_context =
210 _current_context->bind_new_context(context_name);
211 _current_context = temp_context;
213 catch (CosNaming::NamingContext::AlreadyBound&){
214 CORBA::Object_var obj = _current_context->resolve(context_name);
215 _current_context = CosNaming::NamingContext::_narrow(obj);
221 catch (CosNaming::NamingContext::AlreadyBound&){
222 INFOS("Register() : CosNaming::NamingContext::AlreadyBound");
225 catch (CosNaming::NamingContext::NotFound& ex){
226 CosNaming::Name n = ex.rest_of_name;
228 if (ex.why == CosNaming::NamingContext::missing_node)
229 INFOS("Register() : " << (char *) n[0].id
230 << " (" << (char *) n[0].kind << ") not found");
232 if (ex.why == CosNaming::NamingContext::not_context)
233 INFOS("Register() : " << (char *) n[0].id
234 << " (" << (char *) n[0].kind
235 << ") is not a context");
237 if (ex.why == CosNaming::NamingContext::not_object)
238 INFOS("Register() : " << (char *) n[0].id
239 << " (" << (char *) n[0].kind
240 << ") is not an object");
243 catch (CosNaming::NamingContext::CannotProceed&){
244 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
247 catch (CosNaming::NamingContext::InvalidName&){
248 INFOS("Register(): CosNaming::NamingContext::InvalidName");
251 catch (CORBA::SystemException&){
252 INFOS("Register():CORBA::SystemException: "
253 << "unable to contact the naming service");
254 throw ServiceUnreachable();
259 // --- The current directory is now the directory where the object should
262 int sizePath = splitPath.size();
263 if (sizePath > dimension_resultat){
264 ASSERT(sizePath == dimension_resultat+1);
265 context_name.length(1);
268 // --- the last element is an object and not a directory
270 context_name[0].id = CORBA::string_dup(splitPath[dimension_resultat].c_str());
271 context_name[0].kind = CORBA::string_dup("object");
272 //SCRUTE(context_name[0].id);
274 _current_context->bind(context_name, ObjRef);
277 catch (CosNaming::NamingContext::NotFound& ex){
278 CosNaming::Name n = ex.rest_of_name;
280 if (ex.why == CosNaming::NamingContext::missing_node)
281 INFOS("Register() : " << (char *) n[0].id
282 << " (" << (char *) n[0].kind << ") not found");
284 if (ex.why == CosNaming::NamingContext::not_context)
285 INFOS("Register() : " << (char *) n[0].id
286 << " (" << (char *) n[0].kind
287 << ") is not a context");
289 if (ex.why == CosNaming::NamingContext::not_object)
290 INFOS("Register() : " << (char *) n[0].id
291 << " (" << (char *) n[0].kind
292 << ") is not an object");
295 catch (CosNaming::NamingContext::CannotProceed&){
296 INFOS("Register(): CosNaming::NamingContext::CannotProceed");
299 catch (CosNaming::NamingContext::InvalidName&){
300 INFOS("Register(): CosNaming::NamingContext::InvalidName");
303 catch (CosNaming::NamingContext::AlreadyBound&){
304 INFOS("Register(): CosNaming::NamingContext::AlreadyBound, "
305 << "object will be rebind");
306 _current_context->rebind(context_name, ObjRef);
309 catch (CORBA::SystemException&){
310 INFOS("!!!Register(): CORBA::SystemException: "
311 << "unable to contact the naming service");
312 throw ServiceUnreachable();
317 // ============================================================================
318 /*! \brief get the CORBA object reference associated to a name.
320 * get the CORBA object reference associated to a complete name with a path.
321 * If the NamingService is out, the exception ServiceUnreachable is thrown
322 * \param Path pathname. If the pathname begins with a '/', pathname is taken
323 * as an absolute pathname. Else, pathname is taken as a relative
324 * path, to current context. Prefer absolute pathname, relative
325 * pathname are not safe, when SALOME_NamingService object is
326 * shared or use in multithreaded context.
327 * \return the object reference if it exists under the pathname,
328 * or nil reference in other cases.
329 * \sa Register(CORBA::Object_ptr ObjRef, const char* Path),
330 * Change_Directory(const char* Path)
332 // ============================================================================
334 CORBA::Object_ptr SALOME_NamingService::Resolve(const char* Path)
335 throw(ServiceUnreachable)
337 // MESSAGE("BEGIN OF Resolve: " << Path);
339 Utils_Locker lock (&_myMutex);
341 // --- _current_context is replaced to the _root_context
342 // if the Path begins whith '/'
346 _current_context = _root_context;
349 // --- the resolution of the directory path has to be done
350 // to place the current_context to the correct node
352 CosNaming::Name context_name;
353 vector<string> splitPath;
354 _createContextNameDir(Path,
359 ASSERT(!CORBA::is_nil(_current_context));
361 CORBA::Object_var obj = CORBA::Object::_nil();
365 obj = _current_context->resolve(context_name);
368 catch (CosNaming::NamingContext::NotFound& ex)
370 CosNaming::Name n = ex.rest_of_name;
372 if (ex.why == CosNaming::NamingContext::missing_node)
373 MESSAGE("Resolve() : " << (char *) n[0].id
374 << " (" << (char *) n[0].kind << ") not found");
376 if (ex.why == CosNaming::NamingContext::not_context)
378 << (char *) n[0].id << " (" << (char *) n[0].kind
379 << ") is not a context");
381 if (ex.why == CosNaming::NamingContext::not_object)
382 INFOS("Resolve() : " << (char *) n[0].id
383 << " (" << (char *) n[0].kind
384 << ") is not an object");
387 catch (CosNaming::NamingContext::CannotProceed&)
389 INFOS("Resolve(): CosNaming::NamingContext::CannotProceed");
392 catch (CosNaming::NamingContext::InvalidName&)
394 INFOS("Resolve(): CosNaming::NamingContext::InvalidName");
397 catch (CORBA::SystemException&)
399 INFOS("Resolve():CORBA::SystemException : unable to contact"
400 << "the naming service");
401 throw ServiceUnreachable();
407 // ============================================================================
408 /*! \brief get the CORBA object reference associated to an uncomplete name.
410 * get the CORBA object reference associated to an uncomplete name with a
411 * path. Look for the first occurence of name*.
412 * If the NamingService is out, the exception ServiceUnreachable is thrown
413 * \param Path pathname under the form "/path/name" (Absolute reference !)
414 * search the fist reference like "/path(.dir)/name*(.kind)"
415 * \return the object reference if found, or nil reference.
416 * \sa Resolve(const char* Path)
418 // ============================================================================
420 CORBA::Object_ptr SALOME_NamingService::ResolveFirst(const char* Path)
421 throw(ServiceUnreachable)
423 // MESSAGE("ResolveFirst");
425 Utils_Locker lock (&_myMutex);
428 string thePath = Path;
429 string basePath = "";
430 string name = thePath;
432 string::size_type idx = thePath.rfind('/');
434 if (idx != string::npos) // at least one '/' found
436 basePath = thePath.substr(0, idx);
437 name = thePath.substr(idx + 1);
442 CORBA::Object_var obj = CORBA::Object::_nil();
445 if (basePath.empty())
448 isOk = Change_Directory(basePath.c_str());
452 vector<string> listElem = list_directory();
453 vector<string>::iterator its = listElem.begin();
455 while (its != listElem.end())
459 if ((*its).find(name) == 0)
461 return Resolve((*its).c_str());
471 // ============================================================================
472 /*! \brief find a component instance from hostname, containername,
473 * componentName and number of processors.
475 * find a component instance from hostname, containername, componentName and
476 * number of processors.
477 * If the NamingService is out, the exception ServiceUnreachable is thrown.
478 * \param hostname name of the machine on which the component is searched.
479 * \param containerName name of the container in which the component is
481 * \param componentName name of the component we are looking for an existing
483 * \param nbproc in case of multi processor machine, container name is
484 * suffixed with _nbproc.
485 * \return the object reference
487 // ============================================================================
490 SALOME_NamingService::ResolveComponent(const char* hostname,
491 const char* containerName,
492 const char* componentName,
494 throw(ServiceUnreachable)
496 // MESSAGE("ResolveComponent");
498 Utils_Locker lock (&_myMutex);
500 string name = "/Containers/";
504 if ( strlen(containerName) != 0 )
510 char *newContainerName = new char[strlen(containerName) + 8];
511 sprintf(newContainerName, "%s_%d", containerName, nbproc);
512 name += newContainerName;
513 delete [] newContainerName;
517 name += containerName;
521 name += componentName;
523 return ResolveFirst(name.c_str());
529 string basename = name;
530 if (Change_Directory(basename.c_str()))
532 vector<string> contList = list_subdirs();
534 for (unsigned int ind = 0; ind < contList.size(); ind++)
536 name = contList[ind].c_str();
540 char *str_nbproc = new char[8];
541 sprintf(str_nbproc, "_%d", nbproc);
542 if( strstr(name.c_str(),str_nbproc) == NULL)
543 continue; // check only containers with _%d in name
544 delete [] str_nbproc;
548 name += componentName;
550 CORBA::Object_ptr obj = ResolveFirst(name.c_str());
552 if ( !CORBA::is_nil(obj) )
555 Change_Directory(basename.c_str());
559 return CORBA::Object::_nil();
563 // ============================================================================
564 /*! \brief provide a default container name if empty.
566 * the given container name is returned unchanged, unless it is empty.
567 * \param containerName
568 * \return container name, where empty input is replaced by "FactoryServer",
570 * \sa BuildContainerNameForNS(const char *containerName, const char *hostname)
572 // ============================================================================
574 string SALOME_NamingService::ContainerName(const char *containerName)
578 if (strlen(containerName) == 0)
579 ret = "FactoryServer";
586 // ============================================================================
587 /*! \brief build a container name, given a MachineParameters struct.
589 * Build a container name with a MachineParameters struct. In case of multi
590 * processor machine, container name is suffixed with _nbproc. nproc equals
591 * (number of nodes)*(number of processor per nodes).
592 * \param params struct from which we get container name (may be
593 * empty), number of nodes and number of processor
595 * \return a container name without the path.
596 * \sa BuildContainerNameForNS(const Engines::MachineParameters& params,
597 * const char *hostname)
599 // ============================================================================
602 SALOME_NamingService::ContainerName(const Engines::MachineParameters& params)
608 else if ( (params.nb_node <= 0) && (params.nb_proc_per_node <= 0) )
610 else if ( params.nb_node == 0 )
611 nbproc = params.nb_proc_per_node;
612 else if ( params.nb_proc_per_node == 0 )
613 nbproc = params.nb_node;
615 nbproc = params.nb_node * params.nb_proc_per_node;
617 string ret = ContainerName(params.container_name);
621 char *suffix = new char[8];
622 sprintf(suffix, "_%d", nbproc);
630 SALOME_NamingService::ContainerName(const Engines::ContainerParameters& params)
636 else if ( (params.resource_params.nb_node <= 0) && (params.resource_params.nb_proc_per_node <= 0) )
638 else if ( params.resource_params.nb_node == 0 )
639 nbproc = params.resource_params.nb_proc_per_node;
640 else if ( params.resource_params.nb_proc_per_node == 0 )
641 nbproc = params.resource_params.nb_node;
643 nbproc = params.resource_params.nb_node * params.resource_params.nb_proc_per_node;
645 string ret = ContainerName(params.container_name);
649 char *suffix = new char[8];
650 sprintf(suffix, "_%d", nbproc);
657 // ============================================================================
658 /*! \brief build a string representing a container in Naming Service.
660 * Build a string representing the absolute pathname of a container in
661 * SALOME_NamingService. This form gives a suffixed containerName in case of
662 * multi processor machine.
663 * \param containerName name of the container in which the component is
665 * \param hostname name of the host of the container, without domain names.
666 * \return the path under the form /Containers/hostname/containerName
667 * \sa ContainerName(const Engines::MachineParameters& params)
669 // ============================================================================
671 string SALOME_NamingService::BuildContainerNameForNS(const char *containerName,
672 const char *hostname)
674 string ret = "/Containers/";
677 ret += ContainerName(containerName);
682 // ============================================================================
683 /*! \brief build a string representing a container in Naming Service.
685 * Build a string representing the absolute pathname of a container in
686 * SALOME_NamingService.
687 * \param params used as it is, or replaced by FactoryServer if empty.
688 * \param hostname name of the host of the container, without domain names.
689 * \return the path under the form /Containers/hostname/containerName
690 * \sa ContainerName(const char *containerName)
692 // ============================================================================
695 SALOME_NamingService::
696 BuildContainerNameForNS(const Engines::MachineParameters& params,
697 const char *hostname)
699 string ret = "/Containers/";
702 ret += ContainerName(params);
708 SALOME_NamingService::
709 BuildContainerNameForNS(const Engines::ContainerParameters& params,
710 const char *hostname)
712 string ret = "/Containers/";
715 ret += ContainerName(params);
720 // ============================================================================
721 /*! \brief search a name in current directory.
723 * Search a name in the current directory. after call, the current directory
724 * is changed to the directory containing the last occurence of name found.
725 * If no occurence found (see return value), current directory remains
728 * \param name the name to search.
729 * \return number of occurences found.
730 * \sa Change_Directory(const char* Path)
732 // ============================================================================
734 int SALOME_NamingService::Find(const char* name)
735 throw(ServiceUnreachable)
737 MESSAGE("BEGIN OF Find " << name);
739 Utils_Locker lock (&_myMutex);
741 CORBA::Long occurence_number = 0 ;
745 _Find(name, occurence_number);
748 catch (CORBA::SystemException&)
750 INFOS("!!!Find() : CORBA::SystemException : unable to contact"
751 << " the naming service");
752 throw ServiceUnreachable();
755 return occurence_number;
758 // ============================================================================
759 /*! \brief Creates a directory (context_name)
761 * Creates a directory (context_name) relative to the current directory
762 * (current context) or relative to the root directory (root context), if
763 * the path given begins with a '/'.
764 * If the NamingService is out, the exception ServiceUnreachable is thrown.
765 * \param Path A relative or absolute pathname to store the object reference.
766 * If the pathname begins with a '/', pathname is taken
767 * as an absolute pathname. Else, pathname is taken as a relative
768 * path, to current context. Prefer absolute pathname, relative
769 * pathname are not safe, when SALOME_NamingService object is
770 * shared or use in multithreaded context.
771 * \return true if successfull
772 * (creation not strictly garanteed if true, because Register may
773 * catch some specific unlikely exception without throw anything
774 * --- to be corrected ---)
775 * \sa RegisterCORBA::Object_ptr ObjRef, const char* Path)
777 // ============================================================================
779 bool SALOME_NamingService::Create_Directory(const char* Path)
780 throw(ServiceUnreachable)
782 MESSAGE("BEGIN OF Create_Directory");
784 Utils_Locker lock (&_myMutex);
788 // --- if path empty, nothing to create, no context change
793 // --- if path ='/', nothing to create, only change to root_context
797 MESSAGE("Create Directory '/', just change to root_context");
798 _current_context = _root_context;
802 // --- path must end with '/'
804 if (path[path.length()-1] != '/') path += '/';
806 Register(CORBA::Object::_nil(), path.c_str());
810 // ============================================================================
811 /*! \brief change current directory to the given path
813 * change the current directory to the given path in parameter.
814 * Warning: avoid use when the SALOME_NamingService instance is shared by
815 * several threads (current context may be modified by another thread).
816 * If the path is empty, nothing done return OK.
817 * If Path ="/", the current directory changes to the root directory.
818 * If the NamingService is out, the exception ServiceUnreachable is thrown.
819 * \param Path the new current directory
820 * \return true if the change succeeded
822 // ============================================================================
824 bool SALOME_NamingService::Change_Directory(const char* Path)
825 throw(ServiceUnreachable)
827 // MESSAGE("BEGIN OF Change_Directory " << Path);
828 Utils_Locker lock (&_myMutex);
832 // --- if path empty, nothing to do
837 // --- if path ='/', nothing to resolve, only change to root_context
841 // MESSAGE("Change_Directory is called to go to the root_context");
842 _current_context = _root_context;
846 CosNaming::NamingContext_var current_context = _current_context;
847 bool changeOK = false;
849 // --- replace _current_context with _root_context if Path begins whith '/'
852 current_context = _root_context;
854 // --- need to resolve directory path
856 ASSERT(!CORBA::is_nil(current_context));
858 if (path[path.length()-1] != '/') path += '/';
860 CosNaming::Name context_name;
861 vector<string> splitPath;
862 _createContextNameDir(path.c_str(),
867 // --- Context creation
871 CORBA::Object_var obj = current_context->resolve(context_name);
872 current_context = CosNaming::NamingContext::_narrow(obj);
873 ASSERT(!CORBA::is_nil(current_context));
874 _current_context = current_context;
878 catch (CosNaming::NamingContext::NotFound& ex)
880 CosNaming::Name n = ex.rest_of_name;
882 if (ex.why == CosNaming::NamingContext::missing_node)
883 MESSAGE( "Change_Directory() : " << (char *) n[0].id
884 << " (" << (char *) n[0].kind << ") not found");
885 if (ex.why == CosNaming::NamingContext::not_context)
886 INFOS("Change_Directory() : " << (char *) n[0].id
887 << " (" << (char *) n[0].kind
888 << ") is not a context" );
889 if (ex.why == CosNaming::NamingContext::not_object)
890 INFOS( "Change_Directory() : " << (char *) n[0].id
891 << " (" << (char *) n[0].kind
892 << ") is not an object" );
895 catch (CosNaming::NamingContext::CannotProceed&)
897 INFOS("Change_Directory(): CosNaming::NamingContext::CannotProceed");
900 catch (CosNaming::NamingContext::InvalidName&)
902 INFOS("Change_Directory(): CosNaming::NamingContext::InvalidName");
905 catch (CORBA::SystemException&)
907 INFOS("Change_Directory():CORBA::SystemException : unable to contact"
908 << "the naming service");
909 throw ServiceUnreachable();
915 // ============================================================================
916 /*! \brief get the current directory path
918 * Get the current directory path.
919 * If the NamingService is out, the exception ServiceUnreachable is thrown.
920 * \return the path of the current_context
921 * \sa _current_directory
923 // ============================================================================
925 char* SALOME_NamingService::Current_Directory()
926 throw(ServiceUnreachable)
928 MESSAGE("BEGIN OF Current_Directory");
930 Utils_Locker lock (&_myMutex);
932 CosNaming::NamingContext_var ref_context = _current_context;
934 vector<string> splitPath;
937 bool notFound = true ;
939 // --- start search from root context
941 _current_context = _root_context ;
945 _current_directory(splitPath, lengthPath, ref_context, notFound );
948 catch (CORBA::SystemException&)
950 INFOS("Current_Directory(): CORBA::SystemException: unable to contact"
951 << " the naming service" )
952 throw ServiceUnreachable();
956 lengthPath = splitPath.size();
957 for (int k = 0 ; k < lengthPath ;k++)
960 path += splitPath[k];
964 _current_context = ref_context ;
966 return strdup(path.c_str());
969 // ============================================================================
970 /*! \brief list recursively all objects in the current context
972 * List and print via trace all directories and objects in the current
973 * context. Trace must be activated: compile option _DEBUG_
974 * If the NamingService is out, the exception ServiceUnreachable is thrown
976 // ============================================================================
978 void SALOME_NamingService::list()
979 throw(ServiceUnreachable)
981 MESSAGE("Begin of list");
983 Utils_Locker lock (&_myMutex)
986 CosNaming::BindingList_var binding_list;
987 CosNaming::BindingIterator_var binding_iterator;
988 CosNaming::Binding_var binding ;
990 unsigned long nb = 0 ; // --- only for the BindingIterator use,
991 // to access the bindings
993 CosNaming::NamingContext_var ref_context = _current_context;
995 _current_context->list(nb, binding_list, binding_iterator) ;
997 if (! CORBA::is_nil(binding_iterator))
999 while (binding_iterator->next_one(binding))
1001 CosNaming::Name bindingName = binding->binding_name;
1003 if (binding->binding_type == CosNaming::ncontext)
1005 MESSAGE( "Context : " << bindingName[0].id );
1009 Change_Directory(bindingName[0].id);
1012 catch (ServiceUnreachable&)
1014 INFOS( "list(): ServiceUnreachable" )
1015 throw ServiceUnreachable();
1019 _current_context = ref_context ;
1022 else if (binding->binding_type == CosNaming::nobject)
1024 MESSAGE( "Object : " << bindingName[0].id );
1028 binding_iterator->destroy();
1032 // ============================================================================
1033 /*! \brief list all the objects in the current directory.
1035 * get a list of all the objects in the current directory, without recursion
1036 * on the subdirectories. Only the objects are listed, not the directories.
1037 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1038 * \return list of strings with objects found.
1039 * \sa vector<string> list_directory_recurs()
1041 // ============================================================================
1043 vector<string> SALOME_NamingService::list_directory()
1044 throw(ServiceUnreachable)
1046 // MESSAGE("list_directory");
1047 vector<string> dirList ;
1050 CosNaming::BindingList_var binding_list;
1051 CosNaming::BindingIterator_var binding_iterator;
1052 CosNaming::Binding_var binding ;
1054 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1055 // to access the bindings
1057 CosNaming::NamingContext_var ref_context = _current_context;
1059 _current_context->list(nb, binding_list, binding_iterator);
1061 if (binding_iterator->_is_nil())
1064 while (binding_iterator->next_one(binding))
1066 CosNaming::Name bindingName = binding->binding_name;
1068 if (binding->binding_type == CosNaming::nobject)
1070 // remove memory leak
1071 // dirList.push_back(CORBA::string_dup(bindingName[0].id));
1072 dirList.push_back(string(bindingName[0].id));
1076 // for (unsigned int ind = 0; ind < dirList.size(); ind++)
1077 // MESSAGE("list_directory : Object : " << dirList[ind]);
1079 binding_iterator->destroy();
1085 // ============================================================================
1086 /*! \brief list all the subdirectories in the current directory.
1088 * get a list of all the subdirectories in the current directory,
1089 * without recursion on the subdirectories.
1090 * Only the subdirectories are listed, not the objects.
1091 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1092 * \return list of strings with directories found.
1093 * \sa vector<string> list_directory()
1095 // ============================================================================
1097 vector<string> SALOME_NamingService::list_subdirs()
1098 throw(ServiceUnreachable)
1100 MESSAGE("list_subdirs");
1101 vector<string> dirList ;
1104 CosNaming::BindingList_var binding_list;
1105 CosNaming::BindingIterator_var binding_iterator;
1106 CosNaming::Binding_var binding ;
1108 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1109 // to access the bindings
1111 CosNaming::NamingContext_var ref_context = _current_context;
1113 _current_context->list(nb, binding_list, binding_iterator) ;
1115 if (binding_iterator->_is_nil())
1118 while (binding_iterator->next_one(binding))
1120 CosNaming::Name bindingName = binding->binding_name;
1122 if (binding->binding_type == CosNaming::ncontext)
1124 dirList.push_back(bindingName[0].id.in());
1128 for (unsigned int ind = 0; ind < dirList.size(); ind++)
1129 MESSAGE("list_directory : Object : " << dirList[ind]);
1131 binding_iterator->destroy();
1136 // ============================================================================
1137 /*! \brief list all the objects in the current directory and subdirectories.
1139 * get a list of all the objects in the current directory, with recursion
1140 * on the subdirectories. Only the objects are listed, not the directories.
1141 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1142 * \return list of strings with objects found.
1143 * \sa vector<string> list_directory()
1145 // ============================================================================
1147 vector<string> SALOME_NamingService::list_directory_recurs()
1148 throw(ServiceUnreachable)
1150 MESSAGE("list_directory_recurs");
1152 Utils_Locker lock (&_myMutex);
1154 vector<string> dirList ;
1156 char* currentDir = Current_Directory();
1158 _list_directory_recurs(dirList, "", currentDir);
1165 // ============================================================================
1166 /*! \brief destroy an entry in naming service.
1168 * Destroy an association Path - Object Reference.
1169 * If the NamingService is out, the exception ServiceUnreachable is thrown
1170 * \param Path object path
1172 // ============================================================================
1174 void SALOME_NamingService::Destroy_Name(const char* Path)
1175 throw(ServiceUnreachable)
1177 MESSAGE("BEGIN OF Destroy_Name " << Path);
1179 Utils_Locker lock (&_myMutex);
1183 // --- if path empty, nothing to do
1188 // --- if path = '/' not applicable, nothing to do
1193 // --- if path begins with '/', set current directory to root context
1196 _current_context = _root_context;
1198 // --- context of the directory containing the object
1200 CosNaming::Name context_name;
1201 vector<string> splitPath;
1202 int dimension_resultat = _createContextNameDir(path.c_str(),
1209 if (dimension_resultat > 0)
1211 // --- path contains a directory, not only an object name
1212 // switch to the new directory (or return if directory not found)
1216 CORBA::Object_var obj = _current_context->resolve(context_name);
1217 _current_context = CosNaming::NamingContext::_narrow(obj);
1221 catch (CosNaming::NamingContext::NotFound &ex)
1223 // --- failed to resolve
1226 CosNaming::Name n = ex.rest_of_name;
1228 if (ex.why == CosNaming::NamingContext::missing_node)
1229 INFOS( "Destroy_Name(): " << (char *) n[0].id
1230 << " (" << (char *) n[0].kind << ") not found" );
1231 if (ex.why == CosNaming::NamingContext::not_context)
1232 INFOS( "Destroy_Name() : " << (char *) n[0].id
1233 << " (" << (char *) n[0].kind
1234 << ") is not a context" );
1235 if (ex.why == CosNaming::NamingContext::not_object)
1236 INFOS( "Destroy_Name() : " << (char *) n[0].id
1237 << " (" << (char *) n[0].kind
1238 << ") is not an object" );
1241 catch (CosNaming::NamingContext::InvalidName &)
1243 INFOS("Destroy_Name: CosNaming::NamingContext::InvalidName");
1246 catch (CosNaming::NamingContext::CannotProceed &)
1248 INFOS("Destroy_Name: CosNaming::NamingContext::CannotProceed");
1251 catch (CORBA::SystemException&)
1253 INFOS("Destroy_Name : CORBA::SystemException: "
1254 << "unable to contact the naming service");
1255 throw ServiceUnreachable();
1258 if (! exist) return;
1261 ASSERT(!CORBA::is_nil(_current_context));
1263 // --- The current directory is now the directory where the object should
1266 int sizePath = splitPath.size();
1267 if (sizePath > dimension_resultat)
1269 ASSERT(sizePath == dimension_resultat+1);
1270 context_name.length(1);
1274 // --- the last element is an object and not a directory
1276 context_name[0].id =
1277 CORBA::string_dup(splitPath[dimension_resultat].c_str());
1278 context_name[0].kind = CORBA::string_dup("object");
1279 SCRUTE(context_name[0].id);
1281 _current_context->unbind(context_name);
1282 MESSAGE("The object " << context_name[0].id << " has been deleted");
1285 catch (CosNaming::NamingContext::NotFound& ex)
1287 CosNaming::Name n = ex.rest_of_name;
1289 if (ex.why == CosNaming::NamingContext::missing_node)
1290 INFOS( "Destroy_Name() : " << (char *) n[0].id
1291 << " (" << (char *) n[0].kind << ") not found" );
1292 if (ex.why == CosNaming::NamingContext::not_context)
1293 INFOS( "Destroy_Name() : " << (char *) n[0].id
1294 << " (" << (char *) n[0].kind
1295 << ") is not a context" );
1296 if (ex.why == CosNaming::NamingContext::not_object)
1297 INFOS( "Destroy_Name() : " << (char *) n[0].id
1298 << " (" << (char *) n[0].kind
1299 << ") is not an object" );
1302 catch (CosNaming::NamingContext::CannotProceed&)
1304 INFOS( "Destroy_Name(): CosNaming::NamingContext::CannotProceed");
1307 catch (CosNaming::NamingContext::InvalidName&)
1309 INFOS( "Destroy_Name(): CosNaming::NamingContext::InvalidName");
1312 catch (CORBA::SystemException&)
1314 INFOS( "Destroy_Name(): CORBA::SystemException: unable to contact"
1315 << " the naming service");
1316 throw ServiceUnreachable();
1321 // ============================================================================
1322 /*! \brief Destroy an empty directory
1324 * Destroy an empty directory in Naming Service.
1325 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1326 * \param Path directory path
1328 // ============================================================================
1330 void SALOME_NamingService::Destroy_Directory(const char* Path)
1331 throw(ServiceUnreachable)
1333 MESSAGE("BEGIN OF Destroy_Directory " << Path);
1335 Utils_Locker lock (&_myMutex);
1339 // --- if path empty, nothing to do
1344 // --- if path begins with '/', set current directory to root context
1347 _current_context = _root_context;
1349 CosNaming::NamingContext_var ref_context = _current_context;
1351 // --- path must ends with '/' for a directory
1353 if (path[path.size() -1] != '/')
1356 // --- context of the directory
1358 CosNaming::Name context_name;
1359 vector<string> splitPath;
1360 int dimension_resultat = _createContextNameDir(path.c_str(),
1366 if (dimension_resultat > 0)
1368 // --- path contains a directory, not only an object name
1369 // switch to the new directory (or return if directory not found)
1373 CORBA::Object_var obj = _current_context->resolve(context_name);
1374 _current_context = CosNaming::NamingContext::_narrow(obj);
1378 catch (CosNaming::NamingContext::NotFound &ex)
1380 // --- failed to resolve
1383 CosNaming::Name n = ex.rest_of_name;
1385 if (ex.why == CosNaming::NamingContext::missing_node)
1386 INFOS( "Destroy_Directory(): " << (char *) n[0].id
1387 << " (" << (char *) n[0].kind << ") not found" );
1388 if (ex.why == CosNaming::NamingContext::not_context)
1389 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1390 << " (" << (char *) n[0].kind
1391 << ") is not a context" );
1392 if (ex.why == CosNaming::NamingContext::not_object)
1393 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1394 << " (" << (char *) n[0].kind
1395 << ") is not an object" );
1398 catch (CosNaming::NamingContext::InvalidName &)
1400 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1403 catch (CosNaming::NamingContext::CannotProceed &)
1405 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1408 catch (CORBA::SystemException&)
1410 INFOS("Destroy_Directory : CORBA::SystemException: "
1411 << "unable to contact the naming service");
1412 throw ServiceUnreachable();
1415 if (! exist) return;
1418 ASSERT(!CORBA::is_nil(_current_context));
1420 // --- Context Destruction
1422 bool isContextDestroyed = false;
1425 _current_context->destroy();
1426 MESSAGE( "The context " << path << " has been deleted" );
1427 isContextDestroyed = true;
1430 catch (CosNaming::NamingContext::NotEmpty&)
1432 INFOS( "Destroy_Directory(): CosNaming::NamingContext::NoEmpty "
1433 << path << " is not empty" );
1436 catch (CORBA::SystemException&)
1438 INFOS( "Destroy_Directory():CORBA::SystemException : "
1439 << "unable to contact the naming service");
1440 throw ServiceUnreachable();
1443 // --- go to the reference directory
1445 _current_context = ref_context ;
1447 ASSERT(!CORBA::is_nil(_current_context));
1449 if (isContextDestroyed)
1453 _current_context->unbind(context_name);
1454 MESSAGE( "The bind to the context "
1455 << context_name[0].id
1456 << " has been deleted" );
1459 catch (CosNaming::NamingContext::NotFound& ex)
1461 CosNaming::Name n = ex.rest_of_name;
1463 if (ex.why == CosNaming::NamingContext::missing_node)
1464 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1465 << " (" << (char *) n[0].kind << ") not found" );
1466 if (ex.why == CosNaming::NamingContext::not_context)
1467 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1468 << " (" << (char *) n[0].kind
1469 << ") is not a context" );
1470 if (ex.why == CosNaming::NamingContext::not_object)
1471 INFOS( "Destroy_Directory() : " << (char *) n[0].id
1472 << " (" << (char *) n[0].kind
1473 << ") is not an object" );
1476 catch (CosNaming::NamingContext::CannotProceed&)
1478 INFOS("Destroy_Directory: CosNaming::NamingContext::CannotProceed");
1481 catch (CosNaming::NamingContext::InvalidName&)
1483 INFOS("Destroy_Directory: CosNaming::NamingContext::InvalidName");
1486 catch (CORBA::SystemException&)
1488 INFOS("Destroy_Directory:CORBA::SystemException : unable to contact"
1489 << " the naming service");
1490 throw ServiceUnreachable();
1495 // ============================================================================
1496 /*! \brief Destroy a directory with its contents.
1498 * Destroy the objects associations in a directory, and the directory itself,
1499 * if there is no subdirectories.
1500 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1501 * \param Path the directory path.
1503 // ============================================================================
1505 void SALOME_NamingService::Destroy_FullDirectory(const char* Path)
1506 throw(ServiceUnreachable)
1508 MESSAGE("begin of Destroy_FullDirectory " << Path);
1509 if( Change_Directory(Path) )
1511 vector<string> contList = list_directory();
1513 for (unsigned int ind = 0; ind < contList.size(); ind++)
1514 Destroy_Name(contList[ind].c_str());
1516 Destroy_Directory(Path);
1520 // ============================================================================
1521 /*! \brief initialize root context (root directory)
1523 * the root context initialisation must be done when the SALOME_NamingService
1524 * instance is created and before any othe call. See constructors.
1526 // ============================================================================
1528 void SALOME_NamingService::_initialize_root_context()
1530 //MESSAGE("Get the root context");
1534 CORBA::Object_var obj = _orb->resolve_initial_references("NameService");
1535 _root_context = CosNaming::NamingContext::_narrow(obj);
1536 _current_context = _root_context ;
1537 ASSERT(!CORBA::is_nil(_root_context));
1540 catch (CORBA::SystemException&)
1542 INFOS("CORBA::SystemException: unable to contact the naming service");
1543 throw ServiceUnreachable();
1548 INFOS("Unknown Exception: unable to contact the naming service");
1549 throw ServiceUnreachable();
1553 // ============================================================================
1554 /*! \brief transform a string path in CosNaming structure.
1556 * Transform a path given as a string in a CosNaming structure.
1557 * \param path a relative or absolute path, with or without an object.
1558 * An absolute path begins with '/'.
1559 * A path without an object ends with '/'.
1560 * \param context_name CosNaming structure to put the path.
1561 * \param splitPath a vector of string with subdirectories and final
1563 * \param onlyDir if true, final object (if any) is ommited
1565 * if false, final object (if any) is included in
1567 * \return dimension of context_name
1569 // ============================================================================
1572 SALOME_NamingService::_createContextNameDir(string path,
1573 CosNaming::Name& context_name,
1574 vector<string>& splitPath,
1580 string::size_type begIdx, endIdx;
1581 const string delims("/");
1582 splitPath.resize(0);
1583 bool endWithDelim = false;
1585 begIdx = path.find_first_not_of(delims);
1586 while (begIdx != string::npos)
1588 endIdx = path.find_first_of(delims, begIdx);
1589 if (endIdx == path.length()-1)
1590 endWithDelim = true;
1591 if (endIdx == string::npos)
1592 endIdx = path.length();
1593 int lsub = endIdx - begIdx;
1595 splitPath.push_back(path.substr(begIdx, lsub));
1596 begIdx = path.find_first_not_of(delims, endIdx);
1600 if (onlyDir) // only directory part
1602 dim = splitPath.size()-1; // omit final object
1603 if (endWithDelim) // unless the path ends with a delimiter
1605 endWithDelim = true;
1608 dim = splitPath.size(); // directories and final object
1610 context_name.length(dim);
1611 for (int i=0; i<dim; i++)
1613 // SCRUTE(splitPath[i]);
1614 context_name[i].id = CORBA::string_dup(splitPath[i].c_str());
1615 if (!endWithDelim && (i == dim-1)) // here, the last string is an object
1617 context_name[i].kind = CORBA::string_dup("object");
1618 // MESSAGE("--- " <<splitPath[i] <<".object");
1622 context_name[i].kind = CORBA::string_dup("dir");
1623 // MESSAGE("--- " <<splitPath[i] <<".dir");
1629 // ============================================================================
1630 /*! \brief search a name in current directory.
1632 * Search a name in the current directory. after call, the current directory
1633 * is changed to the directory containing the last occurence of name found.
1634 * If no occurence found (see return value), current directory remains
1635 * unchanged. The call is recursive.
1637 * \param name the name to search.
1638 * \param occurence_number number of occurence already found (incremented)
1640 // ============================================================================
1642 void SALOME_NamingService::_Find(const char* name,
1643 CORBA::Long& occurence_number)
1645 MESSAGE("BEGIN OF _Find "<< occurence_number << " " << name);
1647 CosNaming::BindingList_var binding_list;
1648 CosNaming::BindingIterator_var binding_iterator;
1649 CosNaming::Binding_var binding;
1651 unsigned long nb = 0 ; // --- only for the use of the BindingIterator,
1652 // to access the bindings
1654 CosNaming::NamingContext_var ref_context = _current_context;
1655 CosNaming::NamingContext_var found_context = _current_context;
1657 _current_context->list(nb, binding_list, binding_iterator) ;
1659 if (! CORBA::is_nil(binding_iterator))
1661 while (binding_iterator->next_one(binding))
1663 CosNaming::Name bindingName = binding->binding_name;
1665 if (binding->binding_type == CosNaming::ncontext)
1667 // --- We work on a directory,
1668 // the search should be done in this directory
1670 Change_Directory(bindingName[0].id);
1671 _Find(name, occurence_number);
1673 // --- We'll go back to the initial context
1675 _current_context = ref_context ;
1678 else if (binding->binding_type == CosNaming::nobject)
1680 // --- We work on an object...
1682 if (!strcmp( bindingName[0].id, name))
1684 //MESSAGE("One occurence was found");
1687 // --- We keep in memory the directory where
1688 // one occurence was found
1690 found_context = _current_context ;
1695 binding_iterator->destroy();
1697 // --- We go to the last directory where an occurence was found
1699 _current_context = found_context;
1701 SCRUTE(occurence_number);
1704 // ============================================================================
1705 /*! \brief find the current directory path.
1707 * Parse the naming service tree to find the current context and give the
1708 * associated directory path (relative to root context).
1710 * \param lengthResult
1711 * \param contextToFind
1714 // ============================================================================
1717 SALOME_NamingService::
1718 _current_directory(vector<string>& splitPath,
1720 CosNaming::NamingContext_var contextToFind,
1723 MESSAGE("BEGIN OF _current_Directory");
1725 CosNaming::BindingList_var binding_list;
1726 CosNaming::BindingIterator_var binding_iterator;
1727 CosNaming::Binding_var binding;
1729 unsigned long nb = 0 ; // --- only for the BindingIterator use,
1730 // to access the bindings
1732 CosNaming::NamingContext_var ref_context = _current_context;
1733 CosNaming::NamingContext_var temp_context = _current_context;
1735 _current_context->list(nb, binding_list, binding_iterator);
1737 if ( !binding_iterator->_is_nil() )
1739 while ((binding_iterator->next_one(binding)) && notFound)
1741 CosNaming::Name bindingName = binding->binding_name;
1743 if (binding->binding_type == CosNaming::ncontext)
1745 // --- directory, search in it
1747 const char* bindingNameid=bindingName[0].id;
1748 splitPath.push_back(bindingNameid);
1751 CORBA::Object_var obj = _current_context->resolve(bindingName);
1752 temp_context = CosNaming::NamingContext::_narrow(obj);
1754 if (temp_context->_is_equivalent(contextToFind))
1756 MESSAGE("The context is found, we stop the search");
1763 SCRUTE(bindingName[0].id);
1764 Change_Directory(bindingName[0].id);
1765 _current_directory(splitPath,
1772 // --- go back to the initial context
1774 _current_context = ref_context;
1776 MESSAGE("Just before the delete of "
1777 << splitPath[lengthResult-1]);
1778 splitPath.pop_back();
1785 binding_iterator->destroy();
1788 // --- return to the last directory where an occurence was found
1790 _current_context = ref_context ;
1794 // ============================================================================
1795 /*! \brief list recursively all objects in the given directory and subdirs.
1797 * get a list of all the objects in the current directory, with recursion
1798 * on the subdirectories. Only the objects are listed, not the directories.
1799 * If the NamingService is out, the exception ServiceUnreachable is thrown.
1800 * _current_context must refer to absCurDirectory.
1802 * \param myList The list that will be filled.
1803 * \param relativeSubDir The directory relative to absCurDirectory in which
1804 * the objects are found.
1805 * \param absCurDirectory The current directory, absolute path
1807 // ============================================================================
1809 void SALOME_NamingService::_list_directory_recurs(vector<string>& myList,
1810 string relativeSubDir,
1811 string absCurDirectory)
1813 CosNaming::BindingList_var binding_list;
1814 CosNaming::BindingIterator_var binding_iterator;
1815 CosNaming::Binding_var binding ;
1817 unsigned long nb = 0 ; // --- only for thethe use of BindingIterator
1818 // to access the bindings
1822 CosNaming::NamingContext_var ref_context = _current_context;
1824 if (! relativeSubDir.empty())
1826 Change_Directory(relativeSubDir.c_str());
1827 absDir = absCurDirectory + "/" + relativeSubDir;
1831 absDir = absCurDirectory;
1834 _current_context->list(nb, binding_list, binding_iterator) ;
1836 if (! CORBA::is_nil(binding_iterator))
1838 while (binding_iterator->next_one(binding))
1840 CosNaming::Name bindingName = binding->binding_name;
1842 if (binding->binding_type == CosNaming::ncontext)
1844 string relativeSdir(bindingName[0].id);
1845 _list_directory_recurs(myList, relativeSdir, absDir);
1848 else if (binding->binding_type == CosNaming::nobject)
1850 string objName(bindingName[0].id);
1851 string elt = absDir + "/" + objName;
1853 myList.push_back(elt);
1857 binding_iterator->destroy();
1859 if (! relativeSubDir.empty())
1861 _current_context = ref_context;
1865 // ============================================================================
1866 /*! \brief return a stringified reference of root context
1868 * \return a stringified reference of root context
1870 // ============================================================================
1872 char * SALOME_NamingService::getIORaddr()
1874 return _orb->object_to_string(_root_context);
1877 /*! \brief get the orb used by the naming service
1881 CORBA::ORB_ptr SALOME_NamingService::orb()