001: /*
002: * Copyright 2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.ws.soap.saaj;
018:
019: import java.io.IOException;
020: import java.io.OutputStream;
021: import java.util.ArrayList;
022: import java.util.Iterator;
023: import java.util.List;
024: import java.util.Locale;
025: import javax.activation.DataHandler;
026: import javax.xml.namespace.QName;
027: import javax.xml.soap.AttachmentPart;
028: import javax.xml.soap.Detail;
029: import javax.xml.soap.DetailEntry;
030: import javax.xml.soap.MimeHeader;
031: import javax.xml.soap.MimeHeaders;
032: import javax.xml.soap.Name;
033: import javax.xml.soap.SOAPBody;
034: import javax.xml.soap.SOAPElement;
035: import javax.xml.soap.SOAPEnvelope;
036: import javax.xml.soap.SOAPException;
037: import javax.xml.soap.SOAPFault;
038: import javax.xml.soap.SOAPHeader;
039: import javax.xml.soap.SOAPHeaderElement;
040: import javax.xml.soap.SOAPMessage;
041: import javax.xml.transform.Result;
042: import javax.xml.transform.Source;
043: import javax.xml.transform.sax.SAXResult;
044: import javax.xml.transform.sax.SAXSource;
045:
046: import org.springframework.util.ObjectUtils;
047: import org.springframework.util.StringUtils;
048: import org.springframework.ws.soap.SoapVersion;
049: import org.springframework.ws.soap.saaj.support.SaajContentHandler;
050: import org.springframework.ws.soap.saaj.support.SaajUtils;
051: import org.springframework.ws.soap.saaj.support.SaajXmlReader;
052: import org.springframework.ws.transport.TransportOutputStream;
053: import org.springframework.xml.namespace.QNameUtils;
054: import org.xml.sax.InputSource;
055:
056: /**
057: * SAAJ 1.1 specific implementation of the <code>SaajImplementation</code> interface.
058: *
059: * @author Arjen Poutsma
060: * @since 1.0.0
061: */
062: public class Saaj11Implementation implements SaajImplementation {
063:
064: private static final Saaj11Implementation INSTANCE = new Saaj11Implementation();
065:
066: private Saaj11Implementation() {
067: }
068:
069: public static Saaj11Implementation getInstance() {
070: return INSTANCE;
071: }
072:
073: public QName getName(SOAPElement element) {
074: return SaajUtils.toQName(element.getElementName());
075: }
076:
077: public Source getSource(SOAPElement element) {
078: return new SAXSource(new SaajXmlReader(element),
079: new InputSource());
080: }
081:
082: public Result getResult(SOAPElement element) {
083: return new SAXResult(new SaajContentHandler(element));
084: }
085:
086: public String getText(SOAPElement element) {
087: return element.getValue();
088: }
089:
090: public void setText(SOAPElement element, String content)
091: throws SOAPException {
092: element.addTextNode(content);
093: }
094:
095: public void addAttribute(SOAPElement element, QName name,
096: String value) throws SOAPException {
097: Name attributeName = SaajUtils.toName(name, element);
098: element.addAttribute(attributeName, value);
099: }
100:
101: public void removeAttribute(SOAPElement element, QName name)
102: throws SOAPException {
103: Name attributeName = SaajUtils.toName(name, element);
104: element.removeAttribute(attributeName);
105: }
106:
107: public String getAttributeValue(SOAPElement element, QName name)
108: throws SOAPException {
109: Name attributeName = SaajUtils.toName(name, element);
110: return element.getAttributeValue(attributeName);
111: }
112:
113: public Iterator getAllAttibutes(SOAPElement element) {
114: List results = new ArrayList();
115: for (Iterator iterator = element.getAllAttributes(); iterator
116: .hasNext();) {
117: Name attributeName = (Name) iterator.next();
118: results.add(SaajUtils.toQName(attributeName));
119: }
120: return results.iterator();
121: }
122:
123: public QName getFaultCode(SOAPFault fault) {
124: String code = fault.getFaultCode();
125: int idx = code.indexOf(':');
126: if (idx != -1) {
127: String prefix = code.substring(0, idx);
128: String namespace = fault.getNamespaceURI(prefix);
129: if (StringUtils.hasLength(namespace)) {
130: return QNameUtils.createQName(namespace, code
131: .substring(idx + 1), prefix);
132: }
133: }
134: return new QName(code);
135: }
136:
137: public boolean isSoap11(SOAPElement element) {
138: return true;
139: }
140:
141: public DetailEntry addDetailEntry(Detail detail, QName name)
142: throws SOAPException {
143: Name detailEntryName = SaajUtils.toName(name, detail);
144: return detail.addDetailEntry(detailEntryName);
145: }
146:
147: public SOAPHeaderElement addHeaderElement(SOAPHeader header,
148: QName name) throws SOAPException {
149: Name saajName = SaajUtils.toName(name, header);
150: return header.addHeaderElement(saajName);
151: }
152:
153: public SOAPFault addFault(SOAPBody body, QName faultCode,
154: String faultString, Locale locale) throws SOAPException {
155: SOAPFault fault = body.addFault();
156: if (StringUtils.hasLength(faultCode.getNamespaceURI())
157: && StringUtils.hasLength(QNameUtils
158: .getPrefix(faultCode))) {
159: fault.addNamespaceDeclaration(faultCode.getPrefix(),
160: faultCode.getNamespaceURI());
161: fault.setFaultCode(faultCode.getPrefix() + ":"
162: + faultCode.getLocalPart());
163: } else if (faultCode.getNamespaceURI().equals(
164: body.getElementName().getURI())) {
165: fault.setFaultCode(body.getElementName().getPrefix() + ":"
166: + faultCode.getLocalPart());
167: } else {
168: fault.setFaultCode(faultCode.getLocalPart());
169: }
170: fault.setFaultString(faultString);
171: return fault;
172: }
173:
174: /** Returns the envelope of the given message. */
175: public SOAPEnvelope getEnvelope(SOAPMessage message)
176: throws SOAPException {
177: return message.getSOAPPart().getEnvelope();
178: }
179:
180: /** Returns the header of the given envelope. */
181: public SOAPHeader getHeader(SOAPEnvelope envelope)
182: throws SOAPException {
183: return envelope.getHeader();
184: }
185:
186: /** Returns the body of the given envelope. */
187: public SOAPBody getBody(SOAPEnvelope envelope) throws SOAPException {
188: return envelope.getBody();
189: }
190:
191: /** Returns all header elements. */
192: public Iterator examineAllHeaderElements(SOAPHeader header) {
193: return header.getChildElements();
194: }
195:
196: /** Returns all header elements for which the must understand attribute is true, given the actor or role. */
197: public Iterator examineMustUnderstandHeaderElements(
198: SOAPHeader header, String actorOrRole) {
199: List result = new ArrayList();
200: for (Iterator iterator = header
201: .examineHeaderElements(actorOrRole); iterator.hasNext();) {
202: SOAPHeaderElement headerElement = (SOAPHeaderElement) iterator
203: .next();
204: if (headerElement.getMustUnderstand()) {
205: result.add(headerElement);
206: }
207: }
208: return result.iterator();
209: }
210:
211: /** Returns the SOAP 1.1 actor or SOAP 1.2 role attribute for the given header element. */
212: public String getActorOrRole(SOAPHeaderElement headerElement) {
213: return headerElement.getActor();
214: }
215:
216: /** Sets the SOAP 1.1 actor or SOAP 1.2 role attribute for the given header element. */
217: public void setActorOrRole(SOAPHeaderElement headerElement,
218: String actorOrRole) {
219: headerElement.setActor(actorOrRole);
220: }
221:
222: /** Gets the must understand attribute for the given header element. */
223: public boolean getMustUnderstand(SOAPHeaderElement headerElement) {
224: return headerElement.getMustUnderstand();
225: }
226:
227: /** Sets the must understand attribute for the given header element. */
228: public void setMustUnderstand(SOAPHeaderElement headerElement,
229: boolean mustUnderstand) {
230: headerElement.setMustUnderstand(mustUnderstand);
231: }
232:
233: /** Returns <code>true</code> if the body has a fault, <code>false</code> otherwise. */
234: public boolean hasFault(SOAPBody body) {
235: return body.hasFault();
236: }
237:
238: /** Returns the fault for the given body, if any. */
239: public SOAPFault getFault(SOAPBody body) {
240: return body.getFault();
241: }
242:
243: /** Returns the actor for the given fault. */
244: public String getFaultActor(SOAPFault fault) {
245: return fault.getFaultActor();
246: }
247:
248: /** Sets the actor for the given fault. */
249: public void setFaultActor(SOAPFault fault, String actorOrRole)
250: throws SOAPException {
251: fault.setFaultActor(actorOrRole);
252: }
253:
254: /** Returns the fault string for the given fault. */
255: public String getFaultString(SOAPFault fault) {
256: return fault.getFaultString();
257: }
258:
259: /** Returns the fault string language for the given fault. */
260: public Locale getFaultStringLocale(SOAPFault fault) {
261: return Locale.ENGLISH;
262: }
263:
264: /** Returns the fault detail for the given fault. */
265: public Detail getFaultDetail(SOAPFault fault) {
266: return fault.getDetail();
267: }
268:
269: /** Adds a fault detail for the given fault. */
270: public Detail addFaultDetail(SOAPFault fault) throws SOAPException {
271: return fault.addDetail();
272: }
273:
274: public void addTextNode(DetailEntry detailEntry, String text)
275: throws SOAPException {
276: detailEntry.addTextNode(text);
277: }
278:
279: /** Returns an iteration over all detail entries. */
280: public Iterator getDetailEntries(Detail detail) {
281: return detail.getDetailEntries();
282: }
283:
284: public SOAPElement getFirstBodyElement(SOAPBody body) {
285: for (Iterator iterator = body.getChildElements(); iterator
286: .hasNext();) {
287: Object child = iterator.next();
288: if (child instanceof SOAPElement) {
289: return (SOAPElement) child;
290: }
291: }
292: return null;
293: }
294:
295: public void removeContents(SOAPElement element) {
296: for (Iterator iterator = element.getChildElements(); iterator
297: .hasNext();) {
298: iterator.next();
299: iterator.remove();
300: }
301: }
302:
303: public void writeTo(SOAPMessage message, OutputStream outputStream)
304: throws SOAPException, IOException {
305: if (message.saveRequired()) {
306: message.saveChanges();
307: }
308: if (outputStream instanceof TransportOutputStream) {
309: TransportOutputStream transportOutputStream = (TransportOutputStream) outputStream;
310: // some SAAJ implementations (Axis 1) do not have a Content-Type header by default
311: MimeHeaders headers = message.getMimeHeaders();
312: if (ObjectUtils.isEmpty(headers.getHeader("Content-Type"))) {
313: headers.addHeader("Content-Type", SoapVersion.SOAP_11
314: .getContentType());
315: if (message.saveRequired()) {
316: message.saveChanges();
317: }
318: }
319: for (Iterator iterator = headers.getAllHeaders(); iterator
320: .hasNext();) {
321: MimeHeader mimeHeader = (MimeHeader) iterator.next();
322: transportOutputStream.addHeader(mimeHeader.getName(),
323: mimeHeader.getValue());
324: }
325: }
326: message.writeTo(outputStream);
327:
328: }
329:
330: public MimeHeaders getMimeHeaders(SOAPMessage message) {
331: return message.getMimeHeaders();
332: }
333:
334: public Iterator getAttachments(SOAPMessage message) {
335: return message.getAttachments();
336: }
337:
338: public Iterator getAttachment(SOAPMessage message,
339: MimeHeaders mimeHeaders) {
340: return message.getAttachments(mimeHeaders);
341: }
342:
343: public AttachmentPart addAttachmentPart(SOAPMessage message,
344: DataHandler dataHandler) {
345: AttachmentPart attachmentPart = message
346: .createAttachmentPart(dataHandler);
347: message.addAttachmentPart(attachmentPart);
348: return attachmentPart;
349: }
350:
351: //
352: // Unsupported
353: //
354:
355: public String getFaultRole(SOAPFault fault) {
356: throw new UnsupportedOperationException(
357: "SAAJ 1.1 does not support SOAP 1.2");
358: }
359:
360: public void setFaultRole(SOAPFault fault, String role) {
361: throw new UnsupportedOperationException(
362: "SAAJ 1.1 does not support SOAP 1.2");
363: }
364:
365: public SOAPHeaderElement addNotUnderstoodHeaderElement(
366: SOAPHeader header, QName name) {
367: throw new UnsupportedOperationException(
368: "SAAJ 1.1 does not support SOAP 1.2");
369: }
370:
371: public SOAPHeaderElement addUpgradeHeaderElement(SOAPHeader header,
372: String[] supportedSoapUris) {
373: throw new UnsupportedOperationException(
374: "SAAJ 1.1 does not support SOAP 1.2");
375: }
376:
377: public Iterator getFaultSubcodes(SOAPFault fault) {
378: throw new UnsupportedOperationException(
379: "SAAJ 1.1 does not support SOAP 1.2");
380: }
381:
382: public void appendFaultSubcode(SOAPFault fault, QName subcode) {
383: throw new UnsupportedOperationException(
384: "SAAJ 1.1 does not support SOAP 1.2");
385: }
386:
387: public String getFaultNode(SOAPFault fault) {
388: throw new UnsupportedOperationException(
389: "SAAJ 1.1 does not support SOAP 1.2");
390: }
391:
392: public void setFaultNode(SOAPFault fault, String uri) {
393: throw new UnsupportedOperationException(
394: "SAAJ 1.1 does not support SOAP 1.2");
395: }
396:
397: public String getFaultReasonText(SOAPFault fault, Locale locale) {
398: throw new UnsupportedOperationException(
399: "SAAJ 1.1 does not support SOAP 1.2");
400: }
401:
402: public void setFaultReasonText(SOAPFault fault, Locale locale,
403: String text) {
404: throw new UnsupportedOperationException(
405: "SAAJ 1.1 does not support SOAP 1.2");
406: }
407:
408: }
|