11/*
2- * Copyright 2002-2009 the original author or authors.
2+ * Copyright 2005-2011 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
66 * You may obtain a copy of the License at
77 *
8- * http://www.apache.org/licenses/LICENSE-2.0
8+ * http://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424import java .util .List ;
2525import java .util .Map ;
2626
27- import org .apache .commons .logging .Log ;
28- import org .apache .commons .logging .LogFactory ;
29-
3027import org .springframework .beans .BeansException ;
3128import org .springframework .beans .factory .BeanFactoryUtils ;
3229import org .springframework .beans .factory .BeanNameAware ;
4542import org .springframework .ws .server .endpoint .MessageEndpoint ;
4643import org .springframework .ws .server .endpoint .PayloadEndpoint ;
4744import org .springframework .ws .server .endpoint .adapter .MessageEndpointAdapter ;
48- import org .springframework .ws .server .endpoint .adapter .MessageMethodEndpointAdapter ;
4945import org .springframework .ws .server .endpoint .adapter .PayloadEndpointAdapter ;
50- import org .springframework .ws .server .endpoint .adapter .PayloadMethodEndpointAdapter ;
5146import org .springframework .ws .soap .server .SoapMessageDispatcher ;
5247import org .springframework .ws .support .DefaultStrategiesHelper ;
5348import org .springframework .ws .transport .WebServiceMessageReceiver ;
5449
50+ import org .apache .commons .logging .Log ;
51+ import org .apache .commons .logging .LogFactory ;
52+
5553/**
5654 * Central dispatcher for use within Spring-WS, dispatching Web service messages to registered endpoints.
5755 * <p/>
5856 * This dispatcher is quite similar to Spring MVCs {@link DispatcherServlet}. Just like its counterpart, this dispatcher
5957 * is very flexible. This class is SOAP agnostic; in typical SOAP Web Services, the {@link SoapMessageDispatcher}
60- * subclass is used. <ul> <li>It can use any {@link EndpointMapping} implementation - whether standard, or provided as
58+ * subclass is used.
59+ * <ul>
60+ * <li>It can use any {@link EndpointMapping} implementation - whether standard, or provided as
6161 * part of an application - to control the routing of request messages to endpoint objects. Endpoint mappings can be
62- * registered using the <code>endpointMappings</code> property.</li> <li>It can use any {@link EndpointAdapter}; this
63- * allows one to use any endpoint interface or form. Defaults to the {@link MessageEndpointAdapter} and {@link
64- * PayloadEndpointAdapter}, for {@link MessageEndpoint} and {@link PayloadEndpoint}, respectively, and the {@link
65- * MessageMethodEndpointAdapter} and {@link PayloadMethodEndpointAdapter}. Additional endpoint adapters can be added
66- * through the <code>endpointAdapters</code> property.</li> <li>Its exception resolution strategy can be specified via a
62+ * registered using the {@link #setEndpointMappings(List) endpointMappings} property.</li>
63+ * <li>It can use any {@link EndpointAdapter}; this allows one to use any endpoint interface or form. Defaults to
64+ * the {@link MessageEndpointAdapter} and {@link PayloadEndpointAdapter}, for {@link MessageEndpoint} and
65+ * {@link PayloadEndpoint}, respectively, and the
66+ * {@link org.springframework.ws.server.endpoint.adapter.MessageMethodEndpointAdapter MessageMethodEndpointAdapter} and
67+ * {@link org.springframework.ws.server.endpoint.adapter.PayloadMethodEndpointAdapter PayloadMethodEndpointAdapter}.
68+ * Additional endpoint adapters can be added through the {@link #setEndpointAdapters(List) endpointAdapters} property.</li>
69+ * <li>Its exception resolution strategy can be specified via a
6770 * {@link EndpointExceptionResolver}, for example mapping certain exceptions to SOAP Faults. Default is none. Additional
68- * exception resolvers can be added through the <code>endpointExceptionResolvers</code> property.</li> </ul>
71+ * exception resolvers can be added through the {@link #setEndpointExceptionResolvers(List) endpointExceptionResolvers}
72+ * property.</li>
73+ * </ul>
6974 *
7075 * @author Arjen Poutsma
7176 * @see EndpointMapping
@@ -221,6 +226,7 @@ protected final void dispatch(MessageContext messageContext) throws Exception {
221226 interceptorIndex = i ;
222227 if (!interceptor .handleRequest (messageContext , mappedEndpoint .getEndpoint ())) {
223228 triggerHandleResponse (mappedEndpoint , interceptorIndex , messageContext );
229+ triggerAfterCompletion (mappedEndpoint , interceptorIndex , messageContext , null );
224230 return ;
225231 }
226232 }
@@ -231,6 +237,7 @@ protected final void dispatch(MessageContext messageContext) throws Exception {
231237
232238 // Apply handleResponse methods of registered interceptors
233239 triggerHandleResponse (mappedEndpoint , interceptorIndex , messageContext );
240+ triggerAfterCompletion (mappedEndpoint , interceptorIndex , messageContext , null );
234241 }
235242 catch (NoEndpointFoundException ex ) {
236243 // No triggering of interceptors if no endpoint is found
@@ -243,6 +250,7 @@ protected final void dispatch(MessageContext messageContext) throws Exception {
243250 Object endpoint = mappedEndpoint != null ? mappedEndpoint .getEndpoint () : null ;
244251 processEndpointException (messageContext , endpoint , ex );
245252 triggerHandleResponse (mappedEndpoint , interceptorIndex , messageContext );
253+ triggerAfterCompletion (mappedEndpoint , interceptorIndex , messageContext , ex );
246254 }
247255 }
248256
@@ -363,7 +371,41 @@ private void triggerHandleResponse(EndpointInvocationChain mappedEndpoint,
363371 }
364372
365373 /**
366- * Initialize the <code>EndpointAdapters</code> used by this class. If no adapter beans are explictely set by using
374+ * Trigger afterCompletion callbacks on the mapped EndpointInterceptors.
375+ * Will just invoke afterCompletion for all interceptors whose handleRequest invocation
376+ * has successfully completed and returned true, in addition to the last interceptor who
377+ * returned <code>false</code>.
378+ *
379+ * @param mappedEndpoint the mapped EndpointInvocationChain
380+ * @param interceptorIndex index of last interceptor that successfully completed
381+ * @param ex Exception thrown on handler execution, or <code>null</code> if none
382+ * @see EndpointInterceptor#afterCompletion
383+ */
384+ private void triggerAfterCompletion (EndpointInvocationChain mappedEndpoint ,
385+ int interceptorIndex ,
386+ MessageContext messageContext ,
387+ Exception ex ) throws Exception {
388+
389+ // Apply afterCompletion methods of registered interceptors.
390+ if (mappedEndpoint != null ) {
391+ EndpointInterceptor [] interceptors = mappedEndpoint .getInterceptors ();
392+ if (interceptors != null ) {
393+ for (int i = interceptorIndex ; i >= 0 ; i --) {
394+ EndpointInterceptor interceptor = interceptors [i ];
395+ try {
396+ interceptor .afterCompletion (messageContext , mappedEndpoint .getEndpoint (), ex );
397+ }
398+ catch (Throwable ex2 ) {
399+ logger .error ("EndpointInterceptor.afterCompletion threw exception" , ex2 );
400+ }
401+ }
402+ }
403+ }
404+ }
405+
406+
407+ /**
408+ * Initialize the <code>EndpointAdapters</code> used by this class. If no adapter beans are explicitly set by using
367409 * the <code>endpointAdapters</code> property, we use the default strategies.
368410 *
369411 * @see #setEndpointAdapters(java.util.List)
0 commit comments