jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/DOM2TO.java
changeset 12457 c348e06f0e82
parent 6 7f561c08de6b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/DOM2TO.java	Thu Apr 12 08:38:26 2012 -0700
@@ -0,0 +1,436 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/*
+ * Copyright 2001-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: DOM2TO.java,v 1.5 2005/09/28 13:48:44 pvedula Exp $
+ */
+
+package com.sun.org.apache.xalan.internal.xsltc.trax;
+
+import java.io.IOException;
+
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.Document;
+import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
+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.ext.Locator2;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+import com.sun.org.apache.xml.internal.serializer.NamespaceMappings;
+
+/**
+ * @author Santiago Pericas-Geertsen
+ * @author Sunitha Reddy
+ */
+public class DOM2TO implements XMLReader, Locator2 {
+
+    private final static String EMPTYSTRING = "";
+    private static final String XMLNS_PREFIX = "xmlns";
+
+    /**
+     * A reference to the DOM to be traversed.
+     */
+    private Node _dom;
+
+    /**
+     * A reference to the output handler receiving the events.
+     */
+    private SerializationHandler _handler;
+
+
+    private String xmlVersion = null;
+
+    private String xmlEncoding = null;
+
+
+    public DOM2TO(Node root, SerializationHandler handler) {
+        _dom = root;
+        _handler = handler;
+    }
+
+    public ContentHandler getContentHandler() {
+        return null;
+    }
+
+    public void setContentHandler(ContentHandler handler) {
+        // Empty
+    }
+
+    public void parse(InputSource unused) throws IOException, SAXException {
+        parse(_dom);
+    }
+
+    public void parse() throws IOException, SAXException {
+
+        if (_dom != null) {
+            boolean isIncomplete =
+                (_dom.getNodeType() != org.w3c.dom.Node.DOCUMENT_NODE);
+
+            if (isIncomplete) {
+                _handler.startDocument();
+                parse(_dom);
+                _handler.endDocument();
+            }
+            else {
+                parse(_dom);
+            }
+        }
+    }
+
+    /**
+     * Traverse the DOM and generate TO events for a handler. Notice that
+     * we need to handle implicit namespace declarations too.
+     */
+    private void parse(Node node)
+        throws IOException, SAXException
+    {
+        if (node == null) return;
+
+        switch (node.getNodeType()) {
+        case Node.ATTRIBUTE_NODE:         // handled by ELEMENT_NODE
+        case Node.DOCUMENT_TYPE_NODE :
+        case Node.ENTITY_NODE :
+        case Node.ENTITY_REFERENCE_NODE:
+        case Node.NOTATION_NODE :
+            // These node types are ignored!!!
+            break;
+        case Node.CDATA_SECTION_NODE:
+            _handler.startCDATA();
+            _handler.characters(node.getNodeValue());
+            _handler.endCDATA();
+            break;
+
+        case Node.COMMENT_NODE:           // should be handled!!!
+            _handler.comment(node.getNodeValue());
+            break;
+
+        case Node.DOCUMENT_NODE:
+             setDocumentInfo((Document)node);
+             _handler.setDocumentLocator(this);
+             _handler.startDocument();
+            Node next = node.getFirstChild();
+            while (next != null) {
+                parse(next);
+                next = next.getNextSibling();
+            }
+            _handler.endDocument();
+            break;
+
+        case Node.DOCUMENT_FRAGMENT_NODE:
+            next = node.getFirstChild();
+            while (next != null) {
+                parse(next);
+                next = next.getNextSibling();
+            }
+            break;
+
+        case Node.ELEMENT_NODE:
+            // Generate SAX event to start element
+            final String qname = node.getNodeName();
+            _handler.startElement(null, null, qname);
+
+            int colon;
+            String prefix;
+            final NamedNodeMap map = node.getAttributes();
+            final int length = map.getLength();
+
+            // Process all namespace attributes first
+            for (int i = 0; i < length; i++) {
+                final Node attr = map.item(i);
+                final String qnameAttr = attr.getNodeName();
+
+                // Is this a namespace declaration?
+                if (qnameAttr.startsWith(XMLNS_PREFIX)) {
+                    final String uriAttr = attr.getNodeValue();
+                    colon = qnameAttr.lastIndexOf(':');
+                    prefix = (colon > 0) ? qnameAttr.substring(colon + 1)
+                                         : EMPTYSTRING;
+                    _handler.namespaceAfterStartElement(prefix, uriAttr);
+                }
+            }
+
+            // Process all non-namespace attributes next
+            NamespaceMappings nm = new NamespaceMappings();
+            for (int i = 0; i < length; i++) {
+                final Node attr = map.item(i);
+                final String qnameAttr = attr.getNodeName();
+
+                // Is this a regular attribute?
+                if (!qnameAttr.startsWith(XMLNS_PREFIX)) {
+                    final String uriAttr = attr.getNamespaceURI();
+                    // Uri may be implicitly declared
+                    if (uriAttr != null && !uriAttr.equals(EMPTYSTRING) ) {
+                        colon = qnameAttr.lastIndexOf(':');
+
+                        // Fix for bug 26319
+                        // For attributes not given an prefix explictly
+                        // but having a namespace uri we need
+                        // to explicitly generate the prefix
+                        String newPrefix = nm.lookupPrefix(uriAttr);
+                        if (newPrefix == null)
+                            newPrefix = nm.generateNextPrefix();
+                        prefix = (colon > 0) ? qnameAttr.substring(0, colon)
+                            : newPrefix;
+                        _handler.namespaceAfterStartElement(prefix, uriAttr);
+                        _handler.addAttribute((prefix + ":" + qnameAttr),
+                            attr.getNodeValue());
+                    } else {
+                         _handler.addAttribute(qnameAttr, attr.getNodeValue());
+                    }
+                }
+            }
+
+            // Now element namespace and children
+            final String uri = node.getNamespaceURI();
+            final String localName = node.getLocalName();
+
+            // Uri may be implicitly declared
+            if (uri != null) {
+                colon = qname.lastIndexOf(':');
+                prefix = (colon > 0) ? qname.substring(0, colon) : EMPTYSTRING;
+                _handler.namespaceAfterStartElement(prefix, uri);
+            }else {
+                  // Fix for bug 26319
+                  // If an element foo is created using
+                  // createElementNS(null,locName)
+                  // then the  element should be serialized
+                  // <foo xmlns=" "/>
+                  if (uri == null  && localName != null) {
+                     prefix = EMPTYSTRING;
+                     _handler.namespaceAfterStartElement(prefix, EMPTYSTRING);
+                 }
+            }
+
+            // Traverse all child nodes of the element (if any)
+            next = node.getFirstChild();
+            while (next != null) {
+                parse(next);
+                next = next.getNextSibling();
+            }
+
+            // Generate SAX event to close element
+            _handler.endElement(qname);
+            break;
+
+        case Node.PROCESSING_INSTRUCTION_NODE:
+            _handler.processingInstruction(node.getNodeName(),
+                                           node.getNodeValue());
+            break;
+
+        case Node.TEXT_NODE:
+            _handler.characters(node.getNodeValue());
+            break;
+        }
+    }
+
+    /**
+     * 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;
+    }
+
+
+    private void setDocumentInfo(Document document) {
+        if (!document.getXmlStandalone())
+            _handler.setStandalone(Boolean.toString(document.getXmlStandalone()));
+        setXMLVersion(document.getXmlVersion());
+        setEncoding(document.getXmlEncoding());
+    }
+
+    public String getXMLVersion() {
+        return xmlVersion;
+    }
+
+    private void setXMLVersion(String version) {
+        if (version != null) {
+            xmlVersion = version;
+            _handler.setVersion(xmlVersion);
+        }
+    }
+
+    public String getEncoding() {
+        return xmlEncoding;
+    }
+
+    private void setEncoding(String encoding) {
+        if (encoding != null) {
+            xmlEncoding = encoding;
+            _handler.setEncoding(encoding);
+        }
+    }
+
+    // Debugging
+    private String getNodeTypeFromCode(short code) {
+        String retval = null;
+        switch (code) {
+        case Node.ATTRIBUTE_NODE :
+            retval = "ATTRIBUTE_NODE"; break;
+        case Node.CDATA_SECTION_NODE :
+            retval = "CDATA_SECTION_NODE"; break;
+        case Node.COMMENT_NODE :
+            retval = "COMMENT_NODE"; break;
+        case Node.DOCUMENT_FRAGMENT_NODE :
+            retval = "DOCUMENT_FRAGMENT_NODE"; break;
+        case Node.DOCUMENT_NODE :
+            retval = "DOCUMENT_NODE"; break;
+        case Node.DOCUMENT_TYPE_NODE :
+            retval = "DOCUMENT_TYPE_NODE"; break;
+        case Node.ELEMENT_NODE :
+            retval = "ELEMENT_NODE"; break;
+        case Node.ENTITY_NODE :
+            retval = "ENTITY_NODE"; break;
+        case Node.ENTITY_REFERENCE_NODE :
+            retval = "ENTITY_REFERENCE_NODE"; break;
+        case Node.NOTATION_NODE :
+            retval = "NOTATION_NODE"; break;
+        case Node.PROCESSING_INSTRUCTION_NODE :
+            retval = "PROCESSING_INSTRUCTION_NODE"; break;
+        case Node.TEXT_NODE:
+            retval = "TEXT_NODE"; break;
+        }
+        return retval;
+    }
+}