CorbaNaming.cpp
Go to the documentation of this file.
00001 // -*- C++ -*-
00020 #ifdef WIN32
00021 #define ACE_HAS_WINSOCK2 0
00022 #endif //WIN32
00023 
00024 #include <assert.h>
00025 #include <rtm/CorbaNaming.h>
00026 #include <iostream>
00027 
00028 namespace RTC
00029 {
00037   CorbaNaming::CorbaNaming(CORBA::ORB_ptr orb)
00038     : m_varORB(orb), m_nameServer(""),
00039       m_rootContext(CosNaming::NamingContextExt::_nil()),
00040       m_blLength(100)
00041   {
00042   }
00043   
00051   CorbaNaming::CorbaNaming(CORBA::ORB_ptr orb, const char* name_server)
00052     : m_varORB(CORBA::ORB::_duplicate(orb)), m_nameServer(name_server),
00053       m_rootContext(CosNaming::NamingContextExt::_nil()),
00054       m_blLength(100)
00055   {
00056     CORBA::Object_var obj;
00057     m_nameServer = "corbaloc::" + m_nameServer + "/NameService";
00058     try
00059       {
00060         obj = m_varORB->string_to_object(m_nameServer.c_str());
00061         m_rootContext = CosNaming::NamingContextExt::_narrow(obj);
00062         if (CORBA::is_nil(m_rootContext)) throw std::bad_alloc();
00063       }
00064     catch(...)
00065       {
00066         throw std::bad_alloc();
00067       }
00068   }
00069   
00077   void CorbaNaming::init(const char* name_server)
00078   {
00079     m_nameServer = name_server;
00080     m_nameServer = "corbaloc::" + m_nameServer + "/NameService";
00081     CORBA::Object_var obj;
00082     obj = m_varORB->string_to_object(m_nameServer.c_str());
00083     m_rootContext = CosNaming::NamingContextExt::_narrow(obj);
00084     if (CORBA::is_nil(m_rootContext)) throw std::bad_alloc();
00085   }
00086 
00087   bool CorbaNaming::isAlive()
00088   {
00089     try
00090       {
00091         if (m_rootContext->_non_existent()) { return false; }
00092         return true;
00093       }
00094     catch (...)
00095       {
00096         return false;
00097       }
00098     return false;
00099   }
00100   
00108   void CorbaNaming::bind(const CosNaming::Name& name, CORBA::Object_ptr obj,
00109                          const bool force)
00110     throw (SystemException, NotFound, CannotProceed, InvalidName, AlreadyBound)
00111   {
00112     try
00113       {
00114         m_rootContext->bind(name, obj);
00115       }
00116     catch (NotFound& e)
00117       {
00118         force ? bindRecursive(m_rootContext, name, obj) : throw e;
00119       }
00120     catch (CannotProceed& e)
00121       {
00122 #ifndef ORB_IS_RTORB
00123         force ? bindRecursive(e.cxt, e.rest_of_name, obj) : throw e;
00124 #else // ORB_IS_RTORB
00125         force ? bindRecursive(e.cxt(), e.rest_of_name(), obj) : throw e;
00126 #endif // ORB_IS_RTORB
00127       }
00128   }
00129   
00137   void CorbaNaming::bindByString(const char* string_name, CORBA::Object_ptr obj,
00138                                  const bool force)
00139     throw (SystemException, NotFound, CannotProceed, InvalidName, AlreadyBound)
00140   {
00141     this->bind(toName(string_name), obj, force);
00142   }
00143   
00151   void CorbaNaming::bindRecursive(CosNaming::NamingContext_ptr context,
00152                                   const CosNaming::Name& name,
00153                                   CORBA::Object_ptr obj)
00154     throw (SystemException, CannotProceed, InvalidName, AlreadyBound)
00155   {
00156     CORBA::ULong len(name.length());
00157     CosNaming::NamingContext_var cxt;
00158     cxt = CosNaming::NamingContext::_duplicate(context);
00159     
00160     for (CORBA::ULong i = 0; i < len; ++i)
00161       {
00162         if (i == (len - 1))
00163           { // this operation may throw AlreadyBound, 
00164             cxt->bind(subName(name, i, i), obj);
00165             return;
00166           }
00167         else
00168           { // If the context is not a NamingContext, CannotProceed is thrown
00169             if (isNamingContext(cxt))
00170               cxt = bindOrResolveContext(cxt, subName(name, i, i));
00171             else
00172               throw CannotProceed(cxt, subName(name, i));
00173           }
00174       }
00175     return;
00176   }
00177   
00185   void CorbaNaming::rebind(const CosNaming::Name& name,
00186                            CORBA::Object_ptr obj,
00187                            const bool force)
00188     throw (SystemException, NotFound, CannotProceed, InvalidName)
00189   {
00190     try
00191       {
00192         m_rootContext->rebind(name, obj);
00193       }
00194     catch (NotFound& e)
00195       {
00196         force ? rebindRecursive(m_rootContext, name, obj) : throw e;
00197       }
00198     catch (CannotProceed& e)
00199       {
00200 #ifndef ORB_IS_RTORB
00201         force ? rebindRecursive(e.cxt, e.rest_of_name, obj) : throw e;
00202 #else // ORB_IS_RTORB
00203         force ? rebindRecursive(e.cxt(), e.rest_of_name(), obj) : throw e;
00204 #endif // ORB_IS_RTORB
00205       }
00206   }
00207   
00215   void CorbaNaming::rebindByString(const char* string_name,
00216                                    CORBA::Object_ptr obj,
00217                                    const bool force)
00218     throw (SystemException, NotFound, CannotProceed, InvalidName)
00219   {
00220     rebind(toName(string_name), obj, force);
00221   }
00222   
00230   void CorbaNaming::rebindRecursive(CosNaming::NamingContext_ptr context,
00231                                     const CosNaming::Name& name,
00232                                     CORBA::Object_ptr obj)
00233     throw (SystemException, CannotProceed, InvalidName)
00234   {
00235     CORBA::ULong len(name.length());
00236     CosNaming::NamingContext_var cxt;
00237     cxt = CosNaming::NamingContext::_duplicate(context);
00238     
00239     for (CORBA::ULong i = 0; i < len; ++i)
00240       {
00241         if (i == (len - 1))
00242           {
00243             cxt->rebind(subName(name, i, i), obj);
00244             return;
00245           }
00246         else
00247           { // If the context is not a NamingContext, CannotProceed is thrown
00248             if (isNamingContext(cxt))
00249               {
00250                 try
00251                   {
00252                     cxt = cxt->bind_new_context(subName(name, i, i));
00253                   }
00254                 catch (AlreadyBound& e)
00255                   {
00256                     (void)(e);
00257                     cxt = CosNaming::
00258                       NamingContextExt::
00259                       _narrow(cxt->resolve(subName(name, i, i)));
00260                   }
00261               }
00262             else
00263               throw CannotProceed(cxt, subName(name, i));
00264           }
00265       }
00266     return;
00267   }
00268   
00276   void CorbaNaming::bindContext(const CosNaming::Name& name,
00277                                 CosNaming::NamingContext_ptr name_cxt,
00278                                 const bool force)
00279     throw (SystemException, NotFound, CannotProceed, InvalidName, AlreadyBound)
00280   {
00281     bind(name, name_cxt, force);
00282   }
00283   
00291   void CorbaNaming::bindContext(const char* string_name,
00292                                 CosNaming::NamingContext_ptr name_cxt,
00293                                 const bool force)
00294     throw (SystemException, NotFound, CannotProceed, InvalidName, AlreadyBound)
00295   {
00296     bindContext(toName(string_name), name_cxt, force);
00297   }
00298   
00306   void
00307   CorbaNaming::bindContextRecursive(CosNaming::NamingContext_ptr context,
00308                                     const CosNaming::Name& name,
00309                                     CosNaming::NamingContext_ptr name_cxt)
00310   {
00311     bindRecursive(context, name, name_cxt);
00312     return;
00313   }
00314   
00322   void CorbaNaming::rebindContext(const CosNaming::Name& name,
00323                                   CosNaming::NamingContext_ptr name_cxt,
00324                                   const bool force)
00325     throw (SystemException, NotFound, CannotProceed, InvalidName)
00326   {
00327     rebind(name, name_cxt, force);
00328     return;
00329   }
00330   
00338   void CorbaNaming::rebindContext(const char* string_name,
00339                                   CosNaming::NamingContext_ptr name_cxt,
00340                                   const bool force)
00341     throw (SystemException, NotFound, CannotProceed, InvalidName)
00342   {
00343     rebindContext(toName(string_name), name_cxt, force);
00344   }
00345   
00353   void
00354   CorbaNaming::rebindContextRecursive(CosNaming::NamingContext_ptr context,
00355                                       const CosNaming::Name& name,
00356                                       CosNaming::NamingContext_ptr name_cxt)
00357   {
00358     rebindRecursive(context, name, name_cxt);
00359     return;
00360   }
00361   
00369   CORBA::Object_ptr CorbaNaming::resolve(const CosNaming::Name& name)
00370     throw (SystemException, NotFound, CannotProceed, InvalidName)
00371   { 
00372     return m_rootContext->resolve(name);
00373   }
00374   
00382   CORBA::Object_ptr CorbaNaming::resolve(const char* string_name)
00383     throw (SystemException, NotFound, CannotProceed, InvalidName)
00384   { 
00385     return resolve(toName(string_name));
00386   }
00387   
00395   void CorbaNaming::unbind(const CosNaming::Name& name)
00396     throw (SystemException, NotFound, CannotProceed, InvalidName)
00397   {
00398     m_rootContext->unbind(name);
00399   }
00400   
00408   void CorbaNaming::unbind(const char* string_name)
00409     throw (SystemException, NotFound, CannotProceed, InvalidName)
00410   {
00411     unbind(toName(string_name));
00412   }
00413   
00421   CosNaming::NamingContext_ptr CorbaNaming::newContext()
00422   {
00423     return m_rootContext->new_context();
00424   }
00425   
00433   CosNaming::NamingContext_ptr
00434   CorbaNaming::bindNewContext(const CosNaming::Name& name, bool force)
00435     throw (SystemException, NotFound, CannotProceed, InvalidName, AlreadyBound)
00436   {
00437     try
00438       {
00439         return m_rootContext->bind_new_context(name);
00440       }
00441     catch (NotFound& e)
00442       {
00443         force ? bindRecursive(m_rootContext, name, newContext()) : throw e;
00444       }
00445     catch (CannotProceed& e)
00446       {
00447 #ifndef ORB_IS_RTORB
00448         force ? bindRecursive(e.cxt, e.rest_of_name, newContext()) : throw e;
00449 #else // ORB_IS_RTORB
00450         force ? 
00451           bindRecursive(e.cxt(), e.rest_of_name(), newContext()) : throw e;
00452 #endif // ORB_IS_RTORB
00453       }
00454     return CosNaming::NamingContext::_nil();
00455   }
00456   
00464   CosNaming::NamingContext_ptr
00465   CorbaNaming::bindNewContext(const char* string_name, bool force)
00466     throw (SystemException, NotFound, CannotProceed, InvalidName, AlreadyBound)
00467   {
00468     return bindNewContext(toName(string_name));
00469   }
00470   
00478   void CorbaNaming::destroy(CosNaming::NamingContext_ptr context)
00479     throw (SystemException, NotEmpty)
00480   {
00481     context->destroy();
00482   }
00483   
00491   void CorbaNaming::destroyRecursive(CosNaming::NamingContext_ptr context)
00492     throw (SystemException, NotEmpty, NotFound, CannotProceed, InvalidName)
00493   {
00494     CosNaming::BindingList_var     bl;
00495     CosNaming::BindingIterator_var bi;
00496     CORBA::Boolean cont(true);
00497     
00498 #ifndef ORB_IS_RTORB
00499     context->list(m_blLength, bl.out(), bi.out());
00500 #else // ORB_IS_RTORB
00501     //    context->list(m_blLength, bl, bi);
00502     context->list(m_blLength, (CosNaming::BindingList_out)bl,
00503                   (CosNaming::BindingIterator_ptr)bi);
00504 #endif // ORB_IS_RTORB
00505     
00506     while (cont)
00507       {
00508         CORBA::ULong len(bl->length());
00509         
00510         for (CORBA::ULong i = 0; i < len; ++i)
00511           {
00512             if (bl[i].binding_type == CosNaming::ncontext)
00513               { // If Object is context, destroy recursive.
00514                 CosNaming::NamingContext_var next_context;
00515                 next_context = CosNaming::NamingContext::
00516                   _narrow(context->resolve(bl[i].binding_name));
00517                 
00518                 // Recursive function call
00519                 destroyRecursive(next_context); // +++ Recursive call +++
00520                 context->unbind(bl[i].binding_name);
00521                 next_context->destroy();
00522               }
00523             else if (bl[i].binding_type == CosNaming::nobject)
00524               { // If Object is object, unbind it.
00525                 context->unbind(bl[i].binding_name);
00526               }
00527             else assert(0); // never comes here
00528           }
00529         
00530         // no more binding -> do-while loop will be finished
00531         if (CORBA::is_nil(bi)) cont = false;
00532         else bi->next_n(m_blLength, bl);
00533       }
00534     
00535     if (!CORBA::is_nil(bi)) bi->destroy();
00536     return;
00537   }
00538   
00546   void CorbaNaming::clearAll()
00547   {
00548     destroyRecursive(m_rootContext);
00549   }
00550   
00558   void CorbaNaming::list(CosNaming::NamingContext_ptr name_cxt,
00559                          CORBA::ULong how_many,
00560                          CosNaming::BindingList_var& bl,
00561                          CosNaming::BindingIterator_var& bi)
00562   {
00563 #ifndef ORB_IS_RTORB
00564     name_cxt->list(how_many, bl.out(), bi.out());
00565 #else // ORB_IS_RTORB
00566     name_cxt->list(how_many, (CosNaming::BindingList_out)bl,
00567                    (CosNaming::BindingIterator_ptr)bi);
00568 #endif // ORB_IS_RTORB
00569 
00570   }
00571   
00579   char* CorbaNaming::toString(const CosNaming::Name& name)
00580     throw (SystemException, InvalidName)
00581   {
00582     if (name.length() == 0)
00583       throw InvalidName();
00584     
00585     CORBA::ULong slen = 0;
00586     slen = getNameLength(name);
00587     
00588     CORBA::String_var string_name = CORBA::string_alloc(slen);
00589     nameToString(name, (char*)string_name, slen);
00590     
00591     return string_name._retn();
00592   }
00593   
00601   CosNaming::Name CorbaNaming::toName(const char* sname)
00602     throw (SystemException, InvalidName)
00603   {
00604     if (!sname)         throw InvalidName();
00605     if (*sname == '\0') throw InvalidName();
00606     
00607     std::string string_name(sname);
00608     std::vector<std::string> name_comps;
00609     
00610     // String name should include 1 or more names
00611     CORBA::ULong nc_length = 0;
00612     nc_length = split(string_name, std::string("/"), name_comps);
00613     if (!(nc_length > 0)) throw InvalidName();
00614     
00615     // Name components are allocated
00616     CosNaming::Name_var    name = new CosNaming::Name();
00617     name->length(nc_length);
00618     
00619     // Insert id and kind to name components
00620     for (CORBA::ULong i = 0; i < nc_length; ++i)
00621       {
00622         std::string::size_type pos;
00623         pos = name_comps[i].find_last_of(".");
00624         if (pos != name_comps[i].npos)
00625           {
00626             name[i].id   = 
00627               CORBA::string_dup(name_comps[i].substr(0, pos).c_str());
00628             name[i].kind = 
00629               CORBA::string_dup(name_comps[i].substr(pos + 1).c_str());
00630           }
00631         else
00632           {
00633             name[i].id   = CORBA::string_dup(name_comps[i].c_str());
00634 #ifndef ORB_IS_RTORB
00635             name[i].kind = "";
00636 #else // ORB_IS_RTORB
00637             name[i].kind = (char*)"";
00638 #endif // ORB_IS_RTORB
00639           }
00640       }
00641     return name;
00642   }
00643   
00651   char* CorbaNaming::toUrl(char* addr, char* string_name)
00652     throw (SystemException, InvalidAddress, InvalidName)
00653   {
00654     return m_rootContext->to_url(addr, string_name);
00655   }
00656   
00664   CORBA::Object_ptr CorbaNaming::resolveStr(const char* string_name)
00665     throw (SystemException, NotFound, CannotProceed, InvalidName, AlreadyBound)
00666   {
00667     return resolve(string_name);
00668   }
00669   
00670   //======================================================================
00671   // Util functions
00672   //======================================================================
00680   CORBA::Object_ptr
00681   CorbaNaming::bindOrResolve(CosNaming::NamingContext_ptr context,
00682                              const CosNaming::Name& name,
00683                              CORBA::Object_ptr obj)
00684   {
00685     try
00686       {
00687         context->bind(name, obj);
00688         return obj;
00689       }
00690     catch (AlreadyBound& e)
00691       {
00692         (void)(e);
00693         return context->resolve(name);
00694       }
00695     return CORBA::Object::_nil();
00696   }
00697   
00705   CosNaming::NamingContext_ptr
00706   CorbaNaming::bindOrResolveContext(CosNaming::NamingContext_ptr context,
00707                                     const CosNaming::Name& name,
00708                                     CosNaming::NamingContext_ptr new_context)
00709   {
00710     return CosNaming::NamingContext
00711       ::_narrow(bindOrResolve(context, name, new_context));
00712   }
00713   
00721   CosNaming::NamingContext_ptr
00722   CorbaNaming::bindOrResolveContext(CosNaming::NamingContext_ptr context,
00723                                     const CosNaming::Name& name)
00724   {
00725     return bindOrResolveContext(context, name, newContext());
00726   }
00727   
00735   const char* CorbaNaming::getNameServer()
00736   {
00737     return m_nameServer.c_str();
00738   }
00739   
00747   CosNaming::NamingContext_ptr CorbaNaming::getRootContext()
00748   {
00749     return m_rootContext;
00750   }
00751   
00759   bool CorbaNaming::isNamingContext(CORBA::Object_ptr obj)
00760   {
00761     CosNaming::NamingContext_var nc;
00762     nc = CosNaming::NamingContext::_narrow(obj);
00763     return CORBA::is_nil(nc) ? false : true;
00764   }
00765   
00773   bool CorbaNaming::isNamingContext(const CosNaming::Name& name)
00774   {
00775     return isNamingContext(resolve(name));
00776   }
00777   
00785   bool CorbaNaming::isNamingContext(const char* string_name)
00786   {
00787     return isNamingContext(resolve(string_name));
00788   }
00789   
00797   CosNaming::Name CorbaNaming::subName(const CosNaming::Name& name,
00798                                        CORBA::Long begin,
00799                                        CORBA::Long end)
00800   {
00801     if (end < 0) end = name.length() - 1;
00802     
00803     CosNaming::Name sub_name;
00804     CORBA::ULong sub_len(end - (begin - 1));
00805     if (sub_len > 0)
00806       {
00807         sub_name.length(sub_len);
00808       }
00809     else
00810       {
00811         sub_name.length(0);
00812         return sub_name;
00813       }
00814     
00815     for (CORBA::ULong i = 0; i < sub_len; ++i)
00816       {
00817         sub_name[i] = name[begin + i];
00818       }
00819     return sub_name;
00820   }
00821   
00822   //------------------------------------------------------------
00823   // Protected member functions
00824   //------------------------------------------------------------
00832   void CorbaNaming::nameToString(const CosNaming::Name& name,
00833                                  char* string_name,
00834                                  CORBA::ULong slen)
00835   {
00836     char* s = string_name;
00837     for (CORBA::ULong i = 0; i < name.length(); ++i)
00838       {
00839         // Copy id to string_name
00840         for (const char* id = name[i].id; *id != '\0'; ++id)
00841           {
00842             if (*id == '/' || *id == '.' || *id == '\\') *s++ = '\\';
00843             *s++ = *id;
00844           }
00845         // '.' if there is a kind, or no id
00846         if (((const char*)(name[i].id  ))[0] == '\0' || 
00847             ((const char*)(name[i].kind))[0] != '\0')
00848           *s++ = '.';
00849         // Copy kind to string_name
00850         for (const char* kind = name[i].kind; *kind != '\0'; ++kind)
00851           {
00852             if (*kind == '/' || *kind == '.' || *kind == '\\')
00853               *s++ = '\\';
00854             *s++ = *kind;
00855           }
00856         // The end of string_name will be overwritten by '\0'
00857         *s++ = '/';
00858       }
00859     string_name[slen-1] = '\0';
00860   }
00861   
00869   CORBA::ULong CorbaNaming::getNameLength(const CosNaming::Name& name)
00870   {
00871     CORBA::ULong slen = 0;
00872     
00873     for (CORBA::ULong i = 0; i < name.length(); ++i)
00874       {
00875         // Count string length of id(s)
00876         for (const char* id = name[i].id; *id; ++id)
00877           {
00878             // Escape character '/', '.', '\' will convert to "\/", "\.", "\\".
00879             if (*id == '/' || *id == '.' || *id == '\\') slen++;
00880             slen++;
00881           }
00882         // If kind exists, space for '.' is counted
00883         if (((const char*)(name[i].id  ))[0] == '\0' || 
00884             ((const char*)(name[i].kind))[0] != '\0')
00885           {
00886             slen++;
00887           }
00888         // Count string length of kind(s)
00889         for (const char* kind = name[i].kind; *kind; kind++)
00890           {
00891             if (*kind == '/' || *kind == '.' || *kind == '\\') slen++;
00892             slen++;
00893           }
00894         // Space for '/' or '\0'
00895         slen++;
00896       }
00897     return slen;
00898   }
00899   
00907   unsigned int CorbaNaming::split(const std::string& input,
00908                                   const std::string& delimiter,
00909                                   std::vector<std::string>& results)
00910   {
00911     typedef std::string::size_type size;
00912     size delim_size = delimiter.size();
00913     size found_pos(0), begin_pos(0), pre_pos(0), substr_size(0);
00914     
00915     if (input.substr(0, delim_size) == delimiter)
00916       begin_pos = pre_pos = delim_size;
00917     
00918     while (1)
00919       {
00920       REFIND:
00921         found_pos = input.find(delimiter, begin_pos);
00922         if (found_pos == std::string::npos) 
00923           {
00924             results.push_back(input.substr(pre_pos));
00925             break;
00926           }
00927         if ('\\' == input.at(found_pos - 1))
00928           {
00929             begin_pos = found_pos + delim_size;
00930             goto REFIND;
00931           }
00932         
00933         substr_size = found_pos - pre_pos;
00934         
00935         if (substr_size > 0)
00936           {
00937             results.push_back(input.substr(pre_pos, substr_size));
00938           }
00939         begin_pos = found_pos + delim_size;
00940         pre_pos   = found_pos + delim_size;
00941       }
00942     return results.size();
00943   }
00944 }; // namespace RTC


openrtm_aist
Author(s): Noriaki Ando
autogenerated on Thu Aug 27 2015 14:16:37