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

jbpm 与 工作流模式 鉴别器(Discriminator)

    博客分类:
  • java
阅读更多
鉴别器(Discriminator)
Description :    The discriminator is a point in a workow process that waits for one of the
incoming branches to complete before activating the subsequent activity. From that moment on
it waits for all remaining branches to complete and \ignores" them. Once all incoming branches
have been triggered, it resets itself so that it can be triggered again (which is important
otherwise it could not really be used in the context of a loop).


描述:多分支汇聚的时候,只有一个分支可以激活所属任务,这个任务激活以后,其他分支的
到来都会被忽略。
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.TestCase;  
  25.   
  26. import org.jbpm.graph.def.ProcessDefinition;  
  27. import org.jbpm.graph.exe.Token;  
  28. import org.jbpm.graph.node.Join;  
  29.   
  30. /** 
  31.  * http://is.tm.tue.nl/research/patterns/download/swf/pat_9.swf 
  32.  */  
  33. public class Wfp09DiscriminatorTest extends TestCase {  
  34.   
  35.   private static ProcessDefinition discriminatorProcessDefinition = createDiscriminatorProcessDefinition();  
  36.   
  37.   public static ProcessDefinition createDiscriminatorProcessDefinition() {  
  38.     ProcessDefinition pd = createSynchronizingDiscriminatorProcessDefinition();  
  39.       
  40.     // configure the join as a discriminator  
  41.     Join join = (Join) pd.getNode("discriminator");  
  42.     join.setDiscriminator(true);  
  43.       
  44.     return pd;  
  45.   }  
  46.   
  47.   private static ProcessDefinition synchronizingdiscriminatorProcessDefinition = createSynchronizingDiscriminatorProcessDefinition();  
  48.   
  49.   public static ProcessDefinition createSynchronizingDiscriminatorProcessDefinition() {  
  50.     ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(  
  51.       "<process-definition>" +  
  52.       "  <start-state name='start'>" +  
  53.       "    <transition to='a' />" +  
  54.       "  </start-state>" +  
  55.       "  <state name='a'>" +  
  56.       "    <transition to='multichoice' />" +  
  57.       "  </state>" +  
  58.       "  <fork name='multichoice'>" +  
  59.       "    <script>" +  
  60.       "      <variable name='transitionNames' access='write' />" +  
  61.       "      <expression>" +  
  62.       "        transitionNames = new ArrayList();" +  
  63.       "        if ( scenario == 1 ) {" +  
  64.       "          transitionNames.add( \"to b\" );" +  
  65.       "        } else if ( scenario == 2 ) {" +  
  66.       "          transitionNames.add( \"to c\" );" +  
  67.       "        } else if ( scenario >= 3 ) {" +  
  68.       "          transitionNames.add( \"to b\" );" +  
  69.       "          transitionNames.add( \"to c\" );" +  
  70.       "        }" +  
  71.       "      </expression>" +  
  72.       "    </script>" +  
  73.       "    <transition name='to b' to='b' />" +  
  74.       "    <transition name='to c' to='c' />" +  
  75.       "  </fork>" +  
  76.       "  <state name='b'>" +  
  77.       "    <transition to='discriminator' />" +  
  78.       "  </state>" +  
  79.       "  <state name='c'>" +  
  80.       "    <transition to='discriminator' />" +  
  81.       "  </state>" +  
  82.       "  <join name='discriminator'>" +  
  83.       "    <transition to='d' />" +  
  84.       "  </join>" +  
  85.       "  <state name='d' />" +  
  86.       "</process-definition>"  
  87.     );  
  88.             
  89.     return processDefinition;  
  90.   }  
  91.   
  92.   public void testDiscriminatorScenario1() {  
  93.     ProcessDefinition pd = discriminatorProcessDefinition;  
  94.     Token root = Wfp06MultiChoiceTest.executeScenario(pd,1);  
  95.     Token tokenB = root.getChild("to b");   
  96.   
  97.     tokenB.signal();  
  98.     assertSame( pd.getNode("d"), root.getNode() );  
  99.     assertSame( pd.getNode("discriminator"), tokenB.getNode() );  
  100.   }  
  101.     
  102.   public void testDiscriminatorScenario2() {  
  103.     ProcessDefinition pd = discriminatorProcessDefinition;  
  104.     Token root = Wfp06MultiChoiceTest.executeScenario(pd,2);  
  105.     Token tokenC = root.getChild("to c");   
  106.   
  107.     tokenC.signal();  
  108.     assertSame( pd.getNode("d"), root.getNode() );  
  109.     assertSame( pd.getNode("discriminator"), tokenC.getNode() );  
  110.   }  
  111.     
  112.   public void testDiscriminatorScenario3() {  
  113.     ProcessDefinition pd = discriminatorProcessDefinition;  
  114.     Token root = Wfp06MultiChoiceTest.executeScenario(pd,3);  
  115.     Token tokenB = root.getChild("to b");   
  116.     Token tokenC = root.getChild("to c");   
  117.   
  118.     tokenB.signal();  
  119.     assertSame( pd.getNode("d"), root.getNode() );  
  120.     assertSame( pd.getNode("discriminator"), tokenB.getNode() );  
  121.     assertSame( pd.getNode("c"), tokenC.getNode() );  
  122.   
  123.     tokenC.signal();  
  124.     assertSame( pd.getNode("d"), root.getNode() );  
  125.     assertSame( pd.getNode("discriminator"), tokenB.getNode() );  
  126.     assertSame( pd.getNode("discriminator"), tokenC.getNode() );  
  127.   }  
  128.     
  129.   public void testDiscriminatorScenario4() {  
  130.     ProcessDefinition pd = discriminatorProcessDefinition;  
  131.     Token root = Wfp06MultiChoiceTest.executeScenario(pd,4);  
  132.     Token tokenB = root.getChild("to b");   
  133.     Token tokenC = root.getChild("to c");   
  134.   
  135.     tokenC.signal();  
  136.     assertSame( pd.getNode("d"), root.getNode() );  
  137.     assertSame( pd.getNode("b"), tokenB.getNode() );  
  138.     assertSame( pd.getNode("discriminator"), tokenC.getNode() );  
  139.   
  140.     tokenB.signal();  
  141.     assertSame( pd.getNode("d"), root.getNode() );  
  142.     assertSame( pd.getNode("discriminator"), tokenB.getNode() );  
  143.     assertSame( pd.getNode("discriminator"), tokenC.getNode() );  
  144.   }  
  145.   
  146.   public void testDiscriminatorScenario5() {  
  147.     ProcessDefinition pd = synchronizingdiscriminatorProcessDefinition;  
  148.     Token root = Wfp06MultiChoiceTest.executeScenario(pd,5);  
  149.     Token tokenB = root.getChild("to b");   
  150.     Token tokenC = root.getChild("to c");   
  151.   
  152.     tokenB.signal();  
  153.     assertSame( pd.getNode("multichoice"), root.getNode() );  
  154.     assertSame( pd.getNode("discriminator"), tokenB.getNode() );  
  155.     assertSame( pd.getNode("c"), tokenC.getNode() );  
  156.   
  157.     tokenC.signal();  
  158.     assertSame( pd.getNode("d"), root.getNode() );  
  159.     assertSame( pd.getNode("discriminator"), tokenB.getNode() );  
  160.     assertSame( pd.getNode("discriminator"), tokenC.getNode() );  
  161.   }  
  162.   
  163.   public void testDiscriminatorScenario6() {  
  164.     ProcessDefinition pd = synchronizingdiscriminatorProcessDefinition;  
  165.     Token root = Wfp06MultiChoiceTest.executeScenario(pd,3);  
  166.     Token tokenB = root.getChild("to b");   
  167.     Token tokenC = root.getChild("to c");   
  168.   
  169.     tokenC.signal();  
  170.     assertSame( pd.getNode("multichoice"), root.getNode() );  
  171.     assertSame( pd.getNode("b"), tokenB.getNode() );  
  172.     assertSame( pd.getNode("discriminator"), tokenC.getNode() );  
  173.   
  174.     tokenB.signal();  
  175.     assertSame( pd.getNode("d"), root.getNode() );  
  176.     assertSame( pd.getNode("discriminator"), tokenB.getNode() );  
  177.     assertSame( pd.getNode("discriminator"), tokenC.getNode() );  
  178.   }  
  179. }  


