jbpm学习

转http://linliangyi2007.javaeye.com/blog/176345

本片文章,我们将从业务流程的设计开始,通过带领大家完成一个完整工作流的程序设计,来学习jPDL的使用。

业务流程设计
这里我们实现一个相对简化的公司借款申请流程。流程图如下:
fd1de34b-2be7-3579-be1e-c58f04398173.png

在jPDL中,与流程设计相关的文件有三个:processdefinition.xml、gdp.xml、processimage.jpg。 其中processdefinition.xml是流程定义的描述文件;gpd.xml是对图形界面呈现的XML描述;而 processimage.jpg则是对图形界面的快照。下面我们将展示本样例的流程定义文件。

[@more@] 流程定义描述
processdefinition.xml文件

引用

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























































在样例流程中,除了开始和结束结点外,我们定义了三种类型的结点:

任务结点
任务结点是一个需要人工参与的结点类型。当流程进入结点时,会生成相应的任务实例(TaskInstatnce),并通过委派接口 AssignmentHandler或jBPM表达式将任务委派给一个或多个特定的角色或参与者。结点自身进入等待状态,直到任务被参与者完成或者跳过, 流程继续。

判定结点
判定结点的设计目标是根据上下文环境和程序逻辑,判定流程转向。通过指定一个实现DecisionHandlder接口的Java委派类或jBPM表达式,来返回转向(transition)的字符窜类型的名称(可以是中文哦),来达到决定流程方向的功能。

普通结点
普通结点也可以定义相应的处理任务,通过定义相应的ActioinHandler类。同任务结点不同的是,普通结点定义的任务是由流程自动执行的,无须人工干预。

三种结点都可定义结点事件(event):
node-enter,该事件在流程进入结点时触发
node-leave,该事件在流程离开节点是触发
可以在事件上挂接ActioinHandler接口的实现类来完成一些特定的功能。

三种节点都可以定义异步处理方式(async属性):
异步处理意味着每个结点的事务处理是通过消息机制分离的,不再同一线程中统一调用执行。而是由消息监听线程从消息队列中取得消息体来运行相应得程序。
此外我们定义了结点间的转向(transition),用来记录和处理状态的变迁。每个转向中,可以委派一个或多个的ActioinHandler接口实现类,负责处理节点变迁时的上下文状态变更及回调用户定义的处理程序。

流程的程序接口说明

动作处理接口(ActioinHandler)
接口方法:void execute( ExecutionContext executionContext ) throws Exception
该接口是jPDL中最常用的一个回调接口。从它的接口方法可以发现,它仅仅暴露了流程执行上下文变量ExecutionContext。用户程序 通过ExecutionContext来了解流程的执行状态,并通过改变ExecutionContext中的属性值来影响流程的执行。
ActioinHandler接口可以在所有能包含事件(event)、动作(action)元素的地方被回调。

判定处理接口(DecisionHandlder)
接口方法:String decide(ExecutionContext executionContext) throws Exception
判定接口仅适用于判定节点(decision)中。从它的接口方法可以看出,方法要返回一个字符串型的结果,这个结果必须和判定节点拥有的转向(transition)集合中的一条转向名称相匹配。
在DecisionHandlder的接口方法中一样能访问到ExecutionContext变量,这为判定提供了执行上下文的根据。当然,如果有必要,用户也可以在该接口中改变ExecutionContext中的变量值。

委派处理接口(AssignmentHandler)
接口方法:void assign(Assignable assignable, ExecutionContext executionContext) throws Exception;
委派处理接口被用户任务元素(task)的委派(assignment)子元素中,它的职责很明确,就是将任务分配给指定的人员或角色。
在AssignmentHandler接口的方法中,Assignable变量通常指任务实例(TaskInstance)。通过将 ExecutionContext和TaskInstance两个变量都暴露给接口方法,用户就可以根据流程上下文情况,来决定要将指定的任务分配个谁。

流程的部署

