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 (void)
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
235 // This method implements an "intermediate" server side interception
236 // point. Interceptors are invoked in the same order they were
237 // pushed on to the flow stack.
239 if (this->interceptor_list_
.size() != server_request
.interceptor_count ())
241 // This method (i.e. the receive_request() interception point)
242 // should only be invoked if all of the interceptors registered
243 // with the ORB were pushed on to the flow stack by one of the
244 // starting endpoints (such as
245 // receive_request_service_contexts()). If the above condition
246 // evaluates to "true," then it is likely that a starting
247 // interception point was never invoked. This is of course, an
248 // internal error that must be corrected.
249 throw ::CORBA::INTERNAL ();
252 TAO::ServerRequestInfo
request_info (server_request
,
261 bool is_remote_request
= !server_request
.collocated ();
263 for (size_t i
= 0; i
< server_request
.interceptor_count (); ++i
)
265 ServerRequestInterceptor_List::RegisteredInterceptor
& registered
=
266 this->interceptor_list_
.registered_interceptor (i
);
268 if (registered
.details_
.should_be_processed (is_remote_request
))
270 registered
.interceptor_
->receive_request (&request_info
);
273 // Note that no interceptors are pushed on to or popped off
274 // of the flow stack in this interception point since it is
275 // an intermediate interception point.
278 catch (const ::PortableInterceptor::ForwardRequest
& exc
)
280 server_request
.forward_location (exc
.forward
.in ());
281 server_request
.pi_reply_status (PortableInterceptor::LOCATION_FORWARD
);
282 server_request
.reply_status (GIOP::LOCATION_FORWARD
);
283 this->send_other (server_request
,
294 TAO::ServerRequestInterceptor_Adapter_Impl::send_reply (
295 TAO_ServerRequest
&server_request
,
296 TAO::Argument
* const args
[],
298 TAO::Portable_Server::Servant_Upcall
*servant_upcall
,
299 CORBA::TypeCode_ptr
const * exceptions
,
300 CORBA::ULong nexceptions
)
302 // This is an "ending" interception point so we only process the
303 // interceptors pushed on to the flow stack.
305 bool const is_remote_request
= !server_request
.collocated ();
307 // Notice that the interceptors are processed in the opposite order
308 // they were pushed onto the stack since this is an "ending"
309 // interception point.
311 TAO::ServerRequestInfo
request_info (server_request
,
319 size_t const len
= server_request
.interceptor_count ();
320 for (size_t i
= 0; i
< len
; ++i
)
322 // Pop the interceptor off of the flow stack before it is
323 // invoked. This is necessary to prevent an interceptor already
324 // invoked in this "ending" interception point from being
325 // invoked in another "ending" interception point.
326 --server_request
.interceptor_count ();
328 ServerRequestInterceptor_List::RegisteredInterceptor
& registered
=
329 this->interceptor_list_
.registered_interceptor (
330 server_request
.interceptor_count ());
332 if (registered
.details_
.should_be_processed (is_remote_request
))
334 registered
.interceptor_
->send_reply (&request_info
);
338 // The send_reply() interception point does not raise a
339 // PortableInterceptor::ForwardRequest exception so there is no need
340 // to attempt to catch it here.
344 TAO::ServerRequestInterceptor_Adapter_Impl::send_exception (
345 TAO_ServerRequest
&server_request
,
346 TAO::Argument
* const args
[],
348 TAO::Portable_Server::Servant_Upcall
*servant_upcall
,
349 CORBA::TypeCode_ptr
const * exceptions
,
350 CORBA::ULong nexceptions
)
352 // This is an "ending" server side interception point so we only
353 // process the interceptors pushed on to the flow stack.
354 bool const is_remote_request
= !server_request
.collocated ();
356 // Notice that the interceptors are processed in the opposite order
357 // they were pushed onto the stack since this is an "ending" server
358 // side interception point.
360 TAO::ServerRequestInfo
request_info (server_request
,
369 // Unwind the flow stack.
370 size_t const len
= server_request
.interceptor_count ();
371 for (size_t i
= 0; i
< len
; ++i
)
373 // Pop the interceptor off of the flow stack before it is
374 // invoked. This is necessary to prevent an interceptor
375 // already invoked in this "ending" interception point from
376 // being invoked in another "ending" interception point.
377 --server_request
.interceptor_count ();
379 ServerRequestInterceptor_List::RegisteredInterceptor
& registered
=
380 this->interceptor_list_
.registered_interceptor (
381 server_request
.interceptor_count ());
383 if (registered
.details_
.should_be_processed (is_remote_request
))
385 registered
.interceptor_
->send_exception (&request_info
);
389 catch (const ::PortableInterceptor::ForwardRequest
& exc
)
391 server_request
.forward_location (exc
.forward
.in ());
392 server_request
.pi_reply_status (PortableInterceptor::LOCATION_FORWARD
);
393 server_request
.reply_status (GIOP::LOCATION_FORWARD
);
394 this->send_other (server_request
,
401 catch ( ::CORBA::Exception
& ex
)
403 // The send_exception() interception point in the remaining
404 // interceptors must be called so call this method (not the
405 // interceptor's corresponding method) recursively. The call is
406 // made recursively since the caught exception must survive
407 // until the remaining interceptors have been called.
409 // Note that the recursion will stop once the flow stack size
410 // drops to zero, i.e., once each interceptor has been invoked.
411 // This prevents infinite recursion from occuring.
413 server_request
.caught_exception (&ex
);
415 this->send_exception (server_request
,
422 PortableInterceptor::ReplyStatus status
=
423 server_request
.pi_reply_status ();
425 // Only re-throw the exception if it hasn't been transformed by
426 // the send_exception() interception point (e.g. to a
427 // LOCATION_FORWARD).
428 if (status
== PortableInterceptor::SYSTEM_EXCEPTION
429 || status
== PortableInterceptor::USER_EXCEPTION
)
435 TAO::ServerRequestInterceptor_Adapter_Impl::send_other (
436 TAO_ServerRequest
&server_request
,
437 TAO::Argument
* const args
[],
439 TAO::Portable_Server::Servant_Upcall
*servant_upcall
,
440 CORBA::TypeCode_ptr
const * exceptions
,
441 CORBA::ULong nexceptions
)
443 // This is an "ending" server side interception point so we only
444 // process the interceptors pushed on to the flow stack.
445 bool const is_remote_request
= !server_request
.collocated ();
447 TAO::ServerRequestInfo
request_info (server_request
,
454 // Notice that the interceptors are processed in the opposite order
455 // they were pushed onto the stack since this is an "ending" server
456 // side interception point.
460 // Unwind the flow stack.
461 size_t const len
= server_request
.interceptor_count ();
462 for (size_t i
= 0; i
< len
; ++i
)
464 // Pop the interceptor off of the flow stack before it is
465 // invoked. This is necessary to prevent an interceptor
466 // already invoked in this "ending" interception point from
467 // being invoked in another "ending" interception point.
468 --server_request
.interceptor_count ();
470 ServerRequestInterceptor_List::RegisteredInterceptor
& registered
=
471 this->interceptor_list_
.registered_interceptor (
472 server_request
.interceptor_count ());
474 if (registered
.details_
.should_be_processed (is_remote_request
))
476 registered
.interceptor_
->send_other (&request_info
);
480 catch (const ::PortableInterceptor::ForwardRequest
& exc
)
482 server_request
.forward_location (exc
.forward
.in ());
483 server_request
.pi_reply_status (PortableInterceptor::LOCATION_FORWARD
);
484 server_request
.reply_status (GIOP::LOCATION_FORWARD
);
485 this->send_other (server_request
,
495 TAO::ServerRequestInterceptor_Adapter_Impl::add_interceptor (
496 PortableInterceptor::ServerRequestInterceptor_ptr interceptor
)
498 this->interceptor_list_
.add_interceptor (interceptor
);
502 TAO::ServerRequestInterceptor_Adapter_Impl::add_interceptor (
503 PortableInterceptor::ServerRequestInterceptor_ptr interceptor
,
504 const CORBA::PolicyList
& policies
)
506 this->interceptor_list_
.add_interceptor (interceptor
, policies
);
510 TAO::ServerRequestInterceptor_Adapter_Impl::destroy_interceptors (void)
512 this->interceptor_list_
.destroy_interceptors ();
515 TAO::PICurrent_Impl
*
516 TAO::ServerRequestInterceptor_Adapter_Impl::allocate_pi_current (void)
518 TAO::PICurrent_Impl
*pi
= 0;
526 TAO::ServerRequestInterceptor_Adapter_Impl::deallocate_pi_current (
527 TAO::PICurrent_Impl
*picurrent
)
533 TAO::ServerRequestInterceptor_Adapter_Impl::execute_command (
534 TAO_ServerRequest
& server_request
,
535 TAO::Upcall_Command
& command
)
537 TAO::PICurrent_Guard
const pi_guard (server_request
,
538 true /* Copy TSC to RSC */);
540 // The actual upcall.
544 TAO_END_VERSIONED_NAMESPACE_DECL
546 #endif /* TAO_HAS_INTERCEPTORS == 1 */