原创作者: chenjin   阅读:7860次   评论:0条   更新时间:2011-05-26    
多路选择(Multiple Choice)

Description A point in the workow process where, based on a decision or workow control
data, a number of branches are chosen.

描述:    在工作流程中某一点,当某一个活动执行结束后,根据一个decision 或者 工作流控制数据, 可以选择一个或多个分支执行.

同义词:Conditional routing, selection, OR-split.


java 代码
 
  1. /* 
  2.  * JBoss, Home of Professional Open Source 
  3.  * Copyright 2005, JBoss Inc., and individual contributors as indicated 
  4.  * by the @authors tag. See the copyright.txt in the distribution for a 
  5.  * full listing of individual contributors. 
  6.  * 
  7.  * This is free software; you can redistribute it and/or modify it 
  8.  * under the terms of the GNU Lesser General Public License as 
  9.  * published by the Free Software Foundation; either version 2.1 of 
  10.  * the License, or (at your option) any later version. 
  11.  * 
  12.  * This software is distributed in the hope that it will be useful, 
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
  15.  * Lesser General Public License for more details. 
  16.  * 
  17.  * You should have received a copy of the GNU Lesser General Public 
  18.  * License along with this software; if not, write to the Free 
  19.  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 
  20.  * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 
  21.  */  
  22. package org.jbpm.jpdl.patterns;  
  23.   
  24. import junit.framework.*;  
  25.   
  26. import org.jbpm.context.def.*;  
  27. import org.jbpm.context.exe.*;  
  28. import org.jbpm.graph.action.Script;  
  29. import org.jbpm.graph.def.*;  
  30. import org.jbpm.graph.exe.*;  
  31. import org.jbpm.graph.node.*;  
  32.   
  33. /** 
  34.  * http://is.tm.tue.nl/research/patterns/download/swf/pat_6.swf 
  35.  */  
  36. public class Wfp06MultiChoiceTest extends TestCase {  
  37.     
  38.   private static ProcessDefinition multiChoiceProcessDefinition = createMultiChoiceProcessDefinition();  
  39.   
  40.   public static ProcessDefinition createMultiChoiceProcessDefinition() {  
  41.     ProcessDefinition pd = new ProcessDefinition(  
  42.       new String[]{"start-state start",  
  43.                    "state a",  
  44.                    "fork multichoice",  
  45.                    "state b",  
  46.                    "state c",  
  47.                    "join syncmerge",  
  48.                    "end-state end"},   
  49.       new String[]{"start --> a",  
  50.                    "a --> multichoice",  
  51.                    "multichoice --to b--> b",  
  52.                    "multichoice --to c--> c",  
  53.                    "b --> syncmerge",  
  54.                    "c --> syncmerge",  
  55.                    "syncmerge --> end"});  
  56.       
  57.     // create the script  
  58.     Script script = new Script();  
  59.     script.addVariableAccess(new VariableAccess("transitionNames","write",null));  
  60.     script.setExpression(  
  61.       "transitionNames = new ArrayList();" +  
  62.       "if ( scenario == 1 ) {" +  
  63.       "  transitionNames.add( \"to b\" );" +  
  64.       "} else if ( scenario == 2 ) {" +  
  65.       "  transitionNames.add( \"to c\" );" +  
  66.       "} else if ( scenario >= 3 ) {" +  
  67.       "  transitionNames.add( \"to b\" );" +  
  68.       "  transitionNames.add( \"to c\" );" +  
  69.       "}" );  
  70.       
  71.     // put the script in the multichoice handler  
  72.     Fork fork = (Fork) pd.getNode("multichoice");  
  73.     fork.setScript( script );  
  74.       
  75.     pd.addDefinition( new ContextDefinition() );  
  76.       
  77.     return pd;  
  78.   }  
  79.   
  80.   public void testMultiChoiceScenario1() {  
  81.     ProcessDefinition pd = multiChoiceProcessDefinition;  
  82.     Token root = executeScenario(pd, 1);  
  83.     Token tokenB = root.getChild("to b"); // the default token names are extracted from the leaving transitions   
  84.     Token tokenC = root.getChild("to c"); // the default token names are extracted from the leaving transitions   
  85.     assertNotNull( tokenB );  
  86.     assertNull( tokenC );  
  87.     assertEquals( 1, root.getChildren().size() );  
  88.     assertSame( pd.getNode("b"), tokenB.getNode() );  
  89.   }  
  90.   
  91.   public void testMultiChoiceScenario2() {  
  92.     ProcessDefinition pd = multiChoiceProcessDefinition;  
  93.     Token root = executeScenario(pd, 2);  
  94.     Token tokenB = root.getChild("to b"); // the default token names are extracted from the leaving transitions   
  95.     Token tokenC = root.getChild("to c"); // the default token names are extracted from the leaving transitions   
  96.     assertNull( tokenB );  
  97.     assertNotNull( tokenC );  
  98.     assertEquals( 1, root.getChildren().size() );  
  99.     assertSame( pd.getNode("c"), tokenC.getNode() );  
  100.   }  
  101.   
  102.   public void testMultiChoiceScenario3() {  
  103.     ProcessDefinition pd = multiChoiceProcessDefinition;  
  104.     Token root = executeScenario(pd, 3);  
  105.     Token tokenB = root.getChild("to b"); // the default token names are extracted from the leaving transitions   
  106.     Token tokenC = root.getChild("to c"); // the default token names are extracted from the leaving transitions   
  107.     assertNotNull( tokenB );  
  108.     assertNotNull( tokenC );  
  109.     assertEquals( 2, root.getChildren().size() );  
  110.     assertSame( pd.getNode("b"), tokenB.getNode() );  
  111.     assertSame( pd.getNode("c"), tokenC.getNode() );  
  112.   }  
  113.   
  114.   public static Token executeScenario(ProcessDefinition pd, int scenario) {  
  115.     ProcessInstance pi = new ProcessInstance( pd );  
  116.     ContextInstance ci = (ContextInstance) pi.getInstance( ContextInstance.class );  
  117.     pi.signal();  
  118.     Token root = pi.getRootToken();  
  119.     assertSame( pd.getNode("a"), root.getNode() );  
  120.     ci.setVariable( "scenario"new Integer(scenario) );  
  121.     root.signal();  
  122.     return root;  
  123.   }  
  124. }  


