src/share/jaxws_classes/com/sun/xml/internal/ws/encoding/StreamSOAPCodec.java

Wed, 27 Apr 2016 01:27:09 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:27:09 +0800
changeset 0
373ffda63c9a
child 637
9c07ef4934dd
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/jaxws/
changeset: 657:d47a47f961ee
tag: jdk8u25-b17

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.xml.internal.ws.encoding;
aoqi@0 27
aoqi@0 28 import static com.sun.xml.internal.ws.binding.WebServiceFeatureList.getSoapVersion;
aoqi@0 29
aoqi@0 30 import com.oracle.webservices.internal.impl.encoding.StreamDecoderImpl;
aoqi@0 31 import com.oracle.webservices.internal.impl.internalspi.encoding.StreamDecoder;
aoqi@0 32 import com.sun.istack.internal.NotNull;
aoqi@0 33 import com.sun.istack.internal.Nullable;
aoqi@0 34 import com.sun.xml.internal.stream.buffer.MutableXMLStreamBuffer;
aoqi@0 35 import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
aoqi@0 36 import com.sun.xml.internal.stream.buffer.XMLStreamBufferMark;
aoqi@0 37 import com.sun.xml.internal.stream.buffer.stax.StreamReaderBufferCreator;
aoqi@0 38 import com.sun.xml.internal.ws.api.SOAPVersion;
aoqi@0 39 import com.sun.xml.internal.ws.api.WSBinding;
aoqi@0 40 import com.sun.xml.internal.ws.api.WSFeatureList;
aoqi@0 41 import com.sun.xml.internal.ws.api.message.AttachmentSet;
aoqi@0 42 import com.sun.xml.internal.ws.api.message.Header;
aoqi@0 43 import com.sun.xml.internal.ws.api.message.HeaderList;
aoqi@0 44 import com.sun.xml.internal.ws.api.message.Message;
aoqi@0 45 import com.sun.xml.internal.ws.api.message.Packet;
aoqi@0 46 import com.sun.xml.internal.ws.api.pipe.ContentType;
aoqi@0 47 import com.sun.xml.internal.ws.api.streaming.XMLStreamWriterFactory;
aoqi@0 48 import com.sun.xml.internal.ws.developer.SerializationFeature;
aoqi@0 49 import com.sun.xml.internal.ws.message.AttachmentSetImpl;
aoqi@0 50 import com.sun.xml.internal.ws.message.stream.StreamMessage;
aoqi@0 51 import com.sun.xml.internal.ws.protocol.soap.VersionMismatchException;
aoqi@0 52 import com.sun.xml.internal.ws.server.UnsupportedMediaException;
aoqi@0 53 import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil;
aoqi@0 54 import com.sun.xml.internal.ws.util.ServiceFinder;
aoqi@0 55
aoqi@0 56 import javax.xml.stream.XMLStreamConstants;
aoqi@0 57 import javax.xml.stream.XMLStreamException;
aoqi@0 58 import javax.xml.stream.XMLStreamReader;
aoqi@0 59 import javax.xml.stream.XMLStreamWriter;
aoqi@0 60 import javax.xml.ws.WebServiceException;
aoqi@0 61 import java.io.IOException;
aoqi@0 62 import java.io.InputStream;
aoqi@0 63 import java.io.OutputStream;
aoqi@0 64 import java.nio.channels.ReadableByteChannel;
aoqi@0 65 import java.nio.channels.WritableByteChannel;
aoqi@0 66 import java.nio.charset.Charset;
aoqi@0 67 import java.util.HashMap;
aoqi@0 68 import java.util.List;
aoqi@0 69 import java.util.Map;
aoqi@0 70
aoqi@0 71 /**
aoqi@0 72 * A stream SOAP codec.
aoqi@0 73 *
aoqi@0 74 * @author Paul Sandoz
aoqi@0 75 */
aoqi@0 76 @SuppressWarnings({"StringEquality"})
aoqi@0 77 public abstract class StreamSOAPCodec implements com.sun.xml.internal.ws.api.pipe.StreamSOAPCodec, RootOnlyCodec {
aoqi@0 78
aoqi@0 79 private static final String SOAP_ENVELOPE = "Envelope";
aoqi@0 80 private static final String SOAP_HEADER = "Header";
aoqi@0 81 private static final String SOAP_BODY = "Body";
aoqi@0 82
aoqi@0 83 private final SOAPVersion soapVersion;
aoqi@0 84 protected final SerializationFeature serializationFeature;
aoqi@0 85
aoqi@0 86 private final StreamDecoder streamDecoder;
aoqi@0 87
aoqi@0 88 // charset of last decoded message. Will be used for encoding server's
aoqi@0 89 // response messages with the request message's encoding
aoqi@0 90 // it will stored in the packet.invocationProperties
aoqi@0 91 private final static String DECODED_MESSAGE_CHARSET = "decodedMessageCharset";
aoqi@0 92
aoqi@0 93 /*package*/ StreamSOAPCodec(SOAPVersion soapVersion) {
aoqi@0 94 this(soapVersion, null);
aoqi@0 95 }
aoqi@0 96
aoqi@0 97 /*package*/ StreamSOAPCodec(WSBinding binding) {
aoqi@0 98 this(binding.getSOAPVersion(), binding.getFeature(SerializationFeature.class));
aoqi@0 99 }
aoqi@0 100
aoqi@0 101 StreamSOAPCodec(WSFeatureList features) {
aoqi@0 102 this(getSoapVersion(features), features.get(SerializationFeature.class));
aoqi@0 103 }
aoqi@0 104
aoqi@0 105 private StreamSOAPCodec(SOAPVersion soapVersion, @Nullable SerializationFeature sf) {
aoqi@0 106 this.soapVersion = soapVersion;
aoqi@0 107 this.serializationFeature = sf;
aoqi@0 108 this.streamDecoder = selectStreamDecoder();
aoqi@0 109 }
aoqi@0 110
aoqi@0 111 private StreamDecoder selectStreamDecoder() {
aoqi@0 112 for (StreamDecoder sd : ServiceFinder.find(StreamDecoder.class)) {
aoqi@0 113 return sd;
aoqi@0 114 }
aoqi@0 115
aoqi@0 116 return new StreamDecoderImpl();
aoqi@0 117 }
aoqi@0 118
aoqi@0 119 public ContentType getStaticContentType(Packet packet) {
aoqi@0 120 return getContentType(packet);
aoqi@0 121 }
aoqi@0 122
aoqi@0 123 public ContentType encode(Packet packet, OutputStream out) {
aoqi@0 124 if (packet.getMessage() != null) {
aoqi@0 125 String encoding = getPacketEncoding(packet);
aoqi@0 126 packet.invocationProperties.remove(DECODED_MESSAGE_CHARSET);
aoqi@0 127 XMLStreamWriter writer = XMLStreamWriterFactory.create(out, encoding);
aoqi@0 128 try {
aoqi@0 129 packet.getMessage().writeTo(writer);
aoqi@0 130 writer.flush();
aoqi@0 131 } catch (XMLStreamException e) {
aoqi@0 132 throw new WebServiceException(e);
aoqi@0 133 }
aoqi@0 134 XMLStreamWriterFactory.recycle(writer);
aoqi@0 135 }
aoqi@0 136 return getContentType(packet);
aoqi@0 137 }
aoqi@0 138
aoqi@0 139 protected abstract ContentType getContentType(Packet packet);
aoqi@0 140
aoqi@0 141 protected abstract String getDefaultContentType();
aoqi@0 142
aoqi@0 143 public ContentType encode(Packet packet, WritableByteChannel buffer) {
aoqi@0 144 //TODO: not yet implemented
aoqi@0 145 throw new UnsupportedOperationException();
aoqi@0 146 }
aoqi@0 147
aoqi@0 148 protected abstract List<String> getExpectedContentTypes();
aoqi@0 149
aoqi@0 150 public void decode(InputStream in, String contentType, Packet packet) throws IOException {
aoqi@0 151 decode(in, contentType, packet, new AttachmentSetImpl());
aoqi@0 152 }
aoqi@0 153
aoqi@0 154 /*
aoqi@0 155 * Checks against expected Content-Type headers that is handled by a codec
aoqi@0 156 *
aoqi@0 157 * @param ct the Content-Type of the request
aoqi@0 158 * @param expected expected Content-Types for a codec
aoqi@0 159 * @return true if the codec supports this Content-Type
aoqi@0 160 * false otherwise
aoqi@0 161 */
aoqi@0 162 private static boolean isContentTypeSupported(String ct, List<String> expected) {
aoqi@0 163 for(String contentType : expected) {
aoqi@0 164 if (ct.contains(contentType)) {
aoqi@0 165 return true;
aoqi@0 166 }
aoqi@0 167 }
aoqi@0 168 return false;
aoqi@0 169 }
aoqi@0 170
aoqi@0 171 /**
aoqi@0 172 * Decodes a message from {@link XMLStreamReader} that points to
aoqi@0 173 * the beginning of a SOAP infoset.
aoqi@0 174 *
aoqi@0 175 * @param reader
aoqi@0 176 * can point to the start document or the start element.
aoqi@0 177 */
aoqi@0 178 public final @NotNull Message decode(@NotNull XMLStreamReader reader) {
aoqi@0 179 return decode(reader,new AttachmentSetImpl());
aoqi@0 180 }
aoqi@0 181
aoqi@0 182 /**
aoqi@0 183 * Decodes a message from {@link XMLStreamReader} that points to
aoqi@0 184 * the beginning of a SOAP infoset.
aoqi@0 185 *
aoqi@0 186 * @param reader
aoqi@0 187 * can point to the start document or the start element.
aoqi@0 188 * @param attachmentSet
aoqi@0 189 * {@link StreamSOAPCodec} can take attachments parsed outside,
aoqi@0 190 * so that this codec can be used as a part of a biggre codec
aoqi@0 191 * (like MIME multipart codec.)
aoqi@0 192 */
aoqi@0 193 public final Message decode(XMLStreamReader reader, @NotNull AttachmentSet attachmentSet) {
aoqi@0 194 return decode(soapVersion, reader, attachmentSet);
aoqi@0 195 }
aoqi@0 196
aoqi@0 197 public static final Message decode(SOAPVersion soapVersion, XMLStreamReader reader, @NotNull AttachmentSet attachmentSet) {
aoqi@0 198 // Move to soap:Envelope and verify
aoqi@0 199 if(reader.getEventType()!=XMLStreamConstants.START_ELEMENT)
aoqi@0 200 XMLStreamReaderUtil.nextElementContent(reader);
aoqi@0 201 XMLStreamReaderUtil.verifyReaderState(reader,XMLStreamConstants.START_ELEMENT);
aoqi@0 202 if (SOAP_ENVELOPE.equals(reader.getLocalName()) && !soapVersion.nsUri.equals(reader.getNamespaceURI())) {
aoqi@0 203 throw new VersionMismatchException(soapVersion, soapVersion.nsUri, reader.getNamespaceURI());
aoqi@0 204 }
aoqi@0 205 XMLStreamReaderUtil.verifyTag(reader, soapVersion.nsUri, SOAP_ENVELOPE);
aoqi@0 206 return new StreamMessage(soapVersion, reader, attachmentSet);
aoqi@0 207 }
aoqi@0 208
aoqi@0 209 public void decode(ReadableByteChannel in, String contentType, Packet packet ) {
aoqi@0 210 throw new UnsupportedOperationException();
aoqi@0 211 }
aoqi@0 212
aoqi@0 213 public final StreamSOAPCodec copy() {
aoqi@0 214 return this;
aoqi@0 215 }
aoqi@0 216
aoqi@0 217 public void decode(InputStream in, String contentType, Packet packet, AttachmentSet att ) throws IOException {
aoqi@0 218 List<String> expectedContentTypes = getExpectedContentTypes();
aoqi@0 219 if (contentType != null && !isContentTypeSupported(contentType,expectedContentTypes)) {
aoqi@0 220 throw new UnsupportedMediaException(contentType, expectedContentTypes);
aoqi@0 221 }
aoqi@0 222 com.oracle.webservices.internal.api.message.ContentType pct = packet.getInternalContentType();
aoqi@0 223 ContentTypeImpl cti = (pct != null && pct instanceof ContentTypeImpl) ?
aoqi@0 224 (ContentTypeImpl)pct : new ContentTypeImpl(contentType);
aoqi@0 225 String charset = cti.getCharSet();
aoqi@0 226 if (charset != null && !Charset.isSupported(charset)) {
aoqi@0 227 throw new UnsupportedMediaException(charset);
aoqi@0 228 }
aoqi@0 229 if (charset != null) {
aoqi@0 230 packet.invocationProperties.put(DECODED_MESSAGE_CHARSET, charset);
aoqi@0 231 } else {
aoqi@0 232 packet.invocationProperties.remove(DECODED_MESSAGE_CHARSET);
aoqi@0 233 }
aoqi@0 234 packet.setMessage(streamDecoder.decode(in, charset, att, soapVersion));
aoqi@0 235 }
aoqi@0 236
aoqi@0 237 public void decode(ReadableByteChannel in, String contentType, Packet response, AttachmentSet att ) {
aoqi@0 238 throw new UnsupportedOperationException();
aoqi@0 239 }
aoqi@0 240
aoqi@0 241 /*
aoqi@0 242 * Creates a new {@link StreamSOAPCodec} instance.
aoqi@0 243 */
aoqi@0 244 public static StreamSOAPCodec create(SOAPVersion version) {
aoqi@0 245 if(version==null)
aoqi@0 246 // this decoder is for SOAP, not for XML/HTTP
aoqi@0 247 throw new IllegalArgumentException();
aoqi@0 248 switch(version) {
aoqi@0 249 case SOAP_11:
aoqi@0 250 return new StreamSOAP11Codec();
aoqi@0 251 case SOAP_12:
aoqi@0 252 return new StreamSOAP12Codec();
aoqi@0 253 default:
aoqi@0 254 throw new AssertionError();
aoqi@0 255 }
aoqi@0 256 }
aoqi@0 257
aoqi@0 258 /*
aoqi@0 259 * Creates a new {@link StreamSOAPCodec} instance using binding
aoqi@0 260 */
aoqi@0 261 public static StreamSOAPCodec create(WSFeatureList features) {
aoqi@0 262 SOAPVersion version = getSoapVersion(features);
aoqi@0 263 if(version==null)
aoqi@0 264 // this decoder is for SOAP, not for XML/HTTP
aoqi@0 265 throw new IllegalArgumentException();
aoqi@0 266 switch(version) {
aoqi@0 267 case SOAP_11:
aoqi@0 268 return new StreamSOAP11Codec(features);
aoqi@0 269 case SOAP_12:
aoqi@0 270 return new StreamSOAP12Codec(features);
aoqi@0 271 default:
aoqi@0 272 throw new AssertionError();
aoqi@0 273 }
aoqi@0 274 }
aoqi@0 275
aoqi@0 276 /**
aoqi@0 277 * Creates a new {@link StreamSOAPCodec} instance using binding
aoqi@0 278 *
aoqi@0 279 * @deprecated use {@link #create(WSFeatureList)}
aoqi@0 280 */
aoqi@0 281 public static StreamSOAPCodec create(WSBinding binding) {
aoqi@0 282 SOAPVersion version = binding.getSOAPVersion();
aoqi@0 283 if(version==null)
aoqi@0 284 // this decoder is for SOAP, not for XML/HTTP
aoqi@0 285 throw new IllegalArgumentException();
aoqi@0 286 switch(version) {
aoqi@0 287 case SOAP_11:
aoqi@0 288 return new StreamSOAP11Codec(binding);
aoqi@0 289 case SOAP_12:
aoqi@0 290 return new StreamSOAP12Codec(binding);
aoqi@0 291 default:
aoqi@0 292 throw new AssertionError();
aoqi@0 293 }
aoqi@0 294 }
aoqi@0 295
aoqi@0 296 private String getPacketEncoding(Packet packet) {
aoqi@0 297 // If SerializationFeature is set, just use that encoding
aoqi@0 298 if (serializationFeature != null && serializationFeature.getEncoding() != null) {
aoqi@0 299 return serializationFeature.getEncoding().equals("")
aoqi@0 300 ? SOAPBindingCodec.DEFAULT_ENCODING : serializationFeature.getEncoding();
aoqi@0 301 }
aoqi@0 302
aoqi@0 303 if (packet != null && packet.endpoint != null) {
aoqi@0 304 // Use request message's encoding for Server-side response messages
aoqi@0 305 String charset = (String)packet.invocationProperties.get(DECODED_MESSAGE_CHARSET);
aoqi@0 306 return charset == null
aoqi@0 307 ? SOAPBindingCodec.DEFAULT_ENCODING : charset;
aoqi@0 308 }
aoqi@0 309
aoqi@0 310 // Use default encoding for client-side request messages
aoqi@0 311 return SOAPBindingCodec.DEFAULT_ENCODING;
aoqi@0 312 }
aoqi@0 313
aoqi@0 314 protected ContentTypeImpl.Builder getContenTypeBuilder(Packet packet) {
aoqi@0 315 ContentTypeImpl.Builder b = new ContentTypeImpl.Builder();
aoqi@0 316 String encoding = getPacketEncoding(packet);
aoqi@0 317 if (SOAPBindingCodec.DEFAULT_ENCODING.equalsIgnoreCase(encoding)) {
aoqi@0 318 b.contentType = getDefaultContentType();
aoqi@0 319 b.charset = SOAPBindingCodec.DEFAULT_ENCODING;
aoqi@0 320 return b;
aoqi@0 321 }
aoqi@0 322 b.contentType = getMimeType()+" ;charset="+encoding;
aoqi@0 323 b.charset = encoding;
aoqi@0 324 return b;
aoqi@0 325 }
aoqi@0 326
aoqi@0 327 }

mercurial