1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.ws.soap.server;
18
19 import java.util.ArrayList;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Locale;
23 import javax.xml.namespace.QName;
24
25 import org.springframework.util.ObjectUtils;
26 import org.springframework.util.StringUtils;
27 import org.springframework.ws.context.MessageContext;
28 import org.springframework.ws.server.EndpointInterceptor;
29 import org.springframework.ws.server.EndpointInvocationChain;
30 import org.springframework.ws.server.MessageDispatcher;
31 import org.springframework.ws.soap.SoapBody;
32 import org.springframework.ws.soap.SoapFault;
33 import org.springframework.ws.soap.SoapHeader;
34 import org.springframework.ws.soap.SoapHeaderElement;
35 import org.springframework.ws.soap.SoapMessage;
36 import org.springframework.ws.soap.soap11.Soap11Header;
37 import org.springframework.ws.soap.soap12.Soap12Header;
38
39
40
41
42
43
44
45
46
47
48 public class SoapMessageDispatcher extends MessageDispatcher {
49
50
51 public static final String DEFAULT_MUST_UNDERSTAND_FAULT_STRING =
52 "One or more mandatory SOAP header blocks not understood";
53
54 private String mustUnderstandFaultString = DEFAULT_MUST_UNDERSTAND_FAULT_STRING;
55
56 private Locale mustUnderstandFaultStringLocale = Locale.ENGLISH;
57
58
59
60
61
62 public void setMustUnderstandFaultString(String mustUnderstandFaultString) {
63 this.mustUnderstandFaultString = mustUnderstandFaultString;
64 }
65
66
67 public void setMustUnderstandFaultStringLocale(Locale mustUnderstandFaultStringLocale) {
68 this.mustUnderstandFaultStringLocale = mustUnderstandFaultStringLocale;
69 }
70
71
72
73
74
75
76
77
78
79
80
81
82
83 @Override
84 protected boolean handleRequest(EndpointInvocationChain mappedEndpoint, MessageContext messageContext) {
85 if (messageContext.getRequest() instanceof SoapMessage) {
86 String[] actorsOrRoles = null;
87 boolean isUltimateReceiver = true;
88 if (mappedEndpoint instanceof SoapEndpointInvocationChain) {
89 SoapEndpointInvocationChain soapChain = (SoapEndpointInvocationChain) mappedEndpoint;
90 actorsOrRoles = soapChain.getActorsOrRoles();
91 isUltimateReceiver = soapChain.isUltimateReceiver();
92 }
93 return handleHeaders(mappedEndpoint, messageContext, actorsOrRoles, isUltimateReceiver);
94 }
95 return true;
96 }
97
98 private boolean handleHeaders(EndpointInvocationChain mappedEndpoint,
99 MessageContext messageContext,
100 String[] actorsOrRoles,
101 boolean isUltimateReceiver) {
102 SoapMessage soapRequest = (SoapMessage) messageContext.getRequest();
103 SoapHeader soapHeader = soapRequest.getSoapHeader();
104 if (soapHeader == null) {
105 return true;
106 }
107 Iterator<SoapHeaderElement> headerIterator;
108 if (soapHeader instanceof Soap11Header) {
109 headerIterator = ((Soap11Header) soapHeader).examineHeaderElementsToProcess(actorsOrRoles);
110 }
111 else {
112 headerIterator =
113 ((Soap12Header) soapHeader).examineHeaderElementsToProcess(actorsOrRoles, isUltimateReceiver);
114 }
115 List<QName> notUnderstoodHeaderNames = new ArrayList<QName>();
116 while (headerIterator.hasNext()) {
117 SoapHeaderElement headerElement = headerIterator.next();
118 QName headerName = headerElement.getName();
119 if (headerElement.getMustUnderstand() && logger.isDebugEnabled()) {
120 logger.debug("Handling MustUnderstand header " + headerName);
121 }
122 if (headerElement.getMustUnderstand() && !headerUnderstood(mappedEndpoint, headerElement)) {
123 notUnderstoodHeaderNames.add(headerName);
124 }
125 }
126 if (notUnderstoodHeaderNames.isEmpty()) {
127 return true;
128 }
129 else {
130 SoapMessage response = (SoapMessage) messageContext.getResponse();
131 createMustUnderstandFault(response, notUnderstoodHeaderNames, actorsOrRoles);
132 return false;
133 }
134 }
135
136
137
138
139
140
141
142
143
144 private boolean headerUnderstood(EndpointInvocationChain mappedEndpoint, SoapHeaderElement headerElement) {
145 EndpointInterceptor[] interceptors = mappedEndpoint.getInterceptors();
146 if (ObjectUtils.isEmpty(interceptors)) {
147 return false;
148 }
149 for (EndpointInterceptor interceptor : interceptors) {
150 if (interceptor instanceof SoapEndpointInterceptor &&
151 ((SoapEndpointInterceptor) interceptor).understands(headerElement)) {
152 return true;
153 }
154 }
155 return false;
156 }
157
158 private void createMustUnderstandFault(SoapMessage soapResponse,
159 List<QName> notUnderstoodHeaderNames,
160 String[] actorsOrRoles) {
161 if (logger.isWarnEnabled()) {
162 logger.warn("Could not handle mustUnderstand headers: " +
163 StringUtils.collectionToCommaDelimitedString(notUnderstoodHeaderNames) + ". Returning fault");
164 }
165 SoapBody responseBody = soapResponse.getSoapBody();
166 SoapFault fault =
167 responseBody.addMustUnderstandFault(mustUnderstandFaultString, mustUnderstandFaultStringLocale);
168 if (!ObjectUtils.isEmpty(actorsOrRoles)) {
169 fault.setFaultActorOrRole(actorsOrRoles[0]);
170 }
171 SoapHeader header = soapResponse.getSoapHeader();
172 if (header instanceof Soap12Header) {
173 Soap12Header soap12Header = (Soap12Header) header;
174 for (QName headerName : notUnderstoodHeaderNames) {
175 soap12Header.addNotUnderstoodHeaderElement(headerName);
176 }
177 }
178 }
179
180 }