Revert "Minor modernization of DynamicAny code"
[ACE_TAO.git] / TAO / tao / Profile.h
blob86486eab8541f603ce308f6b8b87301c756bd552
1 // -*- C++ -*-
3 //=============================================================================
4 /**
5 * @file Profile.h
7 * @author Fred Kuhns <fredk@cs.wustl.edu>
8 */
9 //=============================================================================
11 #ifndef TAO_PROFILE_H
12 #define TAO_PROFILE_H
14 #include /**/ "ace/pre.h"
16 #include "tao/Tagged_Components.h"
18 #if !defined (ACE_LACKS_PRAGMA_ONCE)
19 # 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"
25 #include <atomic>
27 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
28 class ACE_Lock;
29 ACE_END_VERSIONED_NAMESPACE_DECL
31 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
33 class TAO_MProfile;
34 class TAO_Stub;
35 class TAO_Endpoint;
36 class TAO_ORB_Core;
38 namespace CORBA
40 /// Forward declaration of PolicyList
41 class PolicyList;
44 /**
45 * @class TAO_Profile
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
54 public:
55 /// Constructor
56 TAO_Profile (CORBA::ULong tag,
57 TAO_ORB_Core *orb_core,
58 const TAO_GIOP_Message_Version &version);
60 /**
61 * @name Non virtual methods for the profile classes.
63 //@{
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);
84 /// MProfile accessor
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);
95 /**
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;
107 //@}
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.
114 //@{
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
127 * 1.2.
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
159 * that bad.)
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
182 /// string.
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;
270 //@}
272 protected:
273 /// If you have a virtual method you need a virtual dtor.
274 virtual ~TAO_Profile ();
277 * @name Protected template methods.
279 //@{
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;
297 //@}
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);
327 private:
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&);
343 protected:
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
356 /// exception.
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_;
365 private:
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
373 /// object.
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
388 // inside the ORB.
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
405 * dropped.
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
412 public:
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 ();
433 protected:
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);
438 private:
439 virtual void create_profile_body (TAO_OutputCDR &encap) const;
441 virtual void parse_string_i (const char *string);
442 private:
443 TAO_opaque body_;
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 */