summaryrefslogtreecommitdiff
path: root/TAO/tao/PI/ClientRequestInterceptor_Adapter_Impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/tao/PI/ClientRequestInterceptor_Adapter_Impl.cpp')
-rw-r--r--TAO/tao/PI/ClientRequestInterceptor_Adapter_Impl.cpp348
1 files changed, 348 insertions, 0 deletions
diff --git a/TAO/tao/PI/ClientRequestInterceptor_Adapter_Impl.cpp b/TAO/tao/PI/ClientRequestInterceptor_Adapter_Impl.cpp
new file mode 100644
index 00000000000..1d1dd7429b2
--- /dev/null
+++ b/TAO/tao/PI/ClientRequestInterceptor_Adapter_Impl.cpp
@@ -0,0 +1,348 @@
+#include "tao/PI/ClientRequestInterceptor_Adapter_Impl.h"
+
+#if TAO_HAS_INTERCEPTORS == 1
+
+#if !defined (__ACE_INLINE__)
+#include "tao/PI/ClientRequestInterceptor_Adapter_Impl.inl"
+#endif /* defined INLINE */
+
+#include "tao/PI/ClientRequestInfo.h"
+
+#include "tao/Invocation_Base.h"
+#include "tao/ORB_Core.h"
+#include "tao/ORB_Core_TSS_Resources.h"
+#include "tao/PortableInterceptorC.h"
+
+ACE_RCSID (PI,
+ ClientRequestInterceptorAdapter_Impl,
+ "$Id$")
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+ void
+ ClientRequestInterceptor_Adapter_Impl::send_request (
+ Invocation_Base &invocation
+ ACE_ENV_ARG_DECL)
+ {
+ // This method implements one of the "starting" client side
+ // interception point.
+
+ bool const is_remote_request = invocation.is_remote_request();
+
+ ACE_TRY
+ {
+ TAO_ClientRequestInfo ri (&invocation);
+
+ for (size_t i = 0 ; i < this->interceptor_list_.size (); ++i)
+ {
+ ClientRequestInterceptor_List::RegisteredInterceptor& registered =
+ this->interceptor_list_.registered_interceptor (i);
+
+ if (registered.details_.should_be_processed (is_remote_request))
+ {
+ registered.interceptor_->
+ send_request (&ri
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // The starting interception point completed successfully.
+ // Push the interceptor on to the flow stack.
+ ++invocation.stack_size ();
+ }
+ }
+ ACE_CATCH (PortableInterceptor::ForwardRequest, exc)
+ {
+ this->process_forward_request (invocation,
+ exc
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
+ }
+
+ void
+ ClientRequestInterceptor_Adapter_Impl::receive_reply (
+ Invocation_Base &invocation
+ ACE_ENV_ARG_DECL)
+ {
+ // This is an "ending" interception point so we only process the
+ // interceptors pushed on to the flow stack.
+
+ bool const is_remote_request = invocation.is_remote_request();
+
+ // Notice that the interceptors are processed in the opposite order
+ // they were pushed onto the stack since this is an "ending"
+ // interception point.
+
+ TAO_ClientRequestInfo ri (&invocation);
+
+ // Unwind the stack.
+ size_t const len = invocation.stack_size ();
+ for (size_t i = 0; i < len; ++i)
+ {
+ // Pop the interceptor off of the flow stack before it is
+ // invoked. This is necessary to prevent an interceptor already
+ // invoked in this "ending" interception point from being
+ // invoked in another "ending" interception point.
+ --invocation.stack_size ();
+
+ ClientRequestInterceptor_List::RegisteredInterceptor& registered =
+ this->interceptor_list_.registered_interceptor (
+ invocation.stack_size ());
+
+ if (registered.details_.should_be_processed (is_remote_request))
+ {
+ registered.interceptor_->
+ receive_reply (
+ &ri
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ }
+
+ // The receive_reply() interception point does not raise a
+ // PortableInterceptor::ForwardRequest exception so there is no need
+ // to attempt to catch it here.
+ }
+
+ void
+ ClientRequestInterceptor_Adapter_Impl::receive_exception (
+ Invocation_Base &invocation
+ ACE_ENV_ARG_DECL)
+ {
+ // This is an "ending" interception point so we only process the
+ // interceptors pushed on to the flow stack.
+
+ bool const is_remote_request = invocation.is_remote_request();
+
+ // Notice that the interceptors are processed in the opposite order
+ // they were pushed onto the stack since this is an "ending"
+ // interception point.
+ ACE_TRY
+ {
+ TAO_ClientRequestInfo ri (&invocation);
+
+ // Unwind the flow stack.
+ size_t const len = invocation.stack_size ();
+ for (size_t i = 0; i < len; ++i)
+ {
+ // Pop the interceptor off of the flow stack before it is
+ // invoked. This is necessary to prevent an interceptor
+ // already invoked in this "ending" interception point from
+ // being invoked in another "ending" interception point.
+ --invocation.stack_size ();
+
+ ClientRequestInterceptor_List::RegisteredInterceptor& registered =
+ this->interceptor_list_.registered_interceptor (
+ invocation.stack_size ());
+
+ if (registered.details_.should_be_processed (is_remote_request))
+ {
+ registered.interceptor_->
+ receive_exception (
+ &ri
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ }
+ }
+ ACE_CATCH (PortableInterceptor::ForwardRequest, exc)
+ {
+ this->process_forward_request (invocation,
+ exc
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ // The receive_exception() interception point in the remaining
+ // interceptors must be called so call this method (not the
+ // interceptor's corresponding method) recursively. The call is
+ // made recursively since the caught exception must survive
+ // until the remaining interceptors have been called.
+
+ // Note that the recursion will stop once the flow stack size
+ // drops to zero, i.e., once each interceptor has been invoked.
+ // This prevents infinite recursion from occuring.
+
+ invocation.exception (&ACE_ANY_EXCEPTION);
+
+ this->receive_exception (invocation ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ PortableInterceptor::ReplyStatus status =
+ this->reply_status (invocation);
+
+ // Only re-throw the exception if it hasn't been transformed by
+ // the receive_exception() interception point (e.g. to a
+ // LOCATION_FORWARD).
+ if (status == PortableInterceptor::SYSTEM_EXCEPTION
+ || status == PortableInterceptor::USER_EXCEPTION)
+ ACE_RE_THROW;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
+ }
+
+ void
+ ClientRequestInterceptor_Adapter_Impl::receive_other (
+ Invocation_Base &invocation
+ ACE_ENV_ARG_DECL)
+ {
+ // This is an "ending" interception point so we only process the
+ // interceptors pushed on to the flow stack.
+
+ bool const is_remote_request = invocation.is_remote_request();
+
+ // Notice that the interceptors are processed in the opposite order
+ // they were pushed onto the stack since this is an "ending"
+ // interception point.
+
+ ACE_TRY
+ {
+ TAO_ClientRequestInfo ri (&invocation);
+
+ // Unwind the stack.
+ size_t const len = invocation.stack_size ();
+ for (size_t i = 0; i < len; ++i)
+ {
+ // Pop the interceptor off of the flow stack before it is
+ // invoked. This is necessary to prevent an interceptor
+ // already invoked in this "ending" interception point from
+ // being invoked in another "ending" interception point.
+ --invocation.stack_size ();
+
+ ClientRequestInterceptor_List::RegisteredInterceptor& registered =
+ this->interceptor_list_.registered_interceptor (
+ invocation.stack_size ());
+
+ if (registered.details_.should_be_processed (is_remote_request))
+ {
+ registered.interceptor_->
+ receive_other (
+ &ri
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ }
+ }
+ ACE_CATCH (PortableInterceptor::ForwardRequest, exc)
+ {
+ this->process_forward_request (invocation,
+ exc
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ // The receive_exception() interception point in the remaining
+ // interceptors must be called so call this method (not the
+ // interceptor's corresponding method) recursively. The call is
+ // made recursively since the caught exception must survive
+ // until the remaining interceptors have been called.
+
+ // Note that the recursion will stop once the flow stack size
+ // drops to zero, i.e., once each interceptor has been invoked.
+ // This prevents infinite recursion from occuring.
+
+ invocation.exception (&ACE_ANY_EXCEPTION);
+
+ this->receive_exception (invocation ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ PortableInterceptor::ReplyStatus status =
+ this->reply_status (invocation);
+
+ // Only re-throw the exception if it hasn't been transformed by
+ // the receive_exception() interception point (e.g. to a
+ // LOCATION_FORWARD).
+ if (status == PortableInterceptor::SYSTEM_EXCEPTION
+ || status == PortableInterceptor::USER_EXCEPTION)
+ ACE_RE_THROW;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
+ }
+
+ void
+ ClientRequestInterceptor_Adapter_Impl::process_forward_request (
+ Invocation_Base &invocation,
+ PortableInterceptor::ForwardRequest &exc
+ ACE_ENV_ARG_DECL)
+ {
+ invocation.forwarded_reference (exc.forward.in ());
+
+ // receive_other() is potentially invoked recursively.
+ this->receive_other (invocation
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ void
+ ClientRequestInterceptor_Adapter_Impl::add_interceptor (
+ PortableInterceptor::ClientRequestInterceptor_ptr interceptor
+ ACE_ENV_ARG_DECL)
+ {
+ this->interceptor_list_.add_interceptor (interceptor ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ void
+ ClientRequestInterceptor_Adapter_Impl::add_interceptor (
+ PortableInterceptor::ClientRequestInterceptor_ptr interceptor,
+ const CORBA::PolicyList& policies
+ ACE_ENV_ARG_DECL)
+ {
+ this->interceptor_list_.add_interceptor (interceptor,
+ policies
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ void
+ ClientRequestInterceptor_Adapter_Impl::destroy_interceptors (
+ ACE_ENV_SINGLE_ARG_DECL)
+ {
+ this->interceptor_list_.destroy_interceptors (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ PortableInterceptor::ReplyStatus
+ ClientRequestInterceptor_Adapter_Impl::reply_status (
+ TAO::Invocation_Base const &invocation_base)
+ {
+ PortableInterceptor::ReplyStatus reply_status;
+
+ switch (invocation_base.invoke_status ())
+ {
+ case TAO::TAO_INVOKE_SUCCESS:
+ reply_status = PortableInterceptor::SUCCESSFUL;
+ break;
+ case TAO::TAO_INVOKE_RESTART:
+ if (invocation_base.is_forwarded ())
+ reply_status = PortableInterceptor::LOCATION_FORWARD;
+ else
+ reply_status = PortableInterceptor::TRANSPORT_RETRY;
+ break;
+ case TAO::TAO_INVOKE_USER_EXCEPTION:
+ reply_status = PortableInterceptor::USER_EXCEPTION;
+ break;
+ case TAO::TAO_INVOKE_SYSTEM_EXCEPTION:
+ reply_status = PortableInterceptor::SYSTEM_EXCEPTION;
+ break;
+ default:
+ reply_status = PortableInterceptor::UNKNOWN;
+ break;
+ }
+
+ return reply_status;
+ }
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_HAS_INTERCEPTORS == 1 */