src/share/jaxws_classes/com/sun/xml/internal/ws/encoding/fastinfoset/FastInfosetCodec.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.encoding.fastinfoset;
    28 import com.sun.xml.internal.fastinfoset.stax.StAXDocumentSerializer;
    29 import com.sun.xml.internal.fastinfoset.stax.StAXDocumentParser;
    30 import com.sun.xml.internal.fastinfoset.vocab.ParserVocabulary;
    31 import com.sun.xml.internal.fastinfoset.vocab.SerializerVocabulary;
    32 import com.sun.xml.internal.ws.api.SOAPVersion;
    33 import com.sun.xml.internal.ws.api.message.Message;
    34 import com.sun.xml.internal.ws.api.message.Messages;
    35 import com.sun.xml.internal.ws.api.pipe.Codec;
    36 import com.sun.xml.internal.ws.api.pipe.ContentType;
    37 import com.sun.xml.internal.ws.api.message.Packet;
    38 import com.sun.xml.internal.ws.encoding.ContentTypeImpl;
    39 import java.io.BufferedInputStream;
    41 import javax.xml.stream.XMLStreamException;
    42 import javax.xml.stream.XMLStreamWriter;
    43 import javax.xml.ws.WebServiceException;
    44 import java.io.OutputStream;
    45 import java.io.InputStream;
    46 import java.io.IOException;
    47 import java.nio.channels.WritableByteChannel;
    48 import java.nio.channels.ReadableByteChannel;
    49 import com.sun.xml.internal.org.jvnet.fastinfoset.FastInfosetSource;
    51 /**
    52  * A codec for encoding/decoding XML infosets to/from fast
    53  * infoset documents.
    54  *
    55  * @author Paul Sandoz
    56  */
    57 public class FastInfosetCodec implements Codec {
    58     private static final int DEFAULT_INDEXED_STRING_SIZE_LIMIT = 32;
    59     private static final int DEFAULT_INDEXED_STRING_MEMORY_LIMIT = 4 * 1024 * 1024; //4M limit
    61     private StAXDocumentParser _parser;
    63     private StAXDocumentSerializer _serializer;
    65     private final boolean _retainState;
    67     private final ContentType _contentType;
    69     /* package */ FastInfosetCodec(boolean retainState) {
    70         _retainState = retainState;
    71         _contentType = (retainState) ? new ContentTypeImpl(FastInfosetMIMETypes.STATEFUL_INFOSET) :
    72             new ContentTypeImpl(FastInfosetMIMETypes.INFOSET);
    73     }
    75     public String getMimeType() {
    76         return _contentType.getContentType();
    77     }
    79     public Codec copy() {
    80         return new FastInfosetCodec(_retainState);
    81     }
    83     public ContentType getStaticContentType(Packet packet) {
    84         return _contentType;
    85     }
    87     public ContentType encode(Packet packet, OutputStream out) {
    88         Message message = packet.getMessage();
    89         if (message != null && message.hasPayload()) {
    90             final XMLStreamWriter writer = getXMLStreamWriter(out);
    91             try {
    92                 writer.writeStartDocument();
    93                 packet.getMessage().writePayloadTo(writer);
    94                 writer.writeEndDocument();
    95                 writer.flush();
    96             } catch (XMLStreamException e) {
    97                 throw new WebServiceException(e);
    98             }
    99         }
   101         return _contentType;
   102     }
   104     public ContentType encode(Packet packet, WritableByteChannel buffer) {
   105         //TODO: not yet implemented
   106         throw new UnsupportedOperationException();
   107     }
   109     public void decode(InputStream in, String contentType, Packet packet) throws IOException {
   110         /* Implements similar logic as the XMLMessage.create(String, InputStream).
   111          * But it's faster, as we know the InputStream has FastInfoset content*/
   112         Message message;
   113         in = hasSomeData(in);
   114         if (in != null) {
   115             message = Messages.createUsingPayload(new FastInfosetSource(in),
   116                     SOAPVersion.SOAP_11);
   117         } else {
   118             message = Messages.createEmpty(SOAPVersion.SOAP_11);
   119         }
   121         packet.setMessage(message);
   122     }
   124     public void decode(ReadableByteChannel in, String contentType, Packet response) {
   125         throw new UnsupportedOperationException();
   126     }
   128     private XMLStreamWriter getXMLStreamWriter(OutputStream out) {
   129         if (_serializer != null) {
   130             _serializer.setOutputStream(out);
   131             return _serializer;
   132         } else {
   133             return _serializer = createNewStreamWriter(out, _retainState);
   134         }
   135     }
   137     /**
   138      * Creates a new {@link FastInfosetCodec} instance.
   139      *
   140      * @return a new {@link FastInfosetCodec} instance.
   141      */
   142     public static FastInfosetCodec create() {
   143         return create(false);
   144     }
   146     /**
   147      * Creates a new {@link FastInfosetCodec} instance.
   148      *
   149      * @param retainState if true the Codec should retain the state of
   150      *        vocabulary tables for multiple encode/decode invocations.
   151      * @return a new {@link FastInfosetCodec} instance.
   152      */
   153     public static FastInfosetCodec create(boolean retainState) {
   154         return new FastInfosetCodec(retainState);
   155     }
   157     /**
   158      * Create a new (@link StAXDocumentSerializer} instance.
   159      *
   160      * @param in the OutputStream to serialize to.
   161      * @param retainState if true the serializer should retain the state of
   162      *        vocabulary tables for multiple serializations.
   163      * @return a new {@link StAXDocumentSerializer} instance.
   164      */
   165     /* package */ static StAXDocumentSerializer createNewStreamWriter(OutputStream out, boolean retainState) {
   166         return createNewStreamWriter(out, retainState, DEFAULT_INDEXED_STRING_SIZE_LIMIT, DEFAULT_INDEXED_STRING_MEMORY_LIMIT);
   167     }
   169     /**
   170      * Create a new (@link StAXDocumentSerializer} instance.
   171      *
   172      * @param in the OutputStream to serialize to.
   173      * @param retainState if true the serializer should retain the state of
   174      *        vocabulary tables for multiple serializations.
   175      * @return a new {@link StAXDocumentSerializer} instance.
   176      */
   177     /* package */ static StAXDocumentSerializer createNewStreamWriter(OutputStream out,
   178             boolean retainState, int indexedStringSizeLimit, int stringsMemoryLimit) {
   179         StAXDocumentSerializer serializer = new StAXDocumentSerializer(out);
   180         if (retainState) {
   181             /**
   182              * Create a serializer vocabulary external to the serializer.
   183              * This will ensure that the vocabulary will never be cleared
   184              * for each serialization and will be retained (and will grow)
   185              * for each serialization
   186              */
   187             SerializerVocabulary vocabulary = new SerializerVocabulary();
   188             serializer.setVocabulary(vocabulary);
   189             serializer.setMinAttributeValueSize(0);
   190             serializer.setMaxAttributeValueSize(indexedStringSizeLimit);
   191             serializer.setMinCharacterContentChunkSize(0);
   192             serializer.setMaxCharacterContentChunkSize(indexedStringSizeLimit);
   193             serializer.setAttributeValueMapMemoryLimit(stringsMemoryLimit);
   194             serializer.setCharacterContentChunkMapMemoryLimit(stringsMemoryLimit);
   195         }
   196         return serializer;
   197     }
   199     /**
   200      * Create a new (@link StAXDocumentParser} instance.
   201      *
   202      * @param in the InputStream to parse from.
   203      * @param retainState if true the parser should retain the state of
   204      *        vocabulary tables for multiple parses.
   205      * @return a new {@link StAXDocumentParser} instance.
   206      */
   207     /* package */ static StAXDocumentParser createNewStreamReader(InputStream in, boolean retainState) {
   208         StAXDocumentParser parser = new StAXDocumentParser(in);
   209         parser.setStringInterning(true);
   210         if (retainState) {
   211             /**
   212              * Create a parser vocabulary external to the parser.
   213              * This will ensure that the vocabulary will never be cleared
   214              * for each parse and will be retained (and will grow)
   215              * for each parse.
   216              */
   217             ParserVocabulary vocabulary = new ParserVocabulary();
   218             parser.setVocabulary(vocabulary);
   219         }
   220         return parser;
   221     }
   223     /**
   224      * Create a new (@link StAXDocumentParser} recyclable instance.
   225      *
   226      * @param in the InputStream to parse from.
   227      * @param retainState if true the parser should retain the state of
   228      *        vocabulary tables for multiple parses.
   229      * @return a new recyclable {@link StAXDocumentParser} instance.
   230      */
   231     /* package */ static StAXDocumentParser createNewStreamReaderRecyclable(InputStream in, boolean retainState) {
   232         StAXDocumentParser parser = new FastInfosetStreamReaderRecyclable(in);
   233         parser.setStringInterning(true);
   234         parser.setForceStreamClose(true);
   235         if (retainState) {
   236             /**
   237              * Create a parser vocabulary external to the parser.
   238              * This will ensure that the vocabulary will never be cleared
   239              * for each parse and will be retained (and will grow)
   240              * for each parse.
   241              */
   242             ParserVocabulary vocabulary = new ParserVocabulary();
   243             parser.setVocabulary(vocabulary);
   244         }
   245         return parser;
   246     }
   248     /**
   249      * Method is copied from com.sun.xml.internal.ws.encoding.xml.XMLMessage
   250      * @TODO method should be public in some util package?
   251      *
   252      * Finds if the stream has some content or not
   253      *
   254      * @return null if there is no data
   255      *         else stream to be used
   256      */
   257     private static InputStream hasSomeData(InputStream in) throws IOException {
   258         if (in != null) {
   259             if (in.available() < 1) {
   260                 if (!in.markSupported()) {
   261                     in = new BufferedInputStream(in);
   262                 }
   263                 in.mark(1);
   264                 if (in.read() != -1) {
   265                     in.reset();
   266                 } else {
   267                     in = null;          // No data
   268                 }
   269             }
   270         }
   271         return in;
   272     }
   273 }

mercurial