//----------------------------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.workflow.script.selector;

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.huihoo.workflow.script.Options;
import org.huihoo.workflow.script.ScriptCompilationContext;
import org.huihoo.workflow.script.compiler.ScriptRuntimeContext;
import org.huihoo.workflow.script.runtime.SelectorScriptBase;
import org.huihoo.workflow.selector.Selector;
import org.huihoo.workflow.selector.SelectorContext;
import org.huihoo.workflow.selector.SelectorException;
import org.huihoo.workflow.server.WorkflowConfig;
import org.huihoo.workflow.server.WorkflowContext;
import org.huihoo.workflow.server.WorkflowWork;
import org.huihoo.workflow.xpdl.WorkflowCondition;
import org.huihoo.workflow.xpdl.WorkflowTransition;

public class ScriptSelectorWrapper
{
	private static Log log = LogFactory.getLog(ScriptSelectorWrapper.class);

	private Selector theSelector;
	private Class selectorClass;

	private WorkflowConfig config;
	private WorkflowTransition workflowTransition;
	private WorkflowCondition workflowCondition;
	private ScriptCompilationContext ctxt;
	private Options options;

	private boolean firstTime = true;
	private boolean reload = true;

	public ScriptSelectorWrapper(
		WorkflowConfig config,
	WorkflowTransition workflowTransition,
		WorkflowCondition workflowCondition,
		Options options,
		ScriptRuntimeContext rctxt)
		throws SelectorException, IOException
	{
		this.config = config;
		this.workflowTransition = workflowTransition;
		this.workflowCondition = workflowCondition;
		this.options = options;

		ctxt = new ScriptCompilationContext(workflowTransition,workflowCondition, options, config.getWorkflowContext(), this, rctxt);
	}

	public ScriptCompilationContext getCompilationContext()
	{
		return ctxt;
	}

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

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

					try
					{
						selectorClass = ctxt.load();
						theSelector = (Selector) selectorClass.newInstance();
					}
					catch (Exception ex1)
					{
						throw new SelectorException(ex1);
					}

					((SelectorScriptBase) theSelector).init(config);
					firstTime = false;
					reload = false;
				}
			}
		}
		return theSelector;
	}

	public WorkflowContext getWorkflowContext()
	{
		return config.getWorkflowContext();
	}

	public boolean evalute(WorkflowWork workflowWork, WorkflowTransition workflowTransition,SelectorContext context) throws SelectorException, IOException
	{
		if (ctxt.isRemoved())
		{
			throw new SelectorException("transition condition not found");
		}

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

		if (reload)
		{
			getScript();
		}

		return theSelector.evalute(workflowWork,workflowTransition, context);

	}

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