diff options
Diffstat (limited to 'TAO/tao/PI/ClientRequestInterceptor_Adapter_Impl.cpp')
-rw-r--r-- | TAO/tao/PI/ClientRequestInterceptor_Adapter_Impl.cpp | 348 |
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 */ |