/*
 * 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.
 */
package org.apache.commons.jelly.tags.xml;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import java.util.List;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamSource;

import org.apache.commons.jelly.JellyContext;
import org.apache.commons.jelly.JellyException;
import org.apache.commons.jelly.JellyTagException;
import org.apache.commons.jelly.MissingAttributeException;
import org.apache.commons.jelly.Script;
import org.apache.commons.jelly.Tag;
import org.apache.commons.jelly.XMLOutput;
import org.apache.commons.jelly.impl.ScriptBlock;
import org.apache.commons.jelly.impl.StaticTagScript;
import org.apache.commons.jelly.impl.TagScript;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.io.DocumentResult;
import org.dom4j.io.DocumentSource;
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.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.XMLReaderFactory;

/** A tag which parses some XML, applies an xslt transform to it
  * and defines a variable with the transformed Document.
  * The XML can either be specified as its body or can be passed in via the
  * xml property which can be a Reader, InputStream, URL or String URI.
  *
  * The XSL can be passed in via the
  * xslt property which can be a Reader, InputStream, URL or String URI.
  *
  * @author Robert Leftwich
  * @version $Revision$
  */
public class TransformTag extends ParseTag {

    /** The Log to which logging calls will be made. */
    private static final Log log = LogFactory.getLog(TransformTag.class);

    /** Property name for lexical handler */
    private static final String LEXICAL_HANDLER_PROPERTY =
        "http://xml.org/sax/properties/lexical-handler";

    /** The xslt to parse, either a String URI, a Reader or InputStream */
    private Object xslt;

    /** The xsl transformer factory */
    private SAXTransformerFactory tf;

    /** the transformer handler, doing the real work */
    private TransformerHandler transformerHandler;

    /**
     * Constructor for TransformTag.
     */
    public TransformTag() {
        super();
        this.tf = (SAXTransformerFactory) TransformerFactory.newInstance();
    }

    // Tag interface
    //-------------------------------------------------------------------------

    /**
     * Process this tag instance
     *
     * @param output The pipeline for xml events
     * @throws Exception - when required attributes are missing
     */
    public void doTag(XMLOutput output) throws MissingAttributeException, JellyTagException {

        if (null == this.getXslt()) {
            throw new MissingAttributeException("The xslt attribute cannot be null");
        }

        // set a resolver to locate uri
        this.tf.setURIResolver(createURIResolver());

        try {
            this.transformerHandler =
                this.tf.newTransformerHandler(this.getObjAsSAXSource(this.getXslt()));
        }
        catch (TransformerConfigurationException e) {
            throw new JellyTagException(e);
        }

        // run any nested param tags
        this.doNestedParamTag(output);

        try {
            // get a reader to provide SAX events to transformer
            XMLReader xmlReader = this.createXMLReader();
            xmlReader.setContentHandler(this.transformerHandler);
            xmlReader.setProperty(LEXICAL_HANDLER_PROPERTY, this.transformerHandler);

            // handle result differently, depending on if var is specified
            String varName = this.getVar();
            if (null == varName) {
                // pass the result of the transform out as SAX events
                this.transformerHandler.setResult(this.createSAXResult(output));
                xmlReader.parse(this.getXMLInputSource());
            }
            else {
                // pass the result of the transform out as a document
                DocumentResult result = new DocumentResult();
                this.transformerHandler.setResult(result);
                xmlReader.parse(this.getXMLInputSource());

                // output the result as a variable
                Document transformedDoc = result.getDocument();
                this.context.setVariable(varName, transformedDoc);
            }
        }
        catch (SAXException e) {
            throw new JellyTagException(e);
        }
        catch (IOException e) {
            throw new JellyTagException(e);
        }

    }

    // Properties
    //-------------------------------------------------------------------------

    /**
     * Gets the source of the XSL which is either a String URI, Reader or
     * InputStream
     *
     * @returns xslt    The source of the xslt
     */
    public Object getXslt() {
        return this.xslt;
    }

    /**
     * Sets the source of the XSL which is either a String URI, Reader or
     * InputStream
     *
     * @param xslt    The source of the xslt
     */
    public void setXslt(Object xslt) {
        this.xslt = xslt;
    }

    public void setParameterValue(String name, Object value) {
        this.transformerHandler.getTransformer().setParameter(name, value);
    }

    // Implementation methods
    //-------------------------------------------------------------------------

    /**
     * Creates a new URI Resolver so that URIs inside the XSLT document can be
     * resolved using the JellyContext
     *
     * @return a URI Resolver for the JellyContext
     */
    protected URIResolver createURIResolver() {
        return new URIResolver() {
            public Source resolve(String href, String base)
                throws TransformerException {

                if (log.isDebugEnabled() ) {
                    log.debug( "base: " + base + " href: " + href );
                }

                // pass if we don't have a systemId
                if (null == href)
                    return null;

                // @todo
                // #### this is a pretty simplistic implementation.
                // #### we should really handle this better such that if
                // #### base is specified as an absolute URL
                // #### we trim the end off it and append href
                return new StreamSource(context.getResourceAsStream(href));
            }
        };
    }

