TAO_CORBALOC_Parser Class Reference

Implements the <corbaloc:> IOR format. More...

#include <CORBALOC_Parser.h>

Inheritance diagram for TAO_CORBALOC_Parser:

Inheritance graph
[legend]
Collaboration diagram for TAO_CORBALOC_Parser:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 TAO_CORBALOC_Parser (void)
 Constructor.

virtual ~TAO_CORBALOC_Parser (void)
 The destructor.

virtual int match_prefix (const char *ior_string) const
virtual CORBA::Object_ptr parse_string (const char *ior, CORBA::ORB_ptr orb) throw (CORBA::SystemException)
 Parse the ior-string that is passed.


Private Member Functions

CORBA::Object_ptr make_stub_from_mprofile (CORBA::ORB_ptr orb, TAO_MProfile &mprofile) throw (CORBA::SystemException)
CORBA::Object_ptr parse_string_rir_helper (const char *corbaloc_name, CORBA::ORB_ptr orb) throw (CORBA::SystemException)
 Gets the pointer to the key_string when the protocol used is RIR.

void make_canonical (const char *ior, size_t ior_len, ACE_CString &canonical_endpoint) throw (CORBA::SystemException)

Detailed Description

Implements the <corbaloc:> IOR format.

This class implements the <corbaloc:> IOR format. It is dynamically loaded by the ORB and used to parse the string to separate the individual from the list of object addresses .

Definition at line 44 of file CORBALOC_Parser.h.


Constructor & Destructor Documentation

TAO_BEGIN_VERSIONED_NAMESPACE_DECL ACE_INLINE TAO_CORBALOC_Parser::TAO_CORBALOC_Parser void   ) 
 

Constructor.

Definition at line 8 of file CORBALOC_Parser.i.

00009 {
00010 }

TAO_BEGIN_VERSIONED_NAMESPACE_DECL TAO_CORBALOC_Parser::~TAO_CORBALOC_Parser void   )  [virtual]
 

The destructor.

Definition at line 32 of file CORBALOC_Parser.cpp.

00033 {
00034 }


Member Function Documentation

void TAO_CORBALOC_Parser::make_canonical const char *  ior,
size_t  ior_len,
ACE_CString canonical_endpoint
throw (CORBA::SystemException) [private]
 

Definition at line 268 of file CORBALOC_Parser.cpp.

References ACE_CString, ACE_DEBUG, ACE_TEXT, ACE_THROW, ACE_INET_Addr::get_host_name(), iiop_token, iiop_token_len, LM_DEBUG, LM_ERROR, MAXHOSTNAMELEN, ACE_OS::strchr(), ACE_OS::strncmp(), and TAO_debug_level.

00273 {
00274   const char *separator = ACE_OS::strchr (ior, ':');
00275 
00276   // A special case for handling iiop
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   // skip past version, if any
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   // IPv6 numeric address in host string?
00301 
00302   // Check if this is an address containing a decimal IPv6 address representation.
00303   if (addr_base < addr_tail && addr_base[0] == '[')
00304     {
00305       // In this case we have to find the end of the numeric address and
00306       // start looking for the port separator from there.
00307       const char *cp_pos = ACE_OS::strchr(addr_base, ']');
00308       if (cp_pos == 0 || cp_pos >= addr_tail)
00309         {
00310           // No valid IPv6 address specified but that will come out later.
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] == ':')    // Look for a port
00322             separator = cp_pos + 1;
00323           else
00324             separator = 0;
00325         }
00326     }
00327 #endif /* ACE_HAS_IPV6 */
00328 
00329   if (separator != 0 && separator < addr_tail)
00330     {
00331       // we have a port number
00332       raw_host.set (addr_base, (separator - addr_base), 1);
00333       raw_port.set (separator, (addr_tail - separator), 1);
00334     }
00335   else
00336     {
00337       // we must default port #
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       // If no host is specified: assign the default host, i.e. the
00350       // local host.
00351       if (host_addr.get_host_name (tmp_host,
00352                                    sizeof (tmp_host)) != 0)
00353         {
00354           // Can't get the IP address since the INET_Addr wasn't
00355           // initialized.  Just throw an exception.
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 }

CORBA::Object_ptr TAO_CORBALOC_Parser::make_stub_from_mprofile CORBA::ORB_ptr  orb,
TAO_MProfile mprofile
throw (CORBA::SystemException) [private]
 

Make a stub from the MProfile that is created in parse_string_mprofile_helper. Using this stub, create an object reference which is sent to the application.

All is well, so release the stub object from its auto_ptr.

Definition at line 46 of file CORBALOC_Parser.cpp.

References CORBA::Object::_nil(), TAO_Pseudo_Var_T< T >::_retn(), ACE_CHECK_RETURN, ACE_ENV_ARG_PARAMETER, TAO_Pseudo_Var_T< T >::in(), CORBA::is_nil(), CORBA::Object_var, CORBA::ORB_ptr, and TAO_Stub_Auto_Ptr::release().

00050 {
00051   // Create a TAO_Stub.
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       /// All is well, so release the stub object from its
00064       /// auto_ptr.
00065       (void) safe_data.release ();
00066 
00067       /// Return the object reference to the application.
00068       return obj._retn ();
00069     }
00070 
00071   /// Shouldnt come here: if so, return nil reference.
00072   return CORBA::Object::_nil ();
00073 }

