1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.ws.server;
18
19 import java.io.ByteArrayOutputStream;
20 import java.util.ArrayList;
21 import java.util.Collections;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Map;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.springframework.beans.BeansException;
29 import org.springframework.beans.factory.BeanFactoryUtils;
30 import org.springframework.beans.factory.BeanNameAware;
31 import org.springframework.context.ApplicationContext;
32 import org.springframework.context.ApplicationContextAware;
33 import org.springframework.core.OrderComparator;
34 import org.springframework.core.io.ClassPathResource;
35 import org.springframework.core.io.Resource;
36 import org.springframework.util.ClassUtils;
37 import org.springframework.util.ObjectUtils;
38 import org.springframework.web.servlet.DispatcherServlet;
39 import org.springframework.ws.FaultAwareWebServiceMessage;
40 import org.springframework.ws.NoEndpointFoundException;
41 import org.springframework.ws.WebServiceMessage;
42 import org.springframework.ws.context.MessageContext;
43 import org.springframework.ws.server.endpoint.MessageEndpoint;
44 import org.springframework.ws.server.endpoint.PayloadEndpoint;
45 import org.springframework.ws.server.endpoint.adapter.MessageEndpointAdapter;
46 import org.springframework.ws.server.endpoint.adapter.MessageMethodEndpointAdapter;
47 import org.springframework.ws.server.endpoint.adapter.PayloadEndpointAdapter;
48 import org.springframework.ws.server.endpoint.adapter.PayloadMethodEndpointAdapter;
49 import org.springframework.ws.soap.server.SoapMessageDispatcher;
50 import org.springframework.ws.transport.WebServiceMessageReceiver;
51 import org.springframework.ws.transport.support.DefaultStrategiesHelper;
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 public class MessageDispatcher implements WebServiceMessageReceiver, BeanNameAware, ApplicationContextAware {
76
77
78 protected final Log logger = LogFactory.getLog(getClass());
79
80
81 public static final String ENDPOINT_NOT_FOUND_LOG_CATEGORY = "org.springframework.ws.server.EndpointNotFound";
82
83
84 protected static final Log endpointNotFoundLogger =
85 LogFactory.getLog(MessageDispatcher.ENDPOINT_NOT_FOUND_LOG_CATEGORY);
86
87
88 public static final String MESSAGE_TRACING_LOG_CATEGORY = "org.springframework.ws.server.MessageTracing";
89
90
91 protected static final Log messageTracingLogger = LogFactory.getLog(MessageDispatcher.MESSAGE_TRACING_LOG_CATEGORY);
92
93 private final DefaultStrategiesHelper defaultStrategiesHelper;
94
95
96 private String beanName;
97
98
99 private List endpointAdapters;
100
101
102 private List endpointExceptionResolvers;
103
104
105 private List endpointMappings;
106
107
108 public MessageDispatcher() {
109 Resource resource = new ClassPathResource(ClassUtils.getShortName(getClass()) + ".properties", getClass());
110 defaultStrategiesHelper = new DefaultStrategiesHelper(resource);
111 }
112
113
114 public List getEndpointAdapters() {
115 return endpointAdapters;
116 }
117
118
119 public void setEndpointAdapters(List endpointAdapters) {
120 this.endpointAdapters = endpointAdapters;
121 }
122
123
124 public List getEndpointExceptionResolvers() {
125 return endpointExceptionResolvers;
126 }
127
128
129 public void setEndpointExceptionResolvers(List endpointExceptionResolvers) {
130 this.endpointExceptionResolvers = endpointExceptionResolvers;
131 }
132
133
134 public List getEndpointMappings() {
135 return endpointMappings;
136 }
137
138
139 public void setEndpointMappings(List endpointMappings) {
140 this.endpointMappings = endpointMappings;
141 }
142
143 public final void setBeanName(String beanName) {
144 this.beanName = beanName;
145 }
146
147 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
148 initEndpointAdapters(applicationContext);
149 initEndpointExceptionResolvers(applicationContext);
150 initEndpointMappings(applicationContext);
151 }
152
153 public void receive(MessageContext messageContext) throws Exception {
154 if (messageTracingLogger.isTraceEnabled()) {
155 ByteArrayOutputStream os = new ByteArrayOutputStream();
156 messageContext.getRequest().writeTo(os);
157 messageTracingLogger.trace("Received request [" + os.toString("UTF-8") + "]");
158 }
159 else if (messageTracingLogger.isDebugEnabled()) {
160 messageTracingLogger.debug("Received request [" + messageContext.getRequest() + "]");
161 }
162 dispatch(messageContext);
163 if (messageContext.hasResponse()) {
164 if (messageTracingLogger.isTraceEnabled()) {
165 ByteArrayOutputStream requestStream = new ByteArrayOutputStream();
166 messageContext.getRequest().writeTo(requestStream);
167 ByteArrayOutputStream responseStream = new ByteArrayOutputStream();
168 messageContext.getResponse().writeTo(responseStream);
169 messageTracingLogger.trace("Sent response [" + responseStream.toString("UTF-8") + "] for request [" +
170 requestStream.toString("UTF-8") + "]");
171 }
172 else if (messageTracingLogger.isDebugEnabled()) {
173 messageTracingLogger.debug("Sendt response [" + messageContext.getResponse() + "] for request [" +
174 messageContext.getRequest() + "]");
175 }
176 }
177 else if (messageTracingLogger.isDebugEnabled()) {
178 messageTracingLogger.debug("MessageDispatcher with name '" + beanName +
179 "' sends no response for request [" + messageContext.getRequest() + "]");
180 }
181 }
182
183
184
185
186
187
188
189
190 protected final void dispatch(MessageContext messageContext) throws Exception {
191 EndpointInvocationChain mappedEndpoint = null;
192 int interceptorIndex = -1;
193 try {
194
195 mappedEndpoint = getEndpoint(messageContext);
196 if (mappedEndpoint == null || mappedEndpoint.getEndpoint() == null) {
197 throw new NoEndpointFoundException(messageContext.getRequest());
198 }
199 if (!handleRequest(mappedEndpoint, messageContext)) {
200 return;
201 }
202
203 if (mappedEndpoint.getInterceptors() != null) {
204 for (int i = 0; i < mappedEndpoint.getInterceptors().length; i++) {
205 EndpointInterceptor interceptor = mappedEndpoint.getInterceptors()[i];
206 interceptorIndex = i;
207 if (!interceptor.handleRequest(messageContext, mappedEndpoint.getEndpoint())) {
208 triggerHandleResponse(mappedEndpoint, interceptorIndex, messageContext);
209 return;
210 }
211 }
212 }
213
214 EndpointAdapter endpointAdapter = getEndpointAdapter(mappedEndpoint.getEndpoint());
215 endpointAdapter.invoke(messageContext, mappedEndpoint.getEndpoint());
216
217
218 triggerHandleResponse(mappedEndpoint, interceptorIndex, messageContext);
219 }
220 catch (NoEndpointFoundException ex) {
221
222 if (endpointNotFoundLogger.isWarnEnabled()) {
223 endpointNotFoundLogger.warn("No endpoint mapping found for [" + messageContext.getRequest() + "]");
224 }
225 throw ex;
226 }
227 catch (Exception ex) {
228 Object endpoint = mappedEndpoint != null ? mappedEndpoint.getEndpoint() : null;
229 processEndpointException(messageContext, endpoint, ex);
230 triggerHandleResponse(mappedEndpoint, interceptorIndex, messageContext);
231 }
232 }
233
234
235
236
237
238
239 protected EndpointInvocationChain getEndpoint(MessageContext messageContext) throws Exception {
240 for (Iterator iterator = endpointMappings.iterator(); iterator.hasNext();) {
241 EndpointMapping endpointMapping = (EndpointMapping) iterator.next();
242 EndpointInvocationChain endpoint = endpointMapping.getEndpoint(messageContext);
243 if (endpoint != null) {
244 if (logger.isDebugEnabled()) {
245 logger.debug("Endpoint mapping [" + endpointMapping + "] maps request to endpoint [" +
246 endpoint.getEndpoint() + "]");
247 }
248 return endpoint;
249 }
250 else if (logger.isDebugEnabled()) {
251 logger.debug("Endpoint mapping [" + endpointMapping + "] has no mapping for request");
252 }
253 }
254 return null;
255 }
256
257
258
259
260
261
262
263 protected EndpointAdapter getEndpointAdapter(Object endpoint) {
264 for (Iterator iterator = endpointAdapters.iterator(); iterator.hasNext();) {
265 EndpointAdapter endpointAdapter = (EndpointAdapter) iterator.next();
266 if (logger.isDebugEnabled()) {
267 logger.debug("Testing endpoint adapter [" + endpointAdapter + "]");
268 }
269 if (endpointAdapter.supports(endpoint)) {
270 return endpointAdapter;
271 }
272 }
273 throw new IllegalStateException("No adapter for endpoint [" + endpoint + "]: Does your endpoint implement a " +
274 "supported interface like MessageHandler or PayloadEndpoint?");
275 }
276
277
278
279
280
281
282
283
284
285
286
287 protected boolean handleRequest(EndpointInvocationChain mappedEndpoint, MessageContext messageContext) {
288 return true;
289 }
290
291
292
293
294
295
296
297
298
299
300
301 protected void processEndpointException(MessageContext messageContext, Object endpoint, Exception ex)
302 throws Exception {
303 for (Iterator iterator = endpointExceptionResolvers.iterator(); iterator.hasNext();) {
304 EndpointExceptionResolver resolver = (EndpointExceptionResolver) iterator.next();
305 if (logger.isDebugEnabled()) {
306 logger.debug("Testing endpoint exception resolver [" + resolver + "]");
307 }
308 if (resolver.resolveException(messageContext, endpoint, ex)) {
309 logger.warn("Endpoint invocation resulted in exception - responding with SOAP Fault", ex);
310 return;
311 }
312 }
313
314 throw ex;
315 }
316
317
318
319
320
321
322
323
324
325
326
327 private void triggerHandleResponse(EndpointInvocationChain mappedEndpoint,
328 int interceptorIndex,
329 MessageContext messageContext) throws Exception {
330 if (mappedEndpoint != null && messageContext.hasResponse() &&
331 !ObjectUtils.isEmpty(mappedEndpoint.getInterceptors())) {
332 boolean hasFault = false;
333 WebServiceMessage response = messageContext.getResponse();
334 if (response instanceof FaultAwareWebServiceMessage) {
335 hasFault = ((FaultAwareWebServiceMessage) response).hasFault();
336 }
337 boolean resume = true;
338 for (int i = interceptorIndex; resume && i >= 0; i--) {
339 EndpointInterceptor interceptor = mappedEndpoint.getInterceptors()[i];
340 if (!hasFault) {
341 resume = interceptor.handleResponse(messageContext, mappedEndpoint.getEndpoint());
342 }
343 else {
344 resume = interceptor.handleFault(messageContext, mappedEndpoint.getEndpoint());
345 }
346 }
347 }
348 }
349
350
351
352
353
354
355
356 private void initEndpointAdapters(ApplicationContext applicationContext) throws BeansException {
357 if (endpointAdapters == null) {
358 Map matchingBeans = BeanFactoryUtils
359 .beansOfTypeIncludingAncestors(applicationContext, EndpointAdapter.class, true, false);
360 if (!matchingBeans.isEmpty()) {
361 endpointAdapters = new ArrayList(matchingBeans.values());
362 Collections.sort(endpointAdapters, new OrderComparator());
363 }
364 else {
365 endpointAdapters =
366 defaultStrategiesHelper.getDefaultStrategies(EndpointAdapter.class, applicationContext);
367 if (logger.isDebugEnabled()) {
368 logger.debug("No EndpointAdapters found, using defaults");
369 }
370 }
371 }
372 }
373
374
375
376
377
378
379
380 private void initEndpointExceptionResolvers(ApplicationContext applicationContext) throws BeansException {
381 if (endpointExceptionResolvers == null) {
382 Map matchingBeans = BeanFactoryUtils
383 .beansOfTypeIncludingAncestors(applicationContext, EndpointExceptionResolver.class, true, false);
384 if (!matchingBeans.isEmpty()) {
385 endpointExceptionResolvers = new ArrayList(matchingBeans.values());
386 Collections.sort(endpointExceptionResolvers, new OrderComparator());
387 }
388 else {
389 endpointExceptionResolvers = defaultStrategiesHelper
390 .getDefaultStrategies(EndpointExceptionResolver.class, applicationContext);
391 if (logger.isDebugEnabled()) {
392 logger.debug("No EndpointExceptionResolvers found, using defaults");
393 }
394 }
395 }
396 }
397
398
399
400
401
402
403
404 private void initEndpointMappings(ApplicationContext applicationContext) throws BeansException {
405 if (endpointMappings == null) {
406 Map matchingBeans = BeanFactoryUtils
407 .beansOfTypeIncludingAncestors(applicationContext, EndpointMapping.class, true, false);
408 if (!matchingBeans.isEmpty()) {
409 endpointMappings = new ArrayList(matchingBeans.values());
410 Collections.sort(endpointMappings, new OrderComparator());
411 }
412 else {
413 endpointMappings = defaultStrategiesHelper
414 .getDefaultStrategies(EndpointMapping.class, applicationContext);
415 if (logger.isDebugEnabled()) {
416 logger.debug("No EndpointMappings found, using defaults");
417 }
418 }
419 }
420 }
421 }