00001 #include "tao/PI/ClientRequestInterceptor_Adapter_Impl.h" 00002 00003 #if TAO_HAS_INTERCEPTORS == 1 00004 00005 #if !defined (__ACE_INLINE__) 00006 #include "tao/PI/ClientRequestInterceptor_Adapter_Impl.inl" 00007 #endif /* defined INLINE */ 00008 00009 #include "tao/PI/ClientRequestInfo.h" 00010 00011 #include "tao/Invocation_Base.h" 00012 #include "tao/ORB_Core.h" 00013 #include "tao/ORB_Core_TSS_Resources.h" 00014 #include "tao/PortableInterceptorC.h" 00015 00016 ACE_RCSID (PI, 00017 ClientRequestInterceptorAdapter_Impl, 00018 "$Id: ClientRequestInterceptor_Adapter_Impl.cpp 81632 2008-05-07 09:19:05Z vzykov $") 00019 00020 TAO_BEGIN_VERSIONED_NAMESPACE_DECL 00021 00022 namespace TAO 00023 { 00024 void 00025 ClientRequestInterceptor_Adapter_Impl::send_request ( 00026 Invocation_Base &invocation) 00027 { 00028 // This method implements one of the "starting" client side 00029 // interception point. 00030 00031 bool const is_remote_request = invocation.is_remote_request(); 00032 00033 try 00034 { 00035 TAO_ClientRequestInfo ri (&invocation); 00036 00037 for (size_t i = 0 ; i < this->interceptor_list_.size (); ++i) 00038 { 00039 ClientRequestInterceptor_List::RegisteredInterceptor& registered = 00040 this->interceptor_list_.registered_interceptor (i); 00041 00042 if (registered.details_.should_be_processed (is_remote_request)) 00043 { 00044 registered.interceptor_->send_request (&ri); 00045 } 00046 00047 // The starting interception point completed successfully. 00048 // Push the interceptor on to the flow stack. 00049 ++invocation.stack_size (); 00050 } 00051 } 00052 catch (const ::PortableInterceptor::ForwardRequest& exc) 00053 { 00054 this->process_forward_request (invocation, exc); 00055 } 00056 } 00057 00058 void 00059 ClientRequestInterceptor_Adapter_Impl::receive_reply ( 00060 Invocation_Base &invocation) 00061 { 00062 // This is an "ending" interception point so we only process the 00063 // interceptors pushed on to the flow stack. 00064 00065 bool const is_remote_request = invocation.is_remote_request(); 00066 00067 // Notice that the interceptors are processed in the opposite order 00068 // they were pushed onto the stack since this is an "ending" 00069 // interception point. 00070 00071 TAO_ClientRequestInfo ri (&invocation); 00072 00073 // Unwind the stack. 00074 size_t const len = invocation.stack_size (); 00075 for (size_t i = 0; i < len; ++i) 00076 { 00077 // Pop the interceptor off of the flow stack before it is 00078 // invoked. This is necessary to prevent an interceptor already 00079 // invoked in this "ending" interception point from being 00080 // invoked in another "ending" interception point. 00081 --invocation.stack_size (); 00082 00083 ClientRequestInterceptor_List::RegisteredInterceptor& registered = 00084 this->interceptor_list_.registered_interceptor ( 00085 invocation.stack_size ()); 00086 00087 if (registered.details_.should_be_processed (is_remote_request)) 00088 { 00089 registered.interceptor_->receive_reply (&ri); 00090 } 00091 } 00092 00093 // The receive_reply() interception point does not raise a 00094 // PortableInterceptor::ForwardRequest exception so there is no need 00095 // to attempt to catch it here. 00096 } 00097 00098 void 00099 ClientRequestInterceptor_Adapter_Impl::receive_exception ( 00100 Invocation_Base &invocation) 00101 { 00102 // This is an "ending" interception point so we only process the 00103 // interceptors pushed on to the flow stack. 00104 00105 bool const is_remote_request = invocation.is_remote_request(); 00106 00107 // Notice that the interceptors are processed in the opposite order 00108 // they were pushed onto the stack since this is an "ending" 00109 // interception point. 00110 try 00111 { 00112 TAO_ClientRequestInfo ri (&invocation); 00113 00114 // Unwind the flow stack. 00115 size_t const len = invocation.stack_size (); 00116 for (size_t i = 0; i < len; ++i) 00117 { 00118 // Pop the interceptor off of the flow stack before it is 00119 // invoked. This is necessary to prevent an interceptor 00120 // already invoked in this "ending" interception point from 00121 // being invoked in another "ending" interception point. 00122 --invocation.stack_size (); 00123 00124 ClientRequestInterceptor_List::RegisteredInterceptor& registered = 00125 this->interceptor_list_.registered_interceptor ( 00126 invocation.stack_size ()); 00127 00128 if (registered.details_.should_be_processed (is_remote_request)) 00129 { 00130 registered.interceptor_->receive_exception (&ri); 00131 } 00132 } 00133 } 00134 catch (const ::PortableInterceptor::ForwardRequest& exc) 00135 { 00136 this->process_forward_request (invocation, exc); 00137 } 00138 catch ( ::CORBA::Exception& ex) 00139 { 00140 // The receive_exception() interception point in the remaining 00141 // interceptors must be called so call this method (not the 00142 // interceptor's corresponding method) recursively. The call is 00143 // made recursively since the caught exception must survive 00144 // until the remaining interceptors have been called. 00145 00146 // Note that the recursion will stop once the flow stack size 00147 // drops to zero, i.e., once each interceptor has been invoked. 00148 // This prevents infinite recursion from occuring. 00149 00150 invocation.exception (&ex); 00151 00152 this->receive_exception (invocation); 00153 00154 PortableInterceptor::ReplyStatus status = 00155 this->pi_reply_status (invocation); 00156 00157 // Only re-throw the exception if it hasn't been transformed by 00158 // the receive_exception() interception point (e.g. to a 00159 // LOCATION_FORWARD). 00160 if (status == PortableInterceptor::SYSTEM_EXCEPTION 00161 || status == PortableInterceptor::USER_EXCEPTION) 00162 throw; 00163 } 00164 } 00165 00166 void 00167 ClientRequestInterceptor_Adapter_Impl::receive_other ( 00168 Invocation_Base &invocation) 00169 { 00170 // This is an "ending" interception point so we only process the 00171 // interceptors pushed on to the flow stack. 00172 00173 bool const is_remote_request = invocation.is_remote_request(); 00174 00175 // Notice that the interceptors are processed in the opposite order 00176 // they were pushed onto the stack since this is an "ending" 00177 // interception point. 00178 00179 try 00180 { 00181 TAO_ClientRequestInfo ri (&invocation); 00182 00183 // Unwind the stack. 00184 size_t const len = invocation.stack_size (); 00185 for (size_t i = 0; i < len; ++i) 00186 { 00187 // Pop the interceptor off of the flow stack before it is 00188 // invoked. This is necessary to prevent an interceptor 00189 // already invoked in this "ending" interception point from 00190 // being invoked in another "ending" interception point. 00191 --invocation.stack_size (); 00192 00193 ClientRequestInterceptor_List::RegisteredInterceptor& registered = 00194 this->interceptor_list_.registered_interceptor ( 00195 invocation.stack_size ()); 00196 00197 if (registered.details_.should_be_processed (is_remote_request)) 00198 { 00199 registered.interceptor_->receive_other (&ri); 00200 } 00201 } 00202 } 00203 catch (const ::PortableInterceptor::ForwardRequest& exc) 00204 { 00205 this->process_forward_request (invocation, exc); 00206 } 00207 catch ( ::CORBA::Exception& ex) 00208 { 00209 // The receive_exception() interception point in the remaining 00210 // interceptors must be called so call this method (not the 00211 // interceptor's corresponding method) recursively. The call is 00212 // made recursively since the caught exception must survive 00213 // until the remaining interceptors have been called. 00214 00215 // Note that the recursion will stop once the flow stack size 00216 // drops to zero, i.e., once each interceptor has been invoked. 00217 // This prevents infinite recursion from occuring. 00218 00219 invocation.exception (&ex); 00220 00221 this->receive_exception (invocation); 00222 00223 PortableInterceptor::ReplyStatus status = 00224 this->pi_reply_status (invocation); 00225 00226 // Only re-throw the exception if it hasn't been transformed by 00227 // the receive_exception() interception point (e.g. to a 00228 // LOCATION_FORWARD). 00229 if (status == PortableInterceptor::SYSTEM_EXCEPTION 00230 || status == PortableInterceptor::USER_EXCEPTION) 00231 throw; 00232 } 00233 } 00234 00235 void 00236 ClientRequestInterceptor_Adapter_Impl::process_forward_request ( 00237 Invocation_Base &invocation, 00238 const PortableInterceptor::ForwardRequest &exc) 00239 { 00240 invocation.forwarded_reference (exc.forward.in ()); 00241 00242 // receive_other() is potentially invoked recursively. 00243 this->receive_other (invocation); 00244 } 00245 00246 void 00247 ClientRequestInterceptor_Adapter_Impl::add_interceptor ( 00248 PortableInterceptor::ClientRequestInterceptor_ptr interceptor) 00249 { 00250 this->interceptor_list_.add_interceptor (interceptor); 00251 } 00252 00253 void 00254 ClientRequestInterceptor_Adapter_Impl::add_interceptor ( 00255 PortableInterceptor::ClientRequestInterceptor_ptr interceptor, 00256 const CORBA::PolicyList& policies) 00257 { 00258 this->interceptor_list_.add_interceptor (interceptor, policies); 00259 } 00260 00261 void 00262 ClientRequestInterceptor_Adapter_Impl::destroy_interceptors (void) 00263 { 00264 this->interceptor_list_.destroy_interceptors (); 00265 } 00266 00267 PortableInterceptor::ReplyStatus 00268 ClientRequestInterceptor_Adapter_Impl::pi_reply_status ( 00269 TAO::Invocation_Base const &invocation_base) 00270 { 00271 PortableInterceptor::ReplyStatus reply_status; 00272 00273 switch (invocation_base.invoke_status ()) 00274 { 00275 case TAO::TAO_INVOKE_SUCCESS: 00276 reply_status = PortableInterceptor::SUCCESSFUL; 00277 break; 00278 case TAO::TAO_INVOKE_RESTART: 00279 if (invocation_base.reply_status () == GIOP::LOCATION_FORWARD || 00280 invocation_base.reply_status () == GIOP::LOCATION_FORWARD_PERM) 00281 reply_status = PortableInterceptor::LOCATION_FORWARD; 00282 else 00283 reply_status = PortableInterceptor::TRANSPORT_RETRY; 00284 break; 00285 case TAO::TAO_INVOKE_USER_EXCEPTION: 00286 reply_status = PortableInterceptor::USER_EXCEPTION; 00287 break; 00288 case TAO::TAO_INVOKE_SYSTEM_EXCEPTION: 00289 reply_status = PortableInterceptor::SYSTEM_EXCEPTION; 00290 break; 00291 default: 00292 reply_status = PortableInterceptor::UNKNOWN; 00293 break; 00294 } 00295 00296 return reply_status; 00297 } 00298 } 00299 00300 TAO_END_VERSIONED_NAMESPACE_DECL 00301 00302 #endif /* TAO_HAS_INTERCEPTORS == 1 */