Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

Connector_Registry.cpp

Go to the documentation of this file.
00001 #include "tao_pch.h"
00002 // -*- C++ -*-
00003 //
00004 // $Id: Connector_Registry.cpp,v 1.1.1.4.2.1 2003/03/14 16:05:12 chad Exp $
00005 
00006 #include "tao/Connector_Registry.h"
00007 #include "tao/ORB_Core.h"
00008 #include "tao/Profile.h"
00009 #include "tao/Transport_Connector.h"
00010 #include "tao/Protocol_Factory.h"
00011 #include "tao/Endpoint.h"
00012 #include "tao/Environment.h"
00013 #include "tao/debug.h"
00014 #include "tao/Transport_Descriptor_Interface.h"
00015 
00016 #if !defined(__ACE_INLINE__)
00017 #include "tao/Connector_Registry.i"
00018 #endif /* __ACE_INLINE__ */
00019 
00020 ACE_RCSID (tao,
00021            Connector_Registry,
00022            "$Id: Connector_Registry.cpp,v 1.1.1.4.2.1 2003/03/14 16:05:12 chad Exp $")
00023 
00024 TAO_Connector_Registry::TAO_Connector_Registry (void)
00025   : connectors_ (0),
00026     size_ (0)
00027 {
00028 }
00029 
00030 TAO_Connector_Registry::~TAO_Connector_Registry (void)
00031 {
00032   this->close_all ();
00033 
00034   delete [] this->connectors_;
00035   this->connectors_ = 0;
00036   this->size_ = 0;
00037 }
00038 
00039 TAO_Connector *
00040 TAO_Connector_Registry::get_connector (CORBA::ULong tag)
00041 {
00042   TAO_ConnectorSetIterator end =
00043     this->end ();
00044   TAO_ConnectorSetIterator connector =
00045     this->begin ();
00046 
00047   for (;
00048        connector != end ;
00049        connector++)
00050     {
00051       if ((*connector)->tag () == tag)
00052         return *connector;
00053     }
00054 
00055   return 0;
00056 }
00057 
00058 
00059 
00060 int
00061 TAO_Connector_Registry::open (TAO_ORB_Core *orb_core)
00062 {
00063   TAO_ProtocolFactorySet *pfs = orb_core->protocol_factories ();
00064 
00065   // Open one connector for each loaded protocol!
00066   TAO_ProtocolFactorySetItor end = pfs->end ();
00067   TAO_ProtocolFactorySetItor factory = pfs->begin ();
00068 
00069   TAO_Connector *connector = 0;
00070 
00071   // The array containing the TAO_Connectors will never contain more
00072   // than the number of loaded protocols in the ORB core.
00073   if (this->connectors_ == 0)
00074     ACE_NEW_RETURN (this->connectors_,
00075                     TAO_Connector *[pfs->size ()],
00076                     -1);
00077 
00078   for ( ;
00079        factory != end;
00080        ++factory)
00081     {
00082       connector = (*factory)->factory ()->make_connector ();
00083 
00084       if (connector)
00085         {
00086           if (connector->open (orb_core) != 0)
00087             {
00088               delete connector;
00089 
00090               ACE_ERROR_RETURN ((LM_ERROR,
00091                                  ACE_LIB_TEXT ("TAO (%P|%t) unable to open connector for ")
00092                                  ACE_LIB_TEXT ("<%s>.\n"),
00093                                  ACE_TEXT_CHAR_TO_TCHAR((*factory)->protocol_name ().c_str ())),
00094                                 -1);
00095             }
00096 
00097           this->connectors_[this->size_++] = connector;
00098         }
00099       else
00100         return -1;
00101     }
00102 
00103   return 0;
00104 }
00105 
00106 int
00107 TAO_Connector_Registry::close_all (void)
00108 {
00109   TAO_ConnectorSetIterator end = this->end ();
00110 
00111   for (TAO_ConnectorSetIterator i = this->begin ();
00112        i != end;
00113        ++i)
00114     {
00115       if (*i == 0)
00116         continue;
00117 
00118       (*i)->close ();
00119 
00120       delete *i;
00121     }
00122 
00123   this->size_ = 0;
00124 
00125   return 0;
00126 }
00127 
00128 int
00129 TAO_Connector_Registry::connect (TAO_GIOP_Invocation *invocation,
00130                                  TAO_Transport_Descriptor_Interface *desc
00131                                  ACE_ENV_ARG_DECL)
00132 {
00133   TAO_Endpoint *endpoint = desc->endpoint ();
00134   if (endpoint == 0)
00135     return -1;
00136 
00137   // Find the appropriate connector object.
00138   TAO_Connector *connector =
00139     this->get_connector (endpoint->tag ());
00140 
00141   if (connector == 0)
00142       return -1;
00143 
00144   return connector->connect (invocation,
00145                              desc
00146                               ACE_ENV_ARG_PARAMETER);
00147 }
00148 
00149 int
00150 TAO_Connector_Registry::make_mprofile (const char *ior,
00151                                        TAO_MProfile &mprofile
00152                                        ACE_ENV_ARG_DECL)
00153 {
00154   if (!ior)
00155     // Failure: Null IOR string pointer
00156     ACE_THROW_RETURN (CORBA::INV_OBJREF (
00157       CORBA_SystemException::_tao_minor_code (
00158         TAO_DEFAULT_MINOR_CODE,
00159         EINVAL),
00160       CORBA::COMPLETED_NO),
00161       -1);
00162 
00163   TAO_ConnectorSetIterator first_connector = this->begin ();
00164   TAO_ConnectorSetIterator last_connector = this->end ();
00165 
00166   for (TAO_ConnectorSetIterator connector = first_connector;
00167        connector != last_connector;
00168        ++connector)
00169     {
00170       if (*connector)
00171         {
00172           int mp_result = (*connector)->make_mprofile (ior,
00173                                                        mprofile
00174                                                         ACE_ENV_ARG_PARAMETER);
00175 
00176           ACE_CHECK_RETURN (mp_result);
00177 
00178           if (mp_result == 0)
00179             return 0;  // Success
00180         }
00181       else
00182         // Failure: Null pointer to connector in connector registry.
00183         ACE_THROW_RETURN (CORBA::INV_OBJREF (
00184           CORBA_SystemException::_tao_minor_code (
00185             TAO_DEFAULT_MINOR_CODE,
00186             EINVAL),
00187           CORBA::COMPLETED_NO),
00188           -1);
00189     }
00190 
00191   // Failure: None of the connectors were able to parse the URL style
00192   // IOR into an MProfile.
00193   ACE_THROW_RETURN (CORBA::INV_OBJREF (
00194    CORBA_SystemException::_tao_minor_code (
00195       TAO_CONNECTOR_REGISTRY_NO_USABLE_PROTOCOL,
00196       0),
00197    CORBA::COMPLETED_NO),
00198    -1);
00199 }
00200 
00201 TAO_Profile *
00202 TAO_Connector_Registry::create_profile (TAO_InputCDR &cdr)
00203 {
00204   CORBA::ULong tag = 0;
00205 
00206   // If there is an error we abort.
00207   if ((cdr >> tag) == 0)
00208     return 0;
00209 
00210   TAO_Connector *connector =
00211     this->get_connector (tag);
00212 
00213   if (connector == 0)
00214     {
00215       if (TAO_debug_level > 0)
00216         {
00217           ACE_DEBUG ((LM_DEBUG,
00218                       ACE_LIB_TEXT ("TAO (%P|%t) Unknown profile tag 0x%x\n"),
00219                       tag));
00220         }
00221 
00222       TAO_Profile *pfile = 0;
00223       ACE_NEW_RETURN (pfile,
00224                       TAO_Unknown_Profile (tag,
00225                                            cdr.orb_core ()),
00226                       0);
00227       if (pfile->decode (cdr) == -1)
00228         {
00229           pfile->_decr_refcnt ();
00230           pfile = 0;
00231         }
00232 
00233       return pfile;
00234     }
00235 
00236   // OK, we've got a known profile.  It's going to be encapsulated
00237   // ProfileData.  Create a new decoding stream and context for it,
00238   // and skip the data in the parent stream
00239 
00240   // ProfileData is encoded as a sequence of octet. So first get the
00241   // length of the sequence.
00242   CORBA::ULong encap_len = 0;
00243   if ((cdr >> encap_len) == 0)
00244     return 0;
00245 
00246   // Create the decoding stream from the encapsulation in the buffer,
00247   // and skip the encapsulation.
00248   TAO_InputCDR str (cdr, encap_len);
00249 
00250   if (str.good_bit () == 0
00251       || cdr.skip_bytes (encap_len) == 0)
00252     return 0;
00253 
00254   return connector->create_profile (str);
00255 }
00256 
00257 char
00258 TAO_Connector_Registry::object_key_delimiter (const char *ior)
00259 {
00260   if (!ior)
00261     {
00262       errno = EINVAL;
00263       return 0; // Failure: Null IOR string pointer
00264     }
00265 
00266   TAO_ConnectorSetIterator first_connector = this->begin ();
00267   TAO_ConnectorSetIterator last_connector =  this->end ();
00268 
00269   for (TAO_ConnectorSetIterator connector = first_connector;
00270        connector != last_connector;
00271        ++connector)
00272     {
00273       if (*connector)
00274         {
00275           if ((*connector)->check_prefix (ior) == 0)
00276             return (*connector)->object_key_delimiter ();
00277         }
00278     }
00279 
00280   // Failure: None of the connectors were able to match their protocol
00281   // against the provided string.
00282   return 0;
00283 }
00284 
00285 
00286 #if 0
00287 
00288 /*
00289  *        To be removed..
00290  *
00291  * These methods are not needed since they have been deprecated. But
00292  * just having them in  the bottom of the file to be removed later.
00293  *
00294  */
00295 int
00296 TAO_Connector_Registry::preconnect (TAO_ORB_Core *orb_core,
00297                                     TAO_EndpointSet &preconnections)
00298 {
00299   // Put the preconnects in a form that makes it simple for protocol
00300   // implementers to parse.
00301   if (this->preprocess_preconnects (orb_core, preconnections) != 0)
00302     {
00303       if (TAO_debug_level > 0)
00304         ACE_ERROR ((LM_ERROR,
00305                     ACE_LIB_TEXT ("TAO (%P|%t) Unable to preprocess the preconnections.\n")));
00306 
00307       return -1;
00308     }
00309 
00310   TAO_EndpointSetIterator preconnects = preconnections.begin ();
00311 
00312   for (ACE_CString *i = 0;
00313        preconnects.next (i) != 0;
00314        preconnects.advance ())
00315     {
00316       TAO_ConnectorSetIterator first_connector = this->begin ();
00317       TAO_ConnectorSetIterator last_connector = this->end ();
00318 
00319       for (TAO_ConnectorSetIterator connector = first_connector;
00320            connector != last_connector;
00321            ++connector)
00322         if (*connector)
00323           (*connector)->preconnect (i->c_str ());
00324     }
00325 
00326   // No longer need the preconnect set since all associated
00327   // preconnections have been opened by now.  Reclaim the memory used
00328   // by the preconnect set.
00329   preconnections.reset ();
00330 
00331   return 0;  // Success
00332 }
00333 
00334 int
00335 TAO_Connector_Registry::preprocess_preconnects (TAO_ORB_Core *orb_core,
00336                                                 TAO_EndpointSet &preconnects)
00337 {
00338   // Organize all matching protocol endpoints and addrs into a single
00339   // endpoint for the given protocol.
00340   //
00341   // For example, the following endpoints:
00342   //
00343   //   uiop://1.1@/tmp/foobar,/tmp/chicken
00344   //   iiop://1.0@localhost
00345   //   uiop:///tmp/soup
00346   //   iiop://1.1@mopbucket
00347   //
00348   // will be merged to create the following preconnects:
00349   //
00350   //   uiop://1.1@/tmp/foobar,/tmp/chicken,/tmp/soup
00351   //   iiop://1.0@localhost,1.1@mopbucket
00352   //
00353   // The four elements in the preconnect set will be squeezed into two
00354   // elements, in this case. This is done to simplify the preconnect
00355   // parsing code in each protocol specific connector and to make sure
00356   // that all preconnections are established during the first
00357   // attempt.  Otherwise, secondary attempts to establish
00358   // preconnections will not be successful since all preconnections
00359   // will have been idled after during the first attempt, hence the
00360   // need to pass all preconnects during the first attempt.
00361 
00362   const size_t num_protocols =
00363     orb_core->protocol_factories ()->size ();
00364 
00365   ACE_CString *processed = 0;
00366 
00367   ACE_NEW_RETURN (processed,
00368                   ACE_CString[num_protocols],
00369                   -1);
00370 
00371   // Open one connector for each loaded protocol!
00372   TAO_ProtocolFactorySetItor begin =
00373     orb_core->protocol_factories ()->begin ();
00374   TAO_ProtocolFactorySetItor end =
00375     orb_core->protocol_factories ()->end ();
00376 
00377   ACE_CString *tmp = processed;
00378 
00379   // Iterate over the protocols, *not* the connectors!
00380   for (TAO_ProtocolFactorySetItor factory = begin;
00381        factory != end;
00382        ++factory, ++tmp)
00383     {
00384       (*tmp) =
00385         ACE_CString ((*factory)->factory ()->prefix ()) + ACE_CString ("://");
00386 
00387       TAO_EndpointSetIterator p = preconnects.begin ();
00388 
00389       for (ACE_CString *i = 0;
00390            p.next (i) != 0;
00391            p.advance ())
00392         {
00393           const int slot = i->find ("://");
00394 
00395           ACE_CString protocol_name = i->substring (0, slot);
00396 
00397           if (slot != ACE_CString::npos &&
00398               (slot != ACE_static_cast (int, i->length ()) - 3) &&
00399               (*factory)->factory ()->match_prefix (protocol_name.c_str ()))
00400             {
00401               (*tmp) += i->substring (slot + 3); // +3 due to "://"
00402               (*tmp) += ACE_CString (',');
00403             }
00404         }
00405 
00406       // Remove the trailing comma ','.
00407       if ((*tmp)[tmp->length () - 1] == ',')
00408         (*tmp) = tmp->substring (0, tmp->length () - 1);
00409     }
00410 
00411   // Empty the preconnect container.
00412   preconnects.reset ();
00413 
00414   // Now enqueue the re-formed preconnect strings.
00415   for (size_t n = 0; n < num_protocols; ++n)
00416     {
00417       // If no preconnects for the given protocol exist then don't
00418       // enqueue the empty preconnect list for that protocol.
00419       // Such an empty preconnect string should be of the form
00420       //
00421       //     protocol://
00422       //
00423       // so check for the forward slash '/' at the end of the string.
00424       if (processed[n][processed[n].length () - 1] != '/')
00425         {
00426           if (preconnects.enqueue_tail (processed[n]) != 0)
00427             {
00428               delete [] processed;
00429 
00430               return -1;
00431             }
00432         }
00433     }
00434 
00435   delete [] processed;
00436 
00437   return 0;
00438 }
00439 
00440 // End of the portion that needs to be removed.
00441 #endif /*If 0 */

Generated on Mon Jun 16 13:48:06 2003 for TAO by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002