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