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

import java.rmi.RemoteException;
import java.util.Map;

import org.huihoo.workflow.WorkflowException;
import org.huihoo.workflow.WorkflowTransaction;
import org.huihoo.workflow.WorkflowUtilities;
import org.huihoo.workflow.desktop.WorkflowImplementation;
import org.huihoo.workflow.event.WorkEvent;
import org.huihoo.workflow.event.WorkEventListener;
import org.huihoo.workflow.server.WorkflowCase;
import org.huihoo.workflow.server.WorkflowDispatcher;
import org.huihoo.workflow.server.WorkflowWork;
import org.huihoo.workflow.server.WorkflowXPDL;
import org.huihoo.workflow.server.WorkflowXPDLRepository;
import org.huihoo.workflow.store.WorkflowCaseDatabase;
import org.huihoo.workflow.store.WorkflowWorkValidator;
import org.huihoo.workflow.xpdl.WorkflowActivity;
import org.huihoo.workflow.xpdl.WorkflowPackage;
import org.huihoo.workflow.xpdl.WorkflowProcess;

public class RemoteDispatcherImpl extends WorkflowRemoteObject implements WorkflowDispatcher
{
	protected WorkflowImplementation workflow;
	protected String WorkflowTemplate_ID;

	public RemoteDispatcherImpl(WorkflowImplementation workflow, WorkflowXPDL workflowTemplate) throws RemoteException
	{
		super();

		this.workflow = workflow;
		this.WorkflowTemplate_ID = workflowTemplate.getWorkflowPackage().getUUID();

	}

	public WorkflowImplementation getWorkflowImplementation()
	{
		return workflow;
	}

	//------------------------------------------------------------------------------------
	// WorkflowDispatcher core plain utilities   
	//------------------------------------------------------------------------------------                                        
	public boolean accept(String workflowProcess, String workflowCase, String work)
		throws WorkflowException, RemoteException
	{
		WorkflowXPDL workflowtemplate = WorkflowXPDLRepository.getInstance().findWorkflowXPDL(WorkflowTemplate_ID);

		WorkflowCaseDatabase casedatabase = workflowtemplate.getWorkflowTemplate().getCaseDatabase();
		WorkflowPackage workflowpackage = workflow.getWorkflowPackage();
		WorkflowProcess workflowprocess = workflowpackage.findWorkflowProcess(workflowProcess);

		WorkflowTransaction transaction = null;
		WorkflowWork workflowwork = null;
		try
		{
			transaction = casedatabase.getWorkflowTransaction();

			WorkflowCase workflowcase =
				casedatabase.findCase(workflow.getDesktop().getSession(), transaction, workflowprocess, workflowCase);
			workflowwork =
				casedatabase.findWork(
					workflow.getDesktop().getSession(),
					transaction,
					workflowprocess,
					workflowcase,
					work);

			transaction.commit();
		}
		catch (WorkflowException we)
		{
			WorkflowUtilities.rollbackNoThrow(transaction);
			throw we;
		}
		finally
		{
			WorkflowUtilities.releaseNoThrow(transaction);
		}

		return accept(workflowprocess, workflowwork);
	}

