3 //=============================================================================
7 * @author Fred Kuhns <fredk@cs.wustl.edu>
9 //=============================================================================
14 #include /**/ "ace/pre.h"
16 #include "tao/Tagged_Components.h"
18 #if !defined (ACE_LACKS_PRAGMA_ONCE)
20 #endif /* ACE_LACKS_PRAGMA_ONCE */
22 #include "tao/GIOP_Message_Version.h"
23 #include "tao/Refcounted_ObjectKey.h"
24 #include "tao/Service_Callbacks.h"
27 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
29 ACE_END_VERSIONED_NAMESPACE_DECL
31 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
40 /// Forward declaration of PolicyList
47 * @brief Defines the Profile interface
49 * An abstract base class for representing object location
50 * information. This is based on the CORBA IOR definitions.
52 class TAO_Export TAO_Profile
56 TAO_Profile (CORBA::ULong tag
,
57 TAO_ORB_Core
*orb_core
,
58 const TAO_GIOP_Message_Version
&version
);
61 * @name Non virtual methods for the profile classes.
64 /// The tag, each concrete class will have a specific tag value.
65 CORBA::ULong
tag () const;
67 /// Return a pointer to this profile's version. This object
68 /// maintains ownership.
69 const TAO_GIOP_Message_Version
&version () const;
71 /// Get a pointer to the TAO_ORB_Core.
72 TAO_ORB_Core
*orb_core () const;
74 /// Increase the reference count by one on this object.
75 unsigned long _incr_refcnt ();
77 /// Decrement the object's reference count. When this count goes to
78 /// 0 this object will be deleted.
79 unsigned long _decr_refcnt ();
81 /// Keep a pointer to the forwarded profile
82 void forward_to (TAO_MProfile
*mprofiles
);
85 TAO_MProfile
* forward_to ();
87 /// Access the tagged components, notice that they they could be
88 /// empty (or ignored) for non-GIOP protocols (and even for GIOP-1.0)
89 const TAO_Tagged_Components
& tagged_components () const;
90 TAO_Tagged_Components
& tagged_components ();
92 /// Add the given tagged component to the profile.
93 void add_tagged_component (const IOP::TaggedComponent
&component
);
96 * Return the current addressing mode for this profile.
97 * In almost all cases, this is TAO_Target_Specification::Key_Addr.
99 CORBA::Short
addressing_mode () const;
101 /// @deprecated Return a reference to the Object Key.
102 const TAO::ObjectKey
&object_key () const;
104 /// Obtain the object key, return 0 if the profile cannot be parsed.
105 /// The memory is owned by the caller!
106 TAO::ObjectKey
*_key () const;
110 * @name Template methods that needs to be implemented by the
111 * concrete classes. Some of the methods may be overridden only
112 * under specila circumstances.
115 /// Encode this profile in a stream, i.e. marshal it.
116 virtual int encode (TAO_OutputCDR
&stream
) const;
118 /// Initialize this object using the given CDR octet string.
119 virtual int decode (TAO_InputCDR
& cdr
);
122 * This method is used to get the IOP::TaggedProfile. The profile
123 * information that is received from the server side would have
124 * already been decoded. So this method will just make a
125 * IOP::TaggedProfile struct from the existing information and
126 * return the reference to that. This method is necessary for GIOP
129 IOP::TaggedProfile
*create_tagged_profile ();
131 /// This method sets the client exposed policies, i.e., the ones
132 /// propagated in the IOR, for this profile.
133 virtual void policies (CORBA::PolicyList
*policy_list
);
135 /// Accessor for the client exposed policies of this profile.
136 virtual void get_policies (CORBA::PolicyList
&policy_list
);
138 /// Returns true if this profile can specify multicast endpoints.
139 virtual int supports_multicast () const;
141 /// Returns true if this profile supports non blocking oneways
142 virtual bool supports_non_blocking_oneways () const;
145 * Set the addressing mode if a remote servant replies with
146 * an addressing mode exception. If this profile doesn't
147 * support a particular addressing mode, this method needs to
148 * be overridden signal the appropriate error.
150 * ** RACE CONDITION NOTE **
152 * Currently, getting and setting the addressing mode is not
153 * protected by a mutex. Theoretically, this could cause a race
154 * condition if one thread sends a request, then gets an exception
155 * from the remote servant to change the addressing mode, and then
156 * another thread sends a different request to the same servant
157 * using the wrong addressing mode. The result of this is that
158 * we'll get another address change exception. (Annoying, but not
161 * In practice at the current time, the above theoretical case
162 * never happens since the target specification always uses the
163 * object key except for MIOP requests. Remote ORBs can't respond
164 * to MIOP requests even to send exceptions, so even in this case,
165 * the race condition can't happen.
167 * Therefore, for the time being, there is no lock to protect the
168 * addressing mode. Given that the addressing mode is checked in
169 * the critical path, this decision seems like a good thing.
171 virtual void addressing_mode (CORBA::Short addr_mode
);
173 /// The object key delimiter.
174 virtual char object_key_delimiter () const = 0;
176 /// Initialize this object using the given input string.
177 /// Supports URL style of object references
178 virtual void parse_string (const char *string
);
180 /// Return a string representation for this profile. Client must
181 /// deallocate memory. Only one endpoint is included into the
183 virtual char* to_string () const = 0;
186 * Encodes this profile's endpoints into a tagged component.
187 * This is done only if RTCORBA is enabled, since currently this is
188 * the only case when we have more than one endpoint per profile.
190 virtual int encode_endpoints () = 0;
193 * Encodes this profile's endpoints into protocol specific tagged
194 * components. This is used for non-RTCORBA applications that share
195 * endpoints on profiles. The only known implementation is IIOP, using
196 * TAG_ALTERNATE_IIOP_ADDRESS components.
198 virtual int encode_alternate_endpoints ();
201 * Return a pointer to this profile's endpoint. If the profile
202 * contains more than one endpoint, i.e., a list, the method returns
203 * the head of the list.
205 virtual TAO_Endpoint
*endpoint () = 0;
209 * Return a pointer to this profile's endpoint. If the most derived
210 * profile type uses an endpoint that is a type that does not derive
211 * from the endpoint type of the base profile, then this method returns
212 * the base type's endpoint. For example, SSLIOP_Profile derives from
213 * IIOP_Profile, but SSLIOP_Endpoint does not derive from IIOP_Endpoint.
214 * Because SSLIOP is tagged the same as IIOP, this method is required
215 * to facilitate the Endpoint Policy's filtering function.
216 * The default implementation of base_endpoint simply returns endpoint.
218 virtual TAO_Endpoint
*base_endpoint ();
220 /// Return how many endpoints this profile contains.
221 virtual CORBA::ULong
endpoint_count () const = 0;
224 * Return the first endpoint in the list that matches some filtering
225 * constraint, such as IPv6 compatibility for IIOP endpoints. This
226 * method is implemented in terms of TAO_Endpoint::next_filtered().
228 TAO_Endpoint
*first_filtered_endpoint ();
230 /// Return the next filtered endpoint in the list after the one
231 /// passed in. This method is implemented in terms of
232 /// TAO_Endpoint;:next_filtered(). If the supplied source endpoint
233 /// is null, this returns the first filtered endpoint.
234 TAO_Endpoint
*next_filtered_endpoint (TAO_Endpoint
*source
);
237 * Remove the provided endpoint from the profile. Some
238 * subclasses of TAO_Profile already have a protocol-specific
239 * version of remove_endpoint, but this generic interface is
240 * required. The default implementation is a no-op. Protocol
241 * maintainers wishing to add support for the EndpointPolicy must
242 * implement remove_generic_endpoint to call their protocol-specific
243 * version of remove_endpoint
245 virtual void remove_generic_endpoint (TAO_Endpoint
*ep
);
247 /// Add a protocol-agnostic endpoint
248 virtual void add_generic_endpoint (TAO_Endpoint
*ep
);
250 /// Verify profile equivalance.
252 * Two profiles are equivalent if their tag, object_key, version
253 * and all endpoints are the same.
255 * @see do_is_equivalent_i()
256 * @see is_equivalent_hook()
258 * @return @c true if this profile is equivalent to @c other_profile.
260 CORBA::Boolean
is_equivalent (const TAO_Profile
* other_profile
);
263 * Compare the object key for this profile with that of
264 * another. This is weaker than is_equivalent
266 CORBA::Boolean
compare_key (const TAO_Profile
*other
) const;
268 /// Return a hash value for this object.
269 virtual CORBA::ULong
hash (CORBA::ULong max
) = 0;
273 /// If you have a virtual method you need a virtual dtor.
274 virtual ~TAO_Profile ();
277 * @name Protected template methods.
280 /// Decode the protocol specific profile details.
281 virtual int decode_profile (TAO_InputCDR
&cdr
) = 0;
283 /// Creates an encapsulation of the ProfileBody struct in the @a cdr
284 virtual void create_profile_body (TAO_OutputCDR
&cdr
) const = 0;
287 * Helper for decode(). Decodes endpoints from a tagged component.
288 * Decode only if RTCORBA is enabled. Furthermore, we may not find
289 * TAO_TAG_ENDPOINTS component, e.g., if we are talking to nonRT
290 * version of TAO or some other ORB. This is not an error, and we
291 * must proceed. Return 0 on success and -1 on failure.
293 virtual int decode_endpoints () = 0;
295 /// Protocol specific implementation of parse_string ()
296 virtual void parse_string_i (const char *string
) = 0;
299 /// To be used by inherited classes
300 TAO_Profile (CORBA::ULong tag
,
301 TAO_ORB_Core
*orb_core
,
302 const TAO::ObjectKey
&key
,
303 const TAO_GIOP_Message_Version
&version
);
305 /// Helper method that encodes the endpoints for RTCORBA as
306 /// tagged_components.
307 void set_tagged_components (TAO_OutputCDR
&cdr
);
309 /// Profile equivalence template method invoked on subclasses.
311 * TAO_Profile subclasses must implement this template method so
312 * that they can apply their own definition of profile equivalence.
314 virtual CORBA::Boolean
do_is_equivalent (const TAO_Profile
* other
) = 0;
316 /// Allow services to apply their own definition of "equivalence."
318 * This method differs from the @c do_is_equivalent() template
319 * method in that it has a default implementation that may or not be
320 * applicable to all TAO_Profile subclasses.
322 virtual TAO_Service_Callbacks::Profile_Equivalence
is_equivalent_hook (
323 const TAO_Profile
* other
);
325 CORBA::ULong
hash_service_i (CORBA::ULong m
);
328 /// This object keeps ownership of this object
329 TAO_MProfile
*forward_to_i ();
331 /// Verify that the current ORB's configuration supports tagged
332 /// components in IORs.
333 void verify_orb_configuration ();
335 /// Verify that the given profile supports tagged components,
336 /// i.e. is not a GIOP 1.0 profile.
337 void verify_profile_version ();
339 // Profiles should not be copied or assigned!
340 TAO_Profile (const TAO_Profile
&);
341 void operator= (const TAO_Profile
&);
344 /// IIOP version number.
345 TAO_GIOP_Message_Version version_
;
347 /// The tagged components
348 TAO_Tagged_Components tagged_components_
;
350 /// Flag indicating whether the lazy decoding of the client exposed
351 /// policies has taken place.
352 CORBA::Boolean are_policies_parsed_
;
354 /// The current addressing mode.
355 /// This may be changed if a remote server sends back an address mode
357 CORBA::Short addressing_mode_
;
359 /// Our tagged profile
360 IOP::TaggedProfile
*tagged_profile_
;
362 /// Object_key associated with this profile.
363 TAO::Refcounted_ObjectKey
*ref_object_key_
;
366 /// IOP protocol tag.
367 CORBA::ULong
const tag_
;
369 /// Pointer to the ORB core
370 TAO_ORB_Core
* const orb_core_
;
372 /// The TAO_MProfile which contains the profiles for the forwarded
374 TAO_MProfile
* forward_to_
;
376 /// Number of outstanding references to this object.
377 std::atomic
<uint32_t> refcount_
;
379 /// A lock that protects creation of the tagged profile
380 TAO_SYNCH_MUTEX tagged_profile_lock_
;
382 /// Having (tagged_profile_ != 0) doesn't mean yet that
383 /// tagged_profile_ building is finished.
384 bool tagged_profile_created_
;
387 // A helper class to handle the various kinds of octet sequences used
389 typedef TAO::unbounded_value_sequence
<CORBA::Octet
> TAO_opaque
;
391 TAO_Export
CORBA::Boolean
392 operator<< (TAO_OutputCDR
&, const TAO_opaque
&);
394 TAO_Export
CORBA::Boolean
395 operator>> (TAO_InputCDR
&, TAO_opaque
&);
398 * @class TAO_Unknown_Profile
400 * @brief A TAO_Profile class to handle foreign profiles.
402 * The CORBA spec implies that ORBs must be prepared to save and
403 * pass around profiles for protocols it does not recognize. It is
404 * not mandatory to *use* those profiles but they shouldn't be
406 * This class stores the information required to marshal and
407 * demarshal an unknown profile, but simply returns an error if
408 * any of the TAO internal methods are invoked.
410 class TAO_Export TAO_Unknown_Profile
: public TAO_Profile
413 /// Create the profile
414 TAO_Unknown_Profile (CORBA::ULong tag
,
415 TAO_ORB_Core
*orb_core
);
417 // = The TAO_Profile methods look above
418 virtual void parse_string (const char *string
);
419 virtual char object_key_delimiter () const;
420 virtual char* to_string () const;
421 virtual int decode (TAO_InputCDR
& cdr
);
422 virtual int encode (TAO_OutputCDR
&stream
) const;
423 virtual int encode_endpoints ();
425 virtual TAO::ObjectKey
*_key () const;
426 virtual TAO_Endpoint
*endpoint ();
427 virtual CORBA::ULong
endpoint_count () const;
428 virtual CORBA::ULong
hash (CORBA::ULong max
);
430 virtual int decode_profile (TAO_InputCDR
&cdr
);
431 virtual int decode_endpoints ();
434 virtual CORBA::Boolean
do_is_equivalent (const TAO_Profile
* other_profile
);
435 virtual TAO_Service_Callbacks::Profile_Equivalence
is_equivalent_hook (
436 const TAO_Profile
* other_profile
);
439 virtual void create_profile_body (TAO_OutputCDR
&encap
) const;
441 virtual void parse_string_i (const char *string
);
446 TAO_END_VERSIONED_NAMESPACE_DECL
448 #if defined (__ACE_INLINE__)
449 # include "tao/Profile.inl"
450 #endif /* __ACE_INLINE__ */
452 #include /**/ "ace/post.h"
454 #endif /* TAO_PROFILE_H */