    /**
     * Factory method to create a new SAXResult for the given
     * XMLOutput so that the output of an XSLT transform will go
     * directly into the XMLOutput that we are given.
     *
     * @param output The destination of the transform output
     * @return A SAXResult for the transfrom output
     */
    protected Result createSAXResult(XMLOutput output) {
        SAXResult result = new SAXResult(output);
        result.setLexicalHandler(output);
        return result;
    }

    /**
     * Factory method to create a new XMLReader for this tag
     * so that the input of the XSLT transform comes from
     * either the xml var, the nested tag or the tag body.
     *
     * @return XMLReader for the transform input
     * @throws SAXException
     *             If the value of the "org.xml.sax.driver" system property
     *             is null, or if the class cannot be loaded and instantiated.
     */
    protected XMLReader createXMLReader() throws SAXException {
        XMLReader xmlReader = null;
        Object xmlReaderSourceObj = this.getXml();
        // if no xml source specified then get from body
        // otherwise convert it to a SAX source
        if (null == xmlReaderSourceObj) {
            xmlReader = new TagBodyXMLReader(this);
        }
        else {
            xmlReader = XMLReaderFactory.createXMLReader();
        }

        return xmlReader;
    }

    /**
     * Helper method to get the appropriate xml input source
     * so that the input of the XSLT transform comes from
     * either the xml var, the nested tag or the tag body.
     *
     * @return InputSource for the transform input
     */
    protected InputSource getXMLInputSource() {
        InputSource xmlInputSource = null;
        Object xmlInputSourceObj = this.getXml();
        // if no xml source specified then get from tag body
        // otherwise convert it to an input source
        if (null == xmlInputSourceObj) {
            xmlInputSource = new TagBodyInputSource();
        } else {
            xmlInputSource = this.getInputSourceFromObj(xmlInputSourceObj);
        }
        return xmlInputSource;
    }

    /**
     * Helper method to convert the specified object to a SAX source
     *
     * @return SAXSource from the source object or null
     */
    protected SAXSource getObjAsSAXSource(Object saxSourceObj) {
        SAXSource saxSource = null;
        if (null != saxSourceObj) {
            if (saxSourceObj instanceof Document) {
                saxSource =  new DocumentSource((Document) saxSourceObj);
            } else {
                InputSource xmlInputSource =
                    this.getInputSourceFromObj(saxSourceObj);
                saxSource = new SAXSource(xmlInputSource);
            }
        }

        return saxSource;
    }

    /**
     * Helper method to get an xml input source for the supplied object
     *
     * @return InputSource for the object or null
     */
    protected InputSource getInputSourceFromObj(Object sourceObj ) {
        InputSource xmlInputSource = null;
        if (sourceObj instanceof Document) {
            SAXSource saxSource = new DocumentSource((Document) sourceObj);
            xmlInputSource = saxSource.getInputSource();
        } else {
            if (sourceObj instanceof String) {
                String uri = (String) sourceObj;
                xmlInputSource = new InputSource(context.getResourceAsStream(uri));
            }
            else if (sourceObj instanceof Reader) {
                xmlInputSource = new InputSource((Reader) sourceObj);
            }
            else if (sourceObj instanceof InputStream) {
                xmlInputSource = new InputSource((InputStream) sourceObj);
            }
            else if (sourceObj instanceof URL) {
                String uri = ((URL) sourceObj).toString();
                xmlInputSource = new InputSource(context.getResourceAsStream(uri));
            }
            else if (sourceObj instanceof File) {
                try {
                    String uri = ((File) sourceObj).toURL().toString();
                    xmlInputSource = new InputSource(context.getResourceAsStream(uri));
                }
                catch (MalformedURLException e) {
                    throw new IllegalArgumentException(
                        "This should never occur. We should always be able to convert a File to a URL" + e );
                }
            }
            else {
                throw new IllegalArgumentException(
                    "Invalid source argument. Must be a String, Reader, InputStream or URL."
                        + " Was type; "
                        + sourceObj.getClass().getName()
                        + " with value: "
                        + sourceObj);
            }
        }

        return xmlInputSource;
    }

