`
chenjin
  • 浏览: 163214 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

jbpm 与 工作流模式 多路选择(Multiple Choice)

    博客分类:
  • java
阅读更多
多路选择(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.     <!---->start-state>  
  5.     <state name='a'>  
  6.         <transition to='multichoice' />  
  7.     <!---->state>  
  8.     <fork name='multichoice'>  
  9.         <transition name='to b' to='b'>  
  10.             <condition>#{scenario == 1} or #{scenario >= 3}<!---->condition>  
  11.         <!---->transition>  
  12.         <transition name='to c' to='c'>  
  13.             <condition>#{scenario == 2} or #{scenario >= 3}<!---->condition>  
  14.         <!---->transition>  
  15.     <!---->fork>  
  16.     <state name='b'>  
  17.         <transition to='syncmerge' />  
  18.     <!---->state>  
  19.     <state name='c'>  
  20.         <transition to='syncmerge' />  
  21.     <!---->state>  
  22.     <join name='syncmerge'>  
  23.         <transition to='end' />  
  24.     <!---->join>  
  25. <!---->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结束, 下个例子说明.
分享到:
评论
6 楼 Bluesnails 2008-02-25  
自己懒得写,搭个顺风车回复一下吧,楼主的xml文件确实有问题(在3.2下,即使增加了end节点,也不正确,condition只有定义在decision内才有意义,而且如果多个转移满足condition条件,只会执行第一个满足条件的转移,所以对于多路转移,目前好像只能使用script,我改写的xml文件如下,已通过验证)

<?xml version="1.0" encoding="UTF-8"?>

<process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="multiChoice">
	<start-state name="start">
		<transition name="" to="a"></transition>
	</start-state>
	<state name="a">
		<event type="node-enter">
			<script>System.out.println("---enter node a--");</script>
		</event>
		<transition name="" to="multichoice"></transition>
	</state>
	<fork name="multichoice">
		<script>

			<variable name="transitionNames" access="write"></variable>
			<expression>
				transitionNames = new ArrayList(); if ( scenario == 1 )
				{ transitionNames.add( "to b" ); } else if ( scenario
				==2 ) { transitionNames.add( "to c" ); } else if
				(scenario >= 3 ) { transitionNames.add( "to b" );
				transitionNames.add( "to c" );}
			</expression>
		</script>
		<event type="node-enter">
			<script>System.out.println("---enter node fork--");</script>
		</event>
		<transition name="to b" to="b"></transition>
		<transition name="to c" to="c"></transition>
	</fork>
	<state name="b">
		<event type="node-enter">
			<script>System.out.println("---enter node b--");</script>
		</event>
		<transition name="" to="syncmerge"></transition>
	</state>
	<state name="c">
		<event type="node-enter">
			<script>System.out.println("---enter node c--");</script>
		</event>
		<transition name="" to="syncmerge"></transition>
	</state>
	<join name="syncmerge">
		<event type="node-enter">
			<script>
				System.out.println("---enter node syncmerge--");
			</script>
		</event>
		<transition name="" to="end"></transition>
	</join>
	<end-state name="end"></end-state>
</process-definition>

5 楼 chinakite 2007-02-07  
<condition>#{scenario == 1} or #{scenario >= 3}</condition>
上面这个表达式中如果==右边是字符串怎么办啊?
我测试的结果是有时好使有时不好使, 很奇怪
4 楼 chenjin 2006-12-04  
代码是有些问题, 我没有测过, 直接评自己的理解写的. jbpm3 还不是很完善. 很多东西在jira上的工作还没有完善. 比如m out of n 只能在代码中设置,  xml schema  没有同步等等.
3 楼 jeffen2006 2006-12-01  
找到原因了,你写的那个xml对应不上源文件的定义,源文件是在fork下定义一个script元素来完成的,而目前的jbpm版本不支持此种类型的持久化,下面是jbpm给出的解释:
the script in a fork is not persisted.  script in fork might be removed in later versions of jPDL
2 楼 jeffen2006 2006-11-30  
你有没有用xml来做过这个流程,我试验了一下,按照你写的xml代码:
testMultiChoiceScenario1()
选择 to_b 路径的情况
当scenario == 1
不是按照:
    start --> a --> multichoice --> b --> syncmerge --> end

而是fork成:
start --> a --> multichoice --> b --> syncmerge
                multichoice --> c
同样你后面的文章也是失败的。
很奇怪,用jbpm的这2个例子junit是成功的。难道ProcessDefinition pd = new ProcessDefinition(  
      new String[],new String[])这种写法和xml定义的不一致。请试验一下。
1 楼 jeffen2006 2006-11-30  
xml 代码少了<end-state name="end"></end-state>

相关推荐

    jBPM4工作流应用开发指南.pdf

    jBPM4作为该系列的一个版本,提供了一套完整的流程管理和执行框架,允许开发者构建灵活的工作流应用,以实现业务流程自动化。本指南由胡奇编写,旨在为开发者提供一个全面的参考,帮助他们快速学习和掌握使用jBPM4...

    JBPM5工作流引擎 S2SH+JBPM4.4开发工作流的一个完整的请假流程例子

    JBPM5工作流引擎 S2SH+JBPM4.4开发工作流的一个完整的请假流程例子。带有文档教程和所有源码+JAR包。在网上找了半天jbpm6\jbpm7的资料,都很少。所以 环境:Myeclipse2015 JDK1.7 mysql 5.0 Struts2+Spring3.1 1...

    JBPM3.2工作流开发指南

    JBPM3.2工作流开发指南 JBPM是一个扩展性很强的工作流系统,百分百用JAVA语言开发,持久层采用Hibernate实现,理论上说,只要Hibernate支持的数据库JBPM都支持。同时它还能被部署在任何一款JAVA应用服务器上。

    jbpm工作流整合

    jbpm工作流整合是一个关键的主题,它涉及到企业级业务流程管理(BPM)系统的实施与集成。jbpm是一个开源的工作流管理系统,它提供了一套全面的工具和框架,用于设计、执行、监控和优化业务流程。这个压缩包可能包含...

    jbpm工作流引擎总结文档

    jbpm工作流引擎基于J2EE的轻量级,纯java,开源的工作流管理系统。

    jBPM工作流详解

    此外,jBPM通过API和事件机制允许自定义扩展,如添加新的工作流服务或者与外部系统交互。 **4. 决策管理与规则引擎** jBPM内嵌了Drools规则引擎,允许在流程中嵌入复杂的业务决策。Drools支持基于DRD(Decision ...

    jbpm Java工作流 教程

    JBPM设计之初就考虑到了与Java环境的无缝集成,其API提供了丰富的功能,便于开发者在Java应用程序中嵌入工作流逻辑。例如: 1. **流程实例的启动**:通过调用JBPM API,可以在Java代码中启动一个流程实例。 2. **...

    基于JBPM工作流的OA办公系统

    在基于JBPM的OA办公系统中,工作流引擎负责解析流程定义,控制流程实例的执行,并与实际业务逻辑相结合,确保流程按照预设规则运行。 ### 2. JBPM的主要特点 - **可视化建模**:JBPM提供了一款名为BPMN(Business ...

    JBPM4工作流介绍.pptx

    JBPM4是一款强大的工作流管理系统,专为JavaEE开发人员设计,旨在解决复杂流程管理和变更需求。本课程适合对JavaEE开发有经验的技术人员以及流程分析师。JBPM4提供了广泛的应用场景,涵盖了关键业务流程,如订单处理...

    jBPM4工作流应用开发指南完整版带书签

    由于给出的内容是由图片格式转换而来,我们无法直接获取这部分内容的具体文字...开发者可通过这份指南获得在不同业务场景中部署和管理jBPM4工作流的深入理解与技能,进而在企业环境中实现高效和灵活的业务流程自动化。

    JBPM4工作流介绍.ppt

    本篇文章将对JBPM4工作流进行详细的介绍,涵盖工作流的概念、工作流引擎、工作流管理系统等方面的知识点。 一、工作流的概念 工作流是指在一个工作群组中,为了达成某一个共同目的而需要多人协力以串行或平行工作...

    jbpm工作流 基础视频

    jbpm工作流是一款开源的工作流程管理系统,主要用于设计、执行和管理业务流程。它结合了Java技术和BPM(Business Process Management)理念,为开发者提供了一套强大的工具,使得企业能够更有效地自动化和优化业务...

    JBPM工作流全套学习资料

    【JBPM工作流全套学习资料】是一份详尽的学习资源,涵盖了JBPM工作流系统的基础到高级知识。JBPM(Java Business Process Management)是开源的企业级工作流管理系统,它允许开发者设计、部署和执行业务流程。这个...

    jBPM4工作流应用开发指南.rar

    **jBPM4工作流应用开发指南** jBPM4是一款强大的开源工作流管理系统,它为业务流程管理和执行提供了一套完整的解决方案。本指南将深入探讨jBPM4的特性和使用方法,帮助开发者实现高效的工作流应用开发。 **1. jBPM...

    jbpm开发指南 jbpm 工作流 自定义

    jbpm开发指南 jbpm开发指南 jbpm 工作流 自定义

    jbpm4.3 工作流实例 java

    【jbpm4.3 工作流实例与Java结合详解】 在信息技术领域,工作流管理系统(Workflow Management System,简称WfMS)是用于自动化业务流程的软件系统。jbpm(Business Process Management)是一款开源的工作流引擎,...

    jBPM4工作流示例jbpmDemo

    **jbPM4工作流示例jbpmDemo**是一款基于jBPM4的工作流管理系统实例,旨在帮助用户深入了解和掌握jBPM4工作流引擎的使用方法。jBPM4是一款强大的开源工作流管理系统,它提供了流程建模、执行以及监控等功能,广泛应用...

    jBPM4工作流应用开发指南最新版_01.pdf

    jBPM4工作流应用开发指南最新版_01 JBPM4详细指南,非常实用,我就是通过这个文档学习起来的,相当受益

    jBPM4工作流应用开发指南(高清,带书签)

    jBPM4工作流应用开发指南,很详细很全面,高清带书签的,适合新手入门

    jbpm工作流详解

    jBPM与其他工作流框架如OSWorkflow、ActiveBPEL、YAWL等相比,以其开源、灵活和强大的Java支持而受到开发者青睐。在企业级应用中,jBPM常被用于OA(办公自动化)、CRM(客户关系管理)、ERP(企业资源规划)等系统中...

Global site tag (gtag.js) - Google Analytics