src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/XMLStreamReaderToXMLStreamWriter.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.util.xml;
    28 import java.io.IOException;
    30 import javax.xml.bind.attachment.AttachmentMarshaller;
    31 import javax.xml.stream.XMLStreamConstants;
    32 import javax.xml.stream.XMLStreamException;
    33 import javax.xml.stream.XMLStreamReader;
    34 import javax.xml.stream.XMLStreamWriter;
    35 import javax.xml.XMLConstants;
    37 import com.sun.xml.internal.ws.streaming.MtomStreamWriter;
    38 import com.sun.xml.internal.org.jvnet.staxex.Base64Data;
    39 import com.sun.xml.internal.org.jvnet.staxex.XMLStreamReaderEx;
    40 import com.sun.xml.internal.org.jvnet.staxex.XMLStreamWriterEx;
    42 /**
    43  * Reads a sub-tree from {@link XMLStreamReader} and writes to {@link XMLStreamWriter}
    44  * as-is.
    45  *
    46  * <p>
    47  * This class can be sub-classed to implement a simple transformation logic.
    48  *
    49  * @author Kohsuke Kawaguchi
    50  * @author Ryan Shoemaker
    51  */
    52 public class XMLStreamReaderToXMLStreamWriter {
    54     private static final int BUF_SIZE = 4096;
    56     protected XMLStreamReader in;
    57     protected XMLStreamWriter out;
    59     private char[] buf;
    61     boolean optimizeBase64Data = false;
    63     AttachmentMarshaller mtomAttachmentMarshaller;
    65     /**
    66      * Reads one subtree and writes it out.
    67      *
    68      * <p>
    69      * The {@link XMLStreamWriter} never receives a start/end document event.
    70      * Those need to be written separately by the caller.
    71      */
    72     public void bridge(XMLStreamReader in, XMLStreamWriter out) throws XMLStreamException {
    73         assert in!=null && out!=null;
    74         this.in = in;
    75         this.out = out;
    77         optimizeBase64Data = (in instanceof XMLStreamReaderEx);
    79         if (out instanceof XMLStreamWriterEx && out instanceof MtomStreamWriter) {
    80             mtomAttachmentMarshaller = ((MtomStreamWriter) out).getAttachmentMarshaller();
    81         }
    82         // remembers the nest level of elements to know when we are done.
    83         int depth=0;
    85         buf = new char[BUF_SIZE];
    87         // if the parser is at the start tag, proceed to the first element
    88         int event = in.getEventType();
    89         if(event == XMLStreamConstants.START_DOCUMENT) {
    90             // nextTag doesn't correctly handle DTDs
    91             while( !in.isStartElement() ) {
    92                 event = in.next();
    93                 if (event == XMLStreamConstants.COMMENT)
    94                     handleComment();
    95             }
    96         }
    99         if( event!=XMLStreamConstants.START_ELEMENT)
   100             throw new IllegalStateException("The current event is not START_ELEMENT\n but " + event);
   102         do {
   103             // These are all of the events listed in the javadoc for
   104             // XMLEvent.
   105             // The spec only really describes 11 of them.
   106             switch (event) {
   107                 case XMLStreamConstants.START_ELEMENT :
   108                     depth++;
   109                     handleStartElement();
   110                     break;
   111                 case XMLStreamConstants.END_ELEMENT :
   112                     handleEndElement();
   113                     depth--;
   114                     if(depth==0)
   115                         return;
   116                     break;
   117                 case XMLStreamConstants.CHARACTERS :
   118                     handleCharacters();
   119                     break;
   120                 case XMLStreamConstants.ENTITY_REFERENCE :
   121                     handleEntityReference();
   122                     break;
   123                 case XMLStreamConstants.PROCESSING_INSTRUCTION :
   124                     handlePI();
   125                     break;
   126                 case XMLStreamConstants.COMMENT :
   127                     handleComment();
   128                     break;
   129                 case XMLStreamConstants.DTD :
   130                     handleDTD();
   131                     break;
   132                 case XMLStreamConstants.CDATA :
   133                     handleCDATA();
   134                     break;
   135                 case XMLStreamConstants.SPACE :
   136                     handleSpace();
   137                     break;
   138                 case XMLStreamConstants.END_DOCUMENT:
   139                     throw new XMLStreamException("Malformed XML at depth="+depth+", Reached EOF. Event="+event);
   140                 default :
   141                     throw new XMLStreamException("Cannot process event: " + event);
   142             }
   144             event=in.next();
   145         } while (depth!=0);
   146     }
   148     protected void handlePI() throws XMLStreamException {
   149         out.writeProcessingInstruction(
   150             in.getPITarget(),
   151             in.getPIData());
   152     }
   155     protected void handleCharacters() throws XMLStreamException {
   157         CharSequence c = null;
   159         if (optimizeBase64Data) {
   160             c = ((XMLStreamReaderEx)in).getPCDATA();
   161         }
   163         if ((c != null) && (c instanceof Base64Data)) {
   164             if (mtomAttachmentMarshaller != null) {
   165                 Base64Data b64d = (Base64Data) c;
   166                 ((XMLStreamWriterEx)out).writeBinary(b64d.getDataHandler());
   167             } else {
   168                 try {
   169                     ((Base64Data)c).writeTo(out);
   170                 } catch (IOException e) {
   171                     throw new XMLStreamException(e);
   172                 }
   173             }
   174         } else {
   175             for (int start=0,read=buf.length; read == buf.length; start+=buf.length) {
   176                 read = in.getTextCharacters(start, buf, 0, buf.length);
   177                 out.writeCharacters(buf, 0, read);
   178             }
   179         }
   180     }
   182     protected void handleEndElement() throws XMLStreamException {
   183         out.writeEndElement();
   184     }
   186     protected void handleStartElement() throws XMLStreamException {
   187         String nsUri = in.getNamespaceURI();
   188         if(nsUri==null)
   189             out.writeStartElement(in.getLocalName());
   190         else
   191             out.writeStartElement(
   192                 fixNull(in.getPrefix()),
   193                 in.getLocalName(),
   194                 nsUri
   195             );
   197         // start namespace bindings
   198         int nsCount = in.getNamespaceCount();
   199         for (int i = 0; i < nsCount; i++) {
   200             out.writeNamespace(
   201                 in.getNamespacePrefix(i),
   202                 fixNull(in.getNamespaceURI(i)));    // zephyr doesn't like null, I don't know what is correct, so just fix null to "" for now
   203         }
   205         // write attributes
   206         int attCount = in.getAttributeCount();
   207         for (int i = 0; i < attCount; i++) {
   208             handleAttribute(i);
   209         }
   210     }
   212     /**
   213      * Writes out the {@code i}-th attribute of the current element.
   214      *
   215      * <p>
   216      * Used from {@link #handleStartElement()}.
   217      */
   218     protected void handleAttribute(int i) throws XMLStreamException {
   219         String nsUri = in.getAttributeNamespace(i);
   220         String prefix = in.getAttributePrefix(i);
   221          if (fixNull(nsUri).equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
   222              //Its a namespace decl, ignore as it is already written.
   223              return;
   224          }
   226         if(nsUri==null || prefix == null || prefix.equals("")) {
   227             out.writeAttribute(
   228                 in.getAttributeLocalName(i),
   229                 in.getAttributeValue(i)
   230             );
   231         } else {
   232             out.writeAttribute(
   233                 prefix,
   234                 nsUri,
   235                 in.getAttributeLocalName(i),
   236                 in.getAttributeValue(i)
   237             );
   238         }
   239     }
   241     protected void handleDTD() throws XMLStreamException {
   242         out.writeDTD(in.getText());
   243     }
   245     protected void handleComment() throws XMLStreamException {
   246         out.writeComment(in.getText());
   247     }
   249     protected void handleEntityReference() throws XMLStreamException {
   250         out.writeEntityRef(in.getText());
   251     }
   253     protected void handleSpace() throws XMLStreamException {
   254         handleCharacters();
   255     }
   257     protected void handleCDATA() throws XMLStreamException {
   258         out.writeCData(in.getText());
   259     }
   261     private static String fixNull(String s) {
   262         if(s==null)     return "";
   263         else            return s;
   264     }
   265 }

mercurial