3 Replies Latest reply on Apr 12, 2006 5:41 PM by Ronald van Kuijk

    conditional Fork: execute NOT all transition

    Hannes Stillerich Newbie

      (jbpm:3.0.2)
      Hi there,
      I have following use case:

      +----+
       |Fork|
       +----+
       / \
       +--------+ +-------+
       |State A | |State B|
       +--------+ +-------+
       \ /
       +-----+
       |Join |
       +-----+

      Now I want to execute all 4 possible cases:
      A B
      0 0: execute none of the (task)nodes, proceed with join
      0 1: execute only State B
      1 0: execute only State A
      1 1: execute both States

      There are controller variables in the context that decide whether the state should be executed or not.

      So I tried a simple conditioned transition:
      <fork name="fork1>
       <transition name="toStateA" to="State A">
       <script>
       <expression>isStateA.booleanValue()</expression>
       </script>
       </transition>
       <transition name="toStateB" to="State B">
       <script>
       <expression>isStateB.booleanValue()</expression>
       </script>
       </transition>
       </fork>

      But the beanshell scripts dont get considered and it forks into both transitions.
      When you throw a look on the Fork class:
      public void execute(ExecutionContext executionContext) {
       Token token = executionContext.getToken();
       Node forkNode = token.getNode();
      
       // phase one: collect all the transitionNames
       Collection transitionNames = null;
       List forkedTokens = new ArrayList();
      
       // by default, the fork spawns a token for each leaving transition
       if (script==null) {
       transitionNames = forkNode.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 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 RuntimeException("script for fork '"+name+"' should produce one collection (in one writable variable): "+transitionNames);
       }
       }
      ...

      You see, that there has to be directly a script under the fork-node, and that script has to have a list of the transition names as output.

      Ok, I could bybas this trouble by using several decision nodes (in this case 1 with 4 leaving Transition: ->A, ->B, ->fork, ->the node after the join), but if have more than 2 childs, it would quickly get very complicated.

      So, what do you recommend? Maybe its still possible with the the current (3.0.2) API/JPDL, maybe I missed some point.