int TAO_CORBALOC_Parser::match_prefix const char *  ior_string  )  const [virtual]
 

= The IOR_Parser methods, please read the documentation in IOR_Parser.h

Implements TAO_IOR_Parser.

Definition at line 37 of file CORBALOC_Parser.cpp.

References prefix, prefix_len, and ACE_OS::strncmp().

00038 {
00039   // Check if the prefix is 'corbaloc:' and return the result.
00040   return (ACE_OS::strncmp (ior_string,
00041                            prefix,
00042                            prefix_len) == 0);
00043 }

CORBA::Object_ptr TAO_CORBALOC_Parser::parse_string const char *  ior,
CORBA::ORB_ptr  orb
throw (CORBA::SystemException) [virtual]
 

Parse the ior-string that is passed.

Implements TAO_IOR_Parser.

Definition at line 98 of file CORBALOC_Parser.cpp.

References CORBA::Object::_nil(), ACE_CHECK_RETURN, ACE_CString, ACE_ENV_ARG_PARAMETER, ACE_ENV_SINGLE_ARG_PARAMETER, ACE_ERROR, ACE_TEXT, ACE_TEXT_CHAR_TO_TCHAR, ACE_THROW_RETURN, TAO_Connector_Registry::begin(), TAO_Connector_Registry::end(), TAO_MProfile::give_profile(), LM_ERROR, CORBA::Object_ptr, CORBA::ORB_ptr, prefix, rir_token, rir_token_len, ACE_Array_Base< T >::size(), ACE_OS::strchr(), ACE_OS::strlen(), ACE_OS::strncmp(), TAO_ConnectorSetIterator, and TAO_debug_level.

00102 {
00103   // The decomposition of a corbaloc string is in Section 13.6.10.
00104   //
00105   // following the "corbaloc:"
00106   //  a comma separated list of <prot_addr> strings
00107   //    for each,
00108   // Separate out the key, delimited by '/'
00109   // Split out the various parts of our corbaloc string, comma-delimited
00110   // For each part
00111   //   Determine the protocol
00112   //     If rir, defer to another function and return the object
00113   //     If iiop, make the profile with <endpoint>:<port>/<key>
00114   //     If another protocol, use <remainder>/<key>
00115   //   Search through the collection of protocols for the correct one
00116   //     If not found, throw exception
00117   //     If found, make our_connector from it.
00118   //     our_connector->make_mprofile_unchecked (...);
00119   //     object = this->make_stub_from_mprofile (...);
00120   // Return the object
00121 
00122   // Skip the prefix.  We know it is there because this method is only
00123   // called if match_prefix() returns 1.
00124   ior += ACE_OS::strlen(prefix);
00125 
00126   //  First check for rir
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   // set up space for parsed endpoints. there will be at least 1, and
00132   // most likely commas will separate endpoints, although they could be
00133   // part of an endpoint address for some protocols.
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   // Get the Connector Registry from the ORB.
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) { // will loop on comma only.
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 == ',') // more endpoints follow
00189       {
00190         ior++;
00191         continue;
00192       }
00193 
00194     if (*ior == '/') // found key separator
00195       {
00196         ior ++;
00197         break;
00198       }
00199 
00200     if (*ior == '\0') // no key separator appended, use default key
00201       {
00202         break;
00203       }
00204 
00205     if (uiop_compatible && *(ior - 1) == '|')
00206       // Assume this is an old uiop style corbaloc. No need to warn here,
00207       // the UIOP_Connector::corbaloc_scan already did.
00208       break;
00209 
00210     // anything else is a violation.
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   } // end of while
00220 
00221   // At this point, ior points at the start of the object key
00222   ACE_CString obj_key (*ior ? ior : (const char *)"NameService");
00223 
00224   // now take the collection of endpoints along with the decoded key and
00225   // mix them together to get the mprofile.
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           // Although this ought never happen, we want to make some
00242           // indication back to the caller, more as an audit trail than
00243           // anything else. The only failure possible is that there was
00244           // insufficient heap to allocate the mprofile, hence the
00245           // mprofile's size is 0, and give_profile fails.
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   // Get an object stub out.
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 }

CORBA::Object_ptr TAO_CORBALOC_Parser::parse_string_rir_helper const char *  corbaloc_name,
CORBA::ORB_ptr  orb
throw (CORBA::SystemException) [private]
 

Gets the pointer to the key_string when the protocol used is RIR.

Definition at line 76 of file CORBALOC_Parser.cpp.

References TAO_Pseudo_Var_T< T >::_retn(), ACE_CHECK_RETURN, ACE_ENV_ARG_PARAMETER, CORBA::Object_var, CORBA::ORB_ptr, and rir_token_len.

00080 {
00081   // Pass the key string as an argument to resolve_initial_references.
00082   // NameService is the default if an empty key string is supplied.
00083   const char *objkey = ior + rir_token_len;
00084   if (*objkey == '/') // there is an explicit object key, which may
00085                       // validly be null.
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 }


The documentation for this class was generated from the following files:
Generated on Thu Nov 9 12:13:02 2006 for TAO by doxygen 1.3.6