jaxp/src/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/StAXEvent2SAX.java
changeset 12005 a754d69d5e60
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/src/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/StAXEvent2SAX.java	Sun Mar 04 11:55:34 2012 -0800
@@ -0,0 +1,601 @@
+/*
+ * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.org.apache.xalan.internal.xsltc.trax;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.AttributesImpl;
+import org.xml.sax.ext.Locator2;
+import com.sun.org.apache.xalan.internal.xsltc.dom.SAXImpl;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.Characters;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.Namespace;
+import javax.xml.stream.events.ProcessingInstruction;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+import javax.xml.stream.events.StartDocument;
+
+
+/**
+ * @author Suresh Kumar
+ * @author Sunitha Reddy
+ * @since 1.6
+ */
+public class StAXEvent2SAX implements XMLReader, Locator {
+
+    //private final static String EMPTYSTRING = "";
+    //private static final String XMLNS_PREFIX = "xmlns";
+
+    // StAX event source
+    private final XMLEventReader staxEventReader;
+
+    //private Node _dom = null;
+    private ContentHandler _sax = null;
+    private LexicalHandler _lex = null;
+    private SAXImpl _saxImpl = null;
+    //private Hashtable _nsPrefixes = new Hashtable();
+    private String version = null;
+    private String encoding = null;
+
+
+    public StAXEvent2SAX(XMLEventReader staxCore) {
+        staxEventReader = staxCore;
+    }
+
+    public ContentHandler getContentHandler() {
+        return _sax;
+    }
+
+    public void setContentHandler(ContentHandler handler) throws
+        NullPointerException
+    {
+        _sax = handler;
+        if (handler instanceof LexicalHandler) {
+            _lex = (LexicalHandler) handler;
+        }
+
+        if (handler instanceof SAXImpl) {
+            _saxImpl = (SAXImpl)handler;
+        }
+    }
+
+
+    public void parse(InputSource unused) throws IOException, SAXException {
+       try {
+            bridge();
+        } catch (XMLStreamException e) {
+            throw new SAXException(e);
+        }
+    }
+
+
+    //Main Work Starts Here.
+    public void parse() throws IOException, SAXException, XMLStreamException {
+        bridge();
+    }
+
+
+    /*  public void parse() throws IOException, SAXException {
+        if (_dom != null) {
+            boolean isIncomplete =
+                (_dom.getNodeType() != org.w3c.dom.Node.DOCUMENT_NODE);
+
+            if (isIncomplete) {
+                _sax.startDocument();
+                parse(_dom);
+                _sax.endDocument();
+            }
+            else {
+                parse(_dom);
+            }
+        }
+    }
+    */
+
+    /*
+     * @see StAXReaderToContentHandler#bridge()
+     */
+    private void bridge() throws XMLStreamException {
+
+        try {
+            // remembers the nest level of elements to know when we are done.
+            int depth=0;
+            boolean startedAtDocument = false;
+
+            XMLEvent event = staxEventReader.peek();
+
+            if (!event.isStartDocument() && !event.isStartElement()) {
+                throw new IllegalStateException();
+            }
+
+            if (event.getEventType() == XMLStreamConstants.START_DOCUMENT){
+                startedAtDocument = true;
+                version = ((StartDocument)event).getVersion();
+                if (((StartDocument)event).encodingSet())
+                    encoding = ((StartDocument)event).getCharacterEncodingScheme();
+                event=staxEventReader.nextEvent(); // that gets the one we peeked at
+                event=staxEventReader.nextEvent(); // that really gets the next one
+            }
+
+            handleStartDocument(event);
+
+            // Handle the prolog: http://www.w3.org/TR/REC-xml/#NT-prolog
+            while (event.getEventType() != XMLStreamConstants.START_ELEMENT) {
+                switch (event.getEventType()) {
+                    case XMLStreamConstants.CHARACTERS :
+                        handleCharacters(event.asCharacters());
+                        break;
+                    case XMLStreamConstants.PROCESSING_INSTRUCTION :
+                        handlePI((ProcessingInstruction)event);
+                        break;
+                    case XMLStreamConstants.COMMENT :
+                        handleComment();
+                        break;
+                    case XMLStreamConstants.DTD :
+                        handleDTD();
+                        break;
+                    case XMLStreamConstants.SPACE :
+                        handleSpace();
+                        break;
+                    default :
+                        throw new InternalError("processing prolog event: " + event);
+                }
+                event=staxEventReader.nextEvent();
+            }
+
+            // Process the (document) element
+            do {
+                // These are all of the events listed in the javadoc for
+                // XMLEvent.
+                // The spec only really describes 11 of them.
+                switch (event.getEventType()) {
+                    case XMLStreamConstants.START_ELEMENT :
+                        depth++;
+                        handleStartElement(event.asStartElement());
+                        break;
+                    case XMLStreamConstants.END_ELEMENT :
+                        handleEndElement(event.asEndElement());
+                        depth--;
+                        break;
+                    case XMLStreamConstants.CHARACTERS :
+                        handleCharacters(event.asCharacters());
+                        break;
+                    case XMLStreamConstants.ENTITY_REFERENCE :
+                        handleEntityReference();
+                        break;
+                    case XMLStreamConstants.PROCESSING_INSTRUCTION :
+                        handlePI((ProcessingInstruction)event);
+                        break;
+                    case XMLStreamConstants.COMMENT :
+                        handleComment();
+                        break;
+                    case XMLStreamConstants.DTD :
+                        handleDTD();
+                        break;
+                    case XMLStreamConstants.ATTRIBUTE :
+                        handleAttribute();
+                        break;
+                    case XMLStreamConstants.NAMESPACE :
+                        handleNamespace();
+                        break;
+                    case XMLStreamConstants.CDATA :
+                        handleCDATA();
+                        break;
+                    case XMLStreamConstants.ENTITY_DECLARATION :
+                        handleEntityDecl();
+                        break;
+                    case XMLStreamConstants.NOTATION_DECLARATION :
+                        handleNotationDecl();
+                        break;
+                    case XMLStreamConstants.SPACE :
+                        handleSpace();
+                        break;
+                    default :
+                        throw new InternalError("processing event: " + event);
+                }
+
+                event=staxEventReader.nextEvent();
+            } while (depth!=0);
+
+            if (startedAtDocument) {
+                // Handle the Misc (http://www.w3.org/TR/REC-xml/#NT-Misc) that can follow the document element
+                while (event.getEventType() != XMLStreamConstants.END_DOCUMENT) {
+                    switch (event.getEventType()) {
+                        case XMLStreamConstants.CHARACTERS :
+                            handleCharacters(event.asCharacters());
+                            break;
+                        case XMLStreamConstants.PROCESSING_INSTRUCTION :
+                            handlePI((ProcessingInstruction)event);
+                            break;
+                        case XMLStreamConstants.COMMENT :
+                            handleComment();
+                            break;
+                        case XMLStreamConstants.SPACE :
+                            handleSpace();
+                            break;
+                        default :
+                            throw new InternalError("processing misc event after document element: " + event);
+                    }
+                    event=staxEventReader.nextEvent();
+                }
+            }
+
+            handleEndDocument();
+        } catch (SAXException e) {
+            throw new XMLStreamException(e);
+        }
+    }
+
+
+    private void handleEndDocument() throws SAXException {
+        _sax.endDocument();
+    }
+
+    private void handleStartDocument(final XMLEvent event) throws SAXException {
+        _sax.setDocumentLocator(new Locator2() {
+            public int getColumnNumber() {
+                return event.getLocation().getColumnNumber();
+            }
+            public int getLineNumber() {
+                return event.getLocation().getLineNumber();
+            }
+            public String getPublicId() {
+                return event.getLocation().getPublicId();
+            }
+            public String getSystemId() {
+                return event.getLocation().getSystemId();
+            }
+            public String getXMLVersion(){
+                return version;
+            }
+            public String getEncoding(){
+                return encoding;
+            }
+
+        });
+        _sax.startDocument();
+    }
+
+    private void handlePI(ProcessingInstruction event)
+        throws XMLStreamException {
+        try {
+            _sax.processingInstruction(
+                event.getTarget(),
+                event.getData());
+        } catch (SAXException e) {
+            throw new XMLStreamException(e);
+        }
+    }
+
+    private void handleCharacters(Characters event) throws XMLStreamException {
+        try {
+            _sax.characters(
+                event.getData().toCharArray(),
+                0,
+                event.getData().length());
+        } catch (SAXException e) {
+            throw new XMLStreamException(e);
+        }
+    }
+
+    private void handleEndElement(EndElement event) throws XMLStreamException {
+        QName qName = event.getName();
+
+        //construct prefix:localName from qName
+        String qname = "";
+        if (qName.getPrefix() != null && qName.getPrefix().trim().length() != 0){
+            qname = qName.getPrefix() + ":";
+        }
+        qname += qName.getLocalPart();
+
+        try {
+            // fire endElement
+            _sax.endElement(
+                qName.getNamespaceURI(),
+                qName.getLocalPart(),
+                qname);
+
+            // end namespace bindings
+            for( Iterator i = event.getNamespaces(); i.hasNext();) {
+                String prefix = (String)i.next();
+                if( prefix == null ) { // true for default namespace
+                    prefix = "";
+                }
+                _sax.endPrefixMapping(prefix);
+            }
+        } catch (SAXException e) {
+            throw new XMLStreamException(e);
+        }
+    }
+
+    private void handleStartElement(StartElement event)
+        throws XMLStreamException {
+        try {
+            // start namespace bindings
+            for (Iterator i = event.getNamespaces(); i.hasNext();) {
+                String prefix = ((Namespace)i.next()).getPrefix();
+                if (prefix == null) { // true for default namespace
+                    prefix = "";
+                }
+                _sax.startPrefixMapping(
+                    prefix,
+                    event.getNamespaceURI(prefix));
+            }
+
+            // fire startElement
+            QName qName = event.getName();
+            String prefix = qName.getPrefix();
+            String rawname;
+            if (prefix == null || prefix.length() == 0) {
+                rawname = qName.getLocalPart();
+            } else {
+                rawname = prefix + ':' + qName.getLocalPart();
+            }
+
+            Attributes saxAttrs = getAttributes(event);
+            _sax.startElement(
+                qName.getNamespaceURI(),
+                qName.getLocalPart(),
+                rawname,
+                saxAttrs);
+        } catch (SAXException e) {
+            throw new XMLStreamException(e);
+        }
+    }
+
+    /**
+     * Get the attributes associated with the given START_ELEMENT StAXevent.
+     *
+     * @return the StAX attributes converted to an org.xml.sax.Attributes
+     */
+    private Attributes getAttributes(StartElement event) {
+        AttributesImpl attrs = new AttributesImpl();
+
+        if ( !event.isStartElement() ) {
+            throw new InternalError(
+                "getAttributes() attempting to process: " + event);
+        }
+
+        // in SAX, namespace declarations are not part of attributes by default.
+        // (there's a property to control that, but as far as we are concerned
+        // we don't use it.) So don't add xmlns:* to attributes.
+
+        // gather non-namespace attrs
+        for (Iterator i = event.getAttributes(); i.hasNext();) {
+            Attribute staxAttr = (javax.xml.stream.events.Attribute)i.next();
+
+            String uri = staxAttr.getName().getNamespaceURI();
+            if (uri == null) {
+                uri = "";
+            }
+            String localName = staxAttr.getName().getLocalPart();
+            String prefix = staxAttr.getName().getPrefix();
+            String qName;
+            if (prefix == null || prefix.length() == 0) {
+                qName = localName;
+            } else {
+                qName = prefix + ':' + localName;
+            }
+            String type = staxAttr.getDTDType();
+            String value = staxAttr.getValue();
+
+            attrs.addAttribute(uri, localName, qName, type, value);
+        }
+
+        return attrs;
+    }
+
+    private void handleNamespace() {
+        // no-op ???
+        // namespace events don't normally occur outside of a startElement
+        // or endElement
+    }
+
+    private void handleAttribute() {
+        // no-op ???
+        // attribute events don't normally occur outside of a startElement
+        // or endElement
+    }
+
+    private void handleDTD() {
+        // no-op ???
+        // it seems like we need to pass this info along, but how?
+    }
+
+    private void handleComment() {
+        // no-op ???
+    }
+
+    private void handleEntityReference() {
+        // no-op ???
+    }
+
+    private void handleSpace() {
+        // no-op ???
+        // this event is listed in the javadoc, but not in the spec.
+    }
+
+    private void handleNotationDecl() {
+        // no-op ???
+        // this event is listed in the javadoc, but not in the spec.
+    }
+
+    private void handleEntityDecl() {
+        // no-op ???
+        // this event is listed in the javadoc, but not in the spec.
+    }
+
+    private void handleCDATA() {
+        // no-op ???
+        // this event is listed in the javadoc, but not in the spec.
+    }
+
+
+    /**
+     * This class is only used internally so this method should never
+     * be called.
+     */
+    public DTDHandler getDTDHandler() {
+        return null;
+    }
+
+    /**
+     * This class is only used internally so this method should never
+     * be called.
+     */
+    public ErrorHandler getErrorHandler() {
+        return null;
+    }
+
+    /**
+     * This class is only used internally so this method should never
+     * be called.
+     */
+    public boolean getFeature(String name) throws SAXNotRecognizedException,
+        SAXNotSupportedException
+    {
+        return false;
+    }
+
+    /**
+     * This class is only used internally so this method should never
+     * be called.
+     */
+    public void setFeature(String name, boolean value) throws
+        SAXNotRecognizedException, SAXNotSupportedException
+    {
+    }
+
+    /**
+     * This class is only used internally so this method should never
+     * be called.
+     */
+    public void parse(String sysId) throws IOException, SAXException {
+        throw new IOException("This method is not yet implemented.");
+    }
+
+    /**
+     * This class is only used internally so this method should never
+     * be called.
+     */
+    public void setDTDHandler(DTDHandler handler) throws NullPointerException {
+    }
+
+    /**
+     * This class is only used internally so this method should never
+     * be called.
+     */
+    public void setEntityResolver(EntityResolver resolver) throws
+        NullPointerException
+    {
+    }
+
+    /**
+     * This class is only used internally so this method should never
+     * be called.
+     */
+    public EntityResolver getEntityResolver() {
+        return null;
+    }
+
+    /**
+     * This class is only used internally so this method should never
+     * be called.
+     */
+    public void setErrorHandler(ErrorHandler handler) throws
+        NullPointerException
+    {
+    }
+
+    /**
+     * This class is only used internally so this method should never
+     * be called.
+     */
+    public void setProperty(String name, Object value) throws
+        SAXNotRecognizedException, SAXNotSupportedException {
+    }
+
+    /**
+     * This class is only used internally so this method should never
+     * be called.
+     */
+    public Object getProperty(String name) throws SAXNotRecognizedException,
+        SAXNotSupportedException
+    {
+        return null;
+    }
+
+    /**
+     * This class is only used internally so this method should never
+     * be called.
+     */
+    public int getColumnNumber() {
+        return 0;
+    }
+
+    /**
+     * This class is only used internally so this method should never
+     * be called.
+     */
+    public int getLineNumber() {
+        return 0;
+    }
+
+    /**
+     * This class is only used internally so this method should never
+     * be called.
+     */
+    public String getPublicId() {
+        return null;
+    }
+
+    /**
+     * This class is only used internally so this method should never
+     * be called.
+     */
+    public String getSystemId() {
+        return null;
+    }
+}