package org.apache.velocity.app;

/*
 * 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.
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.Properties;

import org.apache.commons.collections.ExtendedProperties;
import org.apache.velocity.Template;
import org.apache.velocity.context.Context;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.RuntimeInstance;
import org.apache.velocity.runtime.log.Log;

/**
 * <p>
 * This class provides a separate new-able instance of the
 * Velocity template engine.  The alternative model for use
 * is using the Velocity class which employs the singleton
 * model.
 * </p>
 * <p>Velocity will call
 * the parameter-less init() at the first use of this class
 * if the init() wasn't explicitly called.  While this will
 * ensure that Velocity functions, it probably won't
 * function in the way you intend, so it is strongly recommended that
 * you call an init() method yourself if you use the default constructor.
 * </p>
 *
 * @version $Id$
 */
public class VelocityEngine implements RuntimeConstants
{
    private RuntimeInstance ri = new RuntimeInstance();


    /**
     *  Init-less CTOR
     */
    public VelocityEngine()
    {
        // do nothing
    }

    /**
     *  CTOR that invokes an init(String), initializing
     *  the engine using the properties file specified
     *
     * @param propsFilename name of properties file to init with
     * @throws Exception
     * @since 1.5
     */
    public VelocityEngine(String propsFilename)
        throws Exception
    {
        ri.init(propsFilename);
    }

    /**
     *  CTOR that invokes an init(String), initializing
     *  the engine using the Properties specified
     *
     * @param p name of properties  to init with
     * @throws Exception
     * @since 1.5
     */
    public VelocityEngine(Properties p)
        throws Exception
    {
        ri.init(p);
    }

    /**
     *  initialize the Velocity runtime engine, using the default
     *  properties of the Velocity distribution
     * @throws Exception
     */
    public void init()
        throws Exception
    {
        ri.init();
    }

    /**
     *  initialize the Velocity runtime engine, using default properties
     *  plus the properties in the properties file passed in as the arg
     *
     *  @param propsFilename file containing properties to use to initialize
     *         the Velocity runtime
     * @throws Exception
     */
    public void init(String propsFilename)
        throws Exception
    {
        ri.init(propsFilename);
    }

    /**
     *  initialize the Velocity runtime engine, using default properties
     *  plus the properties in the passed in java.util.Properties object
     *
     *  @param p  Proprties object containing initialization properties
     * @throws Exception
     *
     */
    public void init(Properties p)
        throws Exception
    {
        ri.init(p);
    }

    /**
     * Set a Velocity Runtime property.
     *
     * @param  key
     * @param  value
     */
    public void setProperty(String key, Object value)
    {
        ri.setProperty(key,value);
    }

    /**
     * Add a Velocity Runtime property.
     *
     * @param  key
     * @param  value
     */
    public void addProperty(String key, Object value)
    {
        ri.addProperty(key,value);
    }

    /**
     * Clear a Velocity Runtime property.
     *
     * @param key of property to clear
     */
    public void clearProperty(String key)
    {
        ri.clearProperty(key);
    }

    /**
     * Set an entire configuration at once. This is
     * useful in cases where the parent application uses
     * the ExtendedProperties class and the velocity configuration
     * is a subset of the parent application's configuration.
     *
     * @param  configuration
     *
     */
    public void setExtendedProperties( ExtendedProperties configuration)
    {
        ri.setConfiguration( configuration );
    }

    /**
     *  Get a Velocity Runtime property.
     *
     *  @param key property to retrieve
     *  @return property value or null if the property
     *        not currently set
     */
    public Object getProperty( String key )
    {
        return ri.getProperty( key );
    }

    /**
     *  renders the input string using the context into the output writer.
     *  To be used when a template is dynamically constructed, or want to use
     *  Velocity as a token replacer.
     *
     *  @param context context to use in rendering input string
     *  @param out  Writer in which to render the output
     *  @param logTag  string to be used as the template name for log
     *                 messages in case of error
     *  @param instring input string containing the VTL to be rendered
     *
     *  @return true if successful, false otherwise.  If false, see
     *             Velocity runtime log
     * @throws ParseErrorException The template could not be parsed.
     * @throws MethodInvocationException A method on a context object could not be invoked.
     * @throws ResourceNotFoundException A referenced resource could not be loaded.
     * @throws IOException While rendering to the writer, an I/O problem occured.
     */
    public  boolean evaluate( Context context,  Writer out,
                                     String logTag, String instring )
        throws ParseErrorException, MethodInvocationException,
            ResourceNotFoundException, IOException
    {
        return ri.evaluate(context, out, logTag, instring);
    }