流程定义文件

xml 代码
 
  1. <process-definition>  
  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.     <script>  
  10.       <variable name='transitionNames' access='write' />  
  11.       <expression>  
  12.         transitionNames = new ArrayList();  
  13.         if ( scenario == 1 ) {  
  14.           transitionNames.add( \"to b\" );  
  15.         } else if ( scenario == 2 ) {  
  16.           transitionNames.add( \"to c\" );  
  17.         } else if ( scenario >= 3 ) {  
  18.           transitionNames.add( \"to b\" );  
  19.           transitionNames.add( \"to c\" );  
  20.         }  
  21.       </expression>  
  22.     </script>  
  23.     <transition name='to b' to='b' />  
  24.     <transition name='to c' to='c' />  
  25.   </fork>  
  26.   <state name='b'>  
  27.     <transition to='discriminator' />  
  28.   </state>  
  29.   <state name='c'>  
  30.     <transition to='discriminator' />  
  31.   </state>  
  32.   <join name='discriminator'>  
  33.     <transition to='d' />  
  34.   </join>  
  35.   <state name='d' />  
  36. </process-definition>  




testDiscriminatorScenario1()

节点执行顺序

    start --> a --> multichoice --> b --> discriminator --> d

testDiscriminatorScenario2()

节点执行顺序

    start --> a --> multichoice --> c --> discriminator --> d

testDiscriminatorScenario3()

节点执行顺序

    start --> a --> multichoice --> b --> discriminator --> d
                multichoice --> c --> discriminator(废弃)


testDiscriminatorScenario4()

节点执行顺序

    start --> a --> multichoice --> b --> discriminator(废弃) --> d
                multichoice --> c --> discriminator


testDiscriminatorScenario5()

节点执行顺序

    start --> a --> multichoice --> b --> discriminator --> d
                multichoice --> c --> discriminator


testDiscriminatorScenario6()

节点执行顺序

    start --> a --> multichoice --> b --> discriminator --> d
                multichoice --> c --> discriminator
分享到:
评论
4 楼 flyffa 2008-12-07  
sorry,应该是更符合Structured Synchronizing Merge模式
3 楼 flyffa 2008-12-07  
这个模式好像实现的有问题吧,按照workflow pattern的说法,应该是b,c两个分支无论谁先到discriminator,都直接往下走到d,而不是在这里等待吧。你这个做法更符合Multiple Merge模式。
2 楼 lovevirus 2006-12-18  
假如你state是taskNode,那么是否要把taskNode中的taskInstance删掉,按平时的理解,如果废弃,那么看不到废弃那分支的任务了,比如请假流程,如果我请假取消,那么另外一个分支中的核实任务应该取消掉吧
1 楼 coolfish 2006-12-15  
jbpm演示的不错,不过这个流程只执行在内存里.象第9个用到join的isDiscriminator属性,第10个模式用到的nOutOfM 属性都没有持久化,在实际场景中肯定用的麻烦了

相关推荐

    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工作流引擎基于J2EE的轻量级,纯java,开源的工作流管理系统。

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

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

    jbpm工作流整合

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

    JBPM4工作流介绍.ppt

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

    jbpm Java工作流 教程

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

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

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

    jBPM工作流详解

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

    JBPM4工作流介绍.pptx

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

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

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

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

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

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

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

    jbpm工作流 基础视频

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

    jBPM4工作流示例jbpmDemo

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

    jbpm4.3 工作流实例 java

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

    JBPM工作流全套学习资料

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

    jBPM4.4工作流开发指南(改进版)

    jBPM4.4工作流开发指南(改进版) 开发环境搭建

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

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

Global site tag (gtag.js) - Google Analytics