package org.apache.turbine.services.velocity;

/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" and
 *    "Apache Turbine" must not be used to endorse or promote products
 *    derived from this software without prior written permission. For
 *    written permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    "Apache Turbine", nor may "Apache" appear in their name, without
 *    prior written permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletConfig;

import org.apache.commons.collections.ExtendedProperties;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.turbine.Turbine;
import org.apache.turbine.pipeline.PipelineData;
import org.apache.turbine.services.InitializationException;
import org.apache.turbine.services.pull.PullService;
import org.apache.turbine.services.pull.TurbinePull;
import org.apache.turbine.services.template.BaseTemplateEngineService;
import org.apache.turbine.util.RunData;
import org.apache.turbine.util.TurbineException;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.event.EventCartridge;
import org.apache.velocity.app.event.MethodExceptionEventHandler;
import org.apache.velocity.context.Context;
import org.apache.velocity.runtime.log.SimpleLog4JLogSystem;

/**
 * This is a Service that can process Velocity templates from within a
 * Turbine Screen. It is used in conjunction with the templating service
 * as a Templating Engine for templates ending in "vm". It registers
 * itself as translation engine with the template service and gets
 * accessed from there. After configuring it in your properties, it
 * should never be necessary to call methods from this service directly.
 *
 * Here's an example of how you might use it from a
 * screen:<br>
 *
 * <code>
 * Context context = TurbineVelocity.getContext(data);<br>
 * context.put("message", "Hello from Turbine!");<br>
 * String results = TurbineVelocity.handleRequest(context,"helloWorld.vm");<br>
 * data.getPage().getBody().addElement(results);<br>
 * </code>
 *
 * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
 * @author <a href="mailto:krzewski@e-point.pl">Rafal Krzewski</a>
 * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
 * @author <a href="mailto:sean@informage.ent">Sean Legassick</a>
 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
 * @author <a href="mailto:epugh@upstate.com">Eric Pugh</a> 
 * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a>
 * @version $Id$
 */
