src/share/jaxws_classes/com/sun/istack/internal/XMLStreamReaderToContentHandler.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.istack.internal;
    28 import org.xml.sax.ContentHandler;
    29 import org.xml.sax.SAXException;
    30 import org.xml.sax.Locator;
    31 import org.xml.sax.Attributes;
    32 import org.xml.sax.helpers.AttributesImpl;
    34 import javax.xml.stream.XMLStreamReader;
    35 import javax.xml.stream.XMLStreamException;
    36 import javax.xml.stream.XMLStreamConstants;
    37 import javax.xml.namespace.QName;
    39 /**
    40  * This is a simple utility class that adapts StAX events from an
    41  * {@link XMLStreamReader} to SAX events on a
    42  * {@link ContentHandler}, bridging between the two
    43  * parser technologies.
    44  *
    45  * @author Ryan.Shoemaker@Sun.COM
    46  * @version 1.0
    47  */
    48 public class XMLStreamReaderToContentHandler {
    50     // StAX event source
    51     private final XMLStreamReader staxStreamReader;
    53     // SAX event sink
    54     private final ContentHandler saxHandler;
    56     // if true, when the conversion is completed, leave the cursor to the last
    57     // event that was fired (such as end element)
    58     private final boolean eagerQuit;
    60     /**
    61      * If true, not start/endDocument event.
    62      */
    63     private final boolean fragment;
    65     // array of the even length of the form { prefix0, uri0, prefix1, uri1, ... }
    66     private final String[] inscopeNamespaces;
    68     /**
    69      * @see #XMLStreamReaderToContentHandler(XMLStreamReader, ContentHandler, boolean, boolean, String[])
    70      */
    71     public XMLStreamReaderToContentHandler(XMLStreamReader staxCore, ContentHandler saxCore, boolean eagerQuit, boolean fragment) {
    72         this(staxCore, saxCore, eagerQuit, fragment, new String[0]);
    73     }
    75     /**
    76      * Construct a new StAX to SAX adapter that will convert a StAX event
    77      * stream into a SAX event stream.
    78      *
    79      * @param staxCore
    80      *                StAX event source
    81      * @param saxCore
    82      *                SAXevent sink
    83      * @param eagerQuit
    84      * @param fragment
    85      * @param inscopeNamespaces
    86      *                array of the even length of the form { prefix0, uri0, prefix1, uri1, ... }
    87      */
    88     public XMLStreamReaderToContentHandler(XMLStreamReader staxCore, ContentHandler saxCore,
    89             boolean eagerQuit, boolean fragment, String[] inscopeNamespaces) {
    90         this.staxStreamReader = staxCore;
    91         this.saxHandler = saxCore;
    92         this.eagerQuit = eagerQuit;
    93         this.fragment = fragment;
    94         this.inscopeNamespaces = inscopeNamespaces;
    95         assert inscopeNamespaces.length%2 == 0;
    96     }
    99     /*
   100      * @see StAXReaderToContentHandler#bridge()
   101      */
   102     public void bridge() throws XMLStreamException {
   104         try {
   105             // remembers the nest level of elements to know when we are done.
   106             int depth=0;
   108             // if the parser is at the start tag, proceed to the first element
   109             int event = staxStreamReader.getEventType();
   110             if(event == XMLStreamConstants.START_DOCUMENT) {
   111                 // nextTag doesn't correctly handle DTDs
   112                 while( !staxStreamReader.isStartElement() )
   113                     event = staxStreamReader.next();
   114             }
   117             if( event!=XMLStreamConstants.START_ELEMENT)
   118                 throw new IllegalStateException("The current event is not START_ELEMENT\n but " + event);
   120             handleStartDocument();
   122             for(int i=0; i < inscopeNamespaces.length; i+=2) {
   123                 saxHandler.startPrefixMapping(inscopeNamespaces[i], inscopeNamespaces[i+1]);
   124             }
   126             OUTER:
   127             do {
   128                 // These are all of the events listed in the javadoc for
   129                 // XMLEvent.
   130                 // The spec only really describes 11 of them.
   131                 switch (event) {
   132                     case XMLStreamConstants.START_ELEMENT :
   133                         depth++;
   134                         handleStartElement();
   135                         break;
   136                     case XMLStreamConstants.END_ELEMENT :
   137                         handleEndElement();
   138                         depth--;
   139                         if(depth==0 && eagerQuit)
   140                             break OUTER;
   141                         break;
   142                     case XMLStreamConstants.CHARACTERS :
   143                         handleCharacters();
   144                         break;
   145                     case XMLStreamConstants.ENTITY_REFERENCE :
   146                         handleEntityReference();
   147                         break;
   148                     case XMLStreamConstants.PROCESSING_INSTRUCTION :
   149                         handlePI();
   150                         break;
   151                     case XMLStreamConstants.COMMENT :
   152                         handleComment();
   153                         break;
   154                     case XMLStreamConstants.DTD :
   155                         handleDTD();
   156                         break;
   157                     case XMLStreamConstants.ATTRIBUTE :
   158                         handleAttribute();
   159                         break;
   160                     case XMLStreamConstants.NAMESPACE :
   161                         handleNamespace();
   162                         break;
   163                     case XMLStreamConstants.CDATA :
   164                         handleCDATA();
   165                         break;
   166                     case XMLStreamConstants.ENTITY_DECLARATION :
   167                         handleEntityDecl();
   168                         break;
   169                     case XMLStreamConstants.NOTATION_DECLARATION :
   170                         handleNotationDecl();
   171                         break;
   172                     case XMLStreamConstants.SPACE :
   173                         handleSpace();
   174                         break;
   175                     default :
   176                         throw new InternalError("processing event: " + event);
   177                 }
   179                 event=staxStreamReader.next();
   180             } while (depth!=0);
   182             for(int i=0; i < inscopeNamespaces.length; i+=2) {
   183                 saxHandler.endPrefixMapping(inscopeNamespaces[i]);
   184             }
   186             handleEndDocument();
   187         } catch (SAXException e) {
   188             throw new XMLStreamException2(e);
   189         }
   190     }
   192     private void handleEndDocument() throws SAXException {
   193         if(fragment)
   194             return;
   196         saxHandler.endDocument();
   197     }
   199     private void handleStartDocument() throws SAXException {
   200         if(fragment)
   201             return;
   203         saxHandler.setDocumentLocator(new Locator() {
   204             public int getColumnNumber() {
   205                 return staxStreamReader.getLocation().getColumnNumber();
   206             }
   207             public int getLineNumber() {
   208                 return staxStreamReader.getLocation().getLineNumber();
   209             }
   210             public String getPublicId() {
   211                 return staxStreamReader.getLocation().getPublicId();
   212             }
   213             public String getSystemId() {
   214                 return staxStreamReader.getLocation().getSystemId();
   215             }
   216         });
   217         saxHandler.startDocument();
   218     }
   220     private void handlePI() throws XMLStreamException {
   221         try {
   222             saxHandler.processingInstruction(
   223                 staxStreamReader.getPITarget(),
   224                 staxStreamReader.getPIData());
   225         } catch (SAXException e) {
   226             throw new XMLStreamException2(e);
   227         }
   228     }
   230     private void handleCharacters() throws XMLStreamException {
   231         try {
   232             saxHandler.characters(
   233                 staxStreamReader.getTextCharacters(),
   234                 staxStreamReader.getTextStart(),
   235                 staxStreamReader.getTextLength() );
   236         } catch (SAXException e) {
   237             throw new XMLStreamException2(e);
   238         }
   239     }
   241     private void handleEndElement() throws XMLStreamException {
   242         QName qName = staxStreamReader.getName();
   244         try {
   245             String pfix = qName.getPrefix();
   246             String rawname = (pfix == null || pfix.length() == 0)
   247                     ? qName.getLocalPart()
   248                     : pfix + ':' + qName.getLocalPart();
   249             // fire endElement
   250             saxHandler.endElement(
   251                 qName.getNamespaceURI(),
   252                 qName.getLocalPart(),
   253                 rawname);
   255             // end namespace bindings
   256             int nsCount = staxStreamReader.getNamespaceCount();
   257             for (int i = nsCount - 1; i >= 0; i--) {
   258                 String prefix = staxStreamReader.getNamespacePrefix(i);
   259                 if (prefix == null) { // true for default namespace
   260                     prefix = "";
   261                 }
   262                 saxHandler.endPrefixMapping(prefix);
   263             }
   264         } catch (SAXException e) {
   265             throw new XMLStreamException2(e);
   266         }
   267     }
   269     private void handleStartElement() throws XMLStreamException {
   271         try {
   272             // start namespace bindings
   273             int nsCount = staxStreamReader.getNamespaceCount();
   274             for (int i = 0; i < nsCount; i++) {
   275                 saxHandler.startPrefixMapping(
   276                     fixNull(staxStreamReader.getNamespacePrefix(i)),
   277                     fixNull(staxStreamReader.getNamespaceURI(i)));
   278             }
   280             // fire startElement
   281             QName qName = staxStreamReader.getName();
   282             String prefix = qName.getPrefix();
   283             String rawname;
   284             if(prefix==null || prefix.length()==0)
   285                 rawname = qName.getLocalPart();
   286             else
   287                 rawname = prefix + ':' + qName.getLocalPart();
   288             Attributes attrs = getAttributes();
   289             saxHandler.startElement(
   290                 qName.getNamespaceURI(),
   291                 qName.getLocalPart(),
   292                 rawname,
   293                 attrs);
   294         } catch (SAXException e) {
   295             throw new XMLStreamException2(e);
   296         }
   297     }
   299     private static String fixNull(String s) {
   300         if(s==null)     return "";
   301         else            return s;
   302     }
   304     /**
   305      * Get the attributes associated with the given START_ELEMENT or ATTRIBUTE
   306      * StAXevent.
   307      *
   308      * @return the StAX attributes converted to an org.xml.sax.Attributes
   309      */
   310     private Attributes getAttributes() {
   311         AttributesImpl attrs = new AttributesImpl();
   313         int eventType = staxStreamReader.getEventType();
   314         if (eventType != XMLStreamConstants.ATTRIBUTE
   315             && eventType != XMLStreamConstants.START_ELEMENT) {
   316             throw new InternalError(
   317                 "getAttributes() attempting to process: " + eventType);
   318         }
   320         // in SAX, namespace declarations are not part of attributes by default.
   321         // (there's a property to control that, but as far as we are concerned
   322         // we don't use it.) So don't add xmlns:* to attributes.
   324         // gather non-namespace attrs
   325         for (int i = 0; i < staxStreamReader.getAttributeCount(); i++) {
   326             String uri = staxStreamReader.getAttributeNamespace(i);
   327             if(uri==null)   uri="";
   328             String localName = staxStreamReader.getAttributeLocalName(i);
   329             String prefix = staxStreamReader.getAttributePrefix(i);
   330             String qName;
   331             if(prefix==null || prefix.length()==0)
   332                 qName = localName;
   333             else
   334                 qName = prefix + ':' + localName;
   335             String type = staxStreamReader.getAttributeType(i);
   336             String value = staxStreamReader.getAttributeValue(i);
   338             attrs.addAttribute(uri, localName, qName, type, value);
   339         }
   341         return attrs;
   342     }
   344     private void handleNamespace() {
   345         // no-op ???
   346         // namespace events don't normally occur outside of a startElement
   347         // or endElement
   348     }
   350     private void handleAttribute() {
   351         // no-op ???
   352         // attribute events don't normally occur outside of a startElement
   353         // or endElement
   354     }
   356     private void handleDTD() {
   357         // no-op ???
   358         // it seems like we need to pass this info along, but how?
   359     }
   361     private void handleComment() {
   362         // no-op ???
   363     }
   365     private void handleEntityReference() {
   366         // no-op ???
   367     }
   369     private void handleSpace() {
   370         // no-op ???
   371         // this event is listed in the javadoc, but not in the spec.
   372     }
   374     private void handleNotationDecl() {
   375         // no-op ???
   376         // this event is listed in the javadoc, but not in the spec.
   377     }
   379     private void handleEntityDecl() {
   380         // no-op ???
   381         // this event is listed in the javadoc, but not in the spec.
   382     }
   384     private void handleCDATA() {
   385         // no-op ???
   386         // this event is listed in the javadoc, but not in the spec.
   387     }
   388 }

mercurial