src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/ContentHandlerToXMLStreamWriter.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, 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.ws.util.xml;
    28 import org.xml.sax.Attributes;
    29 import org.xml.sax.Locator;
    30 import org.xml.sax.SAXException;
    31 import org.xml.sax.helpers.DefaultHandler;
    33 import javax.xml.stream.XMLStreamException;
    34 import javax.xml.stream.XMLStreamWriter;
    35 import java.util.Stack;
    37 /**
    38  * This is a simple utility class that adapts SAX events into StAX
    39  * {@link XMLStreamWriter} events, bridging between
    40  * the two parser technologies.
    41  *
    42  * This ContentHandler does not own the XMLStreamWriter.  Therefore, it will
    43  * not close or flush the writer at any point.
    44  *
    45  * @author Ryan.Shoemaker@Sun.COM
    46  * @version 1.0
    47  */
    48 public class ContentHandlerToXMLStreamWriter extends DefaultHandler {
    50     // SAX events will be sent to this XMLStreamWriter
    51     private final XMLStreamWriter staxWriter;
    53     // storage for prefix bindings
    54     private final Stack prefixBindings;
    56     public ContentHandlerToXMLStreamWriter(XMLStreamWriter staxCore) {
    57         this.staxWriter = staxCore;
    58         prefixBindings = new Stack(); // default of 10 seems reasonable
    59     }
    61     /*
    62      * (non-Javadoc)
    63      *
    64      * @see org.xml.sax.ContentHandler#endDocument()
    65      */
    66     public void endDocument() throws SAXException {
    67         try {
    68             staxWriter.writeEndDocument();
    69             staxWriter.flush();
    70         } catch (XMLStreamException e) {
    71             throw new SAXException(e);
    72         }
    73     }
    75     /*
    76      * (non-Javadoc)
    77      *
    78      * @see org.xml.sax.ContentHandler#startDocument()
    79      */
    80     public void startDocument() throws SAXException {
    81         try {
    82             staxWriter.writeStartDocument();
    83         } catch (XMLStreamException e) {
    84             throw new SAXException(e);
    85         }
    86     }
    88     /*
    89      * (non-Javadoc)
    90      *
    91      * @see org.xml.sax.ContentHandler#characters(char[], int, int)
    92      */
    93     public void characters(char[] ch, int start, int length)
    94         throws SAXException {
    96         try {
    97             staxWriter.writeCharacters(ch, start, length);
    98         } catch (XMLStreamException e) {
    99             throw new SAXException(e);
   100         }
   102     }
   104     /*
   105      * (non-Javadoc)
   106      *
   107      * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
   108      */
   109     public void ignorableWhitespace(char[] ch, int start, int length)
   110         throws SAXException {
   112         characters(ch,start,length);
   113     }
   115     /*
   116      * (non-Javadoc)
   117      *
   118      * @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
   119      */
   120     public void endPrefixMapping(String prefix) throws SAXException {
   121         // TODO: no-op?
   123         // I think we can ignore these SAX events because StAX
   124         // automatically scopes the prefix bindings.
   125     }
   127     /*
   128      * (non-Javadoc)
   129      *
   130      * @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
   131      */
   132     public void skippedEntity(String name) throws SAXException {
   133         try {
   134             staxWriter.writeEntityRef(name);
   135         } catch (XMLStreamException e) {
   136             throw new SAXException(e);
   137         }
   138     }
   140     /*
   141      * (non-Javadoc)
   142      *
   143      * @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
   144      */
   145     public void setDocumentLocator(Locator locator) {
   146         // TODO: no-op?
   147         // there doesn't seem to be any way to pass location info
   148         // along to the XMLStreamWriter. On the XMLEventWriter side, you
   149         // can set the location info on the event objects.
   150     }
   152     /*
   153      * (non-Javadoc)
   154      *
   155      * @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String,
   156      *      java.lang.String)
   157      */
   158     public void processingInstruction(String target, String data)
   159         throws SAXException {
   161         try {
   162             staxWriter.writeProcessingInstruction(target, data);
   163         } catch (XMLStreamException e) {
   164             throw new SAXException(e);
   165         }
   167     }
   169     /*
   170      * (non-Javadoc)
   171      *
   172      * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String,
   173      *      java.lang.String)
   174      */
   175     public void startPrefixMapping(String prefix, String uri)
   176         throws SAXException {
   178         // defend against parsers that pass null in for "xmlns" prefix
   179         if (prefix == null) {
   180             prefix = "";
   181         }
   183         if (prefix.equals("xml")) {
   184             return;
   185         }
   187         prefixBindings.add(prefix);
   188         prefixBindings.add(uri);
   189     }
   191     /*
   192      * (non-Javadoc)
   193      *
   194      * @see org.xml.sax.ContentHandler#endElement(java.lang.String,
   195      *      java.lang.String, java.lang.String)
   196      */
   197     public void endElement(String namespaceURI, String localName, String qName)
   198         throws SAXException {
   200         try {
   201             // TODO: is this all we have to do?
   202             staxWriter.writeEndElement();
   203         } catch (XMLStreamException e) {
   204             throw new SAXException(e);
   205         }
   206     }
   208     /*
   209      * (non-Javadoc)
   210      *
   211      * @see org.xml.sax.ContentHandler#startElement(java.lang.String,
   212      *      java.lang.String, java.lang.String, org.xml.sax.Attributes)
   213      */
   214     public void startElement(
   215         String namespaceURI,
   216         String localName,
   217         String qName,
   218         Attributes atts)
   219         throws SAXException {
   221         try {
   222             staxWriter.writeStartElement(
   223                 getPrefix(qName),
   224                 localName,
   225                 namespaceURI);
   227             String uri, prefix;
   228             while (prefixBindings.size() != 0) {
   229                 uri = (String)prefixBindings.pop();
   230                 prefix = (String)prefixBindings.pop();
   231                 if (prefix.length() == 0) {
   232                     staxWriter.setDefaultNamespace(uri);
   233                 } else {
   234                     staxWriter.setPrefix(prefix, uri);
   235                 }
   237                 // this method handles "", null, and "xmlns" prefixes properly
   238                 staxWriter.writeNamespace(prefix, uri);
   239             }
   241             writeAttributes(atts);
   242         } catch (XMLStreamException e) {
   243             throw new SAXException(e);
   244         }
   246     }
   248     /**
   249      * Generate a StAX writeAttribute event for each attribute
   250      *
   251      * @param atts
   252      *                attributes from the SAX event
   253      */
   254     private void writeAttributes(Attributes atts) throws XMLStreamException {
   255         for (int i = 0; i < atts.getLength(); i++) {
   256             final String prefix = getPrefix(atts.getQName(i));
   257             if(!prefix.equals("xmlns")) { // defend againts broken transformers that report xmlns decls as attrs
   258                 staxWriter.writeAttribute(
   259                     prefix,
   260                     atts.getURI(i),
   261                     atts.getLocalName(i),
   262                     atts.getValue(i));
   263                 }
   264         }
   265     }
   267     /**
   268      * Pull the prefix off of the specified QName.
   269      *
   270      * @param qName
   271      *                the QName
   272      * @return the prefix or the empty string if it doesn't exist.
   273      */
   274     private String getPrefix(String qName) {
   275         int idx = qName.indexOf(':');
   276         if (idx == -1) {
   277             return "";
   278         } else {
   279             return qName.substring(0, idx);
   280         }
   281     }
   283 }

mercurial