    /**
     * Helper method to run any nested param tags
     *
    * @param output The destination for any SAX output (not actually used)
     */
    private void doNestedParamTag(XMLOutput output) throws JellyTagException {
        // find any nested param tags and run them
        Script bodyScript = this.getBody();
        
        if (bodyScript instanceof ScriptBlock) {
            ScriptBlock scriptBlock = (ScriptBlock) bodyScript;
            List scriptList = scriptBlock.getScriptList();
            for (Iterator iter = scriptList.iterator(); iter.hasNext(); ) {
                Script script = (Script) iter.next();
                if (script instanceof TagScript) {

                    Tag tag = null;
                    try {
                        tag = ((TagScript) script).getTag(getContext());
                    } catch (JellyException e) {
                        throw new JellyTagException(e);
                    }

                    if (tag instanceof ParamTag) {
                        script.run(context, output);
                    }


                }
            }
        }
    }

    
    /** A helper class that converts a transform tag body to an XMLReader
      * to hide the details of where the input for the transform is obtained
      *
      * @author <a href="mailto:robert@leftwich.info">Robert Leftwich</a>
      * @version $Revision$
      */
    private class TagBodyXMLReader implements XMLReader {

        /** The tag whose body is to be read. */
        private Tag tag;

        /** The destination for the sax events generated by the reader. */
        private XMLOutput xmlOutput;

        /** Storage for a DTDHandler if set by the user of the reader. */
        private DTDHandler dtdHandler;

        /** Storage for a ErrorHandler if set by the user of the reader. */
        private ErrorHandler errorHandler;

        /** Storage for a EntityResolver if set by the user of the reader. */
        private EntityResolver entityResolver;

        /**
         * Construct an XMLReader for the specified Tag
         *
         * @param tag    The Tag to convert to an XMLReader
         */
        public TagBodyXMLReader(Tag tag)
        {
            this.tag = tag;
            this.xmlOutput = new XMLOutput();
        }

        // Methods
        //-------------------------------------------------------------------------

        /**
         * Parse an XML source.
         *
         * @param input  The source of the xml
         * @throws SAXException -
         *             Any SAX exception, possibly wrapping another exception.
         * @throws IOException -
         *             An IO exception from the parser, possibly from a byte
                       stream or character stream supplied by the application.
         */
        public void parse(InputSource input)
        throws IOException, SAXException
        {
            // safety check that we are being used correctly
            if (input instanceof TagBodyInputSource) {
                this.doInvokeBody();
            } else {
                throw new SAXException("Invalid input source");
            }
        }

        /**
         * Parse an XML source specified by a system id
         *
         * @param input  The system identifier (URI)
         * @throws SAXException -
         *             Any SAX exception, possibly wrapping another exception.
         * @throws IOException -
         *             An IO exception from the parser, possibly from a byte
                       stream or character stream supplied by the application.
         */
        public void parse(String systemId)
        throws IOException, SAXException
        {
            this.doInvokeBody();
        }

        // Helper methods
        //-------------------------------------------------------------------------

        /**
         * Actually invoke the tag body to generate the SAX events
         *
         * @throws SAXException -
         *             Any SAX exception, possibly wrapping another exception.
         */
        private void doInvokeBody() throws SAXException {
            try {
                if (this.shouldParseBody()) {
                    XMLReader anXMLReader = XMLReaderFactory.createXMLReader();
                    anXMLReader.setContentHandler(this.xmlOutput);
                    anXMLReader.setProperty(LEXICAL_HANDLER_PROPERTY,this.xmlOutput);
                    StringWriter writer = new StringWriter();
                    this.tag.invokeBody(XMLOutput.createXMLOutput(writer));
                    Reader reader = new StringReader(writer.toString());
                    anXMLReader.parse(new InputSource(reader));
                } else {
                    this.tag.invokeBody(this.xmlOutput);
                }
            } catch (Exception ex) {
                throw new SAXException(ex);
            }
        }

        /**
         * Helper method to determine if nested body needs to be parsed by (an
         * xml parser, i.e. its only text) to generate SAX events or not
         *
         * @return True if tag body should be parsed or false if invoked only
         * @throws JellyTagException
         */
        private boolean shouldParseBody() throws JellyTagException {
            boolean result = false;
            // check to see if we need to parse the body or just invoke it
            Script bodyScript = this.tag.getBody();
            
            if (bodyScript instanceof ScriptBlock) {
                ScriptBlock scriptBlock = (ScriptBlock) bodyScript;
                List scriptList = scriptBlock.getScriptList();
                for (Iterator iter = scriptList.iterator(); iter.hasNext(); ) {
                    Script script = (Script) iter.next();
                    if (script instanceof StaticTagScript) {
                        result = true;
                         break;
                    }
                }
            }
            return result;
        }

        // Properties
        //-------------------------------------------------------------------------

        /**
         * Gets the SAX ContentHandler to feed SAX events into
         *
         * @return the SAX ContentHandler to use to feed SAX events into
         */
        public ContentHandler getContentHandler() {
            return this.xmlOutput.getContentHandler();
        }

