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.jaxws.handler.logical;
019:
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.util.logging.Logger;
023:
024: import javax.activation.DataSource;
025: import javax.xml.bind.JAXBContext;
026: import javax.xml.bind.JAXBException;
027: import javax.xml.parsers.ParserConfigurationException;
028: import javax.xml.soap.MessageFactory;
029: import javax.xml.soap.SOAPException;
030: import javax.xml.soap.SOAPMessage;
031: import javax.xml.stream.XMLStreamException;
032: import javax.xml.stream.XMLStreamReader;
033: import javax.xml.stream.XMLStreamWriter;
034: import javax.xml.transform.Source;
035: import javax.xml.transform.Transformer;
036: import javax.xml.transform.dom.DOMSource;
037: import javax.xml.transform.stream.StreamResult;
038: import javax.xml.transform.stream.StreamSource;
039: import javax.xml.ws.LogicalMessage;
040: import javax.xml.ws.Service;
041: import javax.xml.ws.WebServiceException;
042:
043: import org.w3c.dom.Element;
044: import org.w3c.dom.Node;
045:
046: import org.apache.cxf.binding.soap.SoapMessage;
047: import org.apache.cxf.helpers.XMLUtils;
048: import org.apache.cxf.interceptor.Fault;
049: import org.apache.cxf.io.CachedOutputStream;
050: import org.apache.cxf.message.Message;
051: import org.apache.cxf.message.XMLMessage;
052: import org.apache.cxf.staxutils.StaxUtils;
053: import org.apache.cxf.staxutils.W3CDOMStreamWriter;
054: import org.apache.cxf.wsdl.WSDLConstants;
055:
056: public class LogicalMessageImpl implements LogicalMessage {
057: private static final Logger LOG = Logger
058: .getLogger(LogicalMessageImpl.class.getName());
059: private final LogicalMessageContextImpl msgContext;
060:
061: public LogicalMessageImpl(LogicalMessageContextImpl lmctx) {
062: msgContext = lmctx;
063: }
064:
065: public Source getPayload() {
066: Source source = null;
067:
068: Service.Mode mode = msgContext.getWrappedMessage()
069: .getExchange().get(Service.Mode.class);
070: Message message = msgContext.getWrappedMessage();
071:
072: if (mode != null) {
073: //Dispatch/Provider case
074: Source obj = message.getContent(Source.class);
075: if (message instanceof SoapMessage) {
076: // StreamSource may only be used once, need to make a copy
077: if (obj instanceof StreamSource) {
078: try {
079: CachedOutputStream cos = new CachedOutputStream();
080: Transformer transformer = XMLUtils
081: .newTransformer();
082: transformer.transform(obj,
083: new StreamResult(cos));
084:
085: obj = new StreamSource(cos.getInputStream());
086: message.setContent(Source.class,
087: new StreamSource(cos.getInputStream()));
088: } catch (Exception e) {
089: throw new Fault(e);
090: }
091: }
092:
093: if (mode == Service.Mode.PAYLOAD) {
094: source = (Source) obj;
095: } else {
096: try {
097: CachedOutputStream cos = new CachedOutputStream();
098: Transformer transformer = XMLUtils
099: .newTransformer();
100:
101: transformer.transform(obj,
102: new StreamResult(cos));
103: SOAPMessage msg = initSOAPMessage(cos
104: .getInputStream());
105: source = new DOMSource(((SOAPMessage) msg)
106: .getSOAPBody().getFirstChild());
107: } catch (Exception e) {
108: throw new Fault(e);
109: }
110: }
111: } else if (message instanceof XMLMessage) {
112: if (obj != null) {
113: source = (Source) obj;
114: } else if (message.getContent(DataSource.class) != null) {
115: throw new Fault(
116: new org.apache.cxf.common.i18n.Message(
117: "GETPAYLOAD_OF_DATASOURCE_NOT_VALID_XMLHTTPBINDING",
118: LOG));
119: }
120: }
121: } else {
122: source = message.getContent(Source.class);
123: if (source == null) {
124: // need to convert
125: SOAPMessage msg = message.getContent(SOAPMessage.class);
126: XMLStreamReader reader = null;
127: if (msg != null) {
128: try {
129: source = new DOMSource(msg.getSOAPBody()
130: .getFirstChild());
131: reader = StaxUtils
132: .createXMLStreamReader(source);
133: } catch (SOAPException e) {
134: throw new Fault(e);
135: }
136: }
137:
138: if (source == null) {
139: try {
140: W3CDOMStreamWriter writer = new W3CDOMStreamWriter();
141: reader = message
142: .getContent(XMLStreamReader.class);
143: StaxUtils.copy(reader, writer);
144: source = new DOMSource(writer.getDocument()
145: .getDocumentElement());
146: reader = StaxUtils.createXMLStreamReader(writer
147: .getDocument());
148: } catch (ParserConfigurationException e) {
149: throw new Fault(e);
150: } catch (XMLStreamException e) {
151: throw new Fault(e);
152: }
153: }
154: message.setContent(XMLStreamReader.class, reader);
155: message.setContent(Source.class, source);
156: } else if (!(source instanceof DOMSource)) {
157: W3CDOMStreamWriter writer;
158: try {
159: writer = new W3CDOMStreamWriter();
160: } catch (ParserConfigurationException e) {
161: throw new Fault(e);
162: }
163: XMLStreamReader reader = message
164: .getContent(XMLStreamReader.class);
165: if (reader == null) {
166: reader = StaxUtils.createXMLStreamReader(source);
167: }
168: try {
169: StaxUtils.copy(reader, writer);
170: } catch (XMLStreamException e) {
171: throw new Fault(e);
172: }
173:
174: source = new DOMSource(writer.getDocument()
175: .getDocumentElement());
176:
177: reader = StaxUtils.createXMLStreamReader(writer
178: .getDocument());
179: message.setContent(XMLStreamReader.class, reader);
180: message.setContent(Source.class, source);
181: }
182: }
183:
184: return source;
185: }
186:
187: public void setPayload(Source s) {
188: Message message = msgContext.getWrappedMessage();
189: Service.Mode mode = msgContext.getWrappedMessage()
190: .getExchange().get(Service.Mode.class);
191: if (mode != null) {
192: if (message instanceof SoapMessage) {
193: if (mode == Service.Mode.MESSAGE) {
194: try {
195: // REVISIT: should try to use the original SOAPMessage
196: // instead of creating a new empty one.
197: SOAPMessage msg = initSOAPMessage(null);
198: write(s, msg.getSOAPBody());
199: s = new DOMSource(((SOAPMessage) msg)
200: .getSOAPPart());
201: } catch (Exception e) {
202: throw new Fault(e);
203: }
204: }
205: } else if (message instanceof XMLMessage
206: && message.getContent(DataSource.class) != null) {
207: throw new Fault(
208: new org.apache.cxf.common.i18n.Message(
209: "GETPAYLOAD_OF_DATASOURCE_NOT_VALID_XMLHTTPBINDING",
210: LOG));
211: }
212: } else {
213: XMLStreamReader reader = StaxUtils.createXMLStreamReader(s);
214: msgContext.getWrappedMessage().setContent(
215: XMLStreamReader.class, reader);
216: }
217: msgContext.getWrappedMessage().setContent(Source.class, s);
218: }
219:
220: public Object getPayload(JAXBContext arg0) {
221: try {
222: return arg0.createUnmarshaller().unmarshal(getPayload());
223: } catch (JAXBException e) {
224: throw new WebServiceException(e);
225: }
226: }
227:
228: public void setPayload(Object arg0, JAXBContext arg1) {
229: try {
230: W3CDOMStreamWriter writer = new W3CDOMStreamWriter();
231: arg1.createMarshaller().marshal(arg0, writer);
232: Source source = new DOMSource(writer.getDocument()
233: .getDocumentElement());
234:
235: setPayload(source);
236: } catch (ParserConfigurationException e) {
237: throw new WebServiceException(e);
238: } catch (JAXBException e) {
239: throw new WebServiceException(e);
240: }
241: }
242:
243: private void write(Source source, Node n) {
244: try {
245: if (source instanceof DOMSource
246: && ((DOMSource) source).getNode() == null) {
247: return;
248: }
249:
250: XMLStreamWriter writer = new W3CDOMStreamWriter((Element) n);
251: XMLStreamReader reader = StaxUtils
252: .createXMLStreamReader(source);
253: StaxUtils.copy(reader, writer);
254: reader.close();
255: } catch (XMLStreamException e) {
256: throw new Fault(e);
257: }
258: }
259:
260: private SOAPMessage initSOAPMessage(InputStream is)
261: throws SOAPException, IOException {
262: SOAPMessage msg = null;
263: if (is != null) {
264: msg = MessageFactory.newInstance().createMessage(null, is);
265: } else {
266: msg = MessageFactory.newInstance().createMessage();
267: }
268: msg.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "true");
269: msg.getSOAPPart().getEnvelope().addNamespaceDeclaration(
270: WSDLConstants.NP_SCHEMA_XSD,
271: WSDLConstants.NU_SCHEMA_XSD);
272: msg.getSOAPPart().getEnvelope().addNamespaceDeclaration(
273: WSDLConstants.NP_SCHEMA_XSI,
274: WSDLConstants.NU_SCHEMA_XSI);
275:
276: return msg;
277: }
278: }
|