    /**
     *  Renders the input stream using the context into the output writer.
     *  To be used when a template is dynamically constructed, or want to
     *  use Velocity as a token replacer.
     *
     *  @param context context to use in rendering input string
     *  @param writer  Writer in which to render the output
     *  @param logTag  string to be used as the template name for log messages
     *                 in case of error
     *  @param instream input stream containing the VTL to be rendered
     *
     *  @return true if successful, false otherwise.  If false, see
     *               Velocity runtime log
     * @throws ParseErrorException
     * @throws MethodInvocationException
     * @throws ResourceNotFoundException
     * @throws IOException
     *  @deprecated Use
     *  {@link #evaluate( Context context, Writer writer,
     *      String logTag, Reader reader ) }
     */
    public boolean evaluate( Context context, Writer writer,
                                    String logTag, InputStream instream )
        throws ParseErrorException, MethodInvocationException,
            ResourceNotFoundException, IOException
    {
        /*
         *  first, parse - convert ParseException if thrown
         */
        BufferedReader br  = null;
        String encoding = null;

        try
        {
            encoding = ri.getString(INPUT_ENCODING,ENCODING_DEFAULT);
            br = new BufferedReader(  new InputStreamReader( instream, encoding));
        }
        catch( UnsupportedEncodingException  uce )
        {
            String msg = "Unsupported input encoding : " + encoding
                + " for template " + logTag;
            throw new ParseErrorException( msg );
        }

        return evaluate( context, writer, logTag, br );
    }

    /**
     *  Renders the input reader using the context into the output writer.
     *  To be used when a template is dynamically constructed, or want to
     *  use Velocity as a token replacer.
     *
     *  @param context context to use in rendering input string
     *  @param writer  Writer in which to render the output
     *  @param logTag  string to be used as the template name for log messages
     *                 in case of error
     *  @param reader Reader containing the VTL to be rendered
     *
     *  @return true if successful, false otherwise.  If false, see
     *               Velocity runtime log
     * @throws ParseErrorException The template could not be parsed.
     * @throws MethodInvocationException A method on a context object could not be invoked.
     * @throws ResourceNotFoundException A referenced resource could not be loaded.
     * @throws IOException While reading from the reader or rendering to the writer,
     *                     an I/O problem occured.
     *  @since Velocity v1.1
     */
    public boolean evaluate(Context context, Writer writer,
                                    String logTag, Reader reader)
        throws ParseErrorException, MethodInvocationException,
            ResourceNotFoundException,IOException
    {
        return ri.evaluate(context, writer, logTag, reader);
    }


    /**
     * Invokes a currently registered Velocimacro with the params provided
     * and places the rendered stream into the writer.
     * <br>
     * Note : currently only accepts args to the VM if they are in the context.
     *
     * @param vmName name of Velocimacro to call
     * @param logTag string to be used for template name in case of error. if null,
     *               the vmName will be used
     * @param params keys for args used to invoke Velocimacro, in java format
     *               rather than VTL (eg  "foo" or "bar" rather than "$foo" or "$bar")
     * @param context Context object containing data/objects used for rendering.
     * @param writer  Writer for output stream
     * @return true if Velocimacro exists and successfully invoked, false otherwise.
     * @throws IOException While rendering to the writer, an I/O problem occured.
     */
    public boolean invokeVelocimacro( String vmName, String logTag,
                                              String params[], Context context,
                                              Writer writer )
        throws Exception
    {
        return ri.invokeVelocimacro(vmName, logTag, params, context, writer);
    }

    /**
     *  Merges a template and puts the rendered stream into the writer.
     *  The default encoding that Velocity uses to read template files is defined in
     *  the property input.encoding and defaults to ISO-8859-1.
     *
     *  @param templateName name of template to be used in merge
     *  @param context  filled context to be used in merge
     *  @param  writer  writer to write template into
     *
     *  @return true if successful, false otherwise.  Errors
     *           logged to velocity log.
     * @throws ResourceNotFoundException
     * @throws ParseErrorException
     * @throws MethodInvocationException
     * @throws Exception
     * @deprecated Use
     *  {@link #mergeTemplate( String templateName, String encoding,
     *                Context context, Writer writer )}
     */
    public boolean mergeTemplate( String templateName,
                                         Context context, Writer writer )
        throws ResourceNotFoundException, ParseErrorException, MethodInvocationException, Exception
    {
        return mergeTemplate( templateName, ri.getString(INPUT_ENCODING,ENCODING_DEFAULT),
                               context, writer );
    }

    /**
     *  merges a template and puts the rendered stream into the writer
     *
     *  @param templateName name of template to be used in merge
     *  @param encoding encoding used in template
     *  @param context  filled context to be used in merge
     *  @param  writer  writer to write template into
     *
     *  @return true if successful, false otherwise.  Errors
     *           logged to velocity log
     * @throws ResourceNotFoundException
     * @throws ParseErrorException
     * @throws MethodInvocationException
     * @throws Exception
     *
     *  @since Velocity v1.1
     */
    public boolean mergeTemplate( String templateName, String encoding,
                                      Context context, Writer writer )
        throws ResourceNotFoundException, ParseErrorException, MethodInvocationException, Exception
    {
        Template template = ri.getTemplate(templateName, encoding);

        if ( template == null )
        {
            String msg = "VelocityEngine.mergeTemplate() was unable to load template '"
                           + templateName + "'";
            getLog().error(msg);
            throw new ResourceNotFoundException(msg);
        }
        else
        {
            template.merge(context, writer);
            return true;
         }
    }