流程定义文件: 

xml 代码
 
  1. <process-definition name="process">  
  2.     <start-state name='start'>  
  3.         <transition to='a' />  
  4.     <!--</span-->start-state>  
  5.     <state name='a'>  
  6.         <transition to='multichoice' />  
  7.     <!--</span-->state>  
  8.     <fork name='multichoice'>  
  9.         <transition name='to b' to='b'>  
  10.             <condition>#{scenario == 1} or #{scenario >= 3}<!--</span-->condition>  
  11.         <!--</span-->transition>  
  12.         <transition name='to c' to='c'>  
  13.             <condition>#{scenario == 2} or #{scenario >= 3}<!--</span-->condition>  
  14.         <!--</span-->transition>  
  15.     <!--</span-->fork>  
  16.     <state name='b'>  
  17.         <transition to='syncmerge' />  
  18.     <!--</span-->state>  
  19.     <state name='c'>  
  20.         <transition to='syncmerge' />  
  21.     <!--</span-->state>  
  22.     <join name='syncmerge'>  
  23.         <transition to='end' />  
  24.     <!--</span-->join>  
  25. <!--</span-->process-definition>  




testMultiChoiceScenario1()

选择 to_b 路径的情况

节点流程执行顺序

    当scenario == 1

    start --> a --> multichoice --> b --> syncmerge --> end

testMultiChoiceScenario2()


选择 to_c 路径的情况

节点流程执行顺序

    当scenario == 2

    start --> a --> multichoice --> c --> syncmerge --> end

testMultiChoiceScenario3()


选择 to_b,to_c 两个路径的情况

节点流程执行顺序

    当scenario == 3

    start --> a --> multichoice --> b --> syncmerge --> end
                            multichoice --> c  --> syncmerge 

本例中流程以synchronizing Merge结束, 下个例子说明.
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

文章信息

Global site tag (gtag.js) - Google Analytics