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