Profile.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file   Profile.h
00006  *
00007  *  $Id: Profile.h 81435 2008-04-25 07:27:57Z johnnyw $
00008  *
00009  *  @author Fred Kuhns <fredk@cs.wustl.edu>
00010  */
00011 //=============================================================================
00012 
00013 #ifndef TAO_PROFILE_H
00014 #define TAO_PROFILE_H
00015 
00016 #include /**/ "ace/pre.h"
00017 
00018 #include "tao/Tagged_Components.h"
00019 
00020 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00021 # pragma once
00022 #endif /* ACE_LACKS_PRAGMA_ONCE */
00023 
00024 #include "tao/GIOP_Message_Version.h"
00025 #include "tao/Refcounted_ObjectKey.h"
00026 #include "tao/Service_Callbacks.h"
00027 #include "tao/Configurable_Refcount.h"
00028 
00029 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00030 class ACE_Lock;
00031 ACE_END_VERSIONED_NAMESPACE_DECL
00032 
00033 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00034 
00035 class TAO_MProfile;
00036 class TAO_Stub;
00037 class TAO_Endpoint;
00038 class TAO_ORB_Core;
00039 
00040 namespace CORBA
00041 {
00042   /// Forward declaration of PolicyList
00043   class PolicyList;
00044 }
00045 
00046 /**
00047  * @class TAO_Profile
00048  *
00049  * @brief Defines the Profile interface
00050  *
00051  * An abstract base class for representing object location
00052  * information.  This is based on the CORBA IOR definitions.
00053  */
00054 class TAO_Export TAO_Profile
00055 {
00056 public:
00057 
00058   /// Constructor
00059   TAO_Profile (CORBA::ULong tag,
00060                TAO_ORB_Core *orb_core,
00061                const TAO_GIOP_Message_Version &version);
00062 
00063   /**
00064    * @name Non virtual methods for the profile classes.
00065   */
00066   //@{
00067   /// The tag, each concrete class will have a specific tag value.
00068   CORBA::ULong tag (void) const;
00069 
00070   /// Return a pointer to this profile's version.  This object
00071   /// maintains ownership.
00072   const TAO_GIOP_Message_Version &version (void) const;
00073 
00074   /// Get a pointer to the TAO_ORB_Core.
00075   TAO_ORB_Core *orb_core (void) const;
00076 
00077   /// Increase the reference count by one on this object.
00078   unsigned long _incr_refcnt (void);
00079 
00080   /// Decrement the object's reference count.  When this count goes to
00081   /// 0 this object will be deleted.
00082   unsigned long _decr_refcnt (void);
00083 
00084   /// Keep a pointer to the forwarded profile
00085   void forward_to (TAO_MProfile *mprofiles);
00086 
00087   /// MProfile accessor
00088   TAO_MProfile* forward_to (void);
00089 
00090   /// Access the tagged components, notice that they they could be
00091   /// empty (or ignored) for non-GIOP protocols (and even for GIOP-1.0)
00092   const TAO_Tagged_Components& tagged_components (void) const;
00093   TAO_Tagged_Components& tagged_components (void);
00094 
00095   /// Add the given tagged component to the profile.
00096   void add_tagged_component (const IOP::TaggedComponent &component);
00097 
00098   /**
00099    * Return the current addressing mode for this profile.
00100    * In almost all cases, this is TAO_Target_Specification::Key_Addr.
00101    */
00102   CORBA::Short addressing_mode (void) const;
00103 
00104   /// @deprecated Return a reference to the Object Key.
00105   const TAO::ObjectKey &object_key (void) const;
00106 
00107   /// Obtain the object key, return 0 if the profile cannot be parsed.
00108   /// The memory is owned by the caller!
00109   TAO::ObjectKey *_key (void) const;
00110   //@}
00111 
00112   /**
00113    * @name Template methods that needs to be implemented by the
00114    * concrete classes. Some of the methods may be overridden only
00115    * under specila circumstances.
00116    */
00117   //@{
00118   /// Encode this profile in a stream, i.e. marshal it.
00119   virtual int encode (TAO_OutputCDR &stream) const;
00120 
00121   /// Initialize this object using the given CDR octet string.
00122   virtual int decode (TAO_InputCDR& cdr);
00123 
00124   /**
00125    * This method is used to get the IOP::TaggedProfile. The profile
00126    * information that is received from the server side would have
00127    * already been decoded. So this method will just make a
00128    * IOP::TaggedProfile struct from the existing information and
00129    * return the reference to that. This method is necessary for GIOP
00130    * 1.2.
00131    */
00132   IOP::TaggedProfile *create_tagged_profile (void);
00133 
00134   /// This method sets the client exposed policies, i.e., the ones
00135   /// propagated in the IOR, for this profile.
00136   virtual void policies (CORBA::PolicyList *policy_list);
00137 
00138   /// Accessor for the client exposed policies of this profile.
00139   virtual void  get_policies (CORBA::PolicyList &policy_list);
00140 
00141   /// Returns true if this profile can specify multicast endpoints.
00142   virtual int supports_multicast (void) const;
00143 
00144   /// Returns true if this profile supports non blocking oneways
00145   virtual bool supports_non_blocking_oneways (void) const;
00146 
00147   /**
00148    * Set the addressing mode if a remote servant replies with
00149    * an addressing mode exception.  If this profile doesn't
00150    * support a particular addressing mode, this method needs to
00151    * be overridden signal the appropriate error.
00152    *
00153    * ** RACE CONDITION NOTE **
00154    *
00155    * Currently, getting and setting the addressing mode is not
00156    * protected by a mutex.  Theoretically, this could cause a race
00157    * condition if one thread sends a request, then gets an exception
00158    * from the remote servant to change the addressing mode, and then
00159    * another thread sends a different request to the same servant
00160    * using the wrong addressing mode.  The result of this is that
00161    * we'll get another address change exception.  (Annoying, but not
00162    * that bad.)
00163    *
00164    * In practice at the current time, the above theoretical case
00165    * never happens since the target specification always uses the
00166    * object key except for MIOP requests.  Remote ORBs can't respond
00167    * to MIOP requests even to send exceptions, so even in this case,
00168    * the race condition can't happen.
00169    *
00170    * Therefore, for the time being, there is no lock to protect the
00171    * addressing mode.  Given that the addressing mode is checked in
00172    * the critical path, this decision seems like a good thing.
00173    */
00174   virtual void addressing_mode (CORBA::Short addr_mode);
00175 
00176   /// The object key delimiter.
00177   virtual char object_key_delimiter (void) const = 0;
00178 
00179   /// Initialize this object using the given input string.
00180   /// Supports URL style of object references
00181   virtual void parse_string (const char *string);
00182 
00183   /// Return a string representation for this profile.  Client must
00184   /// deallocate memory. Only one endpoint is included into the
00185   /// string.
00186   virtual char* to_string (void) = 0;
00187 
00188   /**
00189    * Encodes this profile's endpoints into a tagged component.
00190    * This is done only if RTCORBA is enabled, since currently this is
00191    * the only case when we have more than one endpoint per profile.
00192    */
00193   virtual int encode_endpoints (void) = 0;
00194 
00195   /**
00196    * Encodes this profile's endpoints into protocol specific tagged
00197    * components. This is used for non-RTCORBA applications that share
00198    * endpoints on profiles. The only known implementation is IIOP, using
00199    * TAG_ALTERNATE_IIOP_ADDRESS components.
00200    */
00201   virtual int encode_alternate_endpoints (void);
00202 
00203   /**
00204    * Return a pointer to this profile's endpoint.  If the profile
00205    * contains more than one endpoint, i.e., a list, the method returns
00206    * the head of the list.
00207    */
00208   virtual TAO_Endpoint *endpoint (void) = 0;
00209 
00210 
00211   /**
00212    * Return a pointer to this profile's endpoint.  If the most derived
00213    * profile type uses an endpoint that is a type that does not derive
00214    * from the endpoint type of the base profile, then this method returns
00215    * the base type's endpoint. For example, SSLIOP_Profile derives from
00216    * IIOP_Profile, but SSLIOP_Endpoint does not derive from IIOP_Endpoint.
00217    * Because SSLIOP is tagged the same as IIOP, this method is required
00218    * to facilitate the Endpoint Policy's filtering function.
00219    * The default implementation of base_endpoint simply returns endpoint.
00220    */
00221   virtual TAO_Endpoint *base_endpoint (void);
00222 
00223   /// Return how many endpoints this profile contains.
00224   virtual CORBA::ULong endpoint_count (void) const = 0;
00225 
00226   /**
00227    * Return the first endpoint in the list that matches some filtering
00228    * constraint, such as IPv6 compatibility for IIOP endpoints. This
00229    * method is implemented in terms of TAO_Endpoint::next_filtered().
00230    */
00231   TAO_Endpoint *first_filtered_endpoint (void);
00232 
00233   /// Return the next filtered endpoint in the list after the one
00234   /// passed in. This method is implemented in terms of
00235   /// TAO_Endpoint;:next_filtered(). If the supplied source endpoint
00236   /// is null, this returns the first filtered endpoint.
00237   TAO_Endpoint *next_filtered_endpoint (TAO_Endpoint *source);
00238 
00239   /**
00240    * Remove the provided endpoint from the profile. Some
00241    * subclasses of TAO_Profile already have a protocol-specific
00242    * version of remove_endpoint, but this generic interface is
00243    * required. The default implementation is a no-op. Protocol
00244    * maintainers wishing to add support for the EndpointPolicy must
00245    * implement remove_generic_endpoint to call their protocol-specific
00246    * version of remove_endpoint
00247    */
00248   virtual void remove_generic_endpoint (TAO_Endpoint *ep);
00249 
00250   /// Add a protocol-agnostic endpoint
00251   virtual void add_generic_endpoint (TAO_Endpoint *ep);
00252 
00253   /// Verify profile equivalance.
00254   /**
00255    * Two profiles are equivalent if their tag, object_key, version
00256    * and all endpoints are the same.
00257    *
00258    * @see do_is_equivalent_i()
00259    * @see is_equivalent_hook()
00260    *
00261    * @return @c true if this profile is equivalent to @c other_profile.
00262    */
00263   CORBA::Boolean is_equivalent (const TAO_Profile* other_profile);
00264 
00265   /**
00266    * Compare the object key for this profile with that of
00267    * another. This is weaker than is_equivalent
00268    */
00269   CORBA::Boolean compare_key (const TAO_Profile *other) const;
00270 
00271   /// Return a hash value for this object.
00272   virtual CORBA::ULong hash (CORBA::ULong max) = 0;
00273   //@}
00274 
00275   //@@ TAO_PROFILE_SPL_PUBLIC_METHODS_ADD_HOOK
00276 
00277 protected:
00278   /// If you have a virtual method you need a virtual dtor.
00279   virtual ~TAO_Profile (void);
00280 
00281   /**
00282    * @name Protected template methods.
00283    */
00284   //@{
00285   /// Decode the protocol specific profile details.
00286   virtual int decode_profile (TAO_InputCDR &cdr) = 0;
00287 
00288   /// Creates an encapsulation of the ProfileBody struct in the @a cdr
00289   virtual void create_profile_body (TAO_OutputCDR &cdr) const = 0;
00290 
00291   /**
00292    * Helper for decode().  Decodes endpoints from a tagged component.
00293    * Decode only if RTCORBA is enabled.  Furthermore, we may not find
00294    * TAO_TAG_ENDPOINTS component, e.g., if we are talking to nonRT
00295    * version of TAO or some other ORB.  This is not an error, and we
00296    * must proceed.  Return 0 on success and -1 on failure.
00297    */
00298   virtual int decode_endpoints (void) = 0;
00299 
00300   /// Protocol specific implementation of parse_string ()
00301   virtual void parse_string_i (const char *string) = 0;
00302   //@}
00303 
00304   /// To be used by inherited classes
00305   TAO_Profile (CORBA::ULong tag,
00306                TAO_ORB_Core *orb_core,
00307                const TAO::ObjectKey &key,
00308                const TAO_GIOP_Message_Version &version);
00309 
00310   /// Helper method that encodes the endpoints for RTCORBA as
00311   /// tagged_components.
00312   void set_tagged_components (TAO_OutputCDR &cdr);
00313 
00314   /// Profile equivalence template method invoked on subclasses.
00315   /**
00316    * TAO_Profile subclasses must implement this template method so
00317    * that they can apply their own definition of profile equivalence.
00318    */
00319   virtual CORBA::Boolean do_is_equivalent (const TAO_Profile * other) = 0;
00320 
00321   /// Allow services to apply their own definition of "equivalence."
00322   /**
00323    * This method differs from the @c do_is_equivalent() template
00324    * method in that it has a default implementation that may or not be
00325    * applicable to all TAO_Profile subclasses.
00326    */
00327   virtual TAO_Service_Callbacks::Profile_Equivalence is_equivalent_hook (
00328                                             const TAO_Profile * other);
00329 
00330   CORBA::ULong hash_service_i (CORBA::ULong m);
00331 
00332 private:
00333 
00334   /// This object keeps ownership of this object
00335   TAO_MProfile *forward_to_i (void);
00336 
00337   /// Verify that the current ORB's configuration supports tagged
00338   /// components in IORs.
00339   void verify_orb_configuration (void);
00340 
00341   /// Verify that the given profile supports tagged components,
00342   /// i.e. is not a GIOP 1.0 profile.
00343   void verify_profile_version (void);
00344 
00345   // Profiles should not be copied or assigned!
00346   TAO_Profile (const TAO_Profile&);
00347   void operator= (const TAO_Profile&);
00348 
00349   //@@ TAO_PROFILE_SPL_PROTECTED_METHODS_ADD_HOOK
00350 
00351 protected:
00352 
00353   /// IIOP version number.
00354   TAO_GIOP_Message_Version version_;
00355 
00356   /// The tagged components
00357   TAO_Tagged_Components tagged_components_;
00358 
00359   /// Flag indicating whether the lazy decoding of the client exposed
00360   /// policies has taken place.
00361   CORBA::Boolean are_policies_parsed_;
00362 
00363   /// The current addressing mode.
00364   /// This may be changed if a remote server sends back an address mode
00365   /// exception.
00366   CORBA::Short addressing_mode_;
00367 
00368   /// Our tagged profile
00369   IOP::TaggedProfile *tagged_profile_;
00370 
00371   /// Object_key associated with this profile.
00372   TAO::Refcounted_ObjectKey *ref_object_key_;
00373 
00374 private:
00375   /// IOP protocol tag.
00376   CORBA::ULong const tag_;
00377 
00378   /// Pointer to the ORB core
00379   TAO_ORB_Core * const orb_core_;
00380 
00381   /// The TAO_MProfile which contains the profiles for the forwarded
00382   /// object.
00383   TAO_MProfile* forward_to_;
00384 
00385   /// Number of outstanding references to this object.
00386   TAO_Configurable_Refcount refcount_;
00387 
00388   /// A lock that protects creation of the tagged profile
00389   TAO_SYNCH_MUTEX tagged_profile_lock_;
00390 
00391   /// Having (tagged_profile_ != 0) doesn't mean yet that
00392   /// tagged_profile_ building is finished.
00393   bool tagged_profile_created_;
00394 
00395   //@@ TAO_PROFILE_SPL_PRIVATE_DATA_ADD_HOOK
00396 };
00397 
00398 //@@ TAO_PROFILE_SPL_EXTERN_ADD_HOOK
00399 
00400 // A helper class to handle the various kinds of octet sequences used
00401 // inside the ORB.
00402 
00403 typedef TAO::unbounded_value_sequence<CORBA::Octet> TAO_opaque;
00404 
00405 TAO_Export CORBA::Boolean
00406 operator<< (TAO_OutputCDR&, const TAO_opaque&);
00407 
00408 TAO_Export CORBA::Boolean
00409 operator>> (TAO_InputCDR&, TAO_opaque&);
00410 
00411 /**
00412  * @class TAO_Unknown_Profile
00413  *
00414  * @brief A TAO_Profile class to handle foreign profiles.
00415  *
00416  * The CORBA spec implies that ORBs must be prepared to save and
00417  * pass around profiles for protocols it does not recognize. It is
00418  * not mandatory to *use* those profiles but they shouldn't be
00419  * dropped.
00420  * This class stores the information required to marshal and
00421  * demarshal an unknown profile, but simply returns an error if
00422  * any of the TAO internal methods are invoked.
00423  */
00424 class TAO_Export TAO_Unknown_Profile : public TAO_Profile
00425 {
00426 public:
00427   /// Create the profile
00428   TAO_Unknown_Profile (CORBA::ULong tag,
00429                        TAO_ORB_Core *orb_core);
00430 
00431   // = The TAO_Profile methods look above
00432   virtual void parse_string (const char *string);
00433   virtual char object_key_delimiter (void) const;
00434   virtual char* to_string (void);
00435   virtual int decode (TAO_InputCDR& cdr);
00436   virtual int encode (TAO_OutputCDR &stream) const;
00437   virtual int encode_endpoints (void);
00438 
00439   virtual TAO::ObjectKey *_key (void) const;
00440   virtual TAO_Endpoint *endpoint (void);
00441   virtual CORBA::ULong endpoint_count (void) const;
00442   virtual CORBA::ULong hash (CORBA::ULong max);
00443 
00444   virtual int decode_profile (TAO_InputCDR &cdr);
00445   virtual int decode_endpoints (void);
00446 
00447 protected:
00448 
00449   virtual CORBA::Boolean do_is_equivalent (const TAO_Profile* other_profile);
00450   virtual TAO_Service_Callbacks::Profile_Equivalence is_equivalent_hook (
00451                                            const TAO_Profile* other_profile);
00452 
00453 private:
00454   virtual void create_profile_body (TAO_OutputCDR &encap) const;
00455 
00456   virtual void parse_string_i (const char *string);
00457 private:
00458   TAO_opaque body_;
00459 };
00460 
00461 //@@ TAO_PROFILE_SPL_EXTERN_HOOK
00462 
00463 TAO_END_VERSIONED_NAMESPACE_DECL
00464 
00465 #if defined (__ACE_INLINE__)
00466 # include "tao/Profile.inl"
00467 #endif /* __ACE_INLINE__ */
00468 
00469 #include /**/ "ace/post.h"
00470 
00471 #endif  /* TAO_PROFILE_H */

Generated on Tue Feb 2 17:37:52 2010 for TAO by  doxygen 1.4.7