	public boolean submit(String workflowProcess, String workflowCase, String work)
		throws WorkflowException, RemoteException
	{
		WorkflowXPDL workflowtemplate = WorkflowXPDLRepository.getInstance().findWorkflowXPDL(WorkflowTemplate_ID);

		WorkflowCaseDatabase casedatabase = workflowtemplate.getWorkflowTemplate().getCaseDatabase();
		WorkflowPackage workflowpackage = workflow.getWorkflowPackage();
		WorkflowProcess workflowprocess = workflowpackage.findWorkflowProcess(workflowProcess);

		WorkflowTransaction transaction = null;
		WorkflowWork workflowwork = null;
		try
		{
			transaction = casedatabase.getWorkflowTransaction();

			WorkflowCase workflowcase =
				casedatabase.findCase(workflow.getDesktop().getSession(), transaction, workflowprocess, workflowCase);
			workflowwork =
				casedatabase.findWork(
					workflow.getDesktop().getSession(),
					transaction,
					workflowprocess,
					workflowcase,
					work);

			transaction.commit();
		}
		catch (WorkflowException we)
		{
			WorkflowUtilities.rollbackNoThrow(transaction);
			throw we;
		}
		finally
		{
			WorkflowUtilities.releaseNoThrow(transaction);
		}

		return submit(workflowprocess, workflowwork);
	}
	public boolean resubmit(String workflowProcess, String workflowCase, String work)
		throws WorkflowException, RemoteException
	{
		WorkflowXPDL workflowtemplate = WorkflowXPDLRepository.getInstance().findWorkflowXPDL(WorkflowTemplate_ID);

		WorkflowCaseDatabase casedatabase = workflowtemplate.getWorkflowTemplate().getCaseDatabase();
		WorkflowPackage workflowpackage = workflow.getWorkflowPackage();
		WorkflowProcess workflowprocess = workflowpackage.findWorkflowProcess(workflowProcess);

		WorkflowTransaction transaction = null;
		WorkflowWork workflowwork = null;
		try
		{
			transaction = casedatabase.getWorkflowTransaction();

			WorkflowCase workflowcase =
				casedatabase.findCase(workflow.getDesktop().getSession(), transaction, workflowprocess, workflowCase);
			workflowwork =
				casedatabase.findWork(
					workflow.getDesktop().getSession(),
					transaction,
					workflowprocess,
					workflowcase,
					work);

			transaction.commit();
		}
		catch (WorkflowException we)
		{
			WorkflowUtilities.rollbackNoThrow(transaction);
			throw we;
		}
		finally
		{
			WorkflowUtilities.releaseNoThrow(transaction);
		}

		return resubmit(workflowprocess, workflowwork);
	}

	public boolean backtrack(String workflowProcess, String workflowCase, String work)
		throws WorkflowException, RemoteException
	{
		WorkflowXPDL workflowtemplate = WorkflowXPDLRepository.getInstance().findWorkflowXPDL(WorkflowTemplate_ID);

		WorkflowCaseDatabase casedatabase = workflowtemplate.getWorkflowTemplate().getCaseDatabase();
		WorkflowPackage workflowpackage = workflow.getWorkflowPackage();
		WorkflowProcess workflowprocess = workflowpackage.findWorkflowProcess(workflowProcess);

		WorkflowTransaction transaction = null;
		WorkflowWork workflowwork = null;
		try
		{
			transaction = casedatabase.getWorkflowTransaction();

			WorkflowCase workflowcase =
				casedatabase.findCase(workflow.getDesktop().getSession(), transaction, workflowprocess, workflowCase);
			workflowwork =
				casedatabase.findWork(
					workflow.getDesktop().getSession(),
					transaction,
					workflowprocess,
					workflowcase,
					work);

			transaction.commit();
		}
		catch (WorkflowException we)
		{
			WorkflowUtilities.rollbackNoThrow(transaction);
			throw we;
		}
		finally
		{
			WorkflowUtilities.releaseNoThrow(transaction);
		}

		return backtrack(workflowprocess, workflowwork);
	}
	

	public boolean reverse(String workflowProcess, String workflowCase, String work)
		throws WorkflowException, RemoteException
	{
		WorkflowXPDL workflowtemplate = WorkflowXPDLRepository.getInstance().findWorkflowXPDL(WorkflowTemplate_ID);

		WorkflowCaseDatabase casedatabase = workflowtemplate.getWorkflowTemplate().getCaseDatabase();
		WorkflowPackage workflowpackage = workflow.getWorkflowPackage();
		WorkflowProcess workflowprocess = workflowpackage.findWorkflowProcess(workflowProcess);

		WorkflowTransaction transaction = null;
		WorkflowWork workflowwork = null;
		try
		{
			transaction = casedatabase.getWorkflowTransaction();

			WorkflowCase workflowcase =
				casedatabase.findCase(workflow.getDesktop().getSession(), transaction, workflowprocess, workflowCase);
			workflowwork =
				casedatabase.findWork(
					workflow.getDesktop().getSession(),
					transaction,
					workflowprocess,
					workflowcase,
					work);

			transaction.commit();
		}
		catch (WorkflowException we)
		{
			WorkflowUtilities.rollbackNoThrow(transaction);
			throw we;
		}
		finally
		{
			WorkflowUtilities.releaseNoThrow(transaction);
		}

		return reverse(workflowprocess, workflowwork);
	}

