Tue, 09 Apr 2013 14:51:13 +0100
8010393: Update JAX-WS RI to 2.2.9-b12941
Reviewed-by: alanb, erikj
Contributed-by: miroslav.kos@oracle.com, martin.grebac@oracle.com
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 }