//----------------------------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.impl.store.util;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.huihoo.workflow.WorkflowException;
import org.huihoo.workflow.rules.RuntimeContext;
import org.huihoo.workflow.rules.interpretor.ScriptInterpretor;
import org.huihoo.workflow.runtime.WorkflowCase;
import org.huihoo.workflow.runtime.WorkflowCaseContext;
import org.huihoo.workflow.runtime.WorkflowService;
import org.huihoo.workflow.runtime.WorkflowWork;
import org.huihoo.workflow.store.persistent.UserTransaction;
import org.huihoo.workflow.store.spi.SpiCaseDatabase;
import org.huihoo.workflow.usermodel.WorkflowParticipant;
import org.huihoo.workflow.xpdl.WorkflowActivity;
import org.huihoo.workflow.xpdl.WorkflowCondition;
import org.huihoo.workflow.xpdl.WorkflowPackage;
import org.huihoo.workflow.xpdl.WorkflowParameter;
import org.huihoo.workflow.xpdl.WorkflowProcess;
import org.huihoo.workflow.xpdl.WorkflowTransition;
import org.huihoo.workflow.xpdl.activity.SplitType;
/**
* @author reic
*
* To change the template for this generated type comment go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
public class OutTransitionFilter
{
private static Log log = LogFactory.getLog(OutTransitionFilter.class);
public static List filterOutTransition(
WorkflowService workflowService,
WorkflowParticipant operator,
SpiCaseDatabase caseDatabase,
UserTransaction userTransaction,
WorkflowWork workflowWork)
throws WorkflowException
{
WorkflowActivity workActivity = workflowWork.getWorkflowActivity();
//========================================================================
// ����� (����ֻ��һ��Out WorkflowTransition��WorkflowActivity)
//========================================================================
List disp_outTrans = workActivity.getOutgoingTransitions();
if (disp_outTrans.size() == 1)
{
List filter_outTrans = new ArrayList();
filter_outTrans.add(disp_outTrans.get(0));
log.debug("Only one outTransition,select it unconditionally.["+workActivity+"]" );
return filter_outTrans;
}
SplitType splitType = workActivity.getSplitType();
if (SplitType.SPLIT_AND.equals(splitType))
{
return filterOutTransition_andSplit(workflowService, operator, caseDatabase, userTransaction, workflowWork);
}
else if (SplitType.SPLIT_XOR.equals(splitType))
{
return filterOutTransition_xorSplit(workflowService, operator, caseDatabase, userTransaction, workflowWork);
}
//-----------Default Behavior---------------
return filterOutTransition_orSplit(workflowService, operator, caseDatabase, userTransaction, workflowWork);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public static List filterOutTransition_andSplit(
WorkflowService workflowService,
WorkflowParticipant operator,
SpiCaseDatabase caseDatabase,
UserTransaction userTransaction,
WorkflowWork workflowWork)
throws WorkflowException
{
log.debug(" SplitType.SPLIT_AND select all out transitions");
List outTrans = new ArrayList();
WorkflowActivity workActivity = workflowWork.getWorkflowActivity();
List transList = workActivity.getOutgoingTransitions();
int sizeTrans = transList.size();
for (int i = 0; i < sizeTrans; ++i)
{
outTrans.add(transList.get(i));
}
return outTrans;
}
public static List filterOutTransition_xorSplit(
WorkflowService workflowService,
WorkflowParticipant operator,
SpiCaseDatabase caseDatabase,
UserTransaction userTransaction,
WorkflowWork workflowWork)
throws WorkflowException
{
log.debug(" SplitType.SPLIT_XOR select (single) specific out transitions");
List outTrans = new ArrayList();
WorkflowActivity workActivity = workflowWork.getWorkflowActivity();
List transList = workActivity.getOutgoingTransitions();
WorkflowProcess workflowProcess = workActivity.getWorkflowProcess();
WorkflowPackage workflowPackage = workflowProcess.getWorkflowPackage();
ScriptInterpretor interpretor = workflowService.getScriptInterpretor();
RuntimeContext context = null;
WorkflowCase workflowCase = workflowWork.getWorkflowCase();
WorkflowCaseContext caseContext = workflowCase.getCaseContext();
int sizeTrans = transList.size();
if (sizeTrans > 0)
{
WorkflowTransition transition = null;
for (int i = 0; i < sizeTrans; ++i)
{
if (context != null)
{
context.clear();
}
transition = (WorkflowTransition) transList.get(i);
context = genParameterConext(caseContext, transition);
WorkflowCondition conditon = transition.getCondition();
if (conditon == null)
{
log.debug("[filterOutTransition_xorSplit] ACCEPT transition:" + transition.getInfo() + " | condition: " + conditon);
outTrans.add(transition);
break;
}
else
{
if (interpretor.evalute(workflowWork, transition, context))
{
log.debug("[filterOutTransition_xorSplit] ACCEPT transition:" + transition.getInfo() + " | condition: " + conditon);
try
{
updateContext(workflowProcess, operator, caseDatabase, userTransaction, context, caseContext, false);
}
catch (Throwable ex)
{
throw new WorkflowException(ex);
}
outTrans.add(transition);
break;
}
else
{
log.debug("[filterOutTransition_xorSplit] REJECT transition:" + transition.getInfo() + " | condition: " + conditon);
}
}
} //~end for (int i = 0; i < sizeTrans; ++i)
try
{
updateContext(workflowProcess, operator, caseDatabase, userTransaction, context, caseContext, true);
}
catch (Throwable ex)
{
throw new WorkflowException(ex);
}
}
return outTrans;
}
//------------------Default behavior------------------
public static List filterOutTransition_orSplit(
WorkflowService workflowService,
WorkflowParticipant operator,
SpiCaseDatabase caseDatabase,
UserTransaction userTransaction,
WorkflowWork workflowWork)
throws WorkflowException
{
log.debug(" SplitType.SPLIT_OR select out transitions based on condition evaluation");
List outTrans = new ArrayList();
WorkflowActivity workActivity = workflowWork.getWorkflowActivity();
List transList = workActivity.getOutgoingTransitions();
WorkflowProcess workflowProcess = workActivity.getWorkflowProcess();
WorkflowPackage workflowPackage = workflowProcess.getWorkflowPackage();
ScriptInterpretor interpretor = workflowService.getScriptInterpretor();
RuntimeContext context = null;
WorkflowCase workflowCase = workflowWork.getWorkflowCase();
WorkflowCaseContext caseContext = workflowCase.getCaseContext();
List rejectTrans = new ArrayList();
int sizeTrans = transList.size();
if (sizeTrans > 0)
{
WorkflowTransition transition = null;
for (int i = 0; i < sizeTrans; ++i)
{
if (context != null)
{
context.clear();
}
transition = (WorkflowTransition) transList.get(i);
context = genParameterConext(caseContext, transition);
WorkflowCondition conditon = transition.getCondition();
if (conditon == null)
{
outTrans.add(transition);
log.debug("[filterOutTransition_orSplit] ACCEPT transition:" + transition.getInfo() + " | condition: " + conditon);
}
else
{
if (interpretor.evalute(workflowWork, transition, context))
{
log.debug("[filterOutTransition_orSplit] ACCEPT transition:" + transition.getInfo() + " | condition: " + conditon);
try
{
updateContext(workflowProcess, operator, caseDatabase, userTransaction, context, caseContext, false);
}
catch (Throwable ex)
{
throw new WorkflowException(ex);
}
outTrans.add(transition);
}
else
{
log.debug("[filterOutTransition_orSplit] REJECT transition:" + transition.getInfo() + " | condition: " + conditon);
rejectTrans.add(transition);
} //~end if (interpretor.evalute(workflowWork, transition, context))
} //~end if (conditon == null)
} //~end for (int i = 0; i < sizeTrans; ++i)
updateContext(workflowProcess, operator, caseDatabase, userTransaction, context, caseContext, true);
try
{
JoinActivityFinder.signalOrJoinActivity(userTransaction, workflowWork, outTrans, rejectTrans);
}
catch (SQLException e)
{
throw new WorkflowException(e);
}
}
return outTrans;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
private static RuntimeContext genParameterConext(
WorkflowCaseContext caseContext,
WorkflowTransition workflowTransition)
throws WorkflowException
{
RuntimeContext scriptContext = new RuntimeContext();
Enumeration enum = caseContext.getParameterNames();
while (enum.hasMoreElements())
{
String paramName = (String) enum.nextElement();
try
{
fillContext(scriptContext, caseContext.getParameterByName(paramName).copy());
}
catch (CloneNotSupportedException e)
{
throw new WorkflowException(e);
}
}
return scriptContext;
}
private static void fillContext(RuntimeContext context, WorkflowParameter worlflowParameter) throws WorkflowException
{
context.putParameter(worlflowParameter);
}
private static void updateContext(
WorkflowProcess workflowProcess,
WorkflowParticipant operator,
SpiCaseDatabase caseDatabase,
UserTransaction userTransaction,
RuntimeContext context,
WorkflowCaseContext caseContext,
boolean update)
throws WorkflowException
{
Enumeration enum = caseContext.getParameterNames();
WorkflowParameter workflowParmeter = null;
WorkflowParameter scriptParameter = null;
while (enum.hasMoreElements())
{
String paramName = (String) enum.nextElement();
workflowParmeter = caseContext.getParameterByName(paramName);
scriptParameter = (WorkflowParameter) context.getParameterByName(paramName);
Object value = workflowParmeter.getValue();
Object otherValue = scriptParameter.getValue();
if ((value != null && !value.equals(otherValue)) || (otherValue != null && !otherValue.equals(value)))
{
workflowParmeter.setValue(scriptParameter.getValue());
if (update)
{
caseDatabase.updateWorkflowParameter(
workflowProcess,
operator,
userTransaction,
caseContext.getWorkflowCase(),
workflowParmeter);
}
}
}
}
}