	public boolean fetch(String workflowProcess, String workflowCase, String work)
		throws WorkflowException, RemoteException
	{
		WorkflowXPDL workflowtemplate = WorkflowXPDLRepository.getInstance().findWorkflowXPDL(WorkflowTemplate_ID);

		WorkflowCaseDatabase casedatabase = workflowtemplate.getWorkflowTemplate().getCaseDatabase();
		WorkflowPackage workflowpackage = workflow.getWorkflowPackage();
		WorkflowProcess workflowprocess = workflowpackage.findWorkflowProcess(workflowProcess);

		WorkflowTransaction transaction = null;
		WorkflowWork workflowwork = null;
		try
		{
			transaction = casedatabase.getWorkflowTransaction();

			WorkflowCase workflowcase =
				casedatabase.findCase(workflow.getDesktop().getSession(), transaction, workflowprocess, workflowCase);
			workflowwork =
				casedatabase.findWork(
					workflow.getDesktop().getSession(),
					transaction,
					workflowprocess,
					workflowcase,
					work);

			transaction.commit();
		}
		catch (WorkflowException we)
		{
			WorkflowUtilities.rollbackNoThrow(transaction);
			throw we;
		}
		finally
		{
			WorkflowUtilities.releaseNoThrow(transaction);
		}

		return fetch(workflowprocess, workflowwork);
	}


	//如果用户显式的提供了分发的后继工作项的处理者的话，要求后继分发转移必须唯一
	//此接口属于高级功能，请遵循约束根据需要调用
	public boolean submit(String workflowProcess, String workflowCase, String work, Map userObject)
		throws WorkflowException, RemoteException
	{
		WorkflowXPDL workflowtemplate = WorkflowXPDLRepository.getInstance().findWorkflowXPDL(WorkflowTemplate_ID);

		WorkflowCaseDatabase casedatabase = workflowtemplate.getWorkflowTemplate().getCaseDatabase();
		WorkflowPackage workflowpackage = workflow.getWorkflowPackage();
		WorkflowProcess workflowprocess = workflowpackage.findWorkflowProcess(workflowProcess);

		WorkflowTransaction transaction = null;
		WorkflowWork workflowwork = null;
		try
		{
			transaction = casedatabase.getWorkflowTransaction();

			WorkflowCase workflowcase =
				casedatabase.findCase(workflow.getDesktop().getSession(), transaction, workflowprocess, workflowCase);
			workflowwork =
				casedatabase.findWork(
					workflow.getDesktop().getSession(),
					transaction,
					workflowprocess,
					workflowcase,
					work);

			transaction.commit();
		}
		catch (WorkflowException we)
		{
			WorkflowUtilities.rollbackNoThrow(transaction);
			throw we;
		}
		finally
		{
			WorkflowUtilities.releaseNoThrow(transaction);
		}

		return submit(workflowprocess, workflowwork, userObject);
	}

	//------------------------------------------------------------------------------------
	// WorkflowDispatcher core utilities   
	//------------------------------------------------------------------------------------                                        
	public boolean accept(WorkflowProcess workflowProcess, WorkflowWork work) throws WorkflowException
	{

		WorkflowWorkValidator workValidator =
			WorkflowXPDLRepository.getInstance().findWorkflowXPDL(WorkflowTemplate_ID).getWorkflowTemplate().getWorkValidator();
		if (workValidator != null)
		{
			workValidator.checkAccept(workflow.getDesktop().getSession(), work);
		}

		//------------------------------------------------------------
		//------------------------------------------------------------
		WorkflowActivity activity = work.getActivity();
		WorkEvent event = new WorkEvent(work, WorkEvent.ACCEPTED);
		WorkEventListener[] listeners = activity.getWorkListeners();
		for (int i = 0; i < listeners.length; ++i)
		{
			listeners[i].enter(event);
		}

		boolean resultBoolean = false;
		try
		{
			WorkflowTransaction transaction = null;
			try
			{
				transaction =
					WorkflowXPDLRepository
						.getInstance()
						.findWorkflowXPDL(WorkflowTemplate_ID)
						.getWorkflowTemplate()
						.getCaseDatabase()
						.getWorkflowTransaction();
				resultBoolean =
					WorkflowXPDLRepository.getInstance().findWorkflowXPDL(WorkflowTemplate_ID).getWorkflowTemplate().getWorkflowDispatcher().accept(
						workflow.getDesktop().getSession(),
						transaction,
						workflowProcess,
						work);
				transaction.commit();

			}
			catch (WorkflowException we)
			{
				WorkflowUtilities.rollbackNoThrow(transaction);
				throw we;
			}
			finally
			{
				WorkflowUtilities.releaseNoThrow(transaction);
			}

			for (int i = 0; i < listeners.length; ++i)
			{
				listeners[i].leave(event);
			}

		}
		catch (WorkflowException ex)
		{

			for (int i = 0; i < listeners.length; ++i)
			{
				listeners[i].notify(event, ex);
			}

			throw ex;
		}

		return resultBoolean;
	}

