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.interceptors;
019:
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.util.List;
023: import java.util.logging.Logger;
024:
025: import javax.activation.DataSource;
026: import javax.mail.util.ByteArrayDataSource;
027: import javax.xml.soap.MessageFactory;
028: import javax.xml.soap.MimeHeaders;
029: import javax.xml.soap.SOAPConstants;
030: import javax.xml.soap.SOAPException;
031: import javax.xml.soap.SOAPMessage;
032: import javax.xml.stream.XMLStreamReader;
033: import javax.xml.transform.Source;
034: import javax.xml.transform.Transformer;
035: import javax.xml.transform.stream.StreamResult;
036: import javax.xml.ws.Service;
037: import javax.xml.ws.Service.Mode;
038:
039: import org.w3c.dom.Node;
040:
041: import org.apache.cxf.binding.soap.Soap11;
042: import org.apache.cxf.binding.soap.Soap12;
043: import org.apache.cxf.binding.soap.SoapMessage;
044: import org.apache.cxf.binding.soap.SoapVersion;
045: import org.apache.cxf.databinding.DataReader;
046: import org.apache.cxf.databinding.source.NodeDataReader;
047: import org.apache.cxf.databinding.source.XMLStreamDataReader;
048: import org.apache.cxf.endpoint.Endpoint;
049: import org.apache.cxf.helpers.DOMUtils;
050: import org.apache.cxf.helpers.XMLUtils;
051: import org.apache.cxf.interceptor.AbstractInDatabindingInterceptor;
052: import org.apache.cxf.interceptor.Fault;
053: import org.apache.cxf.interceptor.StaxInInterceptor;
054: import org.apache.cxf.io.CachedOutputStream;
055: import org.apache.cxf.jaxb.JAXBDataBinding;
056: import org.apache.cxf.jaxws.handler.logical.DispatchLogicalHandlerInterceptor;
057: import org.apache.cxf.jaxws.handler.soap.DispatchSOAPHandlerInterceptor;
058: import org.apache.cxf.message.Exchange;
059: import org.apache.cxf.message.Message;
060: import org.apache.cxf.message.MessageContentsList;
061: import org.apache.cxf.message.XMLMessage;
062: import org.apache.cxf.phase.Phase;
063: import org.apache.cxf.service.model.BindingOperationInfo;
064: import org.apache.cxf.service.model.MessageInfo;
065: import org.apache.cxf.service.model.MessagePartInfo;
066: import org.apache.cxf.staxutils.StaxUtils;
067:
068: public class DispatchInDatabindingInterceptor extends
069: AbstractInDatabindingInterceptor {
070:
071: private static final Logger LOG = Logger
072: .getLogger(DispatchInDatabindingInterceptor.class.getName());
073: private Class type;
074: private Service.Mode mode;
075:
076: public DispatchInDatabindingInterceptor(Class type, Mode mode) {
077: super (Phase.READ);
078:
079: this .type = type;
080: this .mode = mode;
081: }
082:
083: public void handleMessage(Message message) throws Fault {
084: Exchange ex = message.getExchange();
085: Endpoint ep = ex.get(Endpoint.class);
086: MessageInfo info = message.get(MessageInfo.class);
087: if (ep.getEndpointInfo().getBinding().getOperations()
088: .iterator().hasNext()) {
089: BindingOperationInfo bop = ep.getEndpointInfo()
090: .getBinding().getOperations().iterator().next();
091: ex.put(BindingOperationInfo.class, bop);
092: info = getMessageInfo(message, bop);
093: }
094:
095: if (isGET(message)) {
096: MessageContentsList params = new MessageContentsList();
097: if (info != null) {
098: for (MessagePartInfo i : info.getMessageParts()) {
099: params.put(i, null);
100: }
101: } else {
102: params.add(null);
103: }
104: message.setContent(List.class, params);
105: LOG
106: .info("DispatchInInterceptor skipped in HTTP GET method");
107: return;
108: }
109:
110: try {
111: InputStream is = message.getContent(InputStream.class);
112: Object obj = null;
113: ex.put(Service.Mode.class, mode);
114:
115: if (message instanceof SoapMessage) {
116: SOAPMessage soapMessage = newSOAPMessage(is,
117: ((SoapMessage) message).getVersion());
118: PostDispatchSOAPHandlerInterceptor postSoap = new PostDispatchSOAPHandlerInterceptor();
119: message.getInterceptorChain().add(postSoap);
120:
121: //soapMessage.writeTo(System.out);
122: message.setContent(SOAPMessage.class, soapMessage);
123: } else if (message instanceof XMLMessage) {
124: if (type.equals(DataSource.class)) {
125: try {
126: obj = new ByteArrayDataSource(is,
127: (String) message
128: .get(Message.CONTENT_TYPE));
129: } catch (IOException e) {
130: throw new Fault(e);
131: }
132: //Treat DataSource specially here as it is not valid to call getPayload from
133: //LogicalHandler for DataSource payload
134: message.setContent(DataSource.class, obj);
135: } else {
136: new StaxInInterceptor().handleMessage(message);
137:
138: DataReader<XMLStreamReader> dataReader = new XMLStreamDataReader();
139: Class readType = type;
140: if (!Source.class.isAssignableFrom(type)) {
141: readType = Source.class;
142: }
143: obj = dataReader.read(null, message
144: .getContent(XMLStreamReader.class),
145: readType);
146: message.setContent(Source.class, obj);
147: }
148: }
149:
150: PostDispatchLogicalHandlerInterceptor postLogical = new PostDispatchLogicalHandlerInterceptor();
151: message.getInterceptorChain().add(postLogical);
152:
153: is.close();
154: } catch (Exception e) {
155: throw new Fault(e);
156: }
157: }
158:
159: private SOAPMessage newSOAPMessage(InputStream is,
160: SoapVersion version) throws Exception {
161: // TODO: Get header from message, this interceptor should after
162: // readHeadersInterceptor
163:
164: MimeHeaders headers = new MimeHeaders();
165: MessageFactory msgFactory = null;
166: if (version == null || version instanceof Soap11) {
167: msgFactory = MessageFactory.newInstance();
168: } else if (version instanceof Soap12) {
169: msgFactory = MessageFactory
170: .newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
171: }
172: return msgFactory.createMessage(headers, is);
173: }
174:
175: //This interceptor is invoked after DispatchSOAPHandlerInterceptor, converts SOAPMessage to Source
176: private class PostDispatchSOAPHandlerInterceptor extends
177: AbstractInDatabindingInterceptor {
178:
179: public PostDispatchSOAPHandlerInterceptor() {
180: super (Phase.USER_PROTOCOL);
181: addAfter(DispatchSOAPHandlerInterceptor.class.getName());
182: }
183:
184: public void handleMessage(Message message) throws Fault {
185: Object obj = null;
186:
187: //Convert SOAPMessage to Source
188: if (message instanceof SoapMessage) {
189: SOAPMessage soapMessage = message
190: .getContent(SOAPMessage.class);
191: message.removeContent(SOAPMessage.class);
192:
193: DataReader<Node> dataReader = new NodeDataReader();
194: Node n = null;
195: if (mode == Service.Mode.MESSAGE) {
196: try {
197: n = soapMessage.getSOAPPart();
198: //This seems to be a problem in SAAJ. Envelope might not be initialized properly
199: //without calling getEnvelope()
200: soapMessage.getSOAPPart().getEnvelope();
201: } catch (SOAPException e) {
202: throw new Fault(e);
203: }
204: } else if (mode == Service.Mode.PAYLOAD) {
205: try {
206: n = DOMUtils.getChild(
207: soapMessage.getSOAPBody(),
208: Node.ELEMENT_NODE);
209: } catch (SOAPException e) {
210: throw new Fault(e);
211: }
212: }
213:
214: Class tempType = type;
215: if (!Source.class.isAssignableFrom(type)) {
216: tempType = Source.class;
217: }
218: obj = dataReader.read(null, n, tempType);
219:
220: message.setContent(Source.class, obj);
221: }
222: }
223: }
224:
225: //This interceptor is invoked after DispatchLogicalHandlerInterceptor, converts Source to object
226: private class PostDispatchLogicalHandlerInterceptor extends
227: AbstractInDatabindingInterceptor {
228:
229: public PostDispatchLogicalHandlerInterceptor() {
230: super (Phase.USER_LOGICAL);
231: addAfter(DispatchLogicalHandlerInterceptor.class.getName());
232: }
233:
234: public void handleMessage(Message message) throws Fault {
235: Object obj = null;
236:
237: //Convert Source to object
238: if (message instanceof SoapMessage) {
239: Source source = message.getContent(Source.class);
240: message.removeContent(Source.class);
241:
242: if (SOAPMessage.class.isAssignableFrom(type)) {
243: try {
244: CachedOutputStream cos = new CachedOutputStream();
245: Transformer transformer = XMLUtils
246: .newTransformer();
247: transformer.transform(source, new StreamResult(
248: cos));
249: obj = newSOAPMessage(cos.getInputStream(),
250: ((SoapMessage) message).getVersion());
251: } catch (Exception e) {
252: throw new Fault(e);
253: }
254: } else if (Source.class.isAssignableFrom(type)) {
255: obj = source;
256: } else {
257: //JAXB
258: try {
259: obj = convertSourceToJaxb(source, message);
260: } catch (Exception e) {
261: throw new Fault(e);
262: }
263: }
264: } else if (message instanceof XMLMessage) {
265: Source source = message.getContent(Source.class);
266: message.removeContent(Source.class);
267: DataSource dataSource = message
268: .getContent(DataSource.class);
269: message.removeContent(DataSource.class);
270:
271: if (source != null) {
272: if (Source.class.isAssignableFrom(type)) {
273: obj = (Source) source;
274: } else {
275: //jaxb
276: try {
277: obj = convertSourceToJaxb(source, message);
278: } catch (Exception e) {
279: throw new Fault(e);
280: }
281: }
282: } else if (dataSource != null
283: && DataSource.class.isAssignableFrom(type)) {
284: obj = (DataSource) dataSource;
285: }
286:
287: }
288: message.setContent(Object.class, obj);
289: }
290:
291: }
292:
293: private Object convertSourceToJaxb(Source source, Message message)
294: throws Exception {
295: CachedOutputStream cos = new CachedOutputStream();
296: Transformer transformer = XMLUtils.newTransformer();
297: transformer.transform(source, new StreamResult(cos));
298: String encoding = (String) message.get(Message.ENCODING);
299:
300: XMLStreamReader reader = null;
301:
302: reader = StaxUtils.getXMLInputFactory().createXMLStreamReader(
303: cos.getInputStream(), encoding);
304:
305: DataReader<XMLStreamReader> dataReader = getDataReader(message);
306: dataReader.setProperty(JAXBDataBinding.UNWRAP_JAXB_ELEMENT,
307: Boolean.FALSE);
308:
309: Object obj = dataReader.read(null, reader, null);
310:
311: return obj;
312:
313: //not sure why code below does not work
314: /*
315: DataReader<XMLStreamReader> dataReader1 =
316: getDataReader(message, XMLStreamReader.class);
317: XMLStreamReader reader1 =
318: StaxUtils.getXMLInputFactory().createXMLStreamReader(source);
319: dataReader.setProperty(JAXBDataBinding.UNWRAP_JAXB_ELEMENT, Boolean.FALSE);
320: obj = dataReader1.read(null, reader1, null);*/
321: }
322:
323: }
|