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

CORBALOC_Parser.cpp

Go to the documentation of this file.
00001 #include "tao_pch.h"
00002 #include "CORBALOC_Parser.h"
00003 #include "ORB_Core.h"
00004 #include "Stub.h"
00005 #include "MProfile.h"
00006 #include "Connector_Registry.h"
00007 #include "tao/debug.h"
00008 
00009 #if !defined(__ACE_INLINE__)
00010 #include "CORBALOC_Parser.i"
00011 #endif /* __ACE_INLINE__ */
00012 
00013 ACE_RCSID (TAO,
00014            CORBALOC_Parser,
00015            "$Id: CORBALOC_Parser.cpp,v 1.1.1.2.2.2 2003/04/21 19:10:23 chad Exp $")
00016 
00017 TAO_CORBALOC_Parser::~TAO_CORBALOC_Parser (void)
00018 {
00019 }
00020 
00021 static const char corbaloc_prefix[] = "corbaloc:";
00022 static const char iiop_prefix[] = "iiop:";
00023 static const char uiop_prefix[] = "uiop:";
00024 static const char shmiop_prefix[] = "shmiop:";
00025 static const char miop_prefix[] = "miop:";
00026 static const char rir_prefix[] = "rir:";
00027 
00028 int
00029 TAO_CORBALOC_Parser::match_prefix (const char *ior_string) const
00030 {
00031   // Check if the prefix is 'corbaloc:' and return the result.
00032   return (ACE_OS::strncmp (ior_string,
00033                            corbaloc_prefix,
00034                            sizeof corbaloc_prefix - 1) == 0);
00035 }
00036 
00037 void
00038 TAO_CORBALOC_Parser::parse_string_count_helper (const char * s,
00039                                                 CORBA::ULong &addr_list_length,
00040                                                 CORBA::ULong &addr_count
00041                                                 ACE_ENV_ARG_DECL)
00042   ACE_THROW_SPEC ((CORBA::SystemException))
00043 {
00044   char object_key_delimiter = '/';
00045 
00046   if (ACE_OS::strncmp (s, "uiop", 4) == 0)
00047       object_key_delimiter = '|';
00048 
00049   for (const char *i = s; *i != '\0'; ++i)
00050     {
00051       if (*i == ',')
00052         {
00053           // Increment the address count
00054           ++addr_count;
00055         }
00056 
00057       if (*i == ':'
00058           && *(i + 1) == '/'
00059           && *(i + 2) == '/')
00060         {
00061           if (TAO_debug_level > 0)
00062             ACE_ERROR((LM_ERROR,
00063                        ACE_TEXT ("TAO (%P|%t) Invalid Syntax: %s\n"),
00064                        s));
00065 
00066           ACE_THROW (CORBA::BAD_PARAM (CORBA::OMGVMCID | 10,
00067                                        CORBA::COMPLETED_NO));
00068         }
00069 
00070       if (*i == object_key_delimiter
00071           && *(i+1) != object_key_delimiter)
00072         {
00073           // Indication that the next characters are to be
00074           // assigned to key_string
00075           return;
00076         }
00077 
00078       ++addr_list_length;
00079     }
00080 }
00081 
00082 void
00083 TAO_CORBALOC_Parser::assign_key_string (char *& cloc_name_ptr,
00084                                         ACE_CString & key_string,
00085                                         CORBA::ULong
00086                                         &addr_list_length,
00087                                         CORBA::ORB_ptr orb,
00088                                         TAO_MProfile &mprofile
00089                                         ACE_ENV_ARG_DECL)
00090   ACE_THROW_SPEC ((CORBA::SystemException))
00091 {
00092   CORBA::String_var end_point;
00093   const char protocol_prefix[] = ":";
00094   const char protocol_suffix_append[] = "://";
00095   const char iiop_prefix[] = "iiop";
00096   const char uiop_prefix[] = "uiop";
00097   const char def_port[] = ":2809";
00098 
00099   // Copy the cloc_name_ptr to cloc_name_cstring.
00100   ACE_CString cloc_name_cstring (cloc_name_ptr,
00101                                  addr_list_length,
00102                                  0,
00103                                  1);
00104 
00105   // pos_colon is the position of the ':' in the iiop_id
00106   // <iiop_id> = ":" | <iiop_prot_token>":"
00107   int pos_colon = cloc_name_cstring.find (':', 0);
00108 
00109   if (ACE_OS::strncmp (cloc_name_ptr,
00110                        protocol_prefix,
00111                        sizeof (protocol_prefix) - 1) == 0)
00112     {
00113       // If there is no protocol explicitly specified then default to
00114       // "iiop".
00115       end_point = CORBA::string_alloc (addr_list_length
00116                                        + sizeof (iiop_prefix) - 1
00117                                        + 1  // Object key separator
00118                                        + 3  // "://"
00119                                        + sizeof (def_port) - 1
00120                                        + ACE_static_cast(CORBA::ULong,
00121                                              key_string.length ()));
00122 
00123       // Copy the default <iiop> prefix.
00124       ACE_OS::strcpy (end_point.inout (),
00125                       iiop_prefix);
00126 
00127       // Append '://'
00128       ACE_OS::strcat (end_point.inout (),
00129                       protocol_suffix_append);
00130     }
00131   else
00132     {
00133       // The case where the protocol to be used is explicitly
00134       // specified.
00135 
00136       // The space allocated for the default IIOP port is not needed
00137       // for all protocols, but it is only 5 bytes.  No biggy.
00138       end_point = CORBA::string_alloc (addr_list_length
00139                                        + 1  // Object key separator
00140                                        + 3  // "://"
00141                                        + sizeof (def_port) - 1
00142                                        + ACE_static_cast(CORBA::ULong,
00143                                              key_string.length ()));
00144 
00145       ACE_CString prot_name = cloc_name_cstring.substring (0,
00146                                                            pos_colon);
00147 
00148       // Form the endpoint
00149 
00150       // Example:
00151       // prot_name.c_str () = iiop
00152       ACE_OS::strcpy (end_point.inout (),
00153                       prot_name.c_str ());;
00154 
00155 
00156       // Example:
00157       // The endpoint will now be of the form 'iiop'
00158 
00159       ACE_OS::strcat (end_point.inout (),
00160                       protocol_suffix_append);
00161 
00162       // The endpoint will now be of the form 'iiop://'
00163     }
00164 
00165   ACE_CString addr =
00166     cloc_name_cstring.substring (pos_colon + 1, -1);
00167 
00168   ACE_OS::strcat (end_point.inout (),
00169                   addr.c_str ());
00170 
00171   // Check for an IIOP corbaloc IOR.  If the port number is not
00172   // specified, append the default corbaloc port number (i.e. "2809")
00173   if (ACE_OS::strncmp (end_point.in (),
00174                        iiop_prefix,
00175                        sizeof (iiop_prefix) - 1) == 0
00176       && addr.find (':') == ACE_CString::npos)
00177     ACE_OS::strcat (end_point.inout (), 
00178                     def_port);
00179 
00180   // Example:
00181   // The End_point will now be of the form
00182   //    'iiop://1.0@doc.ece.uci.edu:12345'
00183 
00184   if (ACE_OS::strncmp (cloc_name_ptr,
00185                        uiop_prefix,
00186                        sizeof (uiop_prefix) - 1) == 0)
00187     {
00188       // The separator for the uiop protocol is '|'. This should
00189       // actually be later changed so that the separator is '/' as the
00190       // other protocols.
00191       ACE_OS::strcat (end_point.inout (), "|");
00192     }
00193   else
00194     {
00195       ACE_OS::strcat (end_point.inout (), "/");
00196     }
00197 
00198   // Append the key string.
00199   ACE_OS::strcat (end_point.inout (),
00200                   key_string.c_str ());
00201 
00202   // Example: The End_point will now be of the form:
00203   // 'iiop://1.0@doc.ece.uci.edu:12345/object_name'
00204 
00205   // Call the mprofile helper which makes an mprofile for this
00206   // endpoint and adds it to the big mprofile.
00207   this->parse_string_mprofile_helper (end_point.in (),
00208                                       orb,
00209                                       mprofile
00210                                       ACE_ENV_ARG_PARAMETER);
00211   ACE_CHECK;
00212 }
00213 
00214 void
00215 TAO_CORBALOC_Parser::parse_string_assign_helper (
00216     ACE_CString &key_string,
00217     ACE_CString &cloc_name,
00218     CORBA::ORB_ptr orb,
00219     TAO_MProfile &mprofile
00220     ACE_ENV_ARG_DECL)
00221   ACE_THROW_SPEC ((CORBA::SystemException))
00222 {
00223   char *cloc_name_ptr = 0;
00224 
00225   // Tokenize using "," as the seperator
00226   char *last_addr = 0;
00227 
00228   cloc_name_ptr =
00229     ACE_OS::strtok_r (ACE_const_cast (char *, cloc_name.c_str ()),
00230                       ",",
00231                       &last_addr);
00232 
00233   CORBA::ULong length;
00234   while (cloc_name_ptr != 0)
00235     {
00236       length = ACE_static_cast(CORBA::ULong, ACE_OS::strlen (cloc_name_ptr));
00237       // Forms the endpoint and calls the mprofile_helper.
00238       this->assign_key_string (cloc_name_ptr,
00239                                key_string,
00240                                length,
00241                                orb,
00242                                mprofile
00243                                ACE_ENV_ARG_PARAMETER);
00244       ACE_CHECK;
00245 
00246       // Get the next token.
00247       cloc_name_ptr = ACE_OS::strtok_r (NULL,
00248                                         ",",
00249                                         &last_addr);
00250     }
00251 }
00252 
00253 
00254 void
00255 TAO_CORBALOC_Parser::parse_string_mprofile_helper (
00256     const char * end_point,
00257     CORBA::ORB_ptr orb,
00258     TAO_MProfile &mprofile
00259     ACE_ENV_ARG_DECL)
00260   ACE_THROW_SPEC ((CORBA::SystemException))
00261 {
00262   TAO_MProfile jth_mprofile;
00263 
00264   TAO_Connector_Registry *conn_reg =
00265     orb->orb_core ()->connector_registry (ACE_ENV_SINGLE_ARG_PARAMETER);
00266   ACE_CHECK;
00267 
00268   int retv =
00269     conn_reg->make_mprofile (end_point,
00270                              jth_mprofile
00271                              ACE_ENV_ARG_PARAMETER);
00272   ACE_CHECK;
00273 
00274   if (retv != 0)
00275     {
00276       ACE_THROW (CORBA::INV_OBJREF (
00277                    CORBA_SystemException::_tao_minor_code (
00278                       TAO_DEFAULT_MINOR_CODE,
00279                       EINVAL),
00280                    CORBA::COMPLETED_NO));
00281     }
00282 
00283   TAO_MProfile *jth_mprofile_ptr = &jth_mprofile;
00284 
00285   /// Add this profile to the main mprofile.
00286   int result = mprofile.add_profiles (jth_mprofile_ptr);
00287 
00288   if (result == -1)
00289     {
00290       // The profile is not added.  Either way, go to the next
00291       // endpoint.
00292     }
00293 }
00294 
00295 CORBA::Object_ptr
00296 TAO_CORBALOC_Parser::make_stub_from_mprofile (CORBA::ORB_ptr orb,
00297                                               TAO_MProfile &mprofile
00298                                               ACE_ENV_ARG_DECL)
00299   ACE_THROW_SPEC ((CORBA::SystemException))
00300 {
00301   // Create a TAO_Stub.
00302   TAO_Stub *data = orb->orb_core ()->create_stub ((const char *) 0,
00303                                                   mprofile
00304                                                   ACE_ENV_ARG_PARAMETER);
00305   ACE_CHECK_RETURN (CORBA::Object::_nil ());
00306 
00307   TAO_Stub_Auto_Ptr safe_data (data);
00308 
00309   CORBA::Object_var obj = orb->orb_core ()->create_object (data);
00310 
00311   if (!CORBA::is_nil (obj.in ()))
00312     {
00313       /// All is well, so release the stub object from its
00314       /// auto_ptr.
00315       (void) safe_data.release ();
00316 
00317       /// Return the object reference to the application.
00318       return obj._retn ();
00319     }
00320 
00321   /// Shouldnt come here: if so, return nil reference.
00322   return CORBA::Object::_nil ();
00323 }
00324 
00325 CORBA::Object_ptr
00326 TAO_CORBALOC_Parser::parse_string_rir_helper (const char *& corbaloc_name,
00327                                               CORBA::ORB_ptr orb
00328                                               ACE_ENV_ARG_DECL)
00329   ACE_THROW_SPEC ((CORBA::SystemException))
00330 {
00331 
00332 
00333   // "rir" protocol. Pass the key string as an
00334   // argument to the resolve_initial_references.
00335   const char *key_string = corbaloc_name + sizeof ("rir:/") -1;
00336 
00337   if (ACE_OS::strcmp (key_string, "") == 0)
00338     {
00339       // If the key string is empty, assume the default
00340       // "NameService".
00341       key_string =  "NameService";
00342     }
00343 
00344   CORBA::Object_var rir_obj =
00345     orb->resolve_initial_references (key_string
00346                                      ACE_ENV_ARG_PARAMETER);
00347   ACE_CHECK_RETURN (CORBA::Object::_nil ());
00348 
00349   return rir_obj._retn ();
00350 }
00351 
00352 int
00353 TAO_CORBALOC_Parser::check_prefix (const char *end_point
00354                                    ACE_ENV_ARG_DECL)
00355   ACE_THROW_SPEC ((CORBA::SystemException))
00356 {
00357 
00358   // This checks if the prefix is "rir:" or not. Returns a -1 if it is
00359   // "rir:" else returns a zero;
00360   // Check for a valid string
00361   if (!end_point || !*end_point)
00362     return -1; // Failure
00363 
00364   const char *protocol[] = {"rir:"};
00365   size_t slot = ACE_OS::strchr (end_point, '/') - end_point;
00366   size_t colon_slot = ACE_OS::strchr (end_point, ':') - end_point;
00367   size_t len0 = ACE_OS::strlen (protocol[0]);
00368 
00369   // Lets first check if it is a valid protocol:
00370   if (colon_slot != 0 &&
00371       !((ACE_OS::strncmp (end_point,
00372                          iiop_prefix,
00373                          sizeof iiop_prefix - 1) == 0) ||
00374 
00375         (ACE_OS::strncmp (end_point,
00376                           shmiop_prefix,
00377                           sizeof shmiop_prefix - 1) == 0) ||
00378 
00379         (ACE_OS::strncmp (end_point,
00380                           uiop_prefix,
00381                           sizeof uiop_prefix - 1) == 0) ||
00382 
00383         (ACE_OS::strncmp (end_point,
00384                           miop_prefix,
00385                           sizeof miop_prefix - 1) == 0) ||
00386 
00387         (ACE_OS::strncmp (end_point,
00388                           rir_prefix,
00389                           sizeof rir_prefix - 1) == 0)))
00390     {
00391       if (TAO_debug_level > 0)
00392         ACE_ERROR ((LM_ERROR,
00393                     ACE_TEXT ("TAO (%P|%t) ")
00394                     ACE_TEXT ("no usable transport protocol ")
00395                     ACE_TEXT ("was found.\n")));
00396 
00397       ACE_THROW_RETURN (CORBA::BAD_PARAM (CORBA::OMGVMCID | 10,
00398                                           CORBA::COMPLETED_NO),
00399                         -1);
00400     }
00401 
00402   // Check for the proper prefix in the IOR.  If the proper prefix
00403   // isn't in the IOR then it is not an IOR we can use.
00404   if (slot == len0
00405       && ACE_OS::strncasecmp (end_point, protocol[0], len0) == 0)
00406     return 0;
00407 
00408   return 1;
00409 }
00410 
00411 CORBA::Object_ptr
00412 TAO_CORBALOC_Parser::parse_string (const char * ior,
00413                                    CORBA::ORB_ptr orb
00414                                    ACE_ENV_ARG_DECL)
00415   ACE_THROW_SPEC ((CORBA::SystemException))
00416 {
00417   /// MProfile which consists of the profiles for each endpoint.
00418   TAO_MProfile mprofile;
00419 
00420   // Skip the prefix.  We know it is there because this method is only
00421   // called if match_prefix() returns 1.
00422   const char *corbaloc_name =
00423     ior + sizeof corbaloc_prefix - 1;
00424 
00425   CORBA::Object_ptr object = CORBA::Object::_nil ();
00426 
00427   // Number of endpoints
00428   CORBA::ULong count_addr = 1;
00429 
00430   // Length of obj_addr_list
00431   CORBA::ULong addr_list_length = 0;
00432 
00433   // If the protocol is not "rir:" and also is a valid protocol
00434   int check_prefix_result = this->check_prefix (corbaloc_name
00435                                                 ACE_ENV_ARG_PARAMETER);
00436   ACE_CHECK_RETURN (CORBA::Object::_nil ());
00437 
00438   if (check_prefix_result != 0)
00439     {
00440       // Count the length of the obj_addr_list and number of
00441       // endpoints in the obj_addr_list
00442       this->parse_string_count_helper (corbaloc_name,
00443                                        addr_list_length,
00444                                        count_addr
00445                                        ACE_ENV_ARG_PARAMETER);
00446       ACE_CHECK_RETURN (CORBA::Object::_nil ());
00447 
00448       // Convert corbaloc_name to an ACE_CString
00449       ACE_CString corbaloc_name_str (corbaloc_name, 0, 1);
00450 
00451       // Get the key_string which is a substring of corbaloc_name_str
00452       ACE_CString key_string =
00453         corbaloc_name_str.substring (addr_list_length + 1);
00454 
00455       // Copy the <obj_addr_list> to cloc_name.
00456       ACE_CString cloc_name (corbaloc_name,
00457                              addr_list_length,
00458                              0,
00459                              1);
00460 
00461       // Get each endpoint: For each endpoint, make a MProfile and add
00462       // it to the main MProfile whose reference is passed to the
00463       // application
00464       this->parse_string_assign_helper (key_string,
00465                                         cloc_name,
00466                                         orb,
00467                                         mprofile
00468                                         ACE_ENV_ARG_PARAMETER);
00469       ACE_CHECK_RETURN (CORBA::Object::_nil ());
00470 
00471       // Create the stub for the mprofile and get the object reference
00472       // to it which is to be returned to the client application.
00473       object = this->make_stub_from_mprofile (orb,
00474                                               mprofile
00475                                               ACE_ENV_ARG_PARAMETER);
00476       ACE_CHECK_RETURN (CORBA::Object::_nil ());
00477     }
00478   else
00479     {
00480       // RIR case:
00481       object = this->parse_string_rir_helper (corbaloc_name,
00482                                               orb
00483                                               ACE_ENV_ARG_PARAMETER);
00484       ACE_CHECK_RETURN (CORBA::Object::_nil ());
00485     }
00486   return object;
00487 }
00488 
00489 ACE_STATIC_SVC_DEFINE (TAO_CORBALOC_Parser,
00490                        ACE_TEXT ("CORBALOC_Parser"),
00491                        ACE_SVC_OBJ_T,
00492                        &ACE_SVC_NAME (TAO_CORBALOC_Parser),
00493                        ACE_Service_Type::DELETE_THIS |
00494                        ACE_Service_Type::DELETE_OBJ,
00495                        0)
00496 
00497 ACE_FACTORY_DEFINE (TAO, TAO_CORBALOC_Parser)
00498 
00499 #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
00500 template class ACE_Array_Base<char *>;
00501 #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
00502 #pragma instantiate ACE_Array_Base<char *>
00503 #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */

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