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