I would vote for the second approach. When its there, we can probably use the similiar approach to remove the sub-chain (interceptor chain reentrance) wherever it is possible.
________________________________ From: Glynn, Eoghan [mailto:[EMAIL PROTECTED] Sent: Wed 1/17/2007 9:42 PM To: [email protected] Subject: RE: When should we close the handlers in CXF? > -----Original Message----- > From: Glynn, Eoghan [mailto:[EMAIL PROTECTED] > Sent: 17 January 2007 12:34 > To: [email protected] > Subject: RE: When should we close the handlers in CXF? > > > Hi Unreal, > > One point to note is that all the other JAX-WS Handler touch > points are driven through a set of interceptors, each > wrapping a chain of a particular Handler type (logical, > protocol etc.). > > So for example the SOAPHanderInterceptor takes care of calling the > handleMessage/Fault() methods of any SOAPHandlers in the chain. > Similarly there's a *separate* LogicalHandlerInterceptor that > traverses the chain of LogicalHandlers. I'm guessing you > already know all this ... > > But the point is that it would be a good idea to maintain the > pattern of wrapper-interceptor calling out to JAX-WS Handler, > and obviously it would be badness to for example put this > JAXWS-specific logic into the ClientImpl code. > > However, because Handler.close() should only be called at the > very *end* of the interceptor chain tarversal, and because we > currently have > *multiple* interceptors wrapping the JAX-WS Handler chains of > various types, the close() call should not be made from > within the existing wrapper interceptors. Otherwise we'd end > up with for example close() called prematurely on the > SOAPHandlers *before* the LogicalHandlers have even been > traversed (inbound on the client-side). > > So we'd need a *single* new wrapper interceptor, positioned > at the end of the in & fault-in interceptor chains, that's > responsible for calling > close() on all types of handler. This could be driven via a > pattern similar to the > LogicalHandlerInterceptor.onCompletion() method (e.g. the new > interceptor walks back along the chain to find the > LogicalHandlerInterceptor & SOAPHandlerInterceptor and calls > onCompletion() on these). On second thoughts, maybe a cleaner may of doing this would be allow an interceptor to register some sort of terminal action with the InterceptorChain to be executed when the chain traversal is complete, e.g. public interface InterceptorChain { void addTerminalAction(Runnable r); //... } Or alternatively take the Runnable as a return value from Interceptor.handleMessage/Fault(). Then in the InterceptorChain impl, run all the TerminalAction(s) from a finally block, e.g. public class PhaseInterceptorChain { public boolean doIntercept(Message m) { try { while (interceptorIterator.hasNext()) { interceptorIterator.next().handleMessage(m); } } finally { for (Runnable r : terminalActions) { r.run(); } } } } Then for example the LogicalHandlerInterceptor.handleMessage() would end with some logic like: if (isRequestor(message) && (isOneway(message) || !isOutbound(message))) { message.getInterceptorChain().addTerminalAction(new Runnable() { public void run() { getInvoker(message).mepComplete(message); } } } Similarly for SOAPHandlerInterceptor etc. Cheers, Eoghan
