//----------------------------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.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.huihoo.workflow.script.Constants;
import org.huihoo.workflow.script.EmbeddedScriptOptions;
import org.huihoo.workflow.script.Options;
import org.huihoo.workflow.script.compiler.ScriptRuntimeContext;
import org.huihoo.workflow.script.util.StringManager;
import org.huihoo.workflow.selector.GenericSelector;
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 ScriptSelector extends GenericSelector
{
	// Logger
	protected static Log log = LogFactory.getLog(ScriptSelector.class);
	/**
		 * The string manager for this package.
		 */
	protected static StringManager sm = StringManager.getManager(Constants.RESOURCE_BUNDLE_BASE);

	protected WorkflowContext context;
	protected WorkflowConfig config;
	protected Options options;
	protected ScriptRuntimeContext rctxt;

	public void init(WorkflowConfig config) throws SelectorException
	{
		super.init(config);
		this.config = config;
		this.context = config.getWorkflowContext();

		this.options = new EmbeddedScriptOptions(config, context);

		// Initialize the Script Runtime Context
		rctxt = new ScriptRuntimeContext(context, options);

		if (log.isDebugEnabled())
		{
			log.debug(sm.getString("script.message.scratch.dir.is", options.getScratchDir().toString()));
			log.debug(sm.getString("script.message.dont.modify.servlets"));
		}
	}

	public boolean evalute(WorkflowWork workflowWork, WorkflowTransition workflowTransition, SelectorContext context)
		throws SelectorException, IOException
	{
		return evaluteWorkflowCondition(
			workflowWork,
			workflowTransition,
			context,
			workflowTransition.getWorkflowCondition());
	}

	public void destroy()
	{
		if (log.isDebugEnabled())
		{
			log.debug("ScriptSelector.destroy()");
		}

		rctxt.destroy();
	}

	//-------------------------------------------------------- 

	public boolean evaluteWorkflowCondition(
		WorkflowWork workflowWork,
		WorkflowTransition workflowTransition,
		SelectorContext context,
		WorkflowCondition workflowCondition)
		throws SelectorException, IOException
	{
		if (workflowCondition == null
			|| workflowCondition.getContent() == null
			|| workflowCondition.getContent().trim().length() == 0)
		{
			//transition unconditionally
			return true;
		}

		ScriptSelectorWrapper wrapper = (ScriptSelectorWrapper) rctxt.getWrapper(workflowCondition);
		if (wrapper == null)
		{
			// First check if the requested script exists, to avoid
			// creating unnecessary directories and files.

			synchronized (this)
			{
				wrapper = (ScriptSelectorWrapper) rctxt.getWrapper(workflowCondition);
				if (wrapper == null)
				{
					wrapper = new ScriptSelectorWrapper(config, workflowTransition,workflowCondition, options, rctxt);
					rctxt.addWrapper(workflowCondition, wrapper);
				}
			}
		}

		return wrapper.evalute(workflowWork, workflowTransition,context);
	}
}