/*
 * Created on 2004-6-13
 *
 * To change the template for this generated file go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */
package workflow.script.interpretor;

import java.io.FileNotFoundException;
import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import workflow.script.Options;
import workflow.script.ParameterContext;
import workflow.script.ScriptCompilationContext;
import workflow.script.ScriptException;
import workflow.script.compiler.ScriptRuntimeContext;
import workflow.script.core.Script;
import workflow.script.core.ScriptContext;
import workflow.wfmc.rtm.WorkflowWork;
import workflow.wfmc.xpdl.WorkflowTransition;

/**
 * @author reic
 *
 * To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */
public class ScriptWrapper
{

	// Logger
	private static Log log = LogFactory.getLog(ScriptWrapper.class);

	private Script theScript;	
	private Class scriptClass;

	private ScriptContext scriptContext;
	private WorkflowTransition workflowTransition;
	private ScriptCompilationContext ctxt;
	private Options options;
	private boolean firstTime = true;
	private boolean reload = true;

	private int tripCount;

	/*
	 * ScriptScriptWrapper for WFS scripts.
	 */
	ScriptWrapper(
	ScriptContext scriptContext,
		WorkflowTransition workflowTransition,
		Options options,
		ScriptRuntimeContext rctxt)
		throws ScriptException
	{

		this.scriptContext = scriptContext;
		this.workflowTransition = workflowTransition;
		this.options = options;

		ctxt =
			new ScriptCompilationContext(workflowTransition, options, scriptContext, this,rctxt);
	}

	public ScriptCompilationContext getServletEngineContext()
	{
		return ctxt;
	}

	public void setReload(boolean reload)
	{
		this.reload = reload;
	}

	public Script getServlet() throws ScriptException, IOException, FileNotFoundException
	{
		if (reload)
		{
			synchronized (this)
			{
				// Synchronizing on jsw enables simultaneous loading
				// of different pages, but not the same page.
				if (reload)
				{
					// This is to maintain the original protocol.
					destroy();

					try
					{
						scriptClass = ctxt.load();
						theScript = (Script) scriptClass.newInstance();
					}
					catch (Exception ex1)
					{
						throw new ScriptException(ex1);
					}

					theScript.init(scriptContext, workflowTransition);
					firstTime = false;
					reload = false;
				}
			}
		}
		return theScript;
	}

	public ScriptContext getServletContext()
	{
		return this.scriptContext;
	}


	public int incTripCount()
	{
		return tripCount++;
	}

	public int decTripCount()
	{
		return tripCount--;
	}

	public boolean evalute(WorkflowWork workflowWork, WorkflowTransition workflowTransition,ParameterContext paramContext)
		throws ScriptException
	{
		try
		{

			if (ctxt.isRemoved())
			{
				throw new FileNotFoundException(workflowTransition.getScriptFileName());
			}


			if (firstTime)
			{
				synchronized (this)
				{
					ctxt.compile();
				}
			}

			if (reload)
			{
				getServlet();
			}


			return theScript.evalute(workflowWork,paramContext);

		}
		catch(ScriptException ex)
		{
			throw ex;
		}
		catch (Exception ex)
		{
			ScriptException newEx=new ScriptException(ex.getMessage());
			newEx.initCause(ex);
			
			throw newEx;
		}
		
	}

	public void destroy()
	{
		if (theScript != null)
		{
			theScript.destroy();
		}
	}
}