用户使用jPDL的流程设计器定义业务流程,当然,你也可以直接用文档编辑器直接编辑processdefinition.xml定义文件。定义文档是可 以直接被ProcessDefinition类载入使用的,但在正式运行的系统中,流程定义信息更多是使用关系型数据库来存储。从流程定义文件将数据导入 流程数据库的过程,我们称之为流程部署。
jPDL的流程部署文件包含processdefinition.xml的定义部分和Java处理器的代码部分,这些文件可以被一起打包成.jpdl的zip格式包而后上传服务器端。这个过程可以在流程设计器界面的“deployment”标签页中操作:
f2144dcf-0c7e-3bb0-a764-6472b9b8ecaa.png
这里我们着重要讲述的是接受部署文件上载的服务器端配置。在jBPM3.2的包中带着一个jPDL的管理控制台web应用,默认名字为jbpm- console。该应用带有接受流程定义包部署的程序,但不是最小化的。实际上完成流程部署功能的,只是jbpm-jpdl.jar核心包中的一个 servlet类:org.jbpm.web.ProcessUploadServlet . 完成这个Servlet的成功部署,需要以下工作:

1. 配置web.xml,将servlet配置成启动时加载,如下:
引用



GDP Deployer Servlet
org.jbpm.web.ProcessUploadServlet
1



