ohair@286: /* alanb@368: * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. ohair@286: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ohair@286: * ohair@286: * This code is free software; you can redistribute it and/or modify it ohair@286: * under the terms of the GNU General Public License version 2 only, as ohair@286: * published by the Free Software Foundation. Oracle designates this ohair@286: * particular file as subject to the "Classpath" exception as provided ohair@286: * by Oracle in the LICENSE file that accompanied this code. ohair@286: * ohair@286: * This code is distributed in the hope that it will be useful, but WITHOUT ohair@286: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ohair@286: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ohair@286: * version 2 for more details (a copy is included in the LICENSE file that ohair@286: * accompanied this code). ohair@286: * ohair@286: * You should have received a copy of the GNU General Public License version ohair@286: * 2 along with this work; if not, write to the Free Software Foundation, ohair@286: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ohair@286: * ohair@286: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@286: * or visit www.oracle.com if you need additional information or have any ohair@286: * questions. ohair@286: */ ohair@286: ohair@286: package com.sun.xml.internal.ws.handler; ohair@286: alanb@368: import com.sun.xml.internal.ws.api.message.MessageHeaders; ohair@286: import com.sun.xml.internal.ws.api.message.Packet; ohair@286: import com.sun.xml.internal.ws.api.message.Message; ohair@286: import com.sun.xml.internal.ws.api.message.AttachmentSet; ohair@286: import com.sun.xml.internal.ws.api.WSBinding; ohair@286: import com.sun.xml.internal.ws.spi.db.BindingContext; ohair@286: import com.sun.xml.internal.ws.spi.db.BindingContextFactory; ohair@286: import com.sun.xml.internal.ws.util.xml.XmlUtil; ohair@286: import com.sun.xml.internal.ws.message.EmptyMessageImpl; ohair@286: import com.sun.xml.internal.ws.message.DOMMessage; ohair@286: import com.sun.xml.internal.ws.message.jaxb.JAXBMessage; ohair@286: import com.sun.xml.internal.ws.message.source.PayloadSourceMessage; ohair@286: ohair@286: import javax.xml.bind.JAXBContext; ohair@286: import javax.xml.bind.JAXBException; ohair@286: import javax.xml.bind.Marshaller; ohair@286: import javax.xml.bind.Unmarshaller; ohair@286: import javax.xml.bind.util.JAXBSource; ohair@286: import javax.xml.transform.Source; ohair@286: import javax.xml.transform.Transformer; ohair@286: import javax.xml.transform.TransformerException; ohair@286: import javax.xml.transform.dom.DOMResult; ohair@286: import javax.xml.transform.dom.DOMSource; ohair@286: import javax.xml.ws.LogicalMessage; ohair@286: import javax.xml.ws.WebServiceException; ohair@286: ohair@286: import org.w3c.dom.Element; ohair@286: import org.w3c.dom.Node; ohair@286: import org.w3c.dom.Document; ohair@286: ohair@286: /** ohair@286: * Implementation of {@link LogicalMessage}. This class implements the methods ohair@286: * used by LogicalHandlers to get/set the request or response either ohair@286: * as a JAXB object or as javax.xml.transform.Source. ohair@286: *

ohair@286: *

The {@link Message} that is passed into the constructor ohair@286: * is used to retrieve the payload of the request or response. ohair@286: * ohair@286: * @author WS Development Team ohair@286: * @see Message ohair@286: * @see LogicalMessageContextImpl ohair@286: */ ohair@286: class LogicalMessageImpl implements LogicalMessage { ohair@286: private Packet packet; ohair@286: // protected JAXBContext defaultJaxbContext; ohair@286: protected BindingContext defaultJaxbContext; ohair@286: private ImmutableLM lm = null; ohair@286: ohair@286: ohair@286: public LogicalMessageImpl(BindingContext defaultJaxbContext, Packet ohair@286: packet) { ohair@286: // don't create extract payload until Users wants it. ohair@286: this.packet = packet; ohair@286: this.defaultJaxbContext = defaultJaxbContext; ohair@286: } ohair@286: ohair@286: public Source getPayload() { ohair@286: if (lm == null) { ohair@286: Source payload = packet.getMessage().copy().readPayloadAsSource(); ohair@286: if (payload instanceof DOMSource) { ohair@286: lm = createLogicalMessageImpl(payload); ohair@286: } ohair@286: return payload; ohair@286: } else { ohair@286: return lm.getPayload(); ohair@286: } ohair@286: } ohair@286: ohair@286: public void setPayload(Source payload) { ohair@286: lm = createLogicalMessageImpl(payload); ohair@286: } ohair@286: ohair@286: private ImmutableLM createLogicalMessageImpl(Source payload) { ohair@286: if (payload == null) { ohair@286: lm = new EmptyLogicalMessageImpl(); ohair@286: } else if (payload instanceof DOMSource) { ohair@286: lm = new DOMLogicalMessageImpl((DOMSource) payload); ohair@286: } else { ohair@286: lm = new SourceLogicalMessageImpl(payload); ohair@286: } ohair@286: return lm; ohair@286: } ohair@286: ohair@286: public Object getPayload(BindingContext context) { ohair@286: if (context == null) { ohair@286: context = defaultJaxbContext; ohair@286: } ohair@286: if (context == null) ohair@286: throw new WebServiceException("JAXBContext parameter cannot be null"); ohair@286: ohair@286: Object o; ohair@286: if (lm == null) { ohair@286: try { ohair@286: o = packet.getMessage().copy().readPayloadAsJAXB(context.createUnmarshaller()); ohair@286: } catch (JAXBException e) { ohair@286: throw new WebServiceException(e); ohair@286: } ohair@286: } else { ohair@286: o = lm.getPayload(context); ohair@286: lm = new JAXBLogicalMessageImpl(context.getJAXBContext(), o); ohair@286: } ohair@286: return o; ohair@286: } ohair@286: ohair@286: public Object getPayload(JAXBContext context) { ohair@286: if (context == null) { ohair@286: return getPayload(defaultJaxbContext); ohair@286: } ohair@286: if (context == null) ohair@286: throw new WebServiceException("JAXBContext parameter cannot be null"); ohair@286: ohair@286: Object o; ohair@286: if (lm == null) { ohair@286: try { ohair@286: o = packet.getMessage().copy().readPayloadAsJAXB(context.createUnmarshaller()); ohair@286: } catch (JAXBException e) { ohair@286: throw new WebServiceException(e); ohair@286: } ohair@286: } else { ohair@286: o = lm.getPayload(context); ohair@286: lm = new JAXBLogicalMessageImpl(context, o); ohair@286: } ohair@286: return o; ohair@286: } ohair@286: ohair@286: public void setPayload(Object payload, BindingContext context) { ohair@286: if (context == null) { ohair@286: context = defaultJaxbContext; ohair@286: } ohair@286: if (payload == null) { ohair@286: lm = new EmptyLogicalMessageImpl(); ohair@286: } else { ohair@286: lm = new JAXBLogicalMessageImpl(context.getJAXBContext(), payload); ohair@286: } ohair@286: } ohair@286: ohair@286: public void setPayload(Object payload, JAXBContext context) { ohair@286: if (context == null) { ohair@286: setPayload(payload, defaultJaxbContext); ohair@286: } ohair@286: if (payload == null) { ohair@286: lm = new EmptyLogicalMessageImpl(); ohair@286: } else { ohair@286: lm = new JAXBLogicalMessageImpl(context, payload); ohair@286: } ohair@286: } ohair@286: ohair@286: public boolean isPayloadModifed() { ohair@286: return (lm != null); ohair@286: } ohair@286: ohair@286: /** ohair@286: * This should be called by first checking if the payload is modified. ohair@286: * ohair@286: * @param headers ohair@286: * @param attachments ohair@286: * @param binding ohair@286: * @return ohair@286: */ alanb@368: public Message getMessage(MessageHeaders headers, AttachmentSet attachments, WSBinding binding) { ohair@286: assert isPayloadModifed(); ohair@286: if(isPayloadModifed()) { ohair@286: return lm.getMessage(headers,attachments,binding); ohair@286: } else { ohair@286: return packet.getMessage(); ohair@286: } ohair@286: ohair@286: } ohair@286: ohair@286: ohair@286: private abstract class ImmutableLM { ohair@286: public abstract Source getPayload(); ohair@286: public abstract Object getPayload(BindingContext context); ohair@286: public abstract Object getPayload(JAXBContext context); alanb@368: public abstract Message getMessage(MessageHeaders headers, AttachmentSet attachments, WSBinding binding); ohair@286: ohair@286: } ohair@286: ohair@286: private class DOMLogicalMessageImpl extends SourceLogicalMessageImpl { ohair@286: private DOMSource dom; ohair@286: ohair@286: public DOMLogicalMessageImpl(DOMSource dom) { ohair@286: super(dom); ohair@286: this.dom = dom; ohair@286: } ohair@286: ohair@286: @Override ohair@286: public Source getPayload() { ohair@286: return dom; ohair@286: } ohair@286: alanb@368: public Message getMessage(MessageHeaders headers, AttachmentSet attachments, WSBinding binding) { ohair@286: Node n = dom.getNode(); ohair@286: if(n.getNodeType()== Node.DOCUMENT_NODE) { ohair@286: n = ((Document)n).getDocumentElement(); ohair@286: } alanb@368: return new DOMMessage(binding.getSOAPVersion(), headers, (Element)n, attachments); ohair@286: } ohair@286: } ohair@286: ohair@286: private class EmptyLogicalMessageImpl extends ImmutableLM { ohair@286: public EmptyLogicalMessageImpl() { ohair@286: ohair@286: } ohair@286: ohair@286: @Override ohair@286: public Source getPayload() { ohair@286: return null; ohair@286: } ohair@286: ohair@286: @Override ohair@286: public Object getPayload(JAXBContext context) { ohair@286: return null; ohair@286: } ohair@286: ohair@286: @Override ohair@286: public Object getPayload(BindingContext context) { ohair@286: return null; ohair@286: } ohair@286: alanb@368: public Message getMessage(MessageHeaders headers, AttachmentSet attachments, WSBinding binding) { ohair@286: return new EmptyMessageImpl(headers,attachments,binding.getSOAPVersion()); ohair@286: } ohair@286: } ohair@286: ohair@286: private class JAXBLogicalMessageImpl extends ImmutableLM { ohair@286: private JAXBContext ctxt; ohair@286: private Object o; ohair@286: ohair@286: public JAXBLogicalMessageImpl(JAXBContext ctxt, Object o) { ohair@286: this.ctxt = ctxt; ohair@286: this.o = o; ohair@286: ohair@286: } ohair@286: ohair@286: @Override ohair@286: public Source getPayload() { ohair@286: JAXBContext context = ctxt; ohair@286: if (context == null) { ohair@286: context = defaultJaxbContext.getJAXBContext(); ohair@286: } ohair@286: try { ohair@286: return new JAXBSource(context, o); ohair@286: } catch (JAXBException e) { ohair@286: throw new WebServiceException(e); ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public Object getPayload(JAXBContext context) { ohair@286: // if(context == ctxt) { ohair@286: // return o; ohair@286: // } ohair@286: try { ohair@286: Source payloadSrc = getPayload(); ohair@286: if (payloadSrc == null) ohair@286: return null; ohair@286: Unmarshaller unmarshaller = context.createUnmarshaller(); ohair@286: return unmarshaller.unmarshal(payloadSrc); ohair@286: } catch (JAXBException e) { ohair@286: throw new WebServiceException(e); ohair@286: } ohair@286: } ohair@286: public Object getPayload(BindingContext context) { ohair@286: // if(context == ctxt) { ohair@286: // return o; ohair@286: // } ohair@286: try { ohair@286: Source payloadSrc = getPayload(); ohair@286: if (payloadSrc == null) ohair@286: return null; ohair@286: Unmarshaller unmarshaller = context.createUnmarshaller(); ohair@286: return unmarshaller.unmarshal(payloadSrc); ohair@286: } catch (JAXBException e) { ohair@286: throw new WebServiceException(e); ohair@286: } ohair@286: } ohair@286: alanb@368: public Message getMessage(MessageHeaders headers, AttachmentSet attachments, WSBinding binding) { ohair@286: return JAXBMessage.create(BindingContextFactory.create(ctxt), o,binding.getSOAPVersion(), headers,attachments); ohair@286: } ohair@286: } ohair@286: ohair@286: private class SourceLogicalMessageImpl extends ImmutableLM { ohair@286: private Source payloadSrc; ohair@286: ohair@286: public SourceLogicalMessageImpl(Source source) { ohair@286: this.payloadSrc = source; ohair@286: } ohair@286: ohair@286: public Source getPayload() { ohair@286: assert (!(payloadSrc instanceof DOMSource)); ohair@286: try { ohair@286: Transformer transformer = XmlUtil.newTransformer(); ohair@286: DOMResult domResult = new DOMResult(); ohair@286: transformer.transform(payloadSrc, domResult); ohair@286: DOMSource dom = new DOMSource(domResult.getNode()); ohair@286: lm = new DOMLogicalMessageImpl((DOMSource) dom); ohair@286: payloadSrc = null; ohair@286: return dom; ohair@286: } catch (TransformerException te) { ohair@286: throw new WebServiceException(te); ohair@286: } ohair@286: } ohair@286: ohair@286: public Object getPayload(JAXBContext context) { ohair@286: try { ohair@286: Source payloadSrc = getPayload(); ohair@286: if (payloadSrc == null) ohair@286: return null; ohair@286: Unmarshaller unmarshaller = context.createUnmarshaller(); ohair@286: return unmarshaller.unmarshal(payloadSrc); ohair@286: } catch (JAXBException e) { ohair@286: throw new WebServiceException(e); ohair@286: } ohair@286: ohair@286: } ohair@286: ohair@286: public Object getPayload(BindingContext context) { ohair@286: try { ohair@286: Source payloadSrc = getPayload(); ohair@286: if (payloadSrc == null) ohair@286: return null; ohair@286: Unmarshaller unmarshaller = context.createUnmarshaller(); ohair@286: return unmarshaller.unmarshal(payloadSrc); ohair@286: } catch (JAXBException e) { ohair@286: throw new WebServiceException(e); ohair@286: } ohair@286: ohair@286: } ohair@286: alanb@368: public Message getMessage(MessageHeaders headers, AttachmentSet attachments, WSBinding binding) { ohair@286: assert (payloadSrc!=null); ohair@286: return new PayloadSourceMessage(headers, payloadSrc, attachments,binding.getSOAPVersion()); ohair@286: } ohair@286: } ohair@286: }