/*
 * 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;
    }
}
