1 /*
2  * Copyright 2005-2014 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *       http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.ws.config.annotation;
18
19 import java.util.ArrayList;
20 import java.util.List;
21
22 import org.springframework.context.annotation.Bean;
23 import org.springframework.context.annotation.Configuration;
24 import org.springframework.core.Ordered;
25 import org.springframework.ws.server.EndpointAdapter;
26 import org.springframework.ws.server.EndpointExceptionResolver;
27 import org.springframework.ws.server.EndpointInterceptor;
28 import org.springframework.ws.server.EndpointMapping;
29 import org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter;
30 import org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver;
31 import org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler;
32 import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
33 import org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping;
34 import org.springframework.ws.soap.addressing.server.AnnotationActionEndpointMapping;
35 import org.springframework.ws.soap.addressing.server.annotation.Action;
36 import org.springframework.ws.soap.server.endpoint.SimpleSoapExceptionResolver;
37 import org.springframework.ws.soap.server.endpoint.SoapFaultAnnotationExceptionResolver;
38 import org.springframework.ws.soap.server.endpoint.annotation.SoapAction;
39 import org.springframework.ws.soap.server.endpoint.annotation.SoapFault;
40 import org.springframework.ws.soap.server.endpoint.mapping.SoapActionAnnotationMethodEndpointMapping;
41
42 /**
43  * This is the main class providing the configuration behind the Spring Web Services Java
44  * config. It is typically imported by adding {@link EnableWs @EnableWs} to an
45  * application {@link Configuration @Configuration} class. An alternative, more
46  * advanced option is to extend directly from this class and override methods as
47  * necessary remembering to add {@link Configuration @Configuration} to the
48  * subclass and {@link Bean @Bean} to overridden {@link Bean @Bean} methods.
49  * For more details see the Javadoc of {@link EnableWs @EnableWs}.
50  *
51  * <p>This class registers the following {@link EndpointMapping}s:
52  * <ul>
53  *    <li>{@link PayloadRootAnnotationMethodEndpointMapping}
54  *    ordered at 0 for mapping requests to {@link PayloadRoot @PayloadRoot} annotated
55  *    controller methods.
56  *    <li>{@link SoapActionAnnotationMethodEndpointMapping}
57  *    ordered at 1 for mapping requests to {@link SoapAction @SoapAction} annotated
58  *    controller methods.
59  *    <li>{@link AnnotationActionEndpointMapping}
60  *    ordered at 2 for mapping requests to {@link Action @Action} annotated
61  *    controller methods.
62  * </ul>
63  *
64  * <p>Registers one {@link EndpointAdapter}:
65  * <ul>
66  *    <li>{@link DefaultMethodEndpointAdapter}
67  *    for processing requests with annotated endpoint methods.
68  * </ul>
69  *
70  * <p>Registers the following {@link EndpointExceptionResolver}s:
71  * <ul>
72  *    <li>{@link SoapFaultAnnotationExceptionResolver} for handling exceptions
73  *    annotated with {@link SoapFault @SoapFault}.
74  *    <li>{@link SimpleSoapExceptionResolver} for creating default exceptions.
75  * </ul>
76  *
77  * @see EnableWs
78  * @see WsConfigurer
79  * @see WsConfigurerAdapter
80  *
81  * @author Arjen Poutsma
82  * @since 2.2
83  */

