//----------------------------BEGIN LICENSE----------------------------
/* 
 * Willow : the Open Source WorkFlow Project
 * Distributable under GNU LGPL license by gun.org
 *
 * Copyright (C) 2004-2010 huihoo.org 
 * Copyright (C) 2004-2010  ZosaTapo <dertyang@hotmail.com> 
 * 
 * ====================================================================
 * Project Homepage : http://www.huihoo.org/willow
 * Source Forge     : http://sourceforge.net/projects/huihoo
 * Mailing list     : willow@lists.sourceforge.net 
 */
//----------------------------END  LICENSE----------------------------

package org.huihoo.willow;

import org.huihoo.workflow.selector.Selector;
import org.huihoo.workflow.selector.SelectorException;
import org.huihoo.workflow.selector.UnavailableException;

/**
 * A <b>Wrapper</b> is a Container that represents an individual script
 * definition from the deployment descriptor of the workflow application.  It
 * provides a convenient mechanism to use Interceptors that see every single
 * request to the script represented by this definition.
 * <p>
 * Implementations of Wrapper are responsible for managing the script life
 * cycle for their underlying script class, including calling init() and
 * destroy() at appropriate times, as well as respecting the existence of
 * the SingleThreadModel declaration on the script class itself.
 * <p>
 * The parent Container attached to a Wrapper will generally be an
 * implementation of Context, representing the script context (and
 * therefore the workflow application) within which this script executes.
 * <p>
 * Child Containers are not allowed on Wrapper implementations, so the
 * <code>addChild()</code> method should throw an
 * <code>IllegalArgumentException</code>.
 *
 */

public interface Wrapper extends Container
{

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

	/**
	 * Return the available date/time for this script, in milliseconds since
	 * the epoch.  If this date/time is in the future, any request for this
	 * script will return an SC_SERVICE_UNAVAILABLE error.  If it is zero,
	 * the script is currently available.  A value equal to Long.MAX_VALUE
	 * is considered to mean that unavailability is permanent.
	 */
	public long getAvailable();

	/**
	 * Set the available date/time for this script, in milliseconds since the
	 * epoch.  If this date/time is in the future, any request for this script
	 * will return an SC_SERVICE_UNAVAILABLE error.  A value equal to
	 * Long.MAX_VALUE is considered to mean that unavailability is permanent.
	 *
	 * @param available The new available date/time
	 */
	public void setAvailable(long available);

	/**
	 * Return the load-on-startup order value (negative value means
	 * load on first call).
	 */
	public int getLoadOnStartup();

	/**
	 * Set the load-on-startup order value (negative value means
	 * load on first call).
	 *
	 * @param value New load-on-startup value
	 */
	public void setLoadOnStartup(int value);

	/**
	 * Return the fully qualified script class name for this script.
	 */
	public String getSelectorClass();

	/**
	 * Set the fully qualified script class name for this script.
	 *
	 * @param servletClass Script class name
	 */
	public void setSelectorClass(String scriptClass);

	/**
	 * Is this script currently unavailable?
	 */
	public boolean isUnavailable();

	// --------------------------------------------------------- Public Methods

	/**
	 * Add a new script initialization parameter for this script.
	 *
	 * @param name Name of this initialization parameter to add
	 * @param value Value of this initialization parameter to add
	 */
	public void addInitParameter(String name, String value);

	/**
	 * Add a mapping associated with the Wrapper.
	 * 
	 * @param pattern The new wrapper mapping
	 */
	public void addMapping(String mapping);

	/**
	 * Allocate an initialized instance of this Script that is ready to have
	 * its <code>service()</code> method called.  
	 *
	 * @exception ScriptException if the script init() method threw
	 *  an exception
	 * @exception ScriptException if a loading error occurs
	 */
	public Selector allocate() throws SelectorException;

	/**
	 * Return this previously allocated script to the pool of available
	 * instances.  If this script class does not implement SingleThreadModel,
	 * no action is actually required.
	 *
	 * @param script The script to be returned
	 *
	 * @exception ScriptException if a deallocation error occurs
	 */
	public void deallocate(Selector script) throws SelectorException;

	/**
	 * Return the value for the specified initialization parameter name,
	 * if any; otherwise return <code>null</code>.
	 *
	 * @param name Name of the requested initialization parameter
	 */
	public String findInitParameter(String name);

	/**
	 * Return the names of all defined initialization parameters for this
	 * script.
	 */
	public String[] findInitParameters();

	/**
	 * Return the mappings associated with this wrapper.
	 */
	public String[] findMappings();

	/**
	 * Load and initialize an instance of this script, if there is not already
	 * at least one initialized instance.  This can be used, for example, to
	 * load servlets that are marked in the deployment descriptor to be loaded
	 * at server startup time.
	 *
	 * @exception ScriptException if the script init() method threw
	 *  an exception
	 * @exception ScriptException if some other loading problem occurs
	 */
	public void load() throws SelectorException;

	/**
	 * Remove the specified initialization parameter from this script.
	 *
	 * @param name Name of the initialization parameter to remove
	 */
	public void removeInitParameter(String name);

	/**
	 * Remove a mapping associated with the wrapper.
	 *
	 * @param mapping The pattern to remove
	 */
	public void removeMapping(String mapping);

	/**
	 * Process an UnavailableException, marking this script as unavailable
	 * for the specified amount of time.
	 *
	 * @param unavailable The exception that occurred, or <code>null</code>
	 *  to mark this script as permanently unavailable
	 */
	public void unavailable(UnavailableException unavailable);

	/**
	 * Unload all initialized instances of this script, after calling the
	 * <code>destroy()</code> method for each instance.  This can be used,
	 * for example, prior to shutting down the entire script engine, or
	 * prior to reloading all of the classes from the Loader associated with
	 * our Loader's repository.
	 *
	 * @exception ScriptException if an unload error occurs
	 */
	public void unload() throws SelectorException;
}