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

Tue, 06 Mar 2012 16:09:35 -0800

author
ohair
date
Tue, 06 Mar 2012 16:09:35 -0800
changeset 286
f50545b5e2f1
child 368
0989ad8c0860
permissions
-rw-r--r--

7150322: Stop using drop source bundles in jaxws
Reviewed-by: darcy, ohrstrom

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

mercurial