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