GDP Deployer Servlet
/upload/*




2. 建立流程定义存储数据库表:
Demo中,我们使用的数据库是MySQL的,在E:Javatoolsjbpm-jpdl-3.2.2db目录下有个 jbpm.jpdl.mysql.sql数据库脚本文件。但我们不能直接导入该文件, 会提示有错误, 应为该文件的SQL语句末尾少了分号,在批量执行时,MySQL报错。需要在每一行SQL的末尾添加一个分号,这样就可以用source命令导入了。

3. 配置Hibernate.cfg.xml
由于jBPM的数据库持久化是依靠Hibernate进行的,因此需要配置Hibernate.cfg.xml使其适应我们的MySQL环境
引用

<!-- hibernate dialect --&gt
org.hibernate.dialect.MySQLInnoDBDialect
com.mysql.jdbc.Driver
jdbc:mysql://localhost:3306/linly
linly
coffee
org.hibernate.cache.HashtableCacheProvider


4. Import需要的jar包
这里的jar包包括三部分:jbpm的核心包;Hibernate及其支撑包;MySQL的JDBC驱动包。
dab51afb-a7d8-3c25-a89a-9a568cb61fca.png 959b13ef-aaba-375e-9787-2b81daa82649.png

到此,我们的配置工作完成,这是实现jBPM流程部署服务端的最小化应用配置。

流程控制及API使用

样例程序中的Handler接口实现

下面,根据上述的接口分类,列出样例程序中的类名及相应的功能说明,具体可参考源代码。
动作处理接口(ActioinHandler)
4f94f587-8d45-3d2d-81f6-81f1f2883661.png
这里要提到一个很重要的区别,就是作用于Node上的ActoinHandler和作用于Transition上的ActoinHandler是 有不同的。区别在于,Node上的ActoinHandler在结束业务逻辑处理后,必须调用 executionContext.leaveNode();或executionContext.leaveNode(transition)来保证流 程向下执行;而作用于Transition上的则不需要。

判定处理接口(DecisionHandlder)
22ea6b44-781c-372e-a6fc-02ea05f1934b.png

委派处理接口(AssignmentHandler)
e941cb8b-4707-35fb-b88c-c8759f0e25a5.png

流程测试剖析

本章节,我们将给大家剖析两个流程测试类。一个是简单的基于内存模型的流程测试FirstFlowProcessTest;一个是更贴近实用的,基于MySQL数据库操作的标准测试案例。通过对这两个测试例程的分析,来直观的学习如何通过Java API操作jPDL。

简单流程测试案例
测试案例类:FirstFlowProcessTest.java
Java代码 复制代码
  1. public class FirstFlowProcessTest extends TestCase {
  2. ProcessDefinition pdf ;
  3. ProcessInstance pi;
  4. public void test4000YuanApplication() throws Exception {
  5. deployProcessDefinition();
  6. createProcessInstance("linly");
  7. submitApplication(4000);
  8. approveByManager(true);
  9. checkTasks();
  10. }
  11. public void test6000YuanApplication() throws Exception {
  12. deployProcessDefinition();
  13. createProcessInstance("linly");
  14. submitApplication(6000);
  15. approveByManager(true);
  16. approveByPresident(true);
  17. checkTasks();
  18. }
  19. public void test7000YuanApplication() throws Exception {
  20. deployProcessDefinition();
  21. createProcessInstance("linly");
  22. submitApplication(7000);
  23. approveByManager(true);
  24. approveByPresident(false);
  25. checkTasks();
  26. }
  27. /**
  28. * 部署流程定义
  29. * @throws Exception
  30. */
  31. protected void deployProcessDefinition() throws Exception{
  32. System.out.println("==FirstFlowProcessTest.deployProcessDefinition()==");
  33. pdf = ProcessDefinition.parseXmlResource("firstflow/processdefinition.xml");
  34. assertNotNull("Definition should not be null", pdf);
  35. }
  36. /**
  37. * 生成流程实例
  38. */
  39. protected void createProcessInstance(String user){
  40. System.out.println("==FirstFlowProcessTest.createProcessInstance()==");
  41. assertNotNull("Definition should not be null", pdf);
  42. //生成实例
  43. pi = pdf.createProcessInstance();
  44. assertNotNull("processInstance should not be null", pi);
  45. //设置流程发起人
  46. pi.getContextInstance().createVariable("initiator", user);
  47. //触发流程转向
  48. pi.signal();
  49. }
  50. /**
  51. * 填写提交申请单
  52. * @param money
  53. */
  54. protected void submitApplication(int money){
  55. System.out.println("==FirstFlowProcessTest.submitApplication()==");
  56. TaskInstance ti = (TaskInstance)pi.getTaskMgmtInstance().getTaskInstances().iterator() .next() ;
  57. System.out.println("ti.actor = " + ti.getActorId());
  58. ContextInstance ci = ti.getContextInstance();
  59. ci.setVariable("money",new Integer(money));
  60. ti.end();
  61. }
  62. /**
  63. * 部门经理审批
  64. * @param pass
  65. */
  66. @SuppressWarnings("unchecked")
  67. protected void approveByManager(boolean pass){
  68. System.out.println("==FirstFlowProcessTest.approveByManager()==");
  69. Iterator it = pi.getTaskMgmtInstance().getTaskInstances().iterator();
  70. for( ;it.hasNext(); ){
  71. TaskInstance ti = it.next();
  72. if(ti.getActorId().equals("DepartmentManager")){
  73. List transitions = ti.getToken().getNode().getLeavingTransitions();
  74. for(Transition t : transitions){
  75. System.out.println("----Transition" + t.getName());
  76. }
  77. assertEquals("DepartmentManager",ti.getActorId());
  78. if(pass){
  79. ti.end("部门经理审批通过");
  80. }else{
  81. ti.end("部门经理驳回");
  82. }
  83. return;
  84. }
  85. }
  86. }
  87. /**
  88. * 总经理审批
  89. * @param pass
  90. */
  91. @SuppressWarnings("unchecked")
  92. protected void approveByPresident(boolean pass){
  93. System.out.println("==FirstFlowProcessTest.approveByPresident()==");
  94. Iterator it = pi.getTaskMgmtInstance().getTaskInstances().iterator();
  95. for( ;it.hasNext(); ){
  96. TaskInstance ti = it.next();
  97. if(ti.getActorId().equals("President")){
  98. List transitions = ti.getToken().getNode().getLeavingTransitions();
  99. for(Transition t : transitions){
  100. System.out.println("----Transition" + t.getName());
  101. }
  102. assertEquals("President",ti.getActorId());
  103. if(pass){
  104. ti.end("总经理审批通过");
  105. }else{
  106. ti.end("总经理驳回");
  107. }
  108. return;
  109. }
  110. }
  111. }
  112. /**
  113. * 打印任务记录
  114. */
  115. @SuppressWarnings("unchecked")
  116. protected void checkTasks(){
  117. System.out.println("==FirstFlowProcessTest.checkTasks()==");
  118. Collection coll = pi.getTaskMgmtInstance().getTaskInstances();
  119. System.out.println("====Process has task:====");
  120. for(TaskInstance ti : coll){
  121. System.out.println("=="+ti.getName()+"==");
  122. System.out.println("=="+ti.getActorId()+"==");
  123. System.out.println("=="+ti.getVariables().toString() +"==");
  124. }
  125. System.out.println("====end====");
  126. }
