/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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$
 */


package org.apache.xalan.xsltc.trax;

import java.io.IOException;
import java.util.Hashtable;
import java.util.Stack;
import java.util.Vector;

import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

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.apache.xalan.xsltc.dom.SAXImpl;

/**
 * @author G. Todd Miller 
 */
public class DOM2SAX implements XMLReader, Locator {

    private final static String EMPTYSTRING = "";
    private static final String XMLNS_PREFIX = "xmlns";

    private Node _dom = null;
    private ContentHandler _sax = null;
    private LexicalHandler _lex = null;
    private SAXImpl _saxImpl = null;
    private Hashtable _nsPrefixes = new Hashtable();

    public DOM2SAX(Node root) {
	_dom = root;
    }

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

    /**
     * Begin the scope of namespace prefix. Forward the event to the 
     * SAX handler only if the prefix is unknown or it is mapped to a 
     * different URI.
     */
    private boolean startPrefixMapping(String prefix, String uri) 
	throws SAXException 
    {
	boolean pushed = true;
	Stack uriStack = (Stack) _nsPrefixes.get(prefix);

	if (uriStack != null) {
	    if (uriStack.isEmpty()) {
		_sax.startPrefixMapping(prefix, uri);
		uriStack.push(uri);
	    }
	    else {
		final String lastUri = (String) uriStack.peek();
		if (!lastUri.equals(uri)) {
		    _sax.startPrefixMapping(prefix, uri);
		    uriStack.push(uri);
		}
		else {
		    pushed = false;
		}
	    }	
	}
	else {
	    _sax.startPrefixMapping(prefix, uri);
	    _nsPrefixes.put(prefix, uriStack = new Stack());
	    uriStack.push(uri);
	}
	return pushed;
    }

    /*
     * End the scope of a name prefix by popping it from the stack and 
     * passing the event to the SAX Handler.
     */
    private void endPrefixMapping(String prefix) 
	throws SAXException
    {
	final Stack uriStack = (Stack) _nsPrefixes.get(prefix);

	if (uriStack != null) {
	    _sax.endPrefixMapping(prefix);
	    uriStack.pop();
	}
    }

    /**
     * If the DOM was created using a DOM 1.0 API, the local name may be 
     * null. If so, get the local name from the qualified name before 
     * generating the SAX event. 
     */
    private static String getLocalName(Node node) {
	final String localName = node.getLocalName();

	if (localName == null) {
	    final String qname = node.getNodeName();
	    final int col = qname.lastIndexOf(':');
	    return (col > 0) ? qname.substring(col + 1) : qname;
	}
	return localName;
    }

    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) {
		_sax.startDocument();
		parse(_dom);
		_sax.endDocument();
	    }
	    else {
		parse(_dom);
	    }
	}
    }

    /**
     * Traverse the DOM and generate SAX events for a handler. A 
     * startElement() event passes all attributes, including namespace 
     * declarations. 
     */
    private void parse(Node node) throws IOException, SAXException {
        Node first = null;
 	if (node == null) return;

        switch (node.getNodeType()) {
	case Node.ATTRIBUTE_NODE:         // handled by ELEMENT_NODE
	case Node.DOCUMENT_FRAGMENT_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:
	    final String cdata = node.getNodeValue();
	    if (_lex != null) {
		_lex.startCDATA();
	        _sax.characters(cdata.toCharArray(), 0, cdata.length());
		_lex.endCDATA();
 	    } 
	    else {
		// in the case where there is no lex handler, we still
		// want the text of the cdate to make its way through.
	        _sax.characters(cdata.toCharArray(), 0, cdata.length());
	    }	
	    break;

	case Node.COMMENT_NODE:           // should be handled!!!
	    if (_lex != null) {
		final String value = node.getNodeValue();
		_lex.comment(value.toCharArray(), 0, value.length());
	    }
	    break;
	case Node.DOCUMENT_NODE:
	    _sax.setDocumentLocator(this);

	    _sax.startDocument();
	    Node next = node.getFirstChild();
	    while (next != null) {
		parse(next);
		next = next.getNextSibling();
	    }
	    _sax.endDocument();
	    break;

	case Node.ELEMENT_NODE:
	    String prefix;
	    Vector pushedPrefixes = new Vector();
	    final AttributesImpl attrs = new AttributesImpl();
	    final NamedNodeMap map = node.getAttributes();
	    final int length = map.getLength();

	    // Process all namespace declarations
	    for (int i = 0; i < length; i++) {
		final Node attr = map.item(i);
		final String qnameAttr = attr.getNodeName();

		// Ignore everything but NS declarations here
		if (qnameAttr.startsWith(XMLNS_PREFIX)) {
		    final String uriAttr = attr.getNodeValue();
		    final int colon = qnameAttr.lastIndexOf(':');
		    prefix = (colon > 0) ? qnameAttr.substring(colon + 1) : EMPTYSTRING;
		    if (startPrefixMapping(prefix, uriAttr)) {
			pushedPrefixes.addElement(prefix);
		    }
		}
	    }

	    // Process all other attributes
	    for (int i = 0; i < length; i++) {
		final Node attr = map.item(i);
		final String qnameAttr = attr.getNodeName();

		// Ignore NS declarations here
		if (!qnameAttr.startsWith(XMLNS_PREFIX)) {
		    final String uriAttr = attr.getNamespaceURI();
		    final String localNameAttr = getLocalName(attr);

		    // Uri may be implicitly declared
		    if (uriAttr != null) {	
			final int colon = qnameAttr.lastIndexOf(':');
			prefix = (colon > 0) ? qnameAttr.substring(0, colon) : EMPTYSTRING;
			if (startPrefixMapping(prefix, uriAttr)) {
			    pushedPrefixes.addElement(prefix);
			}
		    }

		    // Add attribute to list
		    attrs.addAttribute(attr.getNamespaceURI(), getLocalName(attr), 
			qnameAttr, "CDATA", attr.getNodeValue());
		}
	    }

	    // Now process the element itself
	    final String qname = node.getNodeName();
	    final String uri = node.getNamespaceURI();
	    final String localName = getLocalName(node);

	    // Uri may be implicitly declared
	    if (uri != null) {	
		final int colon = qname.lastIndexOf(':');
		prefix = (colon > 0) ? qname.substring(0, colon) : EMPTYSTRING;
		if (startPrefixMapping(prefix, uri)) {
		    pushedPrefixes.addElement(prefix);
		}
	    }

	    // Generate SAX event to start element
	    if (_saxImpl != null) {
	        _saxImpl.startElement(uri, localName, qname, attrs, node);
	    }
	    else {
	        _sax.startElement(uri, localName, qname, attrs);
	    }

	    // 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
	    _sax.endElement(uri, localName, qname);

	    // Generate endPrefixMapping() for all pushed prefixes
	    final int nPushedPrefixes = pushedPrefixes.size();
	    for (int i = 0; i < nPushedPrefixes; i++) {
		endPrefixMapping((String) pushedPrefixes.elementAt(i));
	    }
	    break;

	case Node.PROCESSING_INSTRUCTION_NODE:
	    _sax.processingInstruction(node.getNodeName(),
				       node.getNodeValue());
	    break;

	case Node.TEXT_NODE:
	    final String data = node.getNodeValue();
	    _sax.characters(data.toCharArray(), 0, data.length());
	    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; 
    }

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