1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.ws.soap.saaj;
18
19 import java.io.IOException;
20 import java.io.OutputStream;
21 import java.util.Iterator;
22 import javax.activation.DataHandler;
23 import javax.xml.soap.AttachmentPart;
24 import javax.xml.soap.MimeHeaders;
25 import javax.xml.soap.SOAPBody;
26 import javax.xml.soap.SOAPElement;
27 import javax.xml.soap.SOAPEnvelope;
28 import javax.xml.soap.SOAPException;
29 import javax.xml.soap.SOAPMessage;
30 import javax.xml.soap.SOAPPart;
31
32 import org.springframework.util.Assert;
33 import org.springframework.util.ObjectUtils;
34 import org.springframework.ws.mime.Attachment;
35 import org.springframework.ws.mime.AttachmentException;
36 import org.springframework.ws.soap.AbstractSoapMessage;
37 import org.springframework.ws.soap.SoapEnvelope;
38 import org.springframework.ws.soap.SoapMessage;
39 import org.springframework.ws.soap.SoapVersion;
40 import org.springframework.ws.soap.saaj.support.SaajUtils;
41 import org.springframework.ws.soap.support.SoapUtils;
42 import org.springframework.ws.transport.TransportConstants;
43
44
45
46
47
48
49
50
51
52 public class SaajSoapMessage extends AbstractSoapMessage {
53
54 private static final String CONTENT_TYPE_XOP = "application/xop+xml";
55
56 private SOAPMessage saajMessage;
57
58 private SoapEnvelope envelope;
59
60 private final boolean langAttributeOnSoap11FaultString;
61
62 private SaajImplementation implementation;
63
64
65
66
67
68
69 public SaajSoapMessage(SOAPMessage soapMessage) {
70 this(soapMessage, true);
71 }
72
73
74
75
76
77
78
79
80 public SaajSoapMessage(SOAPMessage soapMessage, boolean langAttributeOnSoap11FaultString) {
81 Assert.notNull(soapMessage, "soapMessage must not be null");
82 saajMessage = soapMessage;
83 this.langAttributeOnSoap11FaultString = langAttributeOnSoap11FaultString;
84 MimeHeaders headers = getImplementation().getMimeHeaders(soapMessage);
85 if (ObjectUtils.isEmpty(headers.getHeader(TransportConstants.HEADER_SOAP_ACTION))) {
86 headers.addHeader(TransportConstants.HEADER_SOAP_ACTION, "\"\"");
87 }
88 }
89
90
91 public SOAPMessage getSaajMessage() {
92 return saajMessage;
93 }
94
95
96 public void setSaajMessage(SOAPMessage soapMessage) {
97 Assert.notNull(soapMessage, "soapMessage must not be null");
98 saajMessage = soapMessage;
99 envelope = null;
100 }
101
102 public SoapEnvelope getEnvelope() {
103 if (envelope == null) {
104 try {
105 SOAPEnvelope saajEnvelope = getImplementation().getEnvelope(getSaajMessage());
106 envelope = new SaajSoapEnvelope(saajEnvelope, langAttributeOnSoap11FaultString);
107 }
108 catch (SOAPException ex) {
109 throw new SaajSoapEnvelopeException(ex);
110 }
111 }
112 return envelope;
113 }
114
115 public String getSoapAction() {
116 MimeHeaders mimeHeaders = getImplementation().getMimeHeaders(getSaajMessage());
117 if (SoapVersion.SOAP_11 == getVersion()) {
118 String[] actions = mimeHeaders.getHeader(TransportConstants.HEADER_SOAP_ACTION);
119 return ObjectUtils.isEmpty(actions) ? TransportConstants.EMPTY_SOAP_ACTION : actions[0];
120 }
121 else if (SoapVersion.SOAP_12 == getVersion()) {
122 String[] contentTypes = mimeHeaders.getHeader(TransportConstants.HEADER_CONTENT_TYPE);
123 return !ObjectUtils.isEmpty(contentTypes) ? SoapUtils.extractActionFromContentType(contentTypes[0]) :
124 TransportConstants.EMPTY_SOAP_ACTION;
125 }
126 else {
127 throw new IllegalStateException("Unsupported SOAP version: " + getVersion());
128 }
129 }
130
131 public void setSoapAction(String soapAction) {
132 MimeHeaders mimeHeaders = getImplementation().getMimeHeaders(getSaajMessage());
133 soapAction = SoapUtils.escapeAction(soapAction);
134 if (SoapVersion.SOAP_11 == getVersion()) {
135 mimeHeaders.setHeader(TransportConstants.HEADER_SOAP_ACTION, soapAction);
136 }
137 else if (SoapVersion.SOAP_12 == getVersion()) {
138
139 if (saajMessage.saveRequired()) {
140 try {
141 saajMessage.saveChanges();
142 }
143 catch (SOAPException ex) {
144 throw new SaajSoapMessageException("Could not save message", ex);
145 }
146 }
147 String[] contentTypes = mimeHeaders.getHeader(TransportConstants.HEADER_CONTENT_TYPE);
148 String contentType = !ObjectUtils.isEmpty(contentTypes) ? contentTypes[0] : getVersion().getContentType();
149 contentType = SoapUtils.setActionInContentType(contentType, soapAction);
150 mimeHeaders.setHeader(TransportConstants.HEADER_CONTENT_TYPE, contentType);
151 mimeHeaders.removeHeader(TransportConstants.HEADER_SOAP_ACTION);
152 }
153 else {
154 throw new IllegalStateException("Unsupported SOAP version: " + getVersion());
155 }
156
157 }
158
159 public void writeTo(OutputStream outputStream) throws IOException {
160 MimeHeaders mimeHeaders = getImplementation().getMimeHeaders(getSaajMessage());
161 if (ObjectUtils.isEmpty(mimeHeaders.getHeader(TransportConstants.HEADER_ACCEPT))) {
162 mimeHeaders.setHeader(TransportConstants.HEADER_ACCEPT, getVersion().getContentType());
163 }
164 try {
165 getImplementation().writeTo(getSaajMessage(), outputStream);
166 outputStream.flush();
167 }
168 catch (SOAPException ex) {
169 throw new SaajSoapMessageException("Could not write message to OutputStream: " + ex.getMessage(), ex);
170 }
171 }
172
173 public boolean isXopPackage() {
174 if (SaajUtils.getSaajVersion(saajMessage) >= SaajUtils.SAAJ_13) {
175 SOAPPart saajPart = saajMessage.getSOAPPart();
176 String[] contentTypes = saajPart.getMimeHeader(TransportConstants.HEADER_CONTENT_TYPE);
177 for (int i = 0; i < contentTypes.length; i++) {
178 if (contentTypes[i].indexOf(CONTENT_TYPE_XOP) != -1) {
179 return true;
180 }
181 }
182 }
183 return false;
184 }
185
186 public boolean convertToXopPackage() {
187 if (SaajUtils.getSaajVersion(saajMessage) >= SaajUtils.SAAJ_13) {
188 convertMessageToXop();
189 convertPartToXop();
190 return true;
191 }
192 else {
193 return false;
194 }
195 }
196
197 private void convertMessageToXop() {
198 MimeHeaders mimeHeaders = saajMessage.getMimeHeaders();
199 String[] oldContentTypes = mimeHeaders.getHeader(TransportConstants.HEADER_CONTENT_TYPE);
200 String oldContentType =
201 !ObjectUtils.isEmpty(oldContentTypes) ? oldContentTypes[0] : getVersion().getContentType();
202 StringBuffer buffer = new StringBuffer(CONTENT_TYPE_XOP);
203 buffer.append(";type=");
204 buffer.append('"');
205 buffer.append(oldContentType);
206 buffer.append('"');
207 mimeHeaders.setHeader(TransportConstants.HEADER_CONTENT_TYPE, buffer.toString());
208 }
209
210 private void convertPartToXop() {
211 SOAPPart saajPart = saajMessage.getSOAPPart();
212 String[] oldContentTypes = saajPart.getMimeHeader(TransportConstants.HEADER_CONTENT_TYPE);
213 String oldContentType =
214 !ObjectUtils.isEmpty(oldContentTypes) ? oldContentTypes[0] : getVersion().getContentType();
215 StringBuffer buffer = new StringBuffer(CONTENT_TYPE_XOP);
216 buffer.append(";type=");
217 buffer.append('"');
218 buffer.append(oldContentType);
219 buffer.append('"');
220 saajPart.setMimeHeader(TransportConstants.HEADER_CONTENT_TYPE, buffer.toString());
221 }
222
223 public Iterator getAttachments() throws AttachmentException {
224 Iterator iterator = getImplementation().getAttachments(getSaajMessage());
225 return new SaajAttachmentIterator(iterator);
226 }
227
228 public Attachment getAttachment(String contentId) {
229 Assert.hasLength(contentId, "contentId must not be empty");
230 MimeHeaders mimeHeaders = new MimeHeaders();
231 mimeHeaders.setHeader(TransportConstants.HEADER_CONTENT_ID, contentId);
232 Iterator iterator = getImplementation().getAttachment(getSaajMessage(), mimeHeaders);
233 if (!iterator.hasNext()) {
234 return null;
235 }
236 AttachmentPart saajAttachment = (AttachmentPart) iterator.next();
237 return new SaajAttachment(saajAttachment);
238 }
239
240 public Attachment addAttachment(String contentId, DataHandler dataHandler) {
241 Assert.hasLength(contentId, "contentId must not be empty");
242 Assert.notNull(dataHandler, "dataHandler must not be null");
243 AttachmentPart saajAttachment = getImplementation().addAttachmentPart(getSaajMessage(), dataHandler);
244 saajAttachment.setContentId(contentId);
245 saajAttachment.setMimeHeader(TransportConstants.HEADER_CONTENT_TRANSFER_ENCODING, "binary");
246 return new SaajAttachment(saajAttachment);
247 }
248
249 protected final SaajImplementation getImplementation() {
250 if (implementation == null) {
251 if (SaajUtils.getSaajVersion(saajMessage) == SaajUtils.SAAJ_13) {
252 implementation = Saaj13Implementation.getInstance();
253 }
254 else if (SaajUtils.getSaajVersion(saajMessage) == SaajUtils.SAAJ_12) {
255 implementation = Saaj12Implementation.getInstance();
256 }
257 else if (SaajUtils.getSaajVersion(saajMessage) == SaajUtils.SAAJ_11) {
258 implementation = Saaj11Implementation.getInstance();
259 }
260 else {
261 throw new IllegalStateException("Could not find SAAJ on the classpath");
262 }
263 }
264 return implementation;
265 }
266
267 public String toString() {
268 StringBuffer buffer = new StringBuffer("SaajSoapMessage");
269 try {
270 SOAPEnvelope envelope = getImplementation().getEnvelope(saajMessage);
271 if (envelope != null) {
272 SOAPBody body = getImplementation().getBody(envelope);
273 if (body != null) {
274 SOAPElement bodyElement = getImplementation().getFirstBodyElement(body);
275 if (bodyElement != null) {
276 buffer.append(' ');
277 buffer.append(getImplementation().getName(bodyElement));
278 }
279 }
280 }
281 }
282 catch (SOAPException ex) {
283
284 }
285 return buffer.toString();
286 }
287
288 private static class SaajAttachmentIterator implements Iterator {
289
290 private final Iterator saajIterator;
291
292 private SaajAttachmentIterator(Iterator saajIterator) {
293 this.saajIterator = saajIterator;
294 }
295
296 public boolean hasNext() {
297 return saajIterator.hasNext();
298 }
299
300 public Object next() {
301 AttachmentPart saajAttachment = (AttachmentPart) saajIterator.next();
302 return new SaajAttachment(saajAttachment);
303 }
304
305 public void remove() {
306 saajIterator.remove();
307 }
308 }
309
310 }