	public boolean submit(WorkflowProcess workflowProcess, WorkflowWork work) throws WorkflowException
	{

		WorkflowWorkValidator workValidator =
			WorkflowXPDLRepository.getInstance().findWorkflowXPDL(WorkflowTemplate_ID).getWorkflowTemplate().getWorkValidator();
		if (workValidator != null)
		{
			workValidator.checkSubmit(workflow.getDesktop().getSession(), work);
		}

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

		WorkflowActivity workflowActivity = work.getActivity();
		WorkEvent event = new WorkEvent(work, WorkEvent.SUBMITED);
		WorkEventListener[] listeners = workflowActivity.getWorkListeners();
		for (int i = 0; i < listeners.length; ++i)
		{
			listeners[i].enter(event);
		}

		boolean resultBoolean = false;
		try
		{
			WorkflowTransaction transaction = null;
			try
			{
				transaction =
					WorkflowXPDLRepository
						.getInstance()
						.findWorkflowXPDL(WorkflowTemplate_ID)
						.getWorkflowTemplate()
						.getCaseDatabase()
						.getWorkflowTransaction();
				resultBoolean =
					WorkflowXPDLRepository.getInstance().findWorkflowXPDL(WorkflowTemplate_ID).getWorkflowTemplate().getWorkflowDispatcher().submit(
						workflow.getDesktop().getSession(),
						transaction,
						workflowProcess,
						work,null);
				transaction.commit();

			}
			catch (WorkflowException we)
			{
				WorkflowUtilities.rollbackNoThrow(transaction);
				throw we;
			}
			finally
			{
				WorkflowUtilities.releaseNoThrow(transaction);
			}

			for (int i = 0; i < listeners.length; ++i)
			{
				listeners[i].leave(event);
			}
		}
		catch (WorkflowException ex)
		{

			for (int i = 0; i < listeners.length; ++i)
			{
				listeners[i].notify(event, ex);
			}

			throw ex;
		}

		return resultBoolean;
	}

	public boolean resubmit(WorkflowProcess workflowProcess, WorkflowWork work) throws WorkflowException
	{

		WorkflowWorkValidator workValidator =
			WorkflowXPDLRepository.getInstance().findWorkflowXPDL(WorkflowTemplate_ID).getWorkflowTemplate().getWorkValidator();
		if (workValidator != null)
		{
			workValidator.checkSubmit(workflow.getDesktop().getSession(), work);
		}

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

		WorkflowActivity workflowActivity = work.getActivity();
		WorkEvent event = new WorkEvent(work, WorkEvent.SUBMITED);
		WorkEventListener[] listeners = workflowActivity.getWorkListeners();
		for (int i = 0; i < listeners.length; ++i)
		{
			listeners[i].enter(event);
		}

		boolean resultBoolean = false;
		try
		{
			WorkflowTransaction transaction = null;
			try
			{
				transaction =
					WorkflowXPDLRepository
						.getInstance()
						.findWorkflowXPDL(WorkflowTemplate_ID)
						.getWorkflowTemplate()
						.getCaseDatabase()
						.getWorkflowTransaction();
				resultBoolean =
					WorkflowXPDLRepository.getInstance().findWorkflowXPDL(WorkflowTemplate_ID).getWorkflowTemplate().getWorkflowDispatcher().resubmit(
						workflow.getDesktop().getSession(),
						transaction,
						workflowProcess,
						work);
				transaction.commit();

			}
			catch (WorkflowException we)
			{
				WorkflowUtilities.rollbackNoThrow(transaction);
				throw we;
			}
			finally
			{
				WorkflowUtilities.releaseNoThrow(transaction);
			}

			for (int i = 0; i < listeners.length; ++i)
			{
				listeners[i].leave(event);
			}
		}
		catch (WorkflowException ex)
		{

			for (int i = 0; i < listeners.length; ++i)
			{
				listeners[i].notify(event, ex);
			}

			throw ex;
		}

		return resultBoolean;
	}
	
