script.read(scriptElement, jpdlReader);
}
}
public void execute(ExecutionContext executionContext) {
Token token = executionContext.getToken();
// phase one: collect all the transitionNames
Collection<?> transitionNames = null;
// by default, the fork spawns a token for each leaving transition
if (script==null) {
transitionNames = getLeavingTransitionsMap().keySet();
} else { // a script is specified
// if a script is specified, use that script to calculate the set
// of leaving transitions to be used for forking tokens.
Map<String, Object> outputMap = script.eval(token);
if (outputMap.size()==1) {
Object result = outputMap.values().iterator().next();
if (result instanceof Collection) {
transitionNames = (Collection<?>) result;
}
}
if (transitionNames==null) {
throw new JbpmException("script for fork '"+name+"' should produce one collection (in one writable variable): "+transitionNames);
}
}
// TODO add some way of blocking the current token here and disable that blocking when the join reactivates this token
// Then an exception can be thrown by in case someone tries to signal a token that is waiting in a fork.
// Suspend and resume can NOT be used for this since that will also suspend any related timers, tasks and messages...
// So a separate kind of blocking should be created for this.
// @see also http://jira.jboss.com/jira/browse/JBPM-642
// phase two: create forked tokens for the collected transition names
Map<String, Token> forkedTokens = new HashMap<String, Token>();
for (Object element : transitionNames) {
String transitionName = (String) element;
Token childToken = createForkedToken(token, transitionName);
forkedTokens.put(transitionName, childToken);
}
// phase three: launch child tokens from the fork over the given transitions
for (Map.Entry<String, Token> forkedToken : forkedTokens.entrySet()) {
Token childToken = forkedToken.getValue();
String leavingTransitionName = forkedToken.getKey();
ExecutionContext childExecutionContext = new ExecutionContext(childToken);
if (leavingTransitionName!=null) {
leave(childExecutionContext, leavingTransitionName);
} else {