00001 #include "tao/CORBALOC_Parser.h"
00002
00003 #if (TAO_HAS_CORBALOC_PARSER == 1)
00004
00005 #include "tao/ORB_Core.h"
00006 #include "tao/Stub.h"
00007 #include "tao/MProfile.h"
00008 #include "tao/Connector_Registry.h"
00009 #include "tao/Transport_Connector.h"
00010 #include "tao/Protocol_Factory.h"
00011 #include "tao/debug.h"
00012 #include "tao/SystemException.h"
00013 #include "ace/Vector_T.h"
00014 #include "ace/INET_Addr.h"
00015 #include "ace/OS_NS_string.h"
00016
00017 #include "ace/os_include/os_netdb.h"
00018
00019 #if !defined(__ACE_INLINE__)
00020 #include "tao/CORBALOC_Parser.inl"
00021 #endif
00022
00023 ACE_RCSID (tao,
00024 CORBALOC_Parser,
00025 "$Id: CORBALOC_Parser.cpp 85181 2009-04-28 07:00:58Z johnnyw $")
00026
00027 static const char prefix[] = "corbaloc:";
00028 static const size_t prefix_len = sizeof prefix - 1;
00029 static const char rir_token[] = "rir:";
00030 static const size_t rir_token_len = sizeof rir_token - 1;
00031 static const char iiop_token[] = "iiop:";
00032 static const char iiop_token_len = sizeof iiop_token - 1;
00033
00034 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00035
00036 TAO_CORBALOC_Parser::~TAO_CORBALOC_Parser (void)
00037 {
00038 }
00039
00040 bool
00041 TAO_CORBALOC_Parser::match_prefix (const char *ior_string) const
00042 {
00043
00044 return (ACE_OS::strncmp (ior_string,
00045 prefix,
00046 prefix_len) == 0);
00047 }
00048
00049 CORBA::Object_ptr
00050 TAO_CORBALOC_Parser::make_stub_from_mprofile (CORBA::ORB_ptr orb,
00051 TAO_MProfile &mprofile)
00052 {
00053
00054 TAO_Stub *data = orb->orb_core ()->create_stub ((const char *) 0, mprofile);
00055
00056 TAO_Stub_Auto_Ptr safe_data (data);
00057
00058 CORBA::Object_var obj = orb->orb_core ()->create_object (data);
00059
00060 if (!CORBA::is_nil (obj.in ()))
00061 {
00062
00063
00064 (void) safe_data.release ();
00065
00066
00067 return obj._retn ();
00068 }
00069
00070
00071 return CORBA::Object::_nil ();
00072 }
00073
00074 CORBA::Object_ptr
00075 TAO_CORBALOC_Parser::parse_string_rir_helper (const char * ior,
00076 CORBA::ORB_ptr orb)
00077 {
00078
00079
00080 const char *objkey = ior + rir_token_len;
00081 if (*objkey == '/')
00082
00083 objkey++;
00084
00085 CORBA::Object_var rir_obj =
00086 orb->resolve_initial_references (*objkey == '\0' ? "NameService" : objkey);
00087
00088 return rir_obj._retn ();
00089 }
00090
00091 CORBA::Object_ptr
00092 TAO_CORBALOC_Parser::parse_string (const char * ior, CORBA::ORB_ptr orb)
00093 {
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 ior += ACE_OS::strlen(prefix);
00116
00117
00118 if (ACE_OS::strncmp (ior,rir_token,rir_token_len) == 0)
00119 return this->parse_string_rir_helper (ior,orb);
00120
00121
00122
00123
00124 size_t max_endpoint_count = 1;
00125 for (const char *comma = ACE_OS::strchr (ior,',');
00126 comma;
00127 comma = ACE_OS::strchr (comma+1,','))
00128 ++max_endpoint_count;
00129
00130 ACE_Array<parsed_endpoint> endpoints(max_endpoint_count);
00131 endpoints.size (0);
00132
00133
00134 TAO_Connector_Registry *conn_reg =
00135 orb->orb_core ()->connector_registry();
00136
00137 while (1) {
00138 size_t len = 0;
00139 size_t ndx = endpoints.size();
00140 endpoints.size(ndx+1);
00141 int uiop_compatible = 0;
00142 TAO_ConnectorSetIterator conn_iter = 0;
00143 for (conn_iter = conn_reg->begin();
00144 conn_iter != conn_reg->end() &&
00145 endpoints[ndx].profile_ == 0;
00146 conn_iter ++)
00147 {
00148 endpoints[ndx].profile_ =
00149 (*conn_iter)->corbaloc_scan(ior,len);
00150
00151 if (endpoints[ndx].profile_)
00152 {
00153 endpoints[ndx].obj_key_sep_ =
00154 (*conn_iter)->object_key_delimiter();
00155 uiop_compatible = (endpoints[ndx].obj_key_sep_ == '|');
00156 this->make_canonical (ior,len,endpoints[ndx].prot_addr_);
00157 ior += len;
00158 break;
00159 }
00160 }
00161
00162 if (endpoints[ndx].profile_ == 0)
00163 {
00164 if (TAO_debug_level)
00165 ACE_ERROR ((LM_ERROR,
00166 ACE_TEXT("(%P|%t) TAO_CORBALOC_Parser::parse_string ")
00167 ACE_TEXT("could not parse from %C"),
00168 ior));
00169 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 10, CORBA::COMPLETED_NO);
00170 }
00171 if (*ior == ',')
00172 {
00173 ++ior;
00174 continue;
00175 }
00176
00177 if (*ior == '/')
00178 {
00179 ++ior;
00180 break;
00181 }
00182
00183 if (*ior == '\0')
00184 {
00185 break;
00186 }
00187
00188 if (uiop_compatible && *(ior - 1) == '|')
00189
00190
00191 break;
00192
00193
00194 if (TAO_debug_level)
00195 ACE_ERROR ((LM_ERROR,
00196 ACE_TEXT("(%P|%t) TAO_CORBALOC_Parser::parse_string ")
00197 ACE_TEXT("could not parse from %C"),
00198 ior));
00199 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 10, CORBA::COMPLETED_NO);
00200 }
00201
00202
00203 ACE_CString obj_key (*ior ? ior : (const char *)"NameService");
00204
00205
00206
00207 TAO_MProfile mprofile (endpoints.size());
00208
00209 for (size_t i = 0; i < endpoints.size(); i++)
00210 {
00211 ACE_CString full_ep = endpoints[i].prot_addr_ +
00212 endpoints[i].obj_key_sep_ +
00213 obj_key;
00214 const char * str = full_ep.c_str();
00215 endpoints[i].profile_->parse_string (str);
00216 int share = orb->orb_core()->orb_params()->shared_profile();
00217 if (mprofile.give_profile(endpoints[i].profile_, share) != -1)
00218 endpoints[i].profile_ = 0;
00219 else
00220 {
00221
00222
00223
00224
00225
00226 if (TAO_debug_level)
00227 ACE_ERROR ((LM_ERROR,
00228 ACE_TEXT("(%P|%t) TAO_CORBALOC_Parser::parse_string ")
00229 ACE_TEXT("mprofile.give_profile failed for i = %d\n"),
00230 i));
00231 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 10, CORBA::COMPLETED_NO);
00232 }
00233 }
00234
00235
00236 return this->make_stub_from_mprofile (orb, mprofile);
00237 }
00238
00239 void
00240 TAO_CORBALOC_Parser::make_canonical (const char *ior,
00241 size_t prot_addr_len,
00242 ACE_CString &canonical_endpoint)
00243 {
00244 const char *separator = ACE_OS::strchr (ior, ':');
00245
00246
00247 if (ior[0] != ':' && ACE_OS::strncmp (ior,iiop_token,iiop_token_len) != 0)
00248 {
00249 canonical_endpoint.set (separator+1,
00250 prot_addr_len - (separator - ior) - 1,1);
00251 return;
00252 }
00253
00254 const char *addr_base = separator+1;
00255 const char *addr_tail = ior + prot_addr_len;
00256
00257 separator = ACE_OS::strchr (addr_base,'@');
00258 if (separator != 0 && separator < addr_tail)
00259 {
00260 canonical_endpoint.set (addr_base,(separator - addr_base)+1,1);
00261 addr_base = separator + 1;
00262 }
00263 else
00264 canonical_endpoint.clear ();
00265
00266 ACE_CString raw_host;
00267 ACE_CString raw_port;
00268 separator = ACE_OS::strchr (addr_base,':');
00269 #if defined (ACE_HAS_IPV6)
00270
00271
00272
00273 if (addr_base < addr_tail && addr_base[0] == '[')
00274 {
00275
00276
00277 const char *cp_pos = ACE_OS::strchr(addr_base, ']');
00278 if (cp_pos == 0 || cp_pos >= addr_tail)
00279 {
00280
00281 if (TAO_debug_level > 0)
00282 {
00283 ACE_ERROR ((LM_ERROR,
00284 ACE_TEXT ("\nTAO (%P|%t) TAO_CORBALOC_Parser: ")
00285 ACE_TEXT ("Invalid IPv6 decimal address specified.\n")));
00286 }
00287 separator = 0;
00288 }
00289 else
00290 {
00291 if (cp_pos[1] == ':')
00292 separator = cp_pos + 1;
00293 else
00294 separator = 0;
00295 }
00296 }
00297 #endif
00298
00299 if (separator != 0 && separator < addr_tail)
00300 {
00301
00302 raw_host.set (addr_base, (separator - addr_base), 1);
00303 raw_port.set (separator, (addr_tail - separator), 1);
00304 }
00305 else
00306 {
00307
00308 if (addr_base < addr_tail)
00309 raw_host.set (addr_base, (addr_tail - addr_base),1);
00310 raw_port.set (":2809");
00311 }
00312
00313 if (raw_host.length() == 0)
00314 {
00315 ACE_INET_Addr host_addr;
00316
00317 char tmp_host [MAXHOSTNAMELEN + 1];
00318
00319
00320
00321 if (host_addr.get_host_name (tmp_host,
00322 sizeof (tmp_host)) != 0)
00323 {
00324
00325
00326
00327 if (TAO_debug_level > 0)
00328 ACE_DEBUG ((LM_DEBUG,
00329 ACE_TEXT ("TAO (%P|%t) ")
00330 ACE_TEXT ("cannot determine hostname.\n")));
00331
00332 throw ::CORBA::INV_OBJREF
00333 (CORBA::SystemException::_tao_minor_code
00334 (TAO::VMCID, EINVAL),
00335 CORBA::COMPLETED_NO);
00336 }
00337 else
00338 {
00339 canonical_endpoint += tmp_host;
00340 }
00341 }
00342 else
00343 {
00344 canonical_endpoint += raw_host;
00345 }
00346
00347 canonical_endpoint += raw_port;
00348 }
00349
00350
00351
00352 ACE_STATIC_SVC_DEFINE (TAO_CORBALOC_Parser,
00353 ACE_TEXT ("CORBALOC_Parser"),
00354 ACE_SVC_OBJ_T,
00355 &ACE_SVC_NAME (TAO_CORBALOC_Parser),
00356 ACE_Service_Type::DELETE_THIS |
00357 ACE_Service_Type::DELETE_OBJ,
00358 0)
00359
00360 ACE_FACTORY_DEFINE (TAO, TAO_CORBALOC_Parser)
00361
00362 TAO_END_VERSIONED_NAMESPACE_DECL
00363
00364 #endif