public class FirstFlowProcessTest extends TestCase {
	ProcessDefinition pdf ;
    ProcessInstance pi;       

	public void test4000YuanApplication() throws Exception {
		deployProcessDefinition();
		createProcessInstance("linly");
		submitApplication(4000);
		approveByManager(true);
		checkTasks();
	}

	public void test6000YuanApplication() throws Exception {
		deployProcessDefinition();
		createProcessInstance("linly");
		submitApplication(6000);
		approveByManager(true);
		approveByPresident(true);
		checkTasks();
	}
	
	public void test7000YuanApplication() throws Exception {
		deployProcessDefinition();
		createProcessInstance("linly");
		submitApplication(7000);
		approveByManager(true);
		approveByPresident(false);
		checkTasks();
	}
	
	/**
	 * 部署流程定义
	 * @throws Exception
	 */
    protected void deployProcessDefinition() throws Exception{
        System.out.println("==FirstFlowProcessTest.deployProcessDefinition()==");
        pdf = ProcessDefinition.parseXmlResource("firstflow/processdefinition.xml");
        assertNotNull("Definition should not be null", pdf);        
    }    
    /**
     * 生成流程实例 
     */
    protected void createProcessInstance(String user){
        System.out.println("==FirstFlowProcessTest.createProcessInstance()==");
    assertNotNull("Definition should not be null", pdf);
        //生成实例
    	pi = pdf.createProcessInstance();
    	assertNotNull("processInstance should not be null", pi);
    	//设置流程发起人
    	pi.getContextInstance().createVariable("initiator", user);
    	//触发流程转向
    	pi.signal();
    }    
    /**
     * 填写提交申请单
     * @param money
     */
    protected void submitApplication(int money){    	
        System.out.println("==FirstFlowProcessTest.submitApplication()==");        
        TaskInstance ti = (TaskInstance)pi.getTaskMgmtInstance().getTaskInstances().iterator() .next() ;        
        System.out.println("ti.actor = " + ti.getActorId());        
        ContextInstance ci = ti.getContextInstance();
        ci.setVariable("money",new Integer(money));
        ti.end();    	
    }    
    /**
     * 部门经理审批
     * @param pass
     */    
    @SuppressWarnings("unchecked")
    protected void approveByManager(boolean pass){    	
        System.out.println("==FirstFlowProcessTest.approveByManager()==");        
        Iterator it = pi.getTaskMgmtInstance().getTaskInstances().iterator();        
        for( ;it.hasNext(); ){        	
        	TaskInstance ti = it.next();        	
        	if(ti.getActorId().equals("DepartmentManager")){
                List transitions = ti.getToken().getNode().getLeavingTransitions();
                for(Transition t : transitions){
                	System.out.println("----Transition" + t.getName());
                }
                assertEquals("DepartmentManager",ti.getActorId());
                if(pass){
                	 ti.end("部门经理审批通过");    	
                }else{
                	ti.end("部门经理驳回");
                }
                return;
        	}
        }        
    }
    
