children stay active after join [token.getActiveChildren()]
atsurfer Feb 7, 2006 3:33 AMHello,
The following graph produces the problem:
<?xml version="1.0" encoding="UTF-8"?> <process-definition xmlns="http://jbpm.org/3/jpdl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jbpm.org/3/jpdl http://jbpm.org/xsd/jpdl-3.0.xsd" name="simple"> <start-state name="start"> <transition name="tr1" to="state1"></transition> </start-state> <state name="left"> <transition name="tr1" to="join1"></transition> </state> <end-state name="end"></end-state> <state name="right"> <transition name="tr2" to="join1"></transition> </state> <fork name="fork1"> <transition name="tr1" to="left"></transition> <transition name="tr2" to="right"></transition> </fork> <join name="join1"> <transition name="tr1" to="state2"></transition> </join> <state name="state1"> <transition name="tr1" to="fork1"></transition> </state> <state name="state2"> <transition name="tr1" to="end"></transition> </state> </process-definition>
I am using the following code:
package com.sample;
import java.util.Iterator;
import java.util.Map;
import junit.framework.TestCase;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.graph.exe.Token;
import org.jbpm.graph.node.Join;
public class SimpleProcessTest extends TestCase {
private ProcessInstance processInstance = null;
public ProcessInstance getProcessInstance() {
return processInstance;
}
public void setProcessInstance(ProcessInstance processInstance) {
this.processInstance = processInstance;
}
public void testSimpleProcess() throws Exception {
// Extract a process definition from the processdefinition.xml file.
ProcessDefinition definition = ProcessDefinition
.parseXmlResource("simple.par/processdefinition.xml");
// Create an instance of the process definition.
ProcessInstance instance = new ProcessInstance(definition);
this.setProcessInstance(instance);
this.signalProcess("tr1");
this.signalProcess("tr1");
this.signalProcess("tr1");
this.signalProcess("tr1");
this.signalProcess("tr2");
this.signalProcess("tr2");
this.signalProcess("tr2");
this.signalProcess("tr1");
}
public void signalProcess(String signal) {
if (signal != null) {
System.out.println("signal : " + signal);
ProcessInstance processInstance = this.getProcessInstance();
this.signalTokens(processInstance.getRootToken(), signal);
System.out.println("----------------------");
} else {
System.out.println("signal = null\n");
}
}
public void signalTokens(Token token, String signal) {
Map activeChildrenMap = token.getActiveChildren();
// if (token.hasActiveChildren())
if (activeChildrenMap.isEmpty() == false) {
System.out.println("token has active children\n");
Iterator itr = activeChildrenMap.values().iterator();
while (itr.hasNext()) {
Token signalToken = (Token) itr.next();
if ((signalToken.getNode() instanceof Join)==false)
signalTokens(signalToken, signal);
else
System.out.println("it's a join\n");
}
} else {
// token itself must be active
System.out.println("token name : " + token.getName());
System.out.println("node name : " + token.getNode().getName());
Map leavingTransitions = token.getNode().getLeavingTransitionsMap();
for (Iterator it = leavingTransitions.entrySet().iterator(); it
.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
String key = (String) entry.getKey();
System.out.println("leaving transition : " + key);
if (key.compareTo(signal) == 0) {
System.out.println("[signalling transition]");
token.signal(signal);
break;
}
}
System.out.println();
}
}
}
the output is the following:
09:24:22,275 DEBUG GraphElement : event 'process-start' on 'ProcessDefinition(simple)' for 'Token(/)'
signal : tr1
token name : null
node name : start
leaving transition : tr1
[signalling transition]
09:24:22,284 DEBUG GraphElement : event 'before-signal' on 'StartState(start)' for 'Token(/)'
09:24:22,287 DEBUG GraphElement : event 'node-leave' on 'StartState(start)' for 'Token(/)'
09:24:22,294 DEBUG GraphElement : event 'transition' on 'Transition(tr1)' for 'Token(/)'
09:24:22,296 DEBUG GraphElement : event 'node-enter' on 'State(state1)' for 'Token(/)'
09:24:22,298 DEBUG GraphElement : event 'after-signal' on 'StartState(start)' for 'Token(/)'
----------------------
signal : tr1
token name : null
node name : state1
leaving transition : tr1
[signalling transition]
09:24:22,306 DEBUG GraphElement : event 'before-signal' on 'State(state1)' for 'Token(/)'
09:24:22,308 DEBUG GraphElement : event 'node-leave' on 'State(state1)' for 'Token(/)'
09:24:22,310 DEBUG GraphElement : event 'transition' on 'Transition(tr1)' for 'Token(/)'
09:24:22,311 DEBUG GraphElement : event 'node-enter' on 'Fork(fork1)' for 'Token(/)'
09:24:22,314 DEBUG GraphElement : event 'node-leave' on 'Fork(fork1)' for 'Token(/tr1)'
09:24:22,317 DEBUG GraphElement : event 'transition' on 'Transition(tr1)' for 'Token(/tr1)'
09:24:22,319 DEBUG GraphElement : event 'node-enter' on 'State(left)' for 'Token(/tr1)'
09:24:22,322 DEBUG GraphElement : event 'node-leave' on 'Fork(fork1)' for 'Token(/tr2)'
09:24:22,323 DEBUG GraphElement : event 'transition' on 'Transition(tr2)' for 'Token(/tr2)'
09:24:22,327 DEBUG GraphElement : event 'node-enter' on 'State(right)' for 'Token(/tr2)'
09:24:22,331 DEBUG GraphElement : event 'after-signal' on 'State(state1)' for 'Token(/)'
----------------------
signal : tr1
token has active children
token name : tr1
node name : left
leaving transition : tr1
[signalling transition]
09:24:22,340 DEBUG GraphElement : event 'before-signal' on 'State(left)' for 'Token(/tr1)'
09:24:22,341 DEBUG GraphElement : event 'node-leave' on 'State(left)' for 'Token(/tr1)'
09:24:22,342 DEBUG GraphElement : event 'transition' on 'Transition(tr1)' for 'Token(/tr1)'
09:24:22,344 DEBUG GraphElement : event 'node-enter' on 'Join(join1)' for 'Token(/tr1)'
09:24:22,346 DEBUG Join : join will not yet reactivate parent: found concurrent token 'Token(/tr2)'
09:24:22,347 DEBUG GraphElement : event 'after-signal' on 'State(left)' for 'Token(/tr1)'
token name : tr2
node name : right
leaving transition : tr2
----------------------
signal : tr1
token has active children
it's a join
token name : tr2
node name : right
leaving transition : tr2
----------------------
signal : tr2
token has active children
it's a join
token name : tr2
node name : right
leaving transition : tr2
[signalling transition]
09:24:22,374 DEBUG GraphElement : event 'before-signal' on 'State(right)' for 'Token(/tr2)'
09:24:22,375 DEBUG GraphElement : event 'node-leave' on 'State(right)' for 'Token(/tr2)'
09:24:22,376 DEBUG GraphElement : event 'transition' on 'Transition(tr2)' for 'Token(/tr2)'
09:24:22,378 DEBUG GraphElement : event 'node-enter' on 'Join(join1)' for 'Token(/tr2)'
09:24:22,380 DEBUG GraphElement : event 'node-leave' on 'Join(join1)' for 'Token(/)'
09:24:22,382 DEBUG GraphElement : event 'transition' on 'Transition(tr1)' for 'Token(/)'
09:24:22,423 DEBUG GraphElement : event 'node-enter' on 'State(state2)' for 'Token(/)'
09:24:22,424 DEBUG GraphElement : event 'after-signal' on 'State(right)' for 'Token(/tr2)'
----------------------
signal : tr2
token has active children
it's a join
it's a join
----------------------
signal : tr2
token has active children
it's a join
it's a join
----------------------
signal : tr1
token has active children
it's a join
it's a join
----------------------
How can I resolve this and have a generic method to signal a graph with a named signal so any active token that has a named transition with the nam of the signal is signalled.
Dank bij voorbaat.