public class TurbineVelocityService
        extends BaseTemplateEngineService
        implements VelocityService,
                   MethodExceptionEventHandler
{
    /** The generic resource loader path property in velocity.*/
    private static final String RESOURCE_LOADER_PATH = ".resource.loader.path";
    
    /** Default character set to use if not specified in the RunData object. */
    private static final String DEFAULT_CHAR_SET = "ISO-8859-1";

    /** The prefix used for URIs which are of type <code>jar</code>. */
    private static final String JAR_PREFIX = "jar:";

    /** The prefix used for URIs which are of type <code>absolute</code>. */
    private static final String ABSOLUTE_PREFIX = "file://";

    /** Logging */
    private static Log log = LogFactory.getLog(TurbineVelocityService.class);

    /** Is the pullModelActive? */
    private boolean pullModelActive = false;

    /** Shall we catch Velocity Errors and report them in the log file? */
    private boolean catchErrors = true;

    /** Internal Reference to the pull Service */
    private PullService pullService = null;


    /**
     * Load all configured components and initialize them. This is
     * a zero parameter variant which queries the Turbine Servlet
     * for its config.
     *
     * @throws InitializationException Something went wrong in the init
     *         stage
     */
    public void init()
            throws InitializationException
    {
        try
        {
            initVelocity();

            // We can only load the Pull Model ToolBox
            // if the Pull service has been listed in the TR.props
            // and the service has successfully been initialized.
            if (TurbinePull.isRegistered())
            {
                pullModelActive = true;

                pullService = TurbinePull.getService();

                log.debug("Activated Pull Tools");
            }

            // Register with the template service.
            registerConfiguration(VelocityService.VELOCITY_EXTENSION);

            setInit(true);
        }
        catch (Exception e)
        {
            throw new InitializationException(
                "Failed to initialize TurbineVelocityService", e);
        }
    }


    /**
     * Inits the service using servlet parameters to obtain path to the
     * configuration file.
     *
     * @param config The ServletConfiguration from Turbine
     *
     * @throws InitializationException Something went wrong when starting up.
     * @deprecated use init() instead.
     */
    public void init(ServletConfig config)
            throws InitializationException
    {
        init();
    }


    /**
     * Create a Context object that also contains the globalContext.
     *
     * @return A Context object.
     */
    public Context getContext()
    {
        Context globalContext = 
                pullModelActive ? pullService.getGlobalContext() : null;

        Context ctx = new VelocityContext(globalContext);
        return ctx;
    }

    /**
     * This method returns a new, empty Context object.
     *
     * @return A Context Object.
     */
    public Context getNewContext()
    {
        Context ctx = new VelocityContext();

        // Attach an Event Cartridge to it, so we get exceptions
        // while invoking methods from the Velocity Screens
        EventCartridge ec = new EventCartridge();
        ec.addEventHandler(this);
        ec.attachToContext(ctx);
        return ctx;
    }

    /**
     * MethodException Event Cartridge handler
     * for Velocity.
     *
     * It logs an execption thrown by the velocity processing
     * on error level into the log file
     *
     * @param clazz The class that threw the exception
     * @param method The Method name that threw the exception
     * @param e The exception that would've been thrown
     * @return A valid value to be used as Return value
     * @throws Exception We threw the exception further up
     */
    public Object methodException(Class clazz, String method, Exception e)
            throws Exception
    {
        log.error("Class " + clazz.getName() + "." + method + " threw Exception", e);

        if (!catchErrors)
        {
            throw e;
        }

        return "[Turbine caught an Error here. Look into the turbine.log for further information]";
    }

    /**
     * Create a Context from the RunData object.  Adds a pointer to
     * the RunData object to the VelocityContext so that RunData
     * is available in the templates.
     * @deprecated. Use PipelineData version.
     * @param data The Turbine RunData object.
     * @return A clone of the WebContext needed by Velocity.
     */
    public Context getContext(RunData data)
    {
        // Attempt to get it from the data first.  If it doesn't
        // exist, create it and then stuff it into the data.
        Context context = (Context)
            data.getTemplateInfo().getTemplateContext(VelocityService.CONTEXT);

        if (context == null)
        {
            context = getContext();
            context.put(VelocityService.RUNDATA_KEY, data);

            if (pullModelActive)
            {
                // Populate the toolbox with request scope, session scope
                // and persistent scope tools (global tools are already in
                // the toolBoxContent which has been wrapped to construct
                // this request-specific context).
                pullService.populateContext(context, data);
            }

            data.getTemplateInfo().setTemplateContext(
                VelocityService.CONTEXT, context);
        }
        return context;
    }

    /**
     * Create a Context from the PipelineData object.  Adds a pointer to
     * the RunData object to the VelocityContext so that RunData
     * is available in the templates.
     *
     * @param data The Turbine RunData object.
     * @return A clone of the WebContext needed by Velocity.
     */
    public Context getContext(PipelineData pipelineData)
    {
        //Map runDataMap = (Map)pipelineData.get(RunData.class);
        RunData data = (RunData)pipelineData;
        // Attempt to get it from the data first.  If it doesn't
        // exist, create it and then stuff it into the data.
        Context context = (Context)
            data.getTemplateInfo().getTemplateContext(VelocityService.CONTEXT);

        if (context == null)
        {
            context = getContext();
            context.put(VelocityService.RUNDATA_KEY, data);
            // we will add both data and pipelineData to the context.
            context.put(VelocityService.PIPELINEDATA_KEY, pipelineData);

            if (pullModelActive)
            {
                // Populate the toolbox with request scope, session scope
                // and persistent scope tools (global tools are already in
                // the toolBoxContent which has been wrapped to construct
                // this request-specific context).
                pullService.populateContext(context, pipelineData);
            }

            data.getTemplateInfo().setTemplateContext(
                VelocityService.CONTEXT, context);
        }
        return context;
    }

    /**
     * Process the request and fill in the template with the values
     * you set in the Context.
     *
     * @param context  The populated context.
     * @param filename The file name of the template.
     * @return The process template as a String.
     *
     * @throws TurbineException Any exception trown while processing will be
     *         wrapped into a TurbineException and rethrown.
     */
    public String handleRequest(Context context, String filename)
        throws TurbineException
    {
        String results = null;
        ByteArrayOutputStream bytes = null;
        OutputStreamWriter writer = null;
        String charset = getCharSet(context);

        try
        {
            bytes = new ByteArrayOutputStream();

            writer = new OutputStreamWriter(bytes, charset);

            executeRequest(context, filename, writer);
            writer.flush();
            results = bytes.toString(charset);
        }
        catch (Exception e)
        {
            renderingError(filename, e);
        }
        finally
        {
            try
            {
                if (bytes != null)
                {
                    bytes.close();
                }
            }
            catch (IOException ignored)
            {
                // do nothing.
            }
        }
        return results;
    }

    /**
     * Process the request and fill in the template with the values
     * you set in the Context.
     *
     * @param context A Context.
     * @param filename A String with the filename of the template.
     * @param output A OutputStream where we will write the process template as
     * a String.
     *
     * @throws TurbineException Any exception trown while processing will be
     *         wrapped into a TurbineException and rethrown.
     */
    public void handleRequest(Context context, String filename,
                              OutputStream output)
            throws TurbineException
    {
        String charset  = getCharSet(context);
        OutputStreamWriter writer = null;

        try
        {
            writer = new OutputStreamWriter(output, charset);
            executeRequest(context, filename, writer);
        }
        catch (Exception e)
        {
            renderingError(filename, e);
        }
        finally
        {
            try
            {
                if (writer != null)
                {
                    writer.flush();
                }
            }
            catch (Exception ignored)
            {
                // do nothing.
            }
        }
    }


    /**
     * Process the request and fill in the template with the values
     * you set in the Context.
     *
     * @param context A Context.
     * @param filename A String with the filename of the template.
     * @param writer A Writer where we will write the process template as
     * a String.
     *
     * @throws TurbineException Any exception trown while processing will be
     *         wrapped into a TurbineException and rethrown.
     */
    public void handleRequest(Context context, String filename, Writer writer)
            throws TurbineException
    {
        try
        {
            executeRequest(context, filename, writer);
        }
        catch (Exception e)
        {
            renderingError(filename, e);
        }
        finally
        {
            try
            {
                if (writer != null)
                {
                    writer.flush();
                }
            }
            catch (Exception ignored)
            {
                // do nothing.
            }
        }
    }


    /**
     * Process the request and fill in the template with the values
     * you set in the Context. Apply the character and template
     * encodings from RunData to the result.
     *
     * @param context A Context.
     * @param filename A String with the filename of the template.
     * @param writer A OutputStream where we will write the process template as
     * a String.
     *
     * @throws Exception A problem occured.
     */
    private void executeRequest(Context context, String filename,
                                Writer writer)
            throws Exception
    {
        String encoding = getEncoding(context);

        if (encoding == null)
        {
          encoding = DEFAULT_CHAR_SET;
        }
		Velocity.mergeTemplate(filename, encoding, context, writer);
    }

    /**
     * Retrieve the required charset from the Turbine RunData in the context
     *
     * @param context A Context.
     * @return The character set applied to the resulting String.
     */
    private String getCharSet(Context context)
    {
        String charset = null;

        Object data = context.get(VelocityService.RUNDATA_KEY);
        if ((data != null) && (data instanceof RunData))
        {
            charset = ((RunData) data).getCharSet();
        }

        return (StringUtils.isEmpty(charset)) ? DEFAULT_CHAR_SET : charset;
    }

    /**
     * Retrieve the required encoding from the Turbine RunData in the context
     *
     * @param context A Context.
     * @return The encoding applied to the resulting String.
     */
    private String getEncoding(Context context)
    {
        String encoding = null;

        Object data = context.get(VelocityService.RUNDATA_KEY);
        if ((data != null) && (data instanceof RunData))
        {
            encoding = ((RunData) data).getTemplateEncoding();
        }

        return encoding;
    }

    /**
     * Macro to handle rendering errors.
     *
     * @param filename The file name of the unrenderable template.
     * @param e        The error.
     *
     * @exception TurbineException Thrown every time.  Adds additional
     *                             information to <code>e</code>.
     */
    private static final void renderingError(String filename, Exception e)
            throws TurbineException
    {
        String err = "Error rendering Velocity template: " + filename;
        log.error(err, e);
        throw new TurbineException(err, e);
    }

    /**
     * Setup the velocity runtime by using a subset of the
     * Turbine configuration which relates to velocity.
     *
     * @exception Exception An Error occured.
     */
    private synchronized void initVelocity()
        throws Exception
    {
        // Get the configuration for this service.
        Configuration conf = getConfiguration();

        catchErrors = conf.getBoolean(CATCH_ERRORS_KEY, CATCH_ERRORS_DEFAULT);
        
        conf.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS,
                SimpleLog4JLogSystem.class.getName());
        conf.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM
                + ".log4j.category", "velocity");
        
        Velocity.setExtendedProperties(createVelocityProperties(conf));
        Velocity.init();
    }


    /**
     * This method generates the Extended Properties object necessary
     * for the initialization of Velocity. It also converts the various
     * resource loader pathes into webapp relative pathes. It also
     *
     * @param conf The Velocity Service configuration
     *
     * @return An ExtendedProperties Object for Velocity
     *
     * @throws Exception If a problem occured while converting the properties.
     */

    public ExtendedProperties createVelocityProperties(Configuration conf)
            throws Exception
    {
        // This bugger is public, because we want to run some Unit tests
        // on it.

        ExtendedProperties veloConfig = new ExtendedProperties();

        // Fix up all the template resource loader pathes to be
        // webapp relative. Copy all other keys verbatim into the
        // veloConfiguration.

        for (Iterator i = conf.getKeys(); i.hasNext();)
        {
            String key = (String) i.next();
            if (!key.endsWith(RESOURCE_LOADER_PATH))
            {
                Object value = conf.getProperty(key);
                if (value instanceof List) {
                    for (Iterator itr = ((List)value).iterator(); itr.hasNext();)
                    {
                        veloConfig.addProperty(key, itr.next());
                    }
                } 
                else
                {
                    veloConfig.addProperty(key, value);
                }
                continue; // for()
            }

            List paths = conf.getList(key, null);
            if (paths == null)
            {
                // We don't copy this into VeloProperties, because
                // null value is unhealthy for the ExtendedProperties object...
                continue; // for()
            }

            Velocity.clearProperty(key);

            // Translate the supplied pathes given here.
            // the following three different kinds of
            // pathes must be translated to be webapp-relative
            //
            // jar:file://path-component!/entry-component
            // file://path-component
            // path/component
            for (Iterator j = paths.iterator(); j.hasNext();)
            {
                String path = (String) j.next();

                log.debug("Translating " + path);

                if (path.startsWith(JAR_PREFIX))
                {
                    // skip jar: -> 4 chars
                    if (path.substring(4).startsWith(ABSOLUTE_PREFIX))
                    {
                        // We must convert up to the jar path separator
                        int jarSepIndex = path.indexOf("!/");

                        // jar:file:// -> skip 11 chars
                        path = (jarSepIndex < 0)
                            ? Turbine.getRealPath(path.substring(11))
                        // Add the path after the jar path separator again to the new url.
                            : (Turbine.getRealPath(path.substring(11, jarSepIndex)) + path.substring(jarSepIndex));

                        log.debug("Result (absolute jar path): " + path);
                    }
                }
                else if(path.startsWith(ABSOLUTE_PREFIX))
                {
                    // skip file:// -> 7 chars
                    path = Turbine.getRealPath(path.substring(7));

                    log.debug("Result (absolute URL Path): " + path);
                }
                // Test if this might be some sort of URL that we haven't encountered yet.
                else if(path.indexOf("://") < 0)
                {
                    path = Turbine.getRealPath(path);

                    log.debug("Result (normal fs reference): " + path);
                }

                log.debug("Adding " + key + " -> " + path);
                // Re-Add this property to the configuration object
                veloConfig.addProperty(key, path);
            }
        }
        return veloConfig;
    }

    /**
     * Find out if a given template exists. Velocity
     * will do its own searching to determine whether
     * a template exists or not.
     *
     * @param template String template to search for
     * @return True if the template can be loaded by Velocity
     */
    public boolean templateExists(String template)
    {
        return Velocity.templateExists(template);
    }

    /**
     * Performs post-request actions (releases context
     * tools back to the object pool).
     *
     * @param context a Velocity Context
     */
    public void requestFinished(Context context)
    {
        if (pullModelActive)
        {
            pullService.releaseTools(context);
        }
    }
}
