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