src/share/jaxws_classes/com/sun/xml/internal/ws/message/jaxb/JAXBDispatchMessage.java

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 368
0989ad8c0860
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

     1 /*
     2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package com.sun.xml.internal.ws.message.jaxb;
    28 import com.sun.xml.internal.ws.api.SOAPVersion;
    29 import com.sun.xml.internal.ws.api.message.Message;
    30 import com.sun.xml.internal.ws.api.message.MessageHeaders;
    31 import com.sun.xml.internal.ws.encoding.SOAPBindingCodec;
    32 import com.sun.xml.internal.ws.message.AbstractMessageImpl;
    33 import com.sun.xml.internal.ws.message.PayloadElementSniffer;
    34 import com.sun.xml.internal.ws.spi.db.BindingContext;
    35 import com.sun.xml.internal.ws.spi.db.XMLBridge;
    36 import com.sun.xml.internal.ws.streaming.MtomStreamWriter;
    37 import com.sun.xml.internal.ws.streaming.XMLStreamWriterUtil;
    38 import org.xml.sax.ContentHandler;
    39 import org.xml.sax.ErrorHandler;
    40 import org.xml.sax.SAXException;
    42 import javax.xml.bind.JAXBContext;
    43 import javax.xml.bind.JAXBException;
    44 import javax.xml.bind.Marshaller;
    45 import javax.xml.bind.attachment.AttachmentMarshaller;
    46 import javax.xml.namespace.QName;
    47 import javax.xml.stream.XMLStreamException;
    48 import javax.xml.stream.XMLStreamReader;
    49 import javax.xml.stream.XMLStreamWriter;
    50 import javax.xml.transform.Source;
    51 import javax.xml.ws.WebServiceException;
    52 import java.io.OutputStream;
    54 /**
    55  * {@link Message} backed by a JAXB bean; this implementation is used when client uses
    56  * Dispatch mechanism in JAXB/MESSAGE mode; difference from {@link JAXBMessage} is
    57  * that {@code jaxbObject} holds whole SOAP message including SOAP envelope;
    58  * it's the client who is responsible for preparing message content.
    59  *
    60  * @author Miroslav Kos (miroslav.kos at oracle.com)
    61  */
    62 public class JAXBDispatchMessage extends AbstractMessageImpl {
    64     private final Object jaxbObject;
    66     private final XMLBridge bridge;
    68     /**
    69      * For the use case of a user-supplied JAXB context that is not
    70      * a known JAXB type, as when creating a Disaptch object with a
    71      * JAXB object parameter, we will marshal and unmarshal directly with
    72      * the context object, as there is no Bond available.  In this case,
    73      * swaRef is not supported.
    74      */
    75     private final JAXBContext rawContext;
    77     /**
    78      * Lazily sniffed payload element name
    79      */
    80     private QName payloadQName;
    82     /**
    83      * Copy constructor.
    84      */
    85     private JAXBDispatchMessage(JAXBDispatchMessage that) {
    86         super(that);
    87         jaxbObject = that.jaxbObject;
    88         rawContext = that.rawContext;
    89         bridge = that.bridge;
    90     }
    92     public JAXBDispatchMessage(JAXBContext rawContext, Object jaxbObject, SOAPVersion soapVersion) {
    93         super(soapVersion);
    94         this.bridge = null;
    95         this.rawContext = rawContext;
    96         this.jaxbObject = jaxbObject;
    97     }
    99     public JAXBDispatchMessage(BindingContext context, Object jaxbObject, SOAPVersion soapVersion) {
   100         super(soapVersion);
   101         this.bridge = context.createFragmentBridge();
   102         this.rawContext = null;
   103         this.jaxbObject = jaxbObject;
   104     }
   106     @Override
   107     protected void writePayloadTo(ContentHandler contentHandler, ErrorHandler errorHandler, boolean fragment) throws SAXException {
   108         throw new UnsupportedOperationException();
   109     }
   111     @Override
   112     public boolean hasHeaders() {
   113         return false;
   114     }
   116     @Override
   117     public MessageHeaders getHeaders() {
   118         return null;
   119     }
   121     @Override
   122     public String getPayloadLocalPart() {
   123         if (payloadQName == null) {
   124             readPayloadElement();
   125         }
   126         return payloadQName.getLocalPart();
   127     }
   129     @Override
   130     public String getPayloadNamespaceURI() {
   131         if (payloadQName == null) {
   132             readPayloadElement();
   133         }
   134         return payloadQName.getNamespaceURI();
   135     }
   137     private void readPayloadElement() {
   138         PayloadElementSniffer sniffer = new PayloadElementSniffer();
   139         try {
   140             if (rawContext != null) {
   141                 Marshaller m = rawContext.createMarshaller();
   142                 m.setProperty("jaxb.fragment", Boolean.FALSE);
   143                 m.marshal(jaxbObject, sniffer);
   144             } else {
   145                 bridge.marshal(jaxbObject, sniffer, null);
   146             }
   148         } catch (JAXBException e) {
   149             // if it's due to us aborting the processing after the first element,
   150             // we can safely ignore this exception.
   151             //
   152             // if it's due to error in the object, the same error will be reported
   153             // when the readHeader() method is used, so we don't have to report
   154             // an error right now.
   155             payloadQName = sniffer.getPayloadQName();
   156         }
   157     }
   159     @Override
   160     public boolean hasPayload() {
   161         return true;
   162     }
   164     @Override
   165     public Source readPayloadAsSource() {
   166         throw new UnsupportedOperationException();
   167     }
   169     @Override
   170     public XMLStreamReader readPayload() throws XMLStreamException {
   171         throw new UnsupportedOperationException();
   172     }
   174     @Override
   175     public void writePayloadTo(XMLStreamWriter sw) throws XMLStreamException {
   176         throw new UnsupportedOperationException();
   177     }
   179     @Override
   180     public Message copy() {
   181         return new JAXBDispatchMessage(this);
   182     }
   184     @Override
   185     @SuppressWarnings("unchecked")
   186     public void writeTo(XMLStreamWriter sw) throws XMLStreamException {
   187         try {
   188             // MtomCodec sets its own AttachmentMarshaller
   189             AttachmentMarshaller am = (sw instanceof MtomStreamWriter)
   190                     ? ((MtomStreamWriter) sw).getAttachmentMarshaller()
   191                     : new AttachmentMarshallerImpl(attachmentSet);
   193             // Get the encoding of the writer
   194             String encoding = XMLStreamWriterUtil.getEncoding(sw);
   196             // Get output stream and use JAXB UTF-8 writer
   197             OutputStream os = bridge.supportOutputStream() ? XMLStreamWriterUtil.getOutputStream(sw) : null;
   198             if (rawContext != null) {
   199                 Marshaller m = rawContext.createMarshaller();
   200                 m.setProperty("jaxb.fragment", Boolean.FALSE);
   201                 m.setAttachmentMarshaller(am);
   202                 if (os != null) {
   203                     m.marshal(jaxbObject, os);
   204                 } else {
   205                     m.marshal(jaxbObject, sw);
   206                 }
   208             } else {
   210                 if (os != null && encoding != null && encoding.equalsIgnoreCase(SOAPBindingCodec.UTF8_ENCODING)) {
   211                     bridge.marshal(jaxbObject, os, sw.getNamespaceContext(), am);
   212                 } else {
   213                     bridge.marshal(jaxbObject, sw, am);
   214                 }
   215             }
   216             //cleanup() is not needed since JAXB doesn't keep ref to AttachmentMarshaller
   217         } catch (JAXBException e) {
   218             // bug 6449684, spec 4.3.4
   219             throw new WebServiceException(e);
   220         }
   221     }
   222 }

mercurial