    /**
     * 总经理审批
     * @param pass
     */
    @SuppressWarnings("unchecked")
    protected void approveByPresident(boolean pass){
    	   System.out.println("==FirstFlowProcessTest.approveByPresident()==");
    	   
           Iterator it = pi.getTaskMgmtInstance().getTaskInstances().iterator();
           
           for( ;it.hasNext(); ){
           	
	           	TaskInstance ti = it.next();
	           	
	           	if(ti.getActorId().equals("President")){
	                List transitions = ti.getToken().getNode().getLeavingTransitions();
	                for(Transition t : transitions){
	                	System.out.println("----Transition" + t.getName());
	                }
	                assertEquals("President",ti.getActorId());
	                if(pass){
	                	 ti.end("总经理审批通过");    	
	                }else{
	                	ti.end("总经理驳回");
	                }
	                return;
	           	}
           }
    }    
    /**
     * 打印任务记录
     */
    @SuppressWarnings("unchecked")
    protected void checkTasks(){       
        System.out.println("==FirstFlowProcessTest.checkTasks()==");
        Collection coll = pi.getTaskMgmtInstance().getTaskInstances();
        System.out.println("====Process has task:====");
        for(TaskInstance ti : coll){
               System.out.println("=="+ti.getName()+"==");
               System.out.println("=="+ti.getActorId()+"==");
               System.out.println("=="+ti.getVariables().toString() +"==");
        }
        System.out.println("====end====");   
    }     


该案例是在没有数据库支持的情况下,对报销流程进行运行测试,测试逻辑如下:

1. 加载流程定义
Java代码 复制代码
  1. ProcessDefinition.parseXmlResource("firstflow/processdefinition.xml")
ProcessDefinition.parseXmlResource("firstflow/processdefinition.xml")
代码说明:
在没有数据库存储的情况下,流程定义通过ProcessDefinition类直接从processdefinition.xml文件中解析加载。

2. 实例化流程对象
Java代码 复制代码
  1. //生成实例
  2. pi = pdf.createProcessInstance();
  3. assertNotNull("processInstance should not be null", pi);
  4. //设置流程发起人
  5. pi.getContextInstance().createVariable("initiator", user);
  6. //触发流程转向
  7. pi.signal();
      //生成实例
       pi = pdf.createProcessInstance();
      assertNotNull("processInstance should not be null", pi);
      //设置流程发起人
       pi.getContextInstance().createVariable("initiator", user);
      //触发流程转向
       pi.signal();
代码说明:
在获得流程定义的实例后,可以用它生成流程实例,使用如下的语句:
pi = pdf.createProcessInstance();
流程实例拥有自己的ContextInstance环境变量对象。它实际上是一个HashMap,以key-value方式记录了流程的上下文变量值,代码中的
pi.getContextInstance().createVariable("initiator", user);就是向环境变量中添加一个key为initiator的对象。
每个流程实例都拥有自己Token令牌对象,主流程有自己的RootToken,子流程也拥有自己的子Token。父流程的Token和子流程的Token相互关联,形成Token树。
Token对象表示流程运行的当前位置(运行到哪个节点了)。通过对Token对象的signal()方法调用,可以使流程向下运行。代码中的 pi.signal();实际上是间接调用了pi.getRootToken().signal();它使得新建的流程继续向下个节点(即借款申请单填 写)进发。

3. 员工发起借款申请
Java代码 复制代码
  1. /**
  2. * 填写提交申请单
  3. * @param money
  4. */
  5. protected void submitApplication(int money){
  6. System.out.println("==FirstFlowProcessTest.submitApplication()==");
  7. TaskInstance ti = (TaskInstance)pi.getTaskMgmtInstance().getTaskInstances().iterator() .next()
  8. System.out.println("ti.actor = " + ti.getActorId());
  9. ContextInstance ci = ti.getContextInstance();
  10. ci.setVariable("money",new Integer(money));
  11. ti.end();
    /**
     * 填写提交申请单
     * @param money
     */
    protected void submitApplication(int money){
    		 System.out.println("==FirstFlowProcessTest.submitApplication()==");
        
        TaskInstance ti = (TaskInstance)pi.getTaskMgmtInstance().getTaskInstances().iterator() .next()         
        System.out.println("ti.actor = " + ti.getActorId());
        ContextInstance ci = ti.getContextInstance();
        ci.setVariable("money",new Integer(money));
        ti.end();
}
代码说明:
在借款流程发起后,流程进入了申请单填写阶段。这个阶段是个人工的任务,需要用户的介入。因此,对于要借款的用户而言,首先是获取填写申请单的任务实例:
TaskInstance ti = (TaskInstance)pi.getTaskMgmtInstance().getTaskInstances().iterator() .next()
在这个测试类中,由于没有数据库。对流程实例的引用是依靠了类的全局标量pi。这里通过pi获取全部的任务列表。实际上有且仅有一个任务,就是我们刚刚发起的申请单填写任务。
接下来,我们获取流程的上下文变量,将申请借款的数额记录在上下文变量中ContextInstance ci = ti.getContextInstance();
ci.setVariable("money",new Integer(money));
最后,我们要结束当前任务,告诉流程继续下行,调用ti.end();这个方法的本质依然是调用了token.signal(),它选择了一个默 认的transition进行转向。这里要说明的是signal方法有多态的实现signal(Transition transition),是可以指定具体转向参数的。

4. 部门领导审批申请
Java代码 复制代码
  1. /**
  2. * 部门经理审批
  3. * @param pass
  4. */
  5. @SuppressWarnings("unchecked")
  6. protected void approveByManager(boolean pass){
  7. System.out.println("==FirstFlowProcessTest.approveByManager()==");
  8. Iterator it = pi.getTaskMgmtInstance().getTaskInstances().iterator();
  9. for( ;it.hasNext(); ){
  10. TaskInstance ti = it.next();
  11. if(ti.getActorId().equals("DepartmentManager")){
  12. List transitions = ti.getToken().getNode().getLeavingTransitions();
  13. for(Transition t : transitions){
  14. System.out.println("----Transition" + t.getName());
  15. }
  16. assertEquals("DepartmentManager",ti.getActorId());
  17. if(pass){
  18. ti.end("部门经理审批通过");
  19. }else{
  20. ti.end("部门经理驳回");
  21. }
  22. return;
  23. }
  24. }
  25. }
     /**
     * 部门经理审批
     * @param pass
     */    
    @SuppressWarnings("unchecked")
    protected void approveByManager(boolean pass){    	
        System.out.println("==FirstFlowProcessTest.approveByManager()==");        
        Iterator it = pi.getTaskMgmtInstance().getTaskInstances().iterator();        
        for( ;it.hasNext(); ){        	
        	TaskInstance ti = it.next();        	
        	if(ti.getActorId().equals("DepartmentManager")){
                List transitions = ti.getToken().getNode().getLeavingTransitions();
                for(Transition t : transitions){
                	System.out.println("----Transition" + t.getName());
                }
                assertEquals("DepartmentManager",ti.getActorId());
                if(pass){
                	 ti.end("部门经理审批通过");    	
                }else{
                	ti.end("部门经理驳回");
                }
                return;
        	}
        } 
}
代码说明:
这里,流程进入了部门经理审批阶段。由于没有数据库支持,我们只能采取遍历任务列表,并比对委派者ID的方式来确定委派给部门经理的任务实例。(在后面的基于数据库的标准案例中,我们会看到如果根据用户的ID来获取分配给指定用户的任务)
ti.getActorId().equals("DepartmentManager") // 比对任务的委派人。
ti.getToken().getNode().getLeavingTransitions();//获取任务在当前节点上的所有转向。
这里我们要特别指出的是ti.end("部门经理审批通过")和ti.end("部门经理驳回")这实际上调用token.signal(transition);来完成任务的转向,从而使流程继续。

5. 总经理审批申请
Java代码 复制代码
  1. /**
  2. * 总经理审批
  3. * @param pass
  4. */
  5. @SuppressWarnings("unchecked")
  6. protected void approveByPresident(boolean pass){
  7. System.out.println("==FirstFlowProcessTest.approveByPresident()==");
  8. Iterator it = pi.getTaskMgmtInstance().getTaskInstances().iterator();
  9. for( ;it.hasNext(); ){
  10. TaskInstance ti = it.next();
  11. if(ti.getActorId().equals("President")){
  12. List transitions = ti.getToken().getNode().getLeavingTransitions();
  13. for(Transition t : transitions){
  14. System.out.println("----Transition" + t.getName());
  15. }
  16. assertEquals("President",ti.getActorId());
  17. if(pass){
  18. ti.end("总经理审批通过");
  19. }else{
  20. ti.end("总经理驳回");
  21. }
  22. return;
  23. }
  24. }
  25. }
     /**
     * 总经理审批
     * @param pass
     */
    @SuppressWarnings("unchecked")
    protected void approveByPresident(boolean pass){
    	   System.out.println("==FirstFlowProcessTest.approveByPresident()=="); 
           Iterator it = pi.getTaskMgmtInstance().getTaskInstances().iterator();
           
           for( ;it.hasNext(); ){           	
	           	TaskInstance ti = it.next();	           	
	           	if(ti.getActorId().equals("President")){
	                List transitions = ti.getToken().getNode().getLeavingTransitions();
	                for(Transition t : transitions){
	                	System.out.println("----Transition" + t.getName());
	                }
	                assertEquals("President",ti.getActorId());
	                if(pass){
	                	 ti.end("总经理审批通过");    	
	                }else{
	                	ti.end("总经理驳回");
	                }
	                return;
	           	}
           }
}
代码说明:
此步代码同“部门经理审批”代码相似,不作更多说明。

标准流程测试案例

该案例模拟了标准运行环境中,基于关系型数据库的jBPM系统是如何执行流程的。
测试案例类:FirstFlowProcessDBTest.java
Java代码 复制代码
  1. public class FirstFlowProcessDBTest {
  2. /*
  3. * 初始化jBPM配置
  4. * 包含对Hibernate的数据库初始化
  5. */
  6. static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();
  7. public static void main(String[] args){
  8. FirstFlowProcessDBTest test = new FirstFlowProcessDBTest();
  9. test.test4000YuanApplication();
  10. test.test6000YuanApplication();
  11. test.test7000YuanApplication();
  12. }
  13. public void test4000YuanApplication(){
  14. ProcessInstance pi = createProcessInstance("linly");
  15. submitApplication("linly" , 4000);
  16. approveByManager(true);
  17. checkTasks(pi);
  18. }
  19. public void test6000YuanApplication() {
  20. ProcessInstance pi = createProcessInstance("linly");
  21. submitApplication("linly" , 6000);
  22. approveByManager(true);
  23. approveByPresident(true);
  24. checkTasks(pi);
  25. }
  26. public void test7000YuanApplication() {
  27. ProcessInstance pi = createProcessInstance("linly");
  28. submitApplication("linly" , 7000);
  29. approveByManager(true);
  30. approveByPresident(false);
  31. checkTasks(pi);
  32. }
  33. /**
  34. * 生成流程实例
  35. */
  36. protected ProcessInstance createProcessInstance(String user){
  37. System.out.println("==FirstFlowProcessTest.createProcessInstance()==");
  38. JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
  39. try {
  40. GraphSession graphSession = jbpmContext.getGraphSession();
  41. /*
  42. * 从数据库获取指定的流程定义
  43. */
  44. ProcessDefinition pdf = graphSession.findLatestProcessDefinition("simple");
  45. //生成流程实例
  46. ProcessInstance pi = pdf.createProcessInstance();
  47. //设置流程发起人
  48. pi.getContextInstance().createVariable("initiator", user);
  49. //触发流程转向
  50. pi.signal();
  51. /*
  52. * 保存流程实例
  53. */
  54. jbpmContext.save(pi);
  55. return pi;
  56. }finally{
  57. jbpmContext.close();
  58. }
  59. }
  60. /**
  61. * 填写提交申请单
  62. * @param money
  63. */
  64. @SuppressWarnings("unchecked")
  65. protected void submitApplication(String actorId , int money){
  66. System.out.println("==FirstFlowProcessTest.submitApplication()==");
  67. JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
  68. try {
  69. /*
  70. *根据操作者ID,获取属于该操作者的任务集
  71. */
  72. List taskInstances = jbpmContext.getTaskList(actorId);
  73. for(TaskInstance ti : taskInstances){
  74. System.out.println("ti.name = " + ti.getName());
  75. System.out.println("ti.actor = " + ti.getActorId());
  76. ContextInstance ci = ti.getContextInstance();
  77. ci.setVariable("money",new Integer(money));
  78. ti.end();
  79. }
  80. }finally{
  81. jbpmContext.close();
  82. }
  83. }
  84. /**
  85. * 部门经理审批
  86. * @param pass
  87. */
  88. @SuppressWarnings("unchecked")
  89. protected void approveByManager(boolean pass){
  90. System.out.println("==FirstFlowProcessTest.approveByManager()==");
  91. JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
  92. try{
  93. List taskInstances = jbpmContext.getTaskList("DepartmentManager");
  94. for(TaskInstance ti : taskInstances){
  95. System.out.println("ti.name = " + ti.getName());
  96. System.out.println("ti.actor = " + ti.getActorId());
  97. if(pass){
  98. ti.end("部门经理审批通过");
  99. }else{
  100. ti.end("部门经理驳回");
  101. }
  102. }
  103. }finally{
  104. jbpmContext.close();
  105. }
  106. }
  107. /**
  108. * 总经理审批
  109. * @param pass
  110. */
  111. @SuppressWarnings("unchecked")
  112. protected void approveByPresident(boolean pass){
  113. System.out.println("==FirstFlowProcessTest.approveByPresident()==");
  114. JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
  115. try{
  116. List taskInstances = jbpmContext.getTaskList("President");
  117. for(TaskInstance ti : taskInstances){
  118. System.out.println("ti.name = " + ti.getName());
  119. System.out.println("ti.actor = " + ti.getActorId());
  120. if(pass){
  121. ti.end("总经理审批通过");
  122. }else{
  123. ti.end("总经理驳回");
  124. }
  125. }
  126. }finally{
  127. jbpmContext.close();
  128. }
  129. }
  130. /**
  131. * 打印任务记录
  132. */
  133. @SuppressWarnings("unchecked")
  134. protected void checkTasks(ProcessInstance pi){
  135. System.out.println("==FirstFlowProcessTest.checkTasks()==");
  136. JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
  137. try{
  138. List coll = jbpmContext.getTaskMgmtSession().findTaskInstancesByProcessInstance(pi);
  139. System.out.println("====Process has task:====");
  140. for(TaskInstance ti : coll){
  141. System.out.println("=="+ti.getName()+"==");
  142. System.out.println("=="+ti.getActorId()+"==");
  143. System.out.println("=="+ti.getVariables().toString() +"==");
  144. }
  145. System.out.println("====end====");
  146. }finally{
  147. jbpmContext.close();
  148. }
  149. }
  150. }
public class FirstFlowProcessDBTest {	
	/*
	 * 初始化jBPM配置
	 * 包含对Hibernate的数据库初始化
	 */
    static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();    
    public static void main(String[] args){
    	FirstFlowProcessDBTest test = new FirstFlowProcessDBTest();
    	test.test4000YuanApplication();
    	test.test6000YuanApplication();
    	test.test7000YuanApplication();
    }
    
	public void test4000YuanApplication(){
		ProcessInstance pi = createProcessInstance("linly");
		submitApplication("linly" , 4000);
		approveByManager(true);
		checkTasks(pi);
	}
	public void test6000YuanApplication() {
		ProcessInstance pi = createProcessInstance("linly");
		submitApplication("linly" , 6000);
		approveByManager(true);
		approveByPresident(true);
		checkTasks(pi);
	}	
	public void test7000YuanApplication() {
		ProcessInstance pi = createProcessInstance("linly");
		submitApplication("linly" , 7000);
		approveByManager(true);
		approveByPresident(false);
		checkTasks(pi);
	} 
    /**
     * 生成流程实例 
     */
    protected ProcessInstance createProcessInstance(String user){
        System.out.println("==FirstFlowProcessTest.createProcessInstance()==");
        JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
        try {
        	 GraphSession graphSession = jbpmContext.getGraphSession();
             /*
              * 从数据库获取指定的流程定义
              */
        	 ProcessDefinition pdf  = graphSession.findLatestProcessDefinition("simple");
        	 //生成流程实例
        	 ProcessInstance pi = pdf.createProcessInstance();
        	 //设置流程发起人
        	 pi.getContextInstance().createVariable("initiator", user);
        	 //触发流程转向
        	 pi.signal();
        	 /*
        	  * 保存流程实例 
        	  */
        	 jbpmContext.save(pi);        	 
        	 return pi;
        }finally{
        	jbpmContext.close();
        }
    }
    
    /**
     * 填写提交申请单
     * @param money
     */
    @SuppressWarnings("unchecked")
    protected void submitApplication(String actorId , int money){
        System.out.println("==FirstFlowProcessTest.submitApplication()=="); 
    	JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
	    try {  	
            /*
             *根据操作者ID,获取属于该操作者的任务集
        
                                                            

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12058779/viewspace-1006094/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/12058779/viewspace-1006094/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值