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 */