/*
 * 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.fop.util;

import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;

import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;

/**
 * ContentHandlerFactory which constructs ContentHandlers that build DOM Documents.
 */
public class DOMBuilderContentHandlerFactory implements ContentHandlerFactory {

    private static SAXTransformerFactory tFactory
            = (SAXTransformerFactory)SAXTransformerFactory.newInstance();

    private String namespaceURI;
    private DOMImplementation domImplementation;

    /**
     * Main Constructor
     * @param namespaceURI the main namespace URI for the DOM to be parsed
     * @param domImplementation the DOMImplementation to use for build the DOM
     */
    public DOMBuilderContentHandlerFactory(String namespaceURI,
                DOMImplementation domImplementation) {
        this.namespaceURI = namespaceURI;
        this.domImplementation = domImplementation;
    }

    /** {@inheritDoc} */
    public String[] getSupportedNamespaces() {
        return new String[] {namespaceURI};
    }

    /** {@inheritDoc} */
    public ContentHandler createContentHandler() throws SAXException {
        return new Handler();
    }

    private class Handler extends DelegatingContentHandler
                implements ContentHandlerFactory.ObjectSource {

        private Document doc;
        private ObjectBuiltListener obListener;

        public Handler() throws SAXException {
            super();
        }

        public Document getDocument() {
            return this.doc;
        }

        /**
         * {@inheritDoc}
         */
        public Object getObject() {
            return getDocument();
        }

        /**
         * {@inheritDoc}
         */
        public void setObjectBuiltListener(ObjectBuiltListener listener) {
            this.obListener = listener;
        }

        /**
         * {@inheritDoc}
         */
        public void startDocument() throws SAXException {
            //Suppress startDocument() call if doc has not been set, yet. It will be done later.
            if (doc != null) {
                super.startDocument();
            }
        }

        /**
         * {@inheritDoc}
         */
        public void startElement(String uri, String localName, String qName, Attributes atts)
                    throws SAXException {
            if (doc == null) {
                TransformerHandler handler;
                try {
                    handler = tFactory.newTransformerHandler();
                } catch (TransformerConfigurationException e) {
                    throw new SAXException("Error creating a new TransformerHandler", e);
                }
                doc = domImplementation.createDocument(namespaceURI, qName, null);
                //It's easier to work with an empty document, so remove the root element
                doc.removeChild(doc.getDocumentElement());
                handler.setResult(new DOMResult(doc));
                setDelegateContentHandler(handler);
                setDelegateLexicalHandler(handler);
                setDelegateDTDHandler(handler);
                handler.startDocument();
            }
            super.startElement(uri, localName, qName, atts);
        }

        /**
         * {@inheritDoc}
         */
        public void endDocument() throws SAXException {
            super.endDocument();
            if (obListener != null) {
                obListener.notifyObjectBuilt(getObject());
            }
        }

    }

}