    /**
     *  Returns a <code>Template</code> from the Velocity
     *  resource management system.
     *
     * @param name The file name of the desired template.
     * @return     The template.
     * @throws ResourceNotFoundException if template not found
     *          from any available source.
     * @throws ParseErrorException if template cannot be parsed due
     *          to syntax (or other) error.
     * @throws Exception if an error occurs in template initialization
     */
    public Template getTemplate(String name)
        throws ResourceNotFoundException, ParseErrorException, Exception
    {
        return ri.getTemplate( name );
    }

    /**
     *  Returns a <code>Template</code> from the Velocity
     *  resource management system.
     *
     * @param name The file name of the desired template.
     * @param encoding The character encoding to use for the template.
     * @return     The template.
     * @throws ResourceNotFoundException if template not found
     *          from any available source.
     * @throws ParseErrorException if template cannot be parsed due
     *          to syntax (or other) error.
     * @throws Exception if an error occurs in template initialization
     *
     *  @since Velocity v1.1
     */
    public Template getTemplate(String name, String encoding)
        throws ResourceNotFoundException, ParseErrorException, Exception
    {
        return ri.getTemplate( name, encoding );
    }

    /**
     *   Determines if a resource is accessable via the currently
     *   configured resource loaders.
     *   <br><br>
     *   Note that the current implementation will <b>not</b>
     *   change the state of the system in any real way - so this
     *   cannot be used to pre-load the resource cache, as the
     *   previous implementation did as a side-effect.
     *   <br><br>
     *   The previous implementation exhibited extreme lazyness and
     *   sloth, and the author has been flogged.
     *
     *   @param resourceName  name of the resource to search for
     *   @return true if found, false otherwise
     *   @since 1.5
     */
    public boolean resourceExists(String resourceName)
    {
        return (ri.getLoaderNameForResource(resourceName) != null);
    }

    /**
     * @param resourceName
     * @return True if the template exists.
     * @see #resourceExists(String)
     * @deprecated Use resourceExists(String) instead.
     */
    public boolean templateExists(String resourceName)
    {
        return resourceExists(resourceName);
    }


    /**
     * Returns a convenient Log instance that wraps the current LogChute.
     * Use this to log error messages. It has the usual methods you'd expect.
     * @return A log object.
     * @since 1.5
     */
    public Log getLog()
    {
        return ri.getLog();
    }

    /**
     * @param message
     * @deprecated Use getLog() and call warn() on it.
     */
    public void warn(Object message)
    {
        getLog().warn(message);
    }

    /**
     * @param message
     * @deprecated Use getLog() and call warn() on it.
     */
    public void info(Object message)
    {
        getLog().info(message);
    }

    /**
     * @param message
     * @deprecated Use getLog() and call warn() on it.
     */
    public void error(Object message)
    {
        getLog().error(message);
    }

    /**
     * @param message
     * @deprecated Use getLog() and call warn() on it.
     */
    public void debug(Object message)
    {
        getLog().debug(message);
    }

    /**
     *  <p>
     *  Sets an application attribute (which can be any Object) that will be
     *  accessible from any component of the system that gets a
     *  RuntimeServices. This allows communication between the application
     *  environment and custom pluggable components of the Velocity engine,
     *  such as ResourceLoaders and LogChutes.
     *  </p>
     *
     *  <p>
     *  Note that there is no enforcement or rules for the key
     *  used - it is up to the application developer.  However, to
     *  help make the intermixing of components possible, using
     *  the target Class name (e.g. com.foo.bar ) as the key
     *  might help avoid collision.
     *  </p>
     *
     *  @param key object 'name' under which the object is stored
     *  @param value object to store under this key
     */
     public void setApplicationAttribute( Object key, Object value )
     {
        ri.setApplicationAttribute(key, value);
     }

     /**
      *  <p>
      *  Return an application attribute (which can be any Object)
      *  that was set by the application in order to be accessible from
      *  any component of the system that gets a RuntimeServices.
      *  This allows communication between the application
      *  environment and custom pluggable components of the
      *  Velocity engine, such as ResourceLoaders and LogChutes.
      *  </p>
      *
      *  @param key object 'name' under which the object is stored
      *  @return value object to store under this key
      * @since 1.5
      */
     public Object getApplicationAttribute( Object key )
     {
        return ri.getApplicationAttribute(key);
     }

}
