src/share/jaxws_classes/com/sun/xml/internal/stream/buffer/stax/StreamWriterBufferProcessor.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) 2005, 2012, 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.stream.buffer.stax;
    28 import com.sun.xml.internal.stream.buffer.AbstractProcessor;
    29 import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
    31 import java.io.IOException;
    32 import java.util.Collections;
    33 import java.util.HashSet;
    34 import java.util.Map;
    35 import java.util.Set;
    37 import com.sun.xml.internal.org.jvnet.staxex.Base64Data;
    38 import com.sun.xml.internal.org.jvnet.staxex.XMLStreamWriterEx;
    40 import javax.xml.stream.XMLStreamException;
    41 import javax.xml.stream.XMLStreamWriter;
    44 /**
    45  * A processor of a {@link XMLStreamBuffer} that writes the XML infoset to a
    46  * {@link XMLStreamWriter}.
    47  *
    48  * @author Paul.Sandoz@Sun.Com
    49  * @author K.Venugopal@sun.com
    50  */
    51 public class StreamWriterBufferProcessor extends AbstractProcessor {
    54     public StreamWriterBufferProcessor() {
    55     }
    57     /**
    58      * @deprecated
    59      *      Use {@link #StreamWriterBufferProcessor(XMLStreamBuffer, boolean)}
    60      */
    61     public StreamWriterBufferProcessor(XMLStreamBuffer buffer) {
    62         setXMLStreamBuffer(buffer,buffer.isFragment());
    63     }
    65     /**
    66      * @param produceFragmentEvent
    67      *      True to generate fragment SAX events without start/endDocument.
    68      *      False to generate a full document SAX events.
    69      */
    70     public StreamWriterBufferProcessor(XMLStreamBuffer buffer,boolean produceFragmentEvent) {
    71         setXMLStreamBuffer(buffer,produceFragmentEvent);
    72     }
    74     public final void process(XMLStreamBuffer buffer, XMLStreamWriter writer) throws XMLStreamException {
    75         setXMLStreamBuffer(buffer,buffer.isFragment());
    76         process(writer);
    77     }
    79     public void process(XMLStreamWriter writer) throws XMLStreamException {
    80         if(_fragmentMode){
    81             writeFragment(writer);
    82         }else{
    83             write(writer);
    84         }
    85     }
    87     /**
    88      * @deprecated
    89      *      Use {@link #setXMLStreamBuffer(XMLStreamBuffer, boolean)}
    90      */
    91     public void setXMLStreamBuffer(XMLStreamBuffer buffer) {
    92         setBuffer(buffer);
    93     }
    95     /**
    96      * @param produceFragmentEvent
    97      *      True to generate fragment SAX events without start/endDocument.
    98      *      False to generate a full document SAX events.
    99      */
   100     public void setXMLStreamBuffer(XMLStreamBuffer buffer, boolean produceFragmentEvent) {
   101         setBuffer(buffer,produceFragmentEvent);
   102     }
   104     /**
   105      * Writes a full XML infoset event to the given writer,
   106      * including start/end document.
   107      * Any inscope namespaces present will be written as namespace
   108      * delcarations on each top-level element.
   109      */
   110     public void write(XMLStreamWriter writer) throws XMLStreamException{
   112         if(!_fragmentMode) {
   113             if(_treeCount>1)
   114                 throw new IllegalStateException("forest cannot be written as a full infoset");
   115             writer.writeStartDocument();
   116         }
   118         while(true) {
   119             int item = getEIIState(peekStructure());
   120             writer.flush();
   122             switch(item) {
   123                 case STATE_DOCUMENT:
   124                     readStructure(); //skip
   125                     break;
   126                 case STATE_ELEMENT_U_LN_QN:
   127                 case STATE_ELEMENT_P_U_LN:
   128                 case STATE_ELEMENT_U_LN:
   129                 case STATE_ELEMENT_LN:
   130                     writeFragment(writer);
   131                     break;
   132                 case STATE_COMMENT_AS_CHAR_ARRAY_SMALL: {
   133                     readStructure();
   134                     final int length = readStructure();
   135                     final int start = readContentCharactersBuffer(length);
   136                     final String comment = new String(_contentCharactersBuffer, start, length);
   137                     writer.writeComment(comment);
   138                     break;
   139                 }
   140                 case STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM: {
   141                     readStructure();
   142                     final int length = readStructure16();
   143                     final int start = readContentCharactersBuffer(length);
   144                     final String comment = new String(_contentCharactersBuffer, start, length);
   145                     writer.writeComment(comment);
   146                     break;
   147                 }
   148                 case STATE_COMMENT_AS_CHAR_ARRAY_COPY: {
   149                     readStructure();
   150                     final char[] ch = readContentCharactersCopy();
   151                     writer.writeComment(new String(ch));
   152                     break;
   153                 }
   154                 case STATE_PROCESSING_INSTRUCTION:
   155                     readStructure();
   156                     writer.writeProcessingInstruction(readStructureString(), readStructureString());
   157                     break;
   158                 case STATE_END: // done
   159                     readStructure();
   160                     writer.writeEndDocument();
   161                     return;
   162                 default:
   163                     throw new XMLStreamException("Invalid State "+item);
   164             }
   165         }
   167     }
   169     /**
   170      * Writes the buffer as a fragment, meaning
   171      * the writer will not receive start/endDocument events.
   172      * Any inscope namespaces present will be written as namespace
   173      * delcarations on each top-level element.
   174      * <p>
   175      * If {@link XMLStreamBuffer} has a forest, this method will write all the forests.
   176      */
   177     public void writeFragment(XMLStreamWriter writer) throws XMLStreamException {
   178         if (writer instanceof XMLStreamWriterEx) {
   179             writeFragmentEx((XMLStreamWriterEx)writer);
   180         } else {
   181             writeFragmentNoEx(writer);
   182         }
   183     }
   185     public void writeFragmentEx(XMLStreamWriterEx writer) throws XMLStreamException {
   186         int depth = 0;  // used to determine when we are done with a tree.
   188         int item = getEIIState(peekStructure());
   189         if(item==STATE_DOCUMENT)
   190             readStructure();    // skip STATE_DOCUMENT
   192         do {
   194             item = readEiiState();
   196             switch(item) {
   197                 case STATE_DOCUMENT:
   198                     throw new AssertionError();
   199                 case STATE_ELEMENT_U_LN_QN: {
   200                     depth ++;
   201                     final String uri = readStructureString();
   202                     final String localName = readStructureString();
   203                     final String prefix = getPrefixFromQName(readStructureString());
   204                     writer.writeStartElement(prefix,localName,uri);
   205                     writeAttributes(writer, isInscope(depth));
   206                     break;
   207                 }
   208                 case STATE_ELEMENT_P_U_LN: {
   209                     depth ++;
   210                     final String prefix = readStructureString();
   211                     final String uri = readStructureString();
   212                     final String localName = readStructureString();
   213                     writer.writeStartElement(prefix,localName,uri);
   214                     writeAttributes(writer, isInscope(depth));
   215                     break;
   216                 }
   217                 case STATE_ELEMENT_U_LN: {
   218                     depth ++;
   219                     final String uri = readStructureString();
   220                     final String localName = readStructureString();
   221                     writer.writeStartElement("",localName,uri);
   222                     writeAttributes(writer, isInscope(depth));
   223                     break;
   224                 }
   225                 case STATE_ELEMENT_LN: {
   226                     depth ++;
   227                     final String localName = readStructureString();
   228                     writer.writeStartElement(localName);
   229                     writeAttributes(writer, isInscope(depth));
   230                     break;
   231                 }
   232                 case STATE_TEXT_AS_CHAR_ARRAY_SMALL: {
   233                     final int length = readStructure();
   234                     final int start = readContentCharactersBuffer(length);
   235                     writer.writeCharacters(_contentCharactersBuffer,start,length);
   236                     break;
   237                 }
   238                 case STATE_TEXT_AS_CHAR_ARRAY_MEDIUM: {
   239                     final int length = readStructure16();
   240                     final int start = readContentCharactersBuffer(length);
   241                     writer.writeCharacters(_contentCharactersBuffer,start,length);
   242                     break;
   243                 }
   244                 case STATE_TEXT_AS_CHAR_ARRAY_COPY: {
   245                     char[] c = readContentCharactersCopy();
   246                     writer.writeCharacters(c,0,c.length);
   247                     break;
   248                 }
   249                 case STATE_TEXT_AS_STRING: {
   250                     final String s = readContentString();
   251                     writer.writeCharacters(s);
   252                     break;
   253                 }
   254                 case STATE_TEXT_AS_OBJECT: {
   255                     final CharSequence c = (CharSequence)readContentObject();
   256                     writer.writePCDATA(c);
   257                     break;
   258                 }
   259                 case STATE_COMMENT_AS_CHAR_ARRAY_SMALL: {
   260                     final int length = readStructure();
   261                     final int start = readContentCharactersBuffer(length);
   262                     final String comment = new String(_contentCharactersBuffer, start, length);
   263                     writer.writeComment(comment);
   264                     break;
   265                 }
   266                 case STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM: {
   267                     final int length = readStructure16();
   268                     final int start = readContentCharactersBuffer(length);
   269                     final String comment = new String(_contentCharactersBuffer, start, length);
   270                     writer.writeComment(comment);
   271                     break;
   272                 }
   273                 case STATE_COMMENT_AS_CHAR_ARRAY_COPY: {
   274                     final char[] ch = readContentCharactersCopy();
   275                     writer.writeComment(new String(ch));
   276                     break;
   277                 }
   278                 case STATE_PROCESSING_INSTRUCTION:
   279                     writer.writeProcessingInstruction(readStructureString(), readStructureString());
   280                     break;
   281                 case STATE_END:
   282                     writer.writeEndElement();
   283                     depth --;
   284                     if(depth==0)
   285                         _treeCount--;
   286                     break;
   287                 default:
   288                     throw new XMLStreamException("Invalid State "+item);
   289             }
   290         } while(depth>0 || _treeCount>0);
   292     }
   294     public void writeFragmentNoEx(XMLStreamWriter writer) throws XMLStreamException {
   295         int depth = 0;
   297         int item = getEIIState(peekStructure());
   298         if(item==STATE_DOCUMENT)
   299             readStructure();    // skip STATE_DOCUMENT
   301         do {
   302             item = readEiiState();
   304             switch(item) {
   305                 case STATE_DOCUMENT:
   306                     throw new AssertionError();
   307                 case STATE_ELEMENT_U_LN_QN: {
   308                     depth ++;
   309                     final String uri = readStructureString();
   310                     final String localName = readStructureString();
   311                     final String prefix = getPrefixFromQName(readStructureString());
   312                     writer.writeStartElement(prefix,localName,uri);
   313                     writeAttributes(writer, isInscope(depth));
   314                     break;
   315                 }
   316                 case STATE_ELEMENT_P_U_LN: {
   317                     depth ++;
   318                     final String prefix = readStructureString();
   319                     final String uri = readStructureString();
   320                     final String localName = readStructureString();
   321                     writer.writeStartElement(prefix,localName,uri);
   322                     writeAttributes(writer, isInscope(depth));
   323                     break;
   324                 }
   325                 case STATE_ELEMENT_U_LN: {
   326                     depth ++;
   327                     final String uri = readStructureString();
   328                     final String localName = readStructureString();
   329                     writer.writeStartElement("",localName,uri);
   330                     writeAttributes(writer, isInscope(depth));
   331                     break;
   332                 }
   333                 case STATE_ELEMENT_LN: {
   334                     depth ++;
   335                     final String localName = readStructureString();
   336                     writer.writeStartElement(localName);
   337                     writeAttributes(writer, isInscope(depth));
   338                     break;
   339                 }
   340                 case STATE_TEXT_AS_CHAR_ARRAY_SMALL: {
   341                     final int length = readStructure();
   342                     final int start = readContentCharactersBuffer(length);
   343                     writer.writeCharacters(_contentCharactersBuffer,start,length);
   344                     break;
   345                 }
   346                 case STATE_TEXT_AS_CHAR_ARRAY_MEDIUM: {
   347                     final int length = readStructure16();
   348                     final int start = readContentCharactersBuffer(length);
   349                     writer.writeCharacters(_contentCharactersBuffer,start,length);
   350                     break;
   351                 }
   352                 case STATE_TEXT_AS_CHAR_ARRAY_COPY: {
   353                     char[] c = readContentCharactersCopy();
   354                     writer.writeCharacters(c,0,c.length);
   355                     break;
   356                 }
   357                 case STATE_TEXT_AS_STRING: {
   358                     final String s = readContentString();
   359                     writer.writeCharacters(s);
   360                     break;
   361                 }
   362                 case STATE_TEXT_AS_OBJECT: {
   363                     final CharSequence c = (CharSequence)readContentObject();
   364                     if (c instanceof Base64Data) {
   365                         try {
   366                             Base64Data bd = (Base64Data)c;
   367                             bd.writeTo(writer);
   368                         } catch (IOException e) {
   369                           throw new XMLStreamException(e);
   370                         }
   371                     } else {
   372                          writer.writeCharacters(c.toString());
   373                     }
   374                     break;
   375                 }
   376                 case STATE_COMMENT_AS_CHAR_ARRAY_SMALL: {
   377                     final int length = readStructure();
   378                     final int start = readContentCharactersBuffer(length);
   379                     final String comment = new String(_contentCharactersBuffer, start, length);
   380                     writer.writeComment(comment);
   381                     break;
   382                 }
   383                 case STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM: {
   384                     final int length = readStructure16();
   385                     final int start = readContentCharactersBuffer(length);
   386                     final String comment = new String(_contentCharactersBuffer, start, length);
   387                     writer.writeComment(comment);
   388                     break;
   389                 }
   390                 case STATE_COMMENT_AS_CHAR_ARRAY_COPY: {
   391                     final char[] ch = readContentCharactersCopy();
   392                     writer.writeComment(new String(ch));
   393                     break;
   394                 }
   395                 case STATE_PROCESSING_INSTRUCTION:
   396                     writer.writeProcessingInstruction(readStructureString(), readStructureString());
   397                     break;
   398                 case STATE_END:
   399                     writer.writeEndElement();
   400                     depth --;
   401                     if(depth==0)
   402                         _treeCount--;
   403                     break;
   404                 default:
   405                     throw new XMLStreamException("Invalid State "+item);
   406             }
   407         } while(depth > 0 || _treeCount>0);
   409     }
   411     private boolean isInscope(int depth) {
   412         return _buffer.getInscopeNamespaces().size() > 0 && depth ==1;
   413     }
   415     /*
   416      * @param inscope: true means write inscope namespaces
   417      */
   418     private void writeAttributes(XMLStreamWriter writer, boolean inscope) throws XMLStreamException {
   419         // prefixSet to collect prefixes that are written before writing inscope namespaces
   420         Set<String> prefixSet = inscope ? new HashSet<String>() : Collections.<String>emptySet();
   421         int item = peekStructure();
   422         if ((item & TYPE_MASK) == T_NAMESPACE_ATTRIBUTE) {
   423             // Skip the namespace declarations on the element
   424             // they will have been added already
   425             item = writeNamespaceAttributes(item, writer, inscope, prefixSet);
   426         }
   427         if (inscope) {
   428             writeInscopeNamespaces(writer, prefixSet);
   429         }
   430         if ((item & TYPE_MASK) == T_ATTRIBUTE) {
   431             writeAttributes(item, writer);
   432         }
   433     }
   435     private static String fixNull(String s) {
   436         if (s == null) return "";
   437         else return s;
   438     }
   440     /*
   441      * @param prefixSet: already written prefixes
   442      */
   443     private void writeInscopeNamespaces(XMLStreamWriter writer, Set<String> prefixSet) throws XMLStreamException {
   444         for (Map.Entry<String, String> e : _buffer.getInscopeNamespaces().entrySet()) {
   445             String key = fixNull(e.getKey());
   446             // If the prefix is already written, do not write the prefix
   447             if (!prefixSet.contains(key)) {
   448                 writer.writeNamespace(key, e.getValue());
   449             }
   450         }
   451     }
   453     private int writeNamespaceAttributes(int item, XMLStreamWriter writer, boolean collectPrefixes, Set<String> prefixSet) throws XMLStreamException {
   454         do {
   455             switch(getNIIState(item)){
   456                 case STATE_NAMESPACE_ATTRIBUTE:
   457                     // Undeclaration of default namespace
   458                     writer.writeDefaultNamespace("");
   459                     if (collectPrefixes) {
   460                         prefixSet.add("");
   461                     }
   462                     break;
   463                 case STATE_NAMESPACE_ATTRIBUTE_P:
   464                     // Undeclaration of namespace
   465                     // Declaration with prefix
   466                     String prefix = readStructureString();
   467                     writer.writeNamespace(prefix, "");
   468                     if (collectPrefixes) {
   469                         prefixSet.add(prefix);
   470                     }
   471                     break;
   472                 case STATE_NAMESPACE_ATTRIBUTE_P_U:
   473                     // Declaration with prefix
   474                     prefix = readStructureString();
   475                     writer.writeNamespace(prefix, readStructureString());
   476                     if (collectPrefixes) {
   477                         prefixSet.add(prefix);
   478                     }
   479                     break;
   480                 case STATE_NAMESPACE_ATTRIBUTE_U:
   481                     // Default declaration
   482                     writer.writeDefaultNamespace(readStructureString());
   483                     if (collectPrefixes) {
   484                         prefixSet.add("");
   485                     }
   486                     break;
   487             }
   488             readStructure();
   490             item = peekStructure();
   491         } while((item & TYPE_MASK) == T_NAMESPACE_ATTRIBUTE);
   493         return item;
   494     }
   496     private void writeAttributes(int item, XMLStreamWriter writer) throws XMLStreamException {
   497         do {
   498             switch(getAIIState(item)) {
   499                 case STATE_ATTRIBUTE_U_LN_QN: {
   500                     final String uri = readStructureString();
   501                     final String localName = readStructureString();
   502                     final String prefix = getPrefixFromQName(readStructureString());
   503                     writer.writeAttribute(prefix,uri,localName,readContentString());
   504                     break;
   505                 }
   506                 case STATE_ATTRIBUTE_P_U_LN:
   507                     writer.writeAttribute(readStructureString(), readStructureString(),
   508                             readStructureString(), readContentString());
   509                     break;
   510                 case STATE_ATTRIBUTE_U_LN:
   511                     writer.writeAttribute(readStructureString(), readStructureString(), readContentString());
   512                     break;
   513                 case STATE_ATTRIBUTE_LN:
   514                     writer.writeAttribute(readStructureString(), readContentString());
   515                     break;
   516             }
   517             // Ignore the attribute type
   518             readStructureString();
   520             readStructure();
   522             item = peekStructure();
   523         } while((item & TYPE_MASK) == T_ATTRIBUTE);
   524     }
   525 }

mercurial