	public boolean fetch(WorkflowProcess workflowProcess, WorkflowWork work) throws WorkflowException
	{
		WorkflowWorkValidator workValidator =
			WorkflowXPDLRepository.getInstance().findWorkflowXPDL(WorkflowTemplate_ID).getWorkflowTemplate().getWorkValidator();
		if (workValidator != null)
		{
			workValidator.checkSubmit(workflow.getDesktop().getSession(), work);
		}

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

		WorkflowActivity workflowActivity = work.getActivity();
		WorkEvent event = new WorkEvent(work, WorkEvent.FETCHED);
		WorkEventListener[] listeners = workflowActivity.getWorkListeners();
		for (int i = 0; i < listeners.length; ++i)
		{
			listeners[i].enter(event);
		}

		boolean resultBoolean = false;
		try
		{
			WorkflowTransaction transaction = null;
			try
			{
				transaction =
					WorkflowXPDLRepository
						.getInstance()
						.findWorkflowXPDL(WorkflowTemplate_ID)
						.getWorkflowTemplate()
						.getCaseDatabase()
						.getWorkflowTransaction();
				resultBoolean =
					WorkflowXPDLRepository.getInstance().findWorkflowXPDL(WorkflowTemplate_ID).getWorkflowTemplate().getWorkflowDispatcher().fetch(
						workflow.getDesktop().getSession(),
						transaction,
						workflowProcess,
						work);
				transaction.commit();

			}
			catch (WorkflowException we)
			{
				WorkflowUtilities.rollbackNoThrow(transaction);
				throw we;
			}
			finally
			{
				WorkflowUtilities.releaseNoThrow(transaction);
			}

			for (int i = 0; i < listeners.length; ++i)
			{
				listeners[i].leave(event);
			}
		}
		catch (WorkflowException ex)
		{

			for (int i = 0; i < listeners.length; ++i)
			{
				listeners[i].notify(event, ex);
			}
			throw ex;
		}

		return resultBoolean;
	}

	public boolean backtrack(WorkflowProcess workflowProcess, WorkflowWork work) throws WorkflowException
	{

		WorkflowWorkValidator workValidator =
			WorkflowXPDLRepository.getInstance().findWorkflowXPDL(WorkflowTemplate_ID).getWorkflowTemplate().getWorkValidator();
		if (workValidator != null)
		{
			workValidator.checkBacktrack(workflow.getDesktop().getSession(), work);
		}

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

		WorkflowActivity workflowActivity = work.getActivity();
		WorkEvent event = new WorkEvent(work, WorkEvent.BACKTRACKED);
		WorkEventListener[] listeners = workflowActivity.getWorkListeners();
		for (int i = 0; i < listeners.length; ++i)
		{
			listeners[i].enter(event);
		}

		boolean resultBoolean = false;
		try
		{
			WorkflowTransaction transaction = null;
			try
			{
				transaction =
					WorkflowXPDLRepository
						.getInstance()
						.findWorkflowXPDL(WorkflowTemplate_ID)
						.getWorkflowTemplate()
						.getCaseDatabase()
						.getWorkflowTransaction();
				resultBoolean =
					WorkflowXPDLRepository.getInstance().findWorkflowXPDL(WorkflowTemplate_ID).getWorkflowTemplate().getWorkflowDispatcher().backtrack(
						workflow.getDesktop().getSession(),
						transaction,
						workflowProcess,
						work);
				transaction.commit();

			}
			catch (WorkflowException we)
			{
				WorkflowUtilities.rollbackNoThrow(transaction);
				throw we;
			}
			finally
			{
				WorkflowUtilities.releaseNoThrow(transaction);
			}

			for (int i = 0; i < listeners.length; ++i)
			{
				listeners[i].leave(event);
			}
		}
		catch (WorkflowException ex)
		{
			for (int i = 0; i < listeners.length; ++i)
			{
				listeners[i].notify(event, ex);
			}
			throw ex;
		}

		return resultBoolean;
	}