84 public class WsConfigurationSupport {
85
86     private List<EndpointInterceptor> interceptors;
87
88     /**
89      * Returns a {@link PayloadRootAnnotationMethodEndpointMapping} ordered at 0 for
90      * mapping requests to annotated endpoints.
91      */

92     @Bean
93     public PayloadRootAnnotationMethodEndpointMapping payloadRootAnnotationMethodEndpointMapping() {
94         PayloadRootAnnotationMethodEndpointMapping endpointMapping =
95                 new PayloadRootAnnotationMethodEndpointMapping();
96         endpointMapping.setOrder(0);
97         endpointMapping.setInterceptors(getInterceptors());
98         return endpointMapping;
99     }
100
101     /**
102      * Returns a {@link SoapActionAnnotationMethodEndpointMapping} ordered at 1 for
103      * mapping requests to annotated endpoints.
104      */

105     @Bean
106     public SoapActionAnnotationMethodEndpointMapping soapActionAnnotationMethodEndpointMapping() {
107         SoapActionAnnotationMethodEndpointMapping endpointMapping =
108                 new SoapActionAnnotationMethodEndpointMapping();
109         endpointMapping.setOrder(1);
110         endpointMapping.setInterceptors(getInterceptors());
111         return endpointMapping;
112     }
113
114     /**
115      * Returns a {@link AnnotationActionEndpointMapping} ordered at 2 for
116      * mapping requests to annotated endpoints.
117      */

118     @Bean
119     public AnnotationActionEndpointMapping annotationActionEndpointMapping() {
120         AnnotationActionEndpointMapping endpointMapping =
121                 new AnnotationActionEndpointMapping();
122         endpointMapping.setOrder(2);
123         endpointMapping.setPostInterceptors(getInterceptors());
124         return endpointMapping;
125     }
126
127     /**
128      * Provide access to the shared handler interceptors used to configure
129      * {@link EndpointMapping} instances with. This method cannot be overridden,
130      * use {@link #addInterceptors(List)} instead.
131      */

132     protected final EndpointInterceptor[] getInterceptors() {
133         if (interceptors == null) {
134             interceptors = new ArrayList<EndpointInterceptor>();
135             addInterceptors(interceptors);
136         }
137         return interceptors.toArray(new EndpointInterceptor[interceptors.size()]);
138     }
139
140     /**
141      * Template method to add endpoint interceptors. Override this method to add Spring-WS
142      * interceptors for pre- and post-processing of endpoint invocation.
143      */

144     protected void addInterceptors(List<EndpointInterceptor> interceptors) {
145     }
146
147     /**
148      * Returns a {@link DefaultMethodEndpointAdapter} for processing requests
149      * through annotated endpoint methods. Consider overriding one of these
150      * other more fine-grained methods:
151      * <ul>
152      *    <li>{@link #addArgumentResolvers(List)} for adding custom argument resolvers.
153      *    <li>{@link #addReturnValueHandlers(List)} for adding custom return value handlers.
154      * </ul>
155      */

156     @Bean
157     public DefaultMethodEndpointAdapter defaultMethodEndpointAdapter() {
158         List<MethodArgumentResolver> argumentResolvers =
159                 new ArrayList<MethodArgumentResolver>();
160         addArgumentResolvers(argumentResolvers);
161
162         List<MethodReturnValueHandler> returnValueHandlers =
163                 new ArrayList<MethodReturnValueHandler>();
164         addReturnValueHandlers(returnValueHandlers);
165
166         DefaultMethodEndpointAdapter adapter = new DefaultMethodEndpointAdapter();
167         adapter.setCustomMethodArgumentResolvers(argumentResolvers);
168         adapter.setCustomMethodReturnValueHandlers(returnValueHandlers);
169
170         return adapter;
171     }
172
173     /**
174      * Add custom {@link MethodArgumentResolver}s to use in addition to
175      * the ones registered by default.
176      * @param argumentResolvers the list of custom converters;
177      *    initially an empty list.
178      */

179     protected void addArgumentResolvers(List<MethodArgumentResolver> argumentResolvers) {
180     }
181
182     /**
183      * Add custom {@link MethodReturnValueHandler}s in addition to the
184      * ones registered by default.
185      * @param returnValueHandlers the list of custom handlers;
186      * initially an empty list.
187      */

188     protected void addReturnValueHandlers(
189             List<MethodReturnValueHandler> returnValueHandlers) {
190     }
191
192     /**
193      * Returns a {@link SoapFaultAnnotationExceptionResolver} ordered at 0 for handling
194      * endpoint exceptions.
195      */

196     @Bean
197     public SoapFaultAnnotationExceptionResolver soapFaultAnnotationExceptionResolver() {
198         SoapFaultAnnotationExceptionResolver exceptionResolver = new SoapFaultAnnotationExceptionResolver();
199         exceptionResolver.setOrder(0);
200
201         return exceptionResolver;
202     }
203
204     /**
205      * Returns a {@link SimpleSoapExceptionResolver} ordered at
206      * {@linkplain Ordered#LOWEST_PRECEDENCE lowest precedence} for handling endpoint
207      * exceptions.
208      */

209     @Bean
210     public SimpleSoapExceptionResolver simpleSoapExceptionResolver() {
211         SimpleSoapExceptionResolver exceptionResolver = new SimpleSoapExceptionResolver();
212         exceptionResolver.setOrder(Ordered.LOWEST_PRECEDENCE);
213
214         return exceptionResolver;
215     }
216
217 }
218