001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.binding.soap.saaj;
019:
020: import java.util.Collection;
021: import java.util.ResourceBundle;
022:
023: import javax.xml.namespace.QName;
024: import javax.xml.soap.AttachmentPart;
025: import javax.xml.soap.MessageFactory;
026: import javax.xml.soap.SOAPConstants;
027: import javax.xml.soap.SOAPException;
028: import javax.xml.soap.SOAPHeader;
029: import javax.xml.soap.SOAPMessage;
030: import javax.xml.soap.SOAPPart;
031: import javax.xml.stream.XMLStreamException;
032: import javax.xml.stream.XMLStreamReader;
033: import javax.xml.transform.dom.DOMSource;
034:
035: import org.w3c.dom.Document;
036: import org.w3c.dom.Element;
037: import org.w3c.dom.Node;
038: import org.w3c.dom.NodeList;
039:
040: import org.apache.cxf.Bus;
041: import org.apache.cxf.binding.soap.Soap11;
042: import org.apache.cxf.binding.soap.SoapFault;
043: import org.apache.cxf.binding.soap.SoapHeader;
044: import org.apache.cxf.binding.soap.SoapMessage;
045: import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
046: import org.apache.cxf.common.i18n.BundleUtils;
047: import org.apache.cxf.databinding.DataBinding;
048: import org.apache.cxf.headers.Header;
049: import org.apache.cxf.headers.HeaderManager;
050: import org.apache.cxf.headers.HeaderProcessor;
051: import org.apache.cxf.interceptor.Fault;
052: import org.apache.cxf.message.Attachment;
053: import org.apache.cxf.phase.Phase;
054: import org.apache.cxf.staxutils.StaxUtils;
055:
056: /**
057: * Builds a SAAJ tree from the Document fragment inside the message which contains
058: * the SOAP headers and from the XMLStreamReader.
059: */
060: public class SAAJInInterceptor extends AbstractSoapInterceptor {
061: private static final ResourceBundle BUNDLE = BundleUtils
062: .getBundle(SAAJInInterceptor.class);
063:
064: public SAAJInInterceptor() {
065: super (Phase.PRE_PROTOCOL);
066: }
067:
068: public SAAJInInterceptor(String phase) {
069: super (phase);
070: }
071:
072: public void handleMessage(SoapMessage message) throws Fault {
073: try {
074: MessageFactory factory = null;
075: if (message.getVersion() instanceof Soap11) {
076: factory = MessageFactory.newInstance();
077: } else {
078: factory = MessageFactory
079: .newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
080: }
081:
082: SOAPMessage soapMessage = factory.createMessage();
083: message.setContent(SOAPMessage.class, soapMessage);
084:
085: SOAPPart part = soapMessage.getSOAPPart();
086:
087: Document node = (Document) message.getContent(Node.class);
088: DOMSource source = new DOMSource(node);
089: part.setContent(source);
090:
091: // TODO: setup mime headers
092: Collection<Attachment> atts = message.getAttachments();
093: if (atts != null) {
094: for (Attachment a : atts) {
095: AttachmentPart ap = soapMessage
096: .createAttachmentPart(a.getDataHandler());
097:
098: soapMessage.addAttachmentPart(ap);
099: }
100: }
101:
102: //replace header element if necessary
103: if (message.hasHeaders()) {
104: replaceHeaders(soapMessage, message);
105: }
106:
107: XMLStreamReader xmlReader = message
108: .getContent(XMLStreamReader.class);
109: StaxUtils.readDocElements(soapMessage.getSOAPBody(),
110: xmlReader, true);
111: DOMSource bodySource = new DOMSource(soapMessage
112: .getSOAPPart().getEnvelope().getBody());
113: xmlReader = StaxUtils.createXMLStreamReader(bodySource);
114: xmlReader.nextTag();
115: xmlReader.nextTag(); // move past body tag
116: message.setContent(XMLStreamReader.class, xmlReader);
117: } catch (SOAPException soape) {
118: throw new SoapFault(new org.apache.cxf.common.i18n.Message(
119: "SOAPHANDLERINTERCEPTOR_EXCEPTION", BUNDLE), soape,
120: message.getVersion().getSender());
121: } catch (XMLStreamException e) {
122: throw new SoapFault(new org.apache.cxf.common.i18n.Message(
123: "SOAPHANDLERINTERCEPTOR_EXCEPTION", BUNDLE), e,
124: message.getVersion().getSender());
125: }
126: }
127:
128: public static void replaceHeaders(SOAPMessage soapMessage,
129: SoapMessage message) throws SOAPException {
130: SOAPHeader header = soapMessage.getSOAPHeader();
131: if (header == null) {
132: return;
133: }
134: NodeList headerEls = header.getChildNodes();
135: int len = headerEls.getLength();
136: for (int i = 0; i < len; i++) {
137: Node nd = headerEls.item(i);
138: if (Node.ELEMENT_NODE == nd.getNodeType()) {
139: Element hel = (Element) nd;
140: Bus b = message.getExchange().get(Bus.class);
141: HeaderProcessor p = null;
142: if (b != null
143: && b.getExtension(HeaderManager.class) != null) {
144: p = b.getExtension(HeaderManager.class)
145: .getHeaderProcessor(hel.getNamespaceURI());
146: }
147:
148: Object obj;
149: DataBinding dataBinding = null;
150: if (p == null || p.getDataBinding() == null) {
151: obj = nd;
152: } else {
153: obj = p.getDataBinding().createReader(Node.class)
154: .read(nd);
155: }
156: //TODO - add the interceptors
157:
158: SoapHeader shead = new SoapHeader(new QName(nd
159: .getNamespaceURI(), nd.getLocalName()), obj,
160: dataBinding);
161: shead.setDirection(SoapHeader.Direction.DIRECTION_IN);
162:
163: String mu = hel.getAttributeNS(message.getVersion()
164: .getNamespace(), message.getVersion()
165: .getAttrNameMustUnderstand());
166: String act = hel.getAttributeNS(message.getVersion()
167: .getNamespace(), message.getVersion()
168: .getAttrNameRole());
169:
170: shead.setActor(act);
171: shead.setMustUnderstand(Boolean.valueOf(mu)
172: || "1".equals(mu));
173: Header oldHdr = message.getHeader(new QName(nd
174: .getNamespaceURI(), nd.getLocalName()));
175: if (oldHdr != null) {
176: message.getHeaders().remove(oldHdr);
177: }
178: message.getHeaders().add(shead);
179: }
180: }
181: }
182:
183: }
|