Merge pull request #1551 from DOCGroup/plm_jira_333
[ACE_TAO.git] / TAO / tao / PI_Server / ServerInterceptorAdapter.cpp
blobd0cf73ac8794b0bab44f0c84b047a60d7f5802c1
1 // -*- C++ -*-
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
23 void
24 TAO::ServerRequestInterceptor_Adapter_Impl::tao_ft_interception_point (
25 TAO_ServerRequest &server_request,
26 TAO::Argument * const args[],
27 size_t nargs,
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.
36 try
38 oc = 0;
40 bool is_remote_request = !server_request.collocated ();
41 TAO::ServerRequestInfo request_info (server_request,
42 args,
43 nargs,
44 servant_upcall,
45 exceptions,
46 nexceptions);
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);
59 if (oc != 0)
61 (void) this->send_other (server_request,
62 args,
63 nargs,
64 servant_upcall,
65 exceptions,
66 nexceptions);
68 return;
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,
82 args,
83 nargs,
84 servant_upcall,
85 exceptions,
86 nexceptions);
90 void
91 TAO::ServerRequestInterceptor_Adapter_Impl::receive_request_service_contexts (
92 TAO_ServerRequest &server_request,
93 TAO::Argument * const args[],
94 size_t nargs,
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,
126 args,
127 nargs,
128 servant_upcall,
129 exceptions,
130 nexceptions);
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,
150 args,
151 nargs,
152 servant_upcall,
153 exceptions,
154 nexceptions);
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.
163 void
164 TAO::ServerRequestInterceptor_Adapter_Impl::receive_request_service_contexts (
165 TAO_ServerRequest &server_request,
166 TAO::Argument * const args[],
167 size_t nargs,
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,
187 args,
188 nargs,
189 servant_upcall,
190 exceptions,
191 nexceptions);
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,
215 args,
216 nargs,
217 servant_upcall,
218 exceptions,
219 nexceptions);
223 #endif /*TAO_HAS_EXTENDED_FT_INTERCEPTORS*/
225 void
226 TAO::ServerRequestInterceptor_Adapter_Impl::receive_request (
227 TAO_ServerRequest &server_request,
228 TAO::Argument * const args[],
229 size_t nargs,
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,
253 args,
254 nargs,
255 servant_upcall,
256 exceptions,
257 nexceptions);
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,
284 args,
285 nargs,
286 servant_upcall,
287 exceptions,
288 nexceptions);
293 void
294 TAO::ServerRequestInterceptor_Adapter_Impl::send_reply (
295 TAO_ServerRequest &server_request,
296 TAO::Argument * const args[],
297 size_t nargs,
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,
312 args,
313 nargs,
314 servant_upcall,
315 exceptions,
316 nexceptions);
318 // Unwind the stack.
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.
343 void
344 TAO::ServerRequestInterceptor_Adapter_Impl::send_exception (
345 TAO_ServerRequest &server_request,
346 TAO::Argument * const args[],
347 size_t nargs,
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,
361 args,
362 nargs,
363 servant_upcall,
364 exceptions,
365 nexceptions);
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,
395 args,
396 nargs,
397 servant_upcall,
398 exceptions,
399 nexceptions);
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,
416 args,
417 nargs,
418 servant_upcall,
419 exceptions,
420 nexceptions);
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)
430 throw;
434 void
435 TAO::ServerRequestInterceptor_Adapter_Impl::send_other (
436 TAO_ServerRequest &server_request,
437 TAO::Argument * const args[],
438 size_t nargs,
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,
448 args,
449 nargs,
450 servant_upcall,
451 exceptions,
452 nexceptions);
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,
486 args,
487 nargs,
488 servant_upcall,
489 exceptions,
490 nexceptions);
494 void
495 TAO::ServerRequestInterceptor_Adapter_Impl::add_interceptor (
496 PortableInterceptor::ServerRequestInterceptor_ptr interceptor)
498 this->interceptor_list_.add_interceptor (interceptor);
501 void
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);
509 void
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;
519 ACE_NEW_RETURN (pi,
520 TAO::PICurrent_Impl,
521 pi);
522 return pi;
525 void
526 TAO::ServerRequestInterceptor_Adapter_Impl::deallocate_pi_current (
527 TAO::PICurrent_Impl *picurrent)
529 delete picurrent;
532 void
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.
541 command.execute ();
544 TAO_END_VERSIONED_NAMESPACE_DECL
546 #endif /* TAO_HAS_INTERCEPTORS == 1 */