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.