/*

   Copyright 2001-2003  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.

 */
package org.apache.batik.dom.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.Reader;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import org.xml.sax.Attributes;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

import org.apache.batik.util.HaltingThread;

/**
 * This class contains methods for creating Document instances
 * from an URI using SAX2.
 *
 * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
 * @version $Id$
 */
public class SAXDocumentFactory
    extends    DefaultHandler
    implements LexicalHandler,
               DocumentFactory {

    /**
     * The DOM implementation used to create the document.
     */
    protected DOMImplementation implementation;

    /**
     * The SAX2 parser classname.
     */
    protected String parserClassName;

    /**
     * The created document.
     */
    protected Document document;
    
    /**
     * The created document descriptor.
     */
    protected DocumentDescriptor documentDescriptor;

    /**
     * Whether a document descriptor must be generated.
     */
    protected boolean createDocumentDescriptor;

    /**
     * The current node.
     */
    protected Node currentNode;

    /**
     * The locator.
     */
    protected Locator locator;

    /**
     * Contains collected string data.  May be Text, CDATA or Comment.
     */
    protected StringBuffer stringBuffer = new StringBuffer();
    /**
     * Indicates if stringBuffer has content, needed in case of 
     * zero sized "text" content.
     */
    protected boolean      stringContent;

    /**
     * True if the parser is currently parsing a DTD.
     */
    protected boolean inDTD;

    /**
     * True if the parser is currently parsing a CDATA section.
     */
    protected boolean inCDATA;

    /**
     * Whether the parser is in validating mode.
     */
    protected boolean isValidating;

    /**
     * The stack used to store the namespace URIs.
     */
    protected HashTableStack namespaces;

    /**
     * The error handler.
     */
    protected ErrorHandler errorHandler;

    protected interface PreInfo {
        public Node createNode(Document doc);
    }

    static class ProcessingInstructionInfo implements PreInfo {
        public String target, data;
        public ProcessingInstructionInfo(String target, String data) {
            this.target = target;
            this.data = data;
        }
        public Node createNode(Document doc) { 
            return doc.createProcessingInstruction(target, data);
        }
    }

    static class CommentInfo implements PreInfo {
        public String comment;
        public CommentInfo(String comment) {
            this.comment = comment;
        }
        public Node createNode(Document doc) { 
            return doc.createComment(comment);
        }
    }

    static class CDataInfo implements PreInfo {
        public String cdata;
        public CDataInfo(String cdata) {
            this.cdata = cdata;
        }
        public Node createNode(Document doc) { 
            return doc.createCDATASection(cdata);
        }
    }

    static class TextInfo implements PreInfo {
        public String text;
        public TextInfo(String text) {
            this.text = text;
        }
        public Node createNode(Document doc) { 
            return doc.createTextNode(text);
        }
    }

    /**
     * Various elements encountered prior to real document root element.
     * List of PreInfo objects.
     */
    protected List preInfo;

    /**
     * Creates a new SAXDocumentFactory object.
     * No document descriptor will be created while generating a document.
     * @param impl The DOM implementation to use for building the DOM tree.
     * @param parser The SAX2 parser classname.
     */
    public SAXDocumentFactory(DOMImplementation impl,
                              String parser) {
	implementation           = impl;
	parserClassName          = parser;
    }

    /**
     * Creates a new SAXDocumentFactory object.
     * @param impl The DOM implementation to use for building the DOM tree.
     * @param parser The SAX2 parser classname.
     * @param dd Whether a document descriptor must be generated.
     */
    public SAXDocumentFactory(DOMImplementation impl,
                              String parser,
                              boolean dd) {
	implementation           = impl;
	parserClassName          = parser;
        createDocumentDescriptor = dd;
    }

    /**
     * Creates a Document instance.
     * @param ns The namespace URI of the root element of the document.
     * @param root The name of the root element of the document.
     * @param uri The document URI.
     * @exception IOException if an error occured while reading the document.
     */
    public Document createDocument(String ns, String root, String uri)
        throws IOException {
        return createDocument(ns, root, uri, new InputSource(uri));
    }

    /**
     * Creates a Document instance.
     * @param uri The document URI.
     * @exception IOException if an error occured while reading the document.
     */
    public Document createDocument(String uri)
        throws IOException {
        return createDocument(new InputSource(uri));
    }

    /**
     * Creates a Document instance.
     * @param ns The namespace URI of the root element of the document.
     * @param root The name of the root element of the document.
     * @param uri The document URI.
     * @param is The document input stream.
     * @exception IOException if an error occured while reading the document.
     */
    public Document createDocument(String ns, String root, String uri, 
				   InputStream is) throws IOException {
        InputSource inp = new InputSource(is);
        inp.setSystemId(uri);
        return createDocument(ns, root, uri, inp);
    }

    /**
     * Creates a Document instance.
     * @param uri The document URI.
     * @param is The document input stream.
     * @exception IOException if an error occured while reading the document.
     */
    public Document createDocument(String uri, InputStream is) 
        throws IOException {
        InputSource inp = new InputSource(is);
        inp.setSystemId(uri);
        return createDocument(inp);
    }

    /**
     * Creates a Document instance.
     * @param ns The namespace URI of the root element of the document.
     * @param root The name of the root element of the document.
     * @param uri The document URI.
     * @param r The document reader.
     * @exception IOException if an error occured while reading the document.
     */
    public Document createDocument(String ns, String root, String uri,
                                   Reader r) throws IOException {
        InputSource inp = new InputSource(r);
        inp.setSystemId(uri);
        return createDocument(ns, root, uri, inp);
    }

    /**
     * Creates a Document instance.
     * @param ns The namespace URI of the root element of the document.
     * @param root The name of the root element of the document.
     * @param uri The document URI.
     * @param r an XMLReaderInstance
     * @exception IOException if an error occured while reading the document.
     */
    public Document createDocument(String ns, String root, String uri,
                                   XMLReader r) throws IOException {
        r.setContentHandler(this);
        r.setDTDHandler(this);
        r.setEntityResolver(this);
        try {
            r.parse(uri);
        } catch (SAXException e) {
            Exception ex = e.getException();
            if (ex != null && ex instanceof InterruptedIOException) {
                throw (InterruptedIOException) ex;
            }
            throw new IOException(e.getMessage());
        }
        currentNode = null;
        Document ret = document;
        document = null;
        return ret;
    }

    /**
     * Creates a Document instance.
     * @param uri The document URI.
     * @param r The document reader.
     * @exception IOException if an error occured while reading the document.
     */
    public Document createDocument(String uri, Reader r) throws IOException {
        InputSource inp = new InputSource(r);
        inp.setSystemId(uri);
        return createDocument(inp);
    }

    /**
     * Creates a Document.
     * @param ns The namespace URI of the root element.
     * @param root The name of the root element.
     * @param uri The document URI.
     * @param is  The document input source.
     * @exception IOException if an error occured while reading the document.
     */
    protected Document createDocument(String ns, String root, String uri,
                                      InputSource is)
	throws IOException {
        Document ret = createDocument(is);
        Element docElem = ret.getDocumentElement();

        String lname = root;
        String nsURI = ns;
        if (ns == null) {
            int idx = lname.indexOf(':');
            String nsp = (idx == -1 || idx == lname.length()-1)
                ? ""
                : lname.substring(0, idx);
            nsURI = namespaces.get(nsp);
            if (idx != -1 && idx != lname.length()-1) {
                lname = lname.substring(idx+1);
            }
        }


        String docElemNS = docElem.getNamespaceURI();
        if ((docElemNS != nsURI) &&
            ((docElemNS == null) || (!docElemNS.equals(nsURI))))
            throw new IOException
                ("Root element namespace does not match that requested:\n" +
                 "Requested: " + nsURI + "\n" +
                 "Found: " + docElemNS);

        if (docElemNS != null) {
            if (!docElem.getLocalName().equals(lname))
                throw new IOException
                    ("Root element does not match that requested:\n" +
                     "Requested: " + lname + "\n" +
                     "Found: " + docElem.getLocalName());
        } else {
            if (!docElem.getNodeName().equals(lname))
                throw new IOException
                    ("Root element does not match that requested:\n" +
                     "Requested: " + lname + "\n" +
                     "Found: " + docElem.getNodeName());
        }

        return ret;
    }


    /**
     * Creates a Document.
     * @param is  The document input source.
     * @exception IOException if an error occured while reading the document.
     */
    protected Document createDocument(InputSource is)
	throws IOException {
	try {
            XMLReader parser =
                XMLReaderFactory.createXMLReader(parserClassName);

            parser.setContentHandler(this);
            parser.setDTDHandler(this);
            parser.setEntityResolver(this);
            parser.setErrorHandler((errorHandler == null) ?
                                   this : errorHandler);

            parser.setFeature("http://xml.org/sax/features/namespaces", 
			      true);
            parser.setFeature("http://xml.org/sax/features/namespace-prefixes",
                              true);
	    parser.setFeature("http://xml.org/sax/features/validation",
			      isValidating);
        parser.setFeature("http://xml.org/sax/features/external-general-entities", false);
        parser.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
	    parser.setProperty("http://xml.org/sax/properties/lexical-handler",
			       this);
            parser.parse(is);
	} catch (SAXException e) {
            Exception ex = e.getException();
            if (ex != null && ex instanceof InterruptedIOException) {
                throw (InterruptedIOException)ex;
            }
            throw new IOException(e.getMessage());
	}

        currentNode  = null;
        Document ret = document;
        document     = null;
        locator      = null;
	return ret;
    }

    /**
     * Returns the document descriptor associated with the latest created
     * document.
     * @return null if no document or descriptor was previously generated.
     */
    public DocumentDescriptor getDocumentDescriptor() {
        return documentDescriptor;
    }

    /**
     * <b>SAX</b>: Implements {@link
     * org.xml.sax.ContentHandler#setDocumentLocator(Locator)}.
     */
    public void setDocumentLocator(Locator l) {
        locator = l;
    }

    /**
     * Sets whether or not the XML parser will validate the XML document
     * depending on the specified parameter.
     *
     * @param isValidating indicates that the XML parser will validate the XML
     * document 
     */
    public void setValidating(boolean isValidating) {
	this.isValidating = isValidating;
    }

    /**
     * Returns true if the XML parser validates the XML stream, false
     * otherwise.
     */
    public boolean isValidating() {
	return isValidating;
    }

    /**
     * Sets a custom error handler.
     */
    public void setErrorHandler(ErrorHandler eh) {
        errorHandler = eh;
    }

    public DOMImplementation getDOMImplementation(String ver) {
        return implementation;
    }

    /**
     * <b>SAX</b>: Implements {@link
     * org.xml.sax.ErrorHandler#fatalError(SAXParseException)}.
     */
    public void fatalError(SAXParseException ex) throws SAXException {
        throw ex;
    }

    /**
     * <b>SAX</b>: Implements {@link
     * org.xml.sax.ErrorHandler#error(SAXParseException)}.
     */
    public void error(SAXParseException ex) throws SAXException {
	throw ex;
    }

    /**
     * <b>SAX</b>: Implements {@link
     * org.xml.sax.ErrorHandler#warning(SAXParseException)}.
     */
    public void warning(SAXParseException ex) throws SAXException {
    }

    /**
     * <b>SAX</b>: Implements {@link
     * org.xml.sax.ContentHandler#startDocument()}.
     */
    public void startDocument() throws SAXException {
        preInfo    = new LinkedList();
        namespaces = new HashTableStack();
	namespaces.put("xml", XMLSupport.XML_NAMESPACE_URI);
	namespaces.put("xmlns", XMLSupport.XMLNS_NAMESPACE_URI);
	namespaces.put("", null);

        inDTD       = false;
        inCDATA     = false;
        currentNode = null;
        document    = null;

        stringBuffer.setLength(0);
        stringContent = false;

        if (createDocumentDescriptor) {
            documentDescriptor = new DocumentDescriptor();
        } else {
            documentDescriptor = null;
        }
    }

    /**
     * <b>SAX</b>: Implements {@link
     * org.xml.sax.ContentHandler#startElement(String,String,String,Attributes)}.
     */
    public void startElement(String     uri,
			     String     localName,
			     String     rawName,
			     Attributes attributes) throws SAXException {
        // Check If we should halt early.
        if (HaltingThread.hasBeenHalted()) {
            throw new SAXException(new InterruptedIOException());
        }

	// Namespaces resolution
	int len = attributes.getLength();
	namespaces.push();
        String version = null;
	for (int i = 0; i < len; i++) {
	    String aname = attributes.getQName(i);
            int slen = aname.length();
            if (slen < 5) 
                continue;
            if (aname.equals("version")) {
                version = attributes.getValue(i);
                continue;
            }
            if (!aname.startsWith("xmlns"))
                continue;
            if (slen == 5) {
                String ns = attributes.getValue(i);
                if (ns.length() == 0)
                    ns = null;
 		namespaces.put("", ns);
	    } else if (aname.charAt(5) == ':') {
                String ns = attributes.getValue(i);
                if (ns.length() == 0) {
                    ns = null;
                }
                namespaces.put(aname.substring(6), ns);
            }
	}

        // Add any collected String Data before element.
        appendStringData();

	// Element creation
	Element e;
	int idx = rawName.indexOf(':');
	String nsp = (idx == -1 || idx == rawName.length()-1)
	    ? ""
	    : rawName.substring(0, idx);
	String nsURI = namespaces.get(nsp);
        if (currentNode == null) {
            implementation = getDOMImplementation(version);
            document = implementation.createDocument(nsURI, rawName, null);
            Iterator i = preInfo.iterator();
            currentNode = e = document.getDocumentElement();
            while (i.hasNext()) {
                PreInfo pi = (PreInfo)i.next();
                Node n = pi.createNode(document);
                document.insertBefore(n, e);
            }
            preInfo = null;
        } else {
            e = document.createElementNS(nsURI, rawName);
            currentNode.appendChild(e);
            currentNode = e;
        }

        // Storage of the line number.
        if (createDocumentDescriptor && locator != null) {
            documentDescriptor.setLocationLine(e, locator.getLineNumber());
        }

	// Attributes creation
	for (int i = 0; i < len; i++) {
	    String aname = attributes.getQName(i);
	    if (aname.equals("xmlns")) {
		e.setAttributeNS(XMLSupport.XMLNS_NAMESPACE_URI,
				 aname,
				 attributes.getValue(i));
	    } else {
		idx = aname.indexOf(':');
		nsURI = (idx == -1)
                    ? null
                    : namespaces.get(aname.substring(0, idx));
		e.setAttributeNS(nsURI, aname, attributes.getValue(i));
	    }
	}
    }

    /**
     * <b>SAX</b>: Implements {@link
     * org.xml.sax.ContentHandler#endElement(String,String,String)}.
     */
    public void endElement(String uri, String localName, String rawName)
	throws SAXException {
        appendStringData(); // add string data if any.

        if (currentNode != null)
            currentNode = currentNode.getParentNode();
	namespaces.pop();
    }

    public void appendStringData() {
        if (!stringContent) return;

        String str = stringBuffer.toString();
        stringBuffer.setLength(0); // reuse buffer.
        stringContent = false;
        if (currentNode == null) {
            if (inCDATA) preInfo.add(new CDataInfo(str));
            else         preInfo.add(new TextInfo(str));
        } else {
            Node n;
            if (inCDATA) n = document.createCDATASection(str);
            else         n = document.createTextNode(str);
            currentNode.appendChild(n);
        }
    }
    
    /**
     * <b>SAX</b>: Implements {@link
     * org.xml.sax.ContentHandler#characters(char[],int,int)}.
     */
    public void characters(char ch[], int start, int length)
        throws SAXException {
        stringBuffer.append(ch, start, length);
        stringContent = true;
    }


    /**
     * <b>SAX</b>: Implements {@link
     * org.xml.sax.ContentHandler#ignorableWhitespace(char[],int,int)}.
     */
    public void ignorableWhitespace(char[] ch,
                                    int start,
                                    int length)
        throws SAXException {
        stringBuffer.append(ch, start, length);
        stringContent = true;
    }

    /**
     * <b>SAX</b>: Implements {@link
     * org.xml.sax.ContentHandler#processingInstruction(String,String)}.
     */
    public void processingInstruction(String target, String data)
        throws SAXException {
	if (inDTD)
            return;
        
        appendStringData(); // Add any collected String Data before PI

        if (currentNode == null)
            preInfo.add(new ProcessingInstructionInfo(target, data));
        else
            currentNode.appendChild
                (document.createProcessingInstruction(target, data));
    }

    // LexicalHandler /////////////////////////////////////////////////////////

    /**
     * <b>SAX</b>: Implements {@link
     * org.xml.sax.ext.LexicalHandler#startDTD(String,String,String)}.
     */
    public void startDTD(String name, String publicId, String systemId)
	throws SAXException {
        appendStringData(); // Add collected string data before entering DTD
	inDTD = true;
    }

    /**
     * <b>SAX</b>: Implements {@link org.xml.sax.ext.LexicalHandler#endDTD()}.
     */
    public void endDTD() throws SAXException {
	inDTD = false;
    }

    /**
     * <b>SAX</b>: Implements
     * {@link org.xml.sax.ext.LexicalHandler#startEntity(String)}.
     */
    public void startEntity(String name) throws SAXException {
    }

    /**
     * <b>SAX</b>: Implements
     * {@link org.xml.sax.ext.LexicalHandler#endEntity(String)}.
     */
    public void endEntity(String name) throws SAXException {
    }

    /**
     * <b>SAX</b>: Implements {@link
     * org.xml.sax.ext.LexicalHandler#startCDATA()}.
     */
    public void startCDATA() throws SAXException {
        appendStringData(); // Add any collected String Data before CData
        inCDATA       = true;
        stringContent = true; // always create CDATA even if empty.
    }

    /**
     * <b>SAX</b>: Implements {@link
     * org.xml.sax.ext.LexicalHandler#endCDATA()}.
     */
    public void endCDATA() throws SAXException {
        appendStringData(); // Add the CDATA section
        inCDATA = false;
    }

    /**
     * <b>SAX</b>: Implements
     * {@link org.xml.sax.ext.LexicalHandler#comment(char[],int,int)}.
     */
    public void comment(char ch[], int start, int length) throws SAXException {
	if (inDTD) return;
        appendStringData();

        String str = new String(ch, start, length);
        if (currentNode == null) {
            preInfo.add(new CommentInfo(str));
        } else {
            currentNode.appendChild(document.createComment(str));
        }
    }
}
