00001
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 {
00164 cxt->bind(subName(name, i, i), obj);
00165 return;
00166 }
00167 else
00168 {
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 {
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
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 {
00514 CosNaming::NamingContext_var next_context;
00515 next_context = CosNaming::NamingContext::
00516 _narrow(context->resolve(bl[i].binding_name));
00517
00518
00519 destroyRecursive(next_context);
00520 context->unbind(bl[i].binding_name);
00521 next_context->destroy();
00522 }
00523 else if (bl[i].binding_type == CosNaming::nobject)
00524 {
00525 context->unbind(bl[i].binding_name);
00526 }
00527 else assert(0);
00528 }
00529
00530
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
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
00616 CosNaming::Name_var name = new CosNaming::Name();
00617 name->length(nc_length);
00618
00619
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
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
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
00840 for (const char* id = name[i].id; *id != '\0'; ++id)
00841 {
00842 if (*id == '/' || *id == '.' || *id == '\\') *s++ = '\\';
00843 *s++ = *id;
00844 }
00845
00846 if (((const char*)(name[i].id ))[0] == '\0' ||
00847 ((const char*)(name[i].kind))[0] != '\0')
00848 *s++ = '.';
00849
00850 for (const char* kind = name[i].kind; *kind != '\0'; ++kind)
00851 {
00852 if (*kind == '/' || *kind == '.' || *kind == '\\')
00853 *s++ = '\\';
00854 *s++ = *kind;
00855 }
00856
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
00876 for (const char* id = name[i].id; *id; ++id)
00877 {
00878
00879 if (*id == '/' || *id == '.' || *id == '\\') slen++;
00880 slen++;
00881 }
00882
00883 if (((const char*)(name[i].id ))[0] == '\0' ||
00884 ((const char*)(name[i].kind))[0] != '\0')
00885 {
00886 slen++;
00887 }
00888
00889 for (const char* kind = name[i].kind; *kind; kind++)
00890 {
00891 if (*kind == '/' || *kind == '.' || *kind == '\\') slen++;
00892 slen++;
00893 }
00894
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 };