	public boolean reverse(WorkflowProcess workflowProcess, WorkflowWork work) throws WorkflowException
	{

		WorkflowWorkValidator workValidator =
			WorkflowXPDLRepository.getInstance().findWorkflowXPDL(WorkflowTemplate_ID).getWorkflowTemplate().getWorkValidator();
		if (workValidator != null)
		{
			workValidator.checkBacktrack(workflow.getDesktop().getSession(), work);
		}

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

		WorkflowActivity workflowActivity = work.getActivity();
		WorkEvent event = new WorkEvent(work, WorkEvent.BACKTRACKED);
		WorkEventListener[] listeners = workflowActivity.getWorkListeners();
		for (int i = 0; i < listeners.length; ++i)
		{
			listeners[i].enter(event);
		}

		boolean resultBoolean = false;
		try
		{
			WorkflowTransaction transaction = null;
			try
			{
				transaction =
					WorkflowXPDLRepository
						.getInstance()
						.findWorkflowXPDL(WorkflowTemplate_ID)
						.getWorkflowTemplate()
						.getCaseDatabase()
						.getWorkflowTransaction();
				resultBoolean =
					WorkflowXPDLRepository.getInstance().findWorkflowXPDL(WorkflowTemplate_ID).getWorkflowTemplate().getWorkflowDispatcher().reverse(
						workflow.getDesktop().getSession(),
						transaction,
						workflowProcess,
						work);
				transaction.commit();

			}
			catch (WorkflowException we)
			{
				WorkflowUtilities.rollbackNoThrow(transaction);
				throw we;
			}
			finally
			{
				WorkflowUtilities.releaseNoThrow(transaction);
			}

			for (int i = 0; i < listeners.length; ++i)
			{
				listeners[i].leave(event);
			}
		}
		catch (WorkflowException ex)
		{
			for (int i = 0; i < listeners.length; ++i)
			{
				listeners[i].notify(event, ex);
			}
			throw ex;
		}

		return resultBoolean;
	}
	
	//如果用户显式的提供了分发的后继工作项的处理者的话，要求后继分发转移必须唯一
	//此接口属于高级功能，请遵循约束根据需要调用
	public boolean submit(WorkflowProcess workflowProcess, WorkflowWork work, Map userObject)
		throws WorkflowException
	{

		WorkflowWorkValidator workValidator =
			WorkflowXPDLRepository.getInstance().findWorkflowXPDL(WorkflowTemplate_ID).getWorkflowTemplate().getWorkValidator();
		if (workValidator != null)
		{
			workValidator.checkBacktrack(workflow.getDesktop().getSession(), work);
		}

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

		WorkflowActivity activity = work.getActivity();
		WorkEvent event = new WorkEvent(work, WorkEvent.BACKTRACKED);
		WorkEventListener[] listeners = activity.getWorkListeners();
		for (int i = 0; i < listeners.length; ++i)
		{
			listeners[i].enter(event);
		}

		boolean resultBoolean = false;
		try
		{
			WorkflowTransaction transaction = null;
			try
			{
				transaction =
					WorkflowXPDLRepository
						.getInstance()
						.findWorkflowXPDL(WorkflowTemplate_ID)
						.getWorkflowTemplate()
						.getCaseDatabase()
						.getWorkflowTransaction();
				resultBoolean =
					WorkflowXPDLRepository.getInstance().findWorkflowXPDL(WorkflowTemplate_ID).getWorkflowTemplate().getWorkflowDispatcher().submit(
						workflow.getDesktop().getSession(),
						transaction,
						workflowProcess,
						work,
						userObject);
				transaction.commit();

			}
			catch (WorkflowException we)
			{
				WorkflowUtilities.rollbackNoThrow(transaction);
				throw we;
			}
			finally
			{
				WorkflowUtilities.releaseNoThrow(transaction);
			}

			for (int i = 0; i < listeners.length; ++i)
			{
				listeners[i].leave(event);
			}

		}
		catch (WorkflowException ex)
		{

			for (int i = 0; i < listeners.length; ++i)
			{
				listeners[i].notify(event, ex);
			}
			throw ex;
		}
		return resultBoolean;

	}
}
