package jadex.bpmn.runtime.handler;
import jadex.bpmn.model.MActivity;
import jadex.bpmn.model.MSequenceEdge;
import jadex.bpmn.runtime.BpmnInterpreter;
import jadex.bpmn.runtime.IActivityHandler;
import jadex.bpmn.runtime.ProcessThread;
import jadex.bpmn.runtime.ProcessThreadValueFetcher;
import jadex.javaparser.IParsedExpression;
import jadex.javaparser.IValueFetcher;
import java.util.List;
/**
* Handler for xor split and join gateways.
*/
public class GatewayXORActivityHandler implements IActivityHandler
{
/**
* Execute an activity.
* @param activity The activity to execute.
* @param instance The process instance.
* @param thread The process thread.
*/
public void execute(MActivity activity, BpmnInterpreter instance, ProcessThread thread)
{
List incoming = activity.getIncomingSequenceEdges();
List outgoing = activity.getOutgoingSequenceEdges();
// Split
if(incoming!=null /* && incoming.size()==1 */ && outgoing!=null && outgoing.size()>1)
{
MSequenceEdge def = null;
IValueFetcher fetcher = new ProcessThreadValueFetcher(thread, false, instance.getValueFetcher());
for(int i=0; i<outgoing.size(); i++)
{
// Take first out edge that is satisfied and not the default edge (without condition)
MSequenceEdge edge = (MSequenceEdge)outgoing.get(i);
IParsedExpression exp = edge.getCondition();
if(exp!=null)
{
if(edge.isDefault())
throw new RuntimeException("Default edge must not have a condition: "+activity+", "+instance+", "+thread+", "+exp);
if(isValid(thread, exp, fetcher))
{
thread.setLastEdge(edge);
def = null;
break;
}
}
else
{
def = edge;
}
}
if(def!=null)
{
thread.setLastEdge(def);
}
}
// Join
else if(incoming!=null && incoming.size()>1 && outgoing!=null && outgoing.size()==1)
{
// Only one thread arrives.
thread.setLastEdge((MSequenceEdge)outgoing.get(0));
}
else
{
throw new UnsupportedOperationException("Invalid number of edges for xor split/join: "+activity+", "+instance);
}
}
/**
* Execute an activity.
* @param activity The activity to execute.
* @param instance The process instance.
* @param thread The process thread.
* @param info The info object.
*/
public void cancel(MActivity activity, BpmnInterpreter instance, ProcessThread thread)
{
}
/**
* Safely evaluate a branch expression.
*/
protected boolean isValid(ProcessThread thread, IParsedExpression exp, IValueFetcher fetcher)
{
boolean ret = false;
try
{
// System.out.println("Evaluating: "+thread.getInstance()+", "+exp.getExpressionText());
ret = ((Boolean)exp.getValue(fetcher)).booleanValue();
// System.out.println("Evaluated: "+ret);
}
catch(Exception e)
{
thread.getInstance().getLogger().warning("Error in branch condition: "+thread+", "+exp+", "+e);
// e.printStackTrace();
}
return ret;
}
}