2 #include "tao/PI_Server/ServerInterceptorAdapter.h"
4 #if TAO_HAS_INTERCEPTORS == 1
6 #include "tao/PI_Server/ServerRequestInfo.h"
7 #include "tao/PI_Server/PICurrent_Guard.h"
9 #include "tao/ServerRequestInterceptor_Adapter.h"
10 #include "tao/TAO_Server_Request.h"
11 #include "tao/ORB_Core.h"
12 #include "tao/PI/PICurrent_Impl.h"
13 #include "tao/PortableServer/Upcall_Command.h"
14 #include "tao/PortableInterceptor.h"
16 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
18 TAO::ServerRequestInterceptor_Adapter_Impl::ServerRequestInterceptor_Adapter_Impl ()
22 #if TAO_HAS_EXTENDED_FT_INTERCEPTORS == 1
24 TAO::ServerRequestInterceptor_Adapter_Impl::tao_ft_interception_point (
25 TAO_ServerRequest
&server_request
,
26 TAO::Argument
* const args
[],
28 TAO::Portable_Server::Servant_Upcall
*servant_upcall
,
29 CORBA::TypeCode_ptr
const * exceptions
,
30 CORBA::ULong nexceptions
,
31 CORBA::OctetSeq_out oc
)
33 // This method implements one of the "starting" server side
34 // interception point.
40 bool is_remote_request
= !server_request
.collocated ();
41 TAO::ServerRequestInfo
request_info (server_request
,
48 for (size_t i
= 0 ; i
< this->interceptor_list_
.size(); ++i
)
50 ServerRequestInterceptor_List::RegisteredInterceptor
& registered
=
51 this->interceptor_list_
.registered_interceptor (i
);
53 if (registered
.details_
.should_be_processed (is_remote_request
))
55 registered
.interceptor_
->
56 tao_ft_interception_point (&request_info
, oc
);
61 (void) this->send_other (server_request
,
71 // The starting interception point completed successfully.
72 // Push the interceptor on to the flow stack.
73 ++server_request
.interceptor_count ();
76 catch (const ::PortableInterceptor::ForwardRequest
& exc
)
78 server_request
.forward_location (exc
.forward
.in ());
79 server_request
.pi_reply_status (PortableInterceptor::LOCATION_FORWARD
);
80 server_request
.reply_status (GIOP::LOCATION_FORWARD
);
81 (void) this->send_other (server_request
,
91 TAO::ServerRequestInterceptor_Adapter_Impl::receive_request_service_contexts (
92 TAO_ServerRequest
&server_request
,
93 TAO::Argument
* const args
[],
95 TAO::Portable_Server::Servant_Upcall
*servant_upcall
,
96 CORBA::TypeCode_ptr
const * exceptions
,
97 CORBA::ULong nexceptions
)
99 // This method implements one of the "intermediate" server side
100 // interception point.
102 if (this->interceptor_list_
.size() != server_request
.interceptor_count ())
104 // This method (i.e. the receive_request() interception point)
105 // should only be invoked if all of the interceptors registered
106 // with the ORB were pushed on to the flow stack by one of the
107 // starting endpoints (such as
108 // tao_ft_interception_point()). If the above condition
109 // evaluates to "true," then it is likely that a starting
110 // interception point was never invoked. This is of course, an
111 // internal error that must be corrected.
112 throw ::CORBA::INTERNAL ();
117 // Copy the request scope current (RSC) to the thread scope
118 // current (TSC) upon leaving this scope, i.e. just after the
119 // receive_request_service_contexts() completes. A "guard" is
120 // used to make the copy also occur if an exception is thrown.
121 TAO::PICurrent_Guard
const pi_guard (server_request
,
122 false /* Copy RSC to TSC */);
124 bool is_remote_request
= !server_request
.collocated ();
125 TAO::ServerRequestInfo
request_info (server_request
,
132 for (size_t i
= 0 ; i
< server_request
.interceptor_count (); ++i
)
134 ServerRequestInterceptor_List::RegisteredInterceptor
& registered
=
135 this->interceptor_list_
.registered_interceptor (i
);
137 if (registered
.details_
.should_be_processed (is_remote_request
))
139 registered
.interceptor_
->
140 receive_request_service_contexts (&request_info
);
144 catch (const ::PortableInterceptor::ForwardRequest
& exc
)
146 server_request
.forward_location (exc
.forward
.in ());
147 server_request
.pi_reply_status (PortableInterceptor::LOCATION_FORWARD
);
148 server_request
.reply_status (GIOP::LOCATION_FORWARD
);
149 (void) this->send_other (server_request
,
158 #elif TAO_HAS_EXTENDED_FT_INTERCEPTORS == 0
160 /// NOTE: Yes, we have two versions of this. This is easier than
161 /// messing around things in the same function, which is harder to
162 /// read and could make the code buggier.
164 TAO::ServerRequestInterceptor_Adapter_Impl::receive_request_service_contexts (
165 TAO_ServerRequest
&server_request
,
166 TAO::Argument
* const args
[],
168 TAO::Portable_Server::Servant_Upcall
*servant_upcall
,
169 CORBA::TypeCode_ptr
const * exceptions
,
170 CORBA::ULong nexceptions
)
172 // This method implements one of the "starting" server side
173 // interception point if extended interceptors are not in place.
177 // Copy the request scope current (RSC) to the thread scope
178 // current (TSC) upon leaving this scope, i.e. just after the
179 // receive_request_service_contexts() completes. A "guard" is
180 // used to make the copy also occur if an exception is thrown.
181 TAO::PICurrent_Guard
const pi_guard (server_request
,
182 false /* Copy RSC to TSC */);
184 bool is_remote_request
= !server_request
.collocated ();
186 TAO::ServerRequestInfo
request_info (server_request
,
193 for (size_t i
= 0 ; i
< this->interceptor_list_
.size(); ++i
)
195 ServerRequestInterceptor_List::RegisteredInterceptor
& registered
=
196 this->interceptor_list_
.registered_interceptor (i
);
198 if (registered
.details_
.should_be_processed (is_remote_request
))
200 registered
.interceptor_
->
201 receive_request_service_contexts (&request_info
);
204 // The starting interception point completed successfully.
205 // Push the interceptor on to the flow stack.
206 ++server_request
.interceptor_count ();
209 catch (const ::PortableInterceptor::ForwardRequest
& exc
)
211 server_request
.forward_location (exc
.forward
.in ());
212 server_request
.pi_reply_status (PortableInterceptor::LOCATION_FORWARD
);
213 server_request
.reply_status (GIOP::LOCATION_FORWARD
);
214 (void) this->send_other (server_request
,
223 #endif /*TAO_HAS_EXTENDED_FT_INTERCEPTORS*/
226 TAO::ServerRequestInterceptor_Adapter_Impl::receive_request (
227 TAO_ServerRequest
&server_request
,
228 TAO::Argument
* const args
[],
230 TAO::Portable_Server::Servant_Upcall
*servant_upcall
,
231 CORBA::TypeCode_ptr
const * exceptions
,
232 CORBA::ULong nexceptions
)
234 // This method implements an "intermediate" server side interception
235 // point. Interceptors are invoked in the same order they were
236 // pushed on to the flow stack.
238 if (this->interceptor_list_
.size() != server_request
.interceptor_count ())
240 // This method (i.e. the receive_request() interception point)
241 // should only be invoked if all of the interceptors registered
242 // with the ORB were pushed on to the flow stack by one of the
243 // starting endpoints (such as
244 // receive_request_service_contexts()). If the above condition
245 // evaluates to "true," then it is likely that a starting
246 // interception point was never invoked. This is of course, an
247 // internal error that must be corrected.
248 throw ::CORBA::INTERNAL ();
251 TAO::ServerRequestInfo
request_info (server_request
,
260 bool const is_remote_request
= !server_request
.collocated ();
262 for (size_t i
= 0; i
< server_request
.interceptor_count (); ++i
)
264 ServerRequestInterceptor_List::RegisteredInterceptor
& registered
=
265 this->interceptor_list_
.registered_interceptor (i
);
267 if (registered
.details_
.should_be_processed (is_remote_request
))
269 registered
.interceptor_
->receive_request (&request_info
);
272 // Note that no interceptors are pushed on to or popped off
273 // of the flow stack in this interception point since it is
274 // an intermediate interception point.
277 catch (const ::PortableInterceptor::ForwardRequest
& exc
)
279 server_request
.forward_location (exc
.forward
.in ());
280 server_request
.pi_reply_status (PortableInterceptor::LOCATION_FORWARD
);
281 server_request
.reply_status (GIOP::LOCATION_FORWARD
);
282 this->send_other (server_request
,
293 TAO::ServerRequestInterceptor_Adapter_Impl::send_reply (
294 TAO_ServerRequest
&server_request
,
295 TAO::Argument
* const args
[],
297 TAO::Portable_Server::Servant_Upcall
*servant_upcall
,
298 CORBA::TypeCode_ptr
const * exceptions
,
299 CORBA::ULong nexceptions
)
301 // This is an "ending" interception point so we only process the
302 // interceptors pushed on to the flow stack.
304 bool const is_remote_request
= !server_request
.collocated ();
306 // Notice that the interceptors are processed in the opposite order
307 // they were pushed onto the stack since this is an "ending"
308 // interception point.
310 TAO::ServerRequestInfo
request_info (server_request
,
318 size_t const len
= server_request
.interceptor_count ();
319 for (size_t i
= 0; i
< len
; ++i
)
321 // Pop the interceptor off of the flow stack before it is
322 // invoked. This is necessary to prevent an interceptor already
323 // invoked in this "ending" interception point from being
324 // invoked in another "ending" interception point.
325 --server_request
.interceptor_count ();
327 ServerRequestInterceptor_List::RegisteredInterceptor
& registered
=
328 this->interceptor_list_
.registered_interceptor (
329 server_request
.interceptor_count ());
331 if (registered
.details_
.should_be_processed (is_remote_request
))
333 registered
.interceptor_
->send_reply (&request_info
);
337 // The send_reply() interception point does not raise a
338 // PortableInterceptor::ForwardRequest exception so there is no need
339 // to attempt to catch it here.
343 TAO::ServerRequestInterceptor_Adapter_Impl::send_exception (
344 TAO_ServerRequest
&server_request
,
345 TAO::Argument
* const args
[],
347 TAO::Portable_Server::Servant_Upcall
*servant_upcall
,
348 CORBA::TypeCode_ptr
const * exceptions
,
349 CORBA::ULong nexceptions
)
351 // This is an "ending" server side interception point so we only
352 // process the interceptors pushed on to the flow stack.
353 bool const is_remote_request
= !server_request
.collocated ();
355 // Notice that the interceptors are processed in the opposite order
356 // they were pushed onto the stack since this is an "ending" server
357 // side interception point.
359 TAO::ServerRequestInfo
request_info (server_request
,
368 // Unwind the flow stack.
369 size_t const len
= server_request
.interceptor_count ();
370 for (size_t i
= 0; i
< len
; ++i
)
372 // Pop the interceptor off of the flow stack before it is
373 // invoked. This is necessary to prevent an interceptor
374 // already invoked in this "ending" interception point from
375 // being invoked in another "ending" interception point.
376 --server_request
.interceptor_count ();
378 ServerRequestInterceptor_List::RegisteredInterceptor
& registered
=
379 this->interceptor_list_
.registered_interceptor (
380 server_request
.interceptor_count ());
382 if (registered
.details_
.should_be_processed (is_remote_request
))
384 registered
.interceptor_
->send_exception (&request_info
);
388 catch (const ::PortableInterceptor::ForwardRequest
& exc
)
390 server_request
.forward_location (exc
.forward
.in ());
391 server_request
.pi_reply_status (PortableInterceptor::LOCATION_FORWARD
);
392 server_request
.reply_status (GIOP::LOCATION_FORWARD
);
393 this->send_other (server_request
,
400 catch ( ::CORBA::Exception
& ex
)
402 // The send_exception() interception point in the remaining
403 // interceptors must be called so call this method (not the
404 // interceptor's corresponding method) recursively. The call is
405 // made recursively since the caught exception must survive
406 // until the remaining interceptors have been called.
408 // Note that the recursion will stop once the flow stack size
409 // drops to zero, i.e., once each interceptor has been invoked.
410 // This prevents infinite recursion from occuring.
412 server_request
.caught_exception (&ex
);
414 this->send_exception (server_request
,
421 PortableInterceptor::ReplyStatus status
=
422 server_request
.pi_reply_status ();
424 // Only re-throw the exception if it hasn't been transformed by
425 // the send_exception() interception point (e.g. to a
426 // LOCATION_FORWARD).
427 if (status
== PortableInterceptor::SYSTEM_EXCEPTION
428 || status
== PortableInterceptor::USER_EXCEPTION
)
434 TAO::ServerRequestInterceptor_Adapter_Impl::send_other (
435 TAO_ServerRequest
&server_request
,
436 TAO::Argument
* const args
[],
438 TAO::Portable_Server::Servant_Upcall
*servant_upcall
,
439 CORBA::TypeCode_ptr
const * exceptions
,
440 CORBA::ULong nexceptions
)
442 // This is an "ending" server side interception point so we only
443 // process the interceptors pushed on to the flow stack.
444 bool const is_remote_request
= !server_request
.collocated ();
446 TAO::ServerRequestInfo
request_info (server_request
,
453 // Notice that the interceptors are processed in the opposite order
454 // they were pushed onto the stack since this is an "ending" server
455 // side interception point.
459 // Unwind the flow stack.
460 size_t const len
= server_request
.interceptor_count ();
461 for (size_t i
= 0; i
< len
; ++i
)
463 // Pop the interceptor off of the flow stack before it is
464 // invoked. This is necessary to prevent an interceptor
465 // already invoked in this "ending" interception point from
466 // being invoked in another "ending" interception point.
467 --server_request
.interceptor_count ();
469 ServerRequestInterceptor_List::RegisteredInterceptor
& registered
=
470 this->interceptor_list_
.registered_interceptor (
471 server_request
.interceptor_count ());
473 if (registered
.details_
.should_be_processed (is_remote_request
))
475 registered
.interceptor_
->send_other (&request_info
);
479 catch (const ::PortableInterceptor::ForwardRequest
& exc
)
481 server_request
.forward_location (exc
.forward
.in ());
482 server_request
.pi_reply_status (PortableInterceptor::LOCATION_FORWARD
);
483 server_request
.reply_status (GIOP::LOCATION_FORWARD
);
484 this->send_other (server_request
,
494 TAO::ServerRequestInterceptor_Adapter_Impl::add_interceptor (
495 PortableInterceptor::ServerRequestInterceptor_ptr interceptor
)
497 this->interceptor_list_
.add_interceptor (interceptor
);
501 TAO::ServerRequestInterceptor_Adapter_Impl::add_interceptor (
502 PortableInterceptor::ServerRequestInterceptor_ptr interceptor
,
503 const CORBA::PolicyList
& policies
)
505 this->interceptor_list_
.add_interceptor (interceptor
, policies
);
509 TAO::ServerRequestInterceptor_Adapter_Impl::destroy_interceptors ()
511 this->interceptor_list_
.destroy_interceptors ();
514 TAO::PICurrent_Impl
*
515 TAO::ServerRequestInterceptor_Adapter_Impl::allocate_pi_current ()
517 TAO::PICurrent_Impl
*pi
= 0;
525 TAO::ServerRequestInterceptor_Adapter_Impl::deallocate_pi_current (
526 TAO::PICurrent_Impl
*picurrent
)
532 TAO::ServerRequestInterceptor_Adapter_Impl::execute_command (
533 TAO_ServerRequest
& server_request
,
534 TAO::Upcall_Command
& command
)
536 TAO::PICurrent_Guard
const pi_guard (server_request
,
537 true /* Copy TSC to RSC */);
539 // The actual upcall.
543 TAO_END_VERSIONED_NAMESPACE_DECL
545 #endif /* TAO_HAS_INTERCEPTORS == 1 */