Profile.h

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

Generated on Thu Nov 9 11:54:21 2006 for TAO by doxygen 1.3.6