        /**
         * Sets the SAX ContentHandler to feed SAX events into
         *
         * @param contentHandler is the ContentHandler to use.
         *      This value cannot be null.
         */
        public void setContentHandler(ContentHandler contentHandler) {
            this.xmlOutput.setContentHandler(contentHandler);
            // often classes will implement LexicalHandler as well
            if (contentHandler instanceof LexicalHandler) {
                this.xmlOutput.setLexicalHandler((LexicalHandler) contentHandler);
            }
        }

        /**
         * Gets the DTD Handler to feed SAX events into
         *
         * @return the DTD Handler to use to feed SAX events into
         */
        public DTDHandler getDTDHandler() {
            return this.dtdHandler;
        }

        /**
         * Sets the DTD Handler to feed SAX events into
         *
         * @param the DTD Handler to use to feed SAX events into
         */
        public void setDTDHandler(DTDHandler dtdHandler) {
            this.dtdHandler = dtdHandler;
        }

        /**
         * Gets the Error Handler to feed SAX events into
         *
         * @return the Error Handler to use to feed SAX events into
         */
        public ErrorHandler getErrorHandler() {
            return this.errorHandler;
        }

        /**
         * Sets the Error Handler to feed SAX events into
         *
         * @param the Error Handler to use to feed SAX events into
         */
        public void setErrorHandler(ErrorHandler errorHandler) {
            // save the error handler
            this.errorHandler = errorHandler;
        }

        /**
         * Gets the Entity Resolver to feed SAX events into
         *
         * @return the Entity Resolver to use to feed SAX events into
         */
        public EntityResolver getEntityResolver() {
            return this.entityResolver;
        }

        /**
         * Sets the Entity Resolver to feed SAX events into
         *
         * @param the Entity Resolver to use to feed SAX events into
         */
        public void setEntityResolver(EntityResolver entityResolver) {
            this.entityResolver = entityResolver;
        }

        /**
         * Lookup the value of a property
         *
         * @param name - The property name, which is a fully-qualified URI.
         * @return - The current value of the property.
         * @throws SAXNotRecognizedException -
         *            When the XMLReader does not recognize the property name.
         * @throws SAXNotSupportedException -
         *            When the XMLReader recognizes the property name but
         *            cannot determine its value at this time.
         */
        public Object getProperty(String name)
        throws SAXNotRecognizedException, SAXNotSupportedException
        {
            // respond to the lexical handler request
            if (name.equalsIgnoreCase(LEXICAL_HANDLER_PROPERTY)) {
                return this.xmlOutput.getLexicalHandler();
            } else {
                // do nothing
                return null;
            }
        }

        /**
         * Set the value of a property
         *
         * @param name - The property name, which is a fully-qualified URI.
         * @param value - The property value
         * @throws SAXNotRecognizedException -
         *            When the XMLReader does not recognize the property name.
         * @throws SAXNotSupportedException -
         *            When the XMLReader recognizes the property name but
         *            cannot determine its value at this time.
         */
        public void setProperty(String name, Object value)
        throws SAXNotRecognizedException, SAXNotSupportedException
        {
            // respond to the lexical handler setting
            if (name.equalsIgnoreCase(LEXICAL_HANDLER_PROPERTY)) {
                this.xmlOutput.setLexicalHandler((LexicalHandler) value);
            }
        }

        /**
         * Lookup the value of a feature
         *
         * @param name - The feature name, which is a fully-qualified URI.
         * @return - The current state of the feature (true or false)
         * @throws SAXNotRecognizedException -
         *            When the XMLReader does not recognize the feature name.
         * @throws SAXNotSupportedException -
         *            When the XMLReader recognizes the feature name but
         *            cannot determine its value at this time.
         */
        public boolean getFeature(String name)
        throws SAXNotRecognizedException, SAXNotSupportedException
        {
            // do nothing
            return false;
        }

        /**
         * Set the value of a feature
         *
         * @param name - The feature name, which is a fully-qualified URI.
         * @param value - The current state of the feature (true or false)
         * @throws SAXNotRecognizedException -
         *            When the XMLReader does not recognize the feature name.
         * @throws SAXNotSupportedException -
         *            When the XMLReader recognizes the feature name but
         *            cannot determine its value at this time.
         */
        public void setFeature(String name, boolean value)
        throws SAXNotRecognizedException, SAXNotSupportedException
        {
            // do nothing
        }
    }

    /** A marker class used by the TagBodyXMLReader as a sanity check
      * (i.e. The source is not actually used)
      *
      */
    private class TagBodyInputSource extends InputSource {

        /**
         * Construct an instance of this marker class
         */
        public TagBodyInputSource() {
        }
    }

}
