溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

jbpm學(xué)習(xí)

發(fā)布時(shí)間:2020-08-17 13:03:04 來(lái)源:ITPUB博客 閱讀:130 作者:333111444 欄目:編程語(yǔ)言

轉(zhuǎn)http://linliangyi2007.javaeye.com/blog/176345

本片文章,我們將從業(yè)務(wù)流程的設(shè)計(jì)開(kāi)始,通過(guò)帶領(lǐng)大家完成一個(gè)完整工作流的程序設(shè)計(jì),來(lái)學(xué)習(xí)jPDL的使用。

業(yè)務(wù)流程設(shè)計(jì)
這里我們實(shí)現(xiàn)一個(gè)相對(duì)簡(jiǎn)化的公司借款申請(qǐng)流程。流程圖如下:
jbpm學(xué)習(xí)

在jPDL中,與流程設(shè)計(jì)相關(guān)的文件有三個(gè):processdefinition.xml、gdp.xml、processimage.jpg。 其中processdefinition.xml是流程定義的描述文件;gpd.xml是對(duì)圖形界面呈現(xiàn)的XML描述;而 processimage.jpg則是對(duì)圖形界面的快照。下面我們將展示本樣例的流程定義文件。

[@more@]流程定義描述

processdefinition.xml文件


引用



在樣例流程中,除了開(kāi)始和結(jié)束結(jié)點(diǎn)外,我們定義了三種類型的結(jié)點(diǎn):

任務(wù)結(jié)點(diǎn)
任務(wù)結(jié)點(diǎn)是一個(gè)需要人工參與的結(jié)點(diǎn)類型。當(dāng)流程進(jìn)入結(jié)點(diǎn)時(shí),會(huì)生成相應(yīng)的任務(wù)實(shí)例(TaskInstatnce),并通過(guò)委派接口 AssignmentHandler或jBPM表達(dá)式將任務(wù)委派給一個(gè)或多個(gè)特定的角色或參與者。結(jié)點(diǎn)自身進(jìn)入等待狀態(tài),直到任務(wù)被參與者完成或者跳過(guò), 流程繼續(xù)。

判定結(jié)點(diǎn)
判定結(jié)點(diǎn)的設(shè)計(jì)目標(biāo)是根據(jù)上下文環(huán)境和程序邏輯,判定流程轉(zhuǎn)向。通過(guò)指定一個(gè)實(shí)現(xiàn)DecisionHandlder接口的Java委派類或jBPM表達(dá)式,來(lái)返回轉(zhuǎn)向(transition)的字符竄類型的名稱(可以是中文哦),來(lái)達(dá)到?jīng)Q定流程方向的功能。

普通結(jié)點(diǎn)
普通結(jié)點(diǎn)也可以定義相應(yīng)的處理任務(wù),通過(guò)定義相應(yīng)的ActioinHandler類。同任務(wù)結(jié)點(diǎn)不同的是,普通結(jié)點(diǎn)定義的任務(wù)是由流程自動(dòng)執(zhí)行的,無(wú)須人工干預(yù)。

三種結(jié)點(diǎn)都可定義結(jié)點(diǎn)事件(event):
node-enter,該事件在流程進(jìn)入結(jié)點(diǎn)時(shí)觸發(fā)
node-leave,該事件在流程離開(kāi)節(jié)點(diǎn)是觸發(fā)
可以在事件上掛接ActioinHandler接口的實(shí)現(xiàn)類來(lái)完成一些特定的功能。

三種節(jié)點(diǎn)都可以定義異步處理方式(async屬性):
異步處理意味著每個(gè)結(jié)點(diǎn)的事務(wù)處理是通過(guò)消息機(jī)制分離的,不再同一線程中統(tǒng)一調(diào)用執(zhí)行。而是由消息監(jiān)聽(tīng)線程從消息隊(duì)列中取得消息體來(lái)運(yùn)行相應(yīng)得程序。
此外我們定義了結(jié)點(diǎn)間的轉(zhuǎn)向(transition),用來(lái)記錄和處理狀態(tài)的變遷。每個(gè)轉(zhuǎn)向中,可以委派一個(gè)或多個(gè)的ActioinHandler接口實(shí)現(xiàn)類,負(fù)責(zé)處理節(jié)點(diǎn)變遷時(shí)的上下文狀態(tài)變更及回調(diào)用戶定義的處理程序。

流程的程序接口說(shuō)明

動(dòng)作處理接口(ActioinHandler)
接口方法:void execute( ExecutionContext executionContext ) throws Exception
該接口是jPDL中最常用的一個(gè)回調(diào)接口。從它的接口方法可以發(fā)現(xiàn),它僅僅暴露了流程執(zhí)行上下文變量ExecutionContext。用戶程序 通過(guò)ExecutionContext來(lái)了解流程的執(zhí)行狀態(tài),并通過(guò)改變ExecutionContext中的屬性值來(lái)影響流程的執(zhí)行。
ActioinHandler接口可以在所有能包含事件(event)、動(dòng)作(action)元素的地方被回調(diào)。

判定處理接口(DecisionHandlder)
接口方法:String decide(ExecutionContext executionContext) throws Exception
判定接口僅適用于判定節(jié)點(diǎn)(decision)中。從它的接口方法可以看出,方法要返回一個(gè)字符串型的結(jié)果,這個(gè)結(jié)果必須和判定節(jié)點(diǎn)擁有的轉(zhuǎn)向(transition)集合中的一條轉(zhuǎn)向名稱相匹配。
在DecisionHandlder的接口方法中一樣能訪問(wèn)到ExecutionContext變量,這為判定提供了執(zhí)行上下文的根據(jù)。當(dāng)然,如果有必要,用戶也可以在該接口中改變ExecutionContext中的變量值。

委派處理接口(AssignmentHandler)
接口方法:void assign(Assignable assignable, ExecutionContext executionContext) throws Exception;
委派處理接口被用戶任務(wù)元素(task)的委派(assignment)子元素中,它的職責(zé)很明確,就是將任務(wù)分配給指定的人員或角色。
在AssignmentHandler接口的方法中,Assignable變量通常指任務(wù)實(shí)例(TaskInstance)。通過(guò)將 ExecutionContext和TaskInstance兩個(gè)變量都暴露給接口方法,用戶就可以根據(jù)流程上下文情況,來(lái)決定要將指定的任務(wù)分配個(gè)誰(shuí)。

流程的部署

用戶使用jPDL的流程設(shè)計(jì)器定義業(yè)務(wù)流程,當(dāng)然,你也可以直接用文檔編輯器直接編輯processdefinition.xml定義文件。定義文檔是可 以直接被ProcessDefinition類載入使用的,但在正式運(yùn)行的系統(tǒng)中,流程定義信息更多是使用關(guān)系型數(shù)據(jù)庫(kù)來(lái)存儲(chǔ)。從流程定義文件將數(shù)據(jù)導(dǎo)入 流程數(shù)據(jù)庫(kù)的過(guò)程,我們稱之為流程部署。
jPDL的流程部署文件包含processdefinition.xml的定義部分和Java處理器的代碼部分,這些文件可以被一起打包成.jpdl的zip格式包而后上傳服務(wù)器端。這個(gè)過(guò)程可以在流程設(shè)計(jì)器界面的“deployment”標(biāo)簽頁(yè)中操作:
這里我們著重要講述的是接受部署文件上載的服務(wù)器端配置。在jBPM3.2的包中帶著一個(gè)jPDL的管理控制臺(tái)web應(yīng)用,默認(rèn)名字為jbpm- console。該應(yīng)用帶有接受流程定義包部署的程序,但不是最小化的。實(shí)際上完成流程部署功能的,只是jbpm-jpdl.jar核心包中的一個(gè) servlet類:org.jbpm.web.ProcessUploadServlet . 完成這個(gè)Servlet的成功部署,需要以下工作:

1. 配置web.xml,將servlet配置成啟動(dòng)時(shí)加載,如下:

引用

2. 建立流程定義存儲(chǔ)數(shù)據(jù)庫(kù)表:
Demo中,我們使用的數(shù)據(jù)庫(kù)是MySQL的,在E:Javatoolsjbpm-jpdl-3.2.2db目錄下有個(gè) jbpm.jpdl.mysql.sql數(shù)據(jù)庫(kù)腳本文件。但我們不能直接導(dǎo)入該文件, 會(huì)提示有錯(cuò)誤, 應(yīng)為該文件的SQL語(yǔ)句末尾少了分號(hào),在批量執(zhí)行時(shí),MySQL報(bào)錯(cuò)。需要在每一行SQL的末尾添加一個(gè)分號(hào),這樣就可以用source命令導(dǎo)入了。

3. 配置Hibernate.cfg.xml
由于jBPM的數(shù)據(jù)庫(kù)持久化是依靠Hibernate進(jìn)行的,因此需要配置Hibernate.cfg.xml使其適應(yīng)我們的MySQL環(huán)境

引用

<!-- hibernate dialect --&gt 

4. Import需要的jar包
這里的jar包包括三部分:jbpm的核心包;Hibernate及其支撐包;MySQL的JDBC驅(qū)動(dòng)包。

到此,我們的配置工作完成,這是實(shí)現(xiàn)jBPM流程部署服務(wù)端的最小化應(yīng)用配置。

流程控制及API使用

樣例程序中的Handler接口實(shí)現(xiàn)

下面,根據(jù)上述的接口分類,列出樣例程序中的類名及相應(yīng)的功能說(shuō)明,具體可參考源代碼。
動(dòng)作處理接口(ActioinHandler)
這里要提到一個(gè)很重要的區(qū)別,就是作用于Node上的ActoinHandler和作用于Transition上的ActoinHandler是 有不同的。區(qū)別在于,Node上的ActoinHandler在結(jié)束業(yè)務(wù)邏輯處理后,必須調(diào)用 executionContext.leaveNode();或executionContext.leaveNode(transition)來(lái)保證流 程向下執(zhí)行;而作用于Transition上的則不需要。

判定處理接口(DecisionHandlder)
委派處理接口(AssignmentHandler)
流程測(cè)試剖析
本章節(jié),我們將給大家剖析兩個(gè)流程測(cè)試類。一個(gè)是簡(jiǎn)單的基于內(nèi)存模型的流程測(cè)試FirstFlowProcessTest;一個(gè)是更貼近實(shí)用的,基于MySQL數(shù)據(jù)庫(kù)操作的標(biāo)準(zhǔn)測(cè)試案例。通過(guò)對(duì)這兩個(gè)測(cè)試?yán)痰姆治?,?lái)直觀的學(xué)習(xí)如何通過(guò)Java API操作jPDL。

簡(jiǎn)單流程測(cè)試案例
測(cè)試案例類:FirstFlowProcessTest.java

Java代碼 
  1. publicclass FirstFlowProcessTest extends TestCase {  
  2.    ProcessDefinition pdf ;  
  3.    ProcessInstance pi;        
  4.  
  5.    publicvoid test4000YuanApplication() throws Exception {  
  6.        deployProcessDefinition();  
  7.        createProcessInstance("linly");  
  8.        submitApplication(4000);  
  9.        approveByManager(true);  
  10.        checkTasks();  
  11.    }  
  12.  
  13.    publicvoid test6000YuanApplication() throws Exception {  
  14.        deployProcessDefinition();  
  15.        createProcessInstance("linly");  
  16.        submitApplication(6000);  
  17.        approveByManager(true);  
  18.        approveByPresident(true);  
  19.        checkTasks();  
  20.    }  
  21.      
  22.    publicvoid test7000YuanApplication() throws Exception {  
  23.        deployProcessDefinition();  
  24.        createProcessInstance("linly");  
  25.        submitApplication(7000);  
  26.        approveByManager(true);  
  27.        approveByPresident(false);  
  28.        checkTasks();  
  29.    }  
  30.      
  31.    /**
  32.     * 部署流程定義
  33.     * @throws Exception
  34.     */  
  35.    protectedvoid deployProcessDefinition() throws Exception{  
  36.        System.out.println("==FirstFlowProcessTest.deployProcessDefinition()==");  
  37.        pdf = ProcessDefinition.parseXmlResource("firstflow/processdefinition.xml");  
  38.        assertNotNull("Definition should not be null", pdf);          
  39.    }      
  40.    /**
  41.     * 生成流程實(shí)例
  42.     */  
  43.    protectedvoid createProcessInstance(String user){  
  44.        System.out.println("==FirstFlowProcessTest.createProcessInstance()==");  
  45.    assertNotNull("Definition should not be null", pdf);  
  46.        //生成實(shí)例  
  47.        pi = pdf.createProcessInstance();  
  48.        assertNotNull("processInstance should not be null", pi);  
  49.        //設(shè)置流程發(fā)起人  
  50.        pi.getContextInstance().createVariable("initiator", user);  
  51.        //觸發(fā)流程轉(zhuǎn)向  
  52.        pi.signal();  
  53.    }      
  54.    /**
  55.     * 填寫(xiě)提交申請(qǐng)單
  56.     * @param money
  57.     */  
  58.    protectedvoid submitApplication(int money){          
  59.        System.out.println("==FirstFlowProcessTest.submitApplication()==");          
  60.        TaskInstance ti = (TaskInstance)pi.getTaskMgmtInstance().getTaskInstances().iterator() .next() ;          
  61.        System.out.println("ti.actor = " + ti.getActorId());          
  62.        ContextInstance ci = ti.getContextInstance();  
  63.        ci.setVariable("money",new Integer(money));  
  64.        ti.end();        
  65.    }      
  66.    /**
  67.     * 部門經(jīng)理審批
  68.     * @param pass
  69.     */      
  70.    @SuppressWarnings("unchecked")  
  71.    protectedvoid approveByManager(boolean pass){        
  72.        System.out.println("==FirstFlowProcessTest.approveByManager()==");          
  73.        Iterator
  74.        for( ;it.hasNext(); ){            
  75.            TaskInstance ti = it.next();              
  76.            if(ti.getActorId().equals("DepartmentManager")){  
  77.                List
  78.                for(Transition t : transitions){  
  79.                    System.out.println("----Transition" + t.getName());  
  80.                }  
  81.                assertEquals("DepartmentManager",ti.getActorId());  
  82.                if(pass){  
  83.                     ti.end("部門經(jīng)理審批通過(guò)");          
  84.                }else{  
  85.                    ti.end("部門經(jīng)理駁回");  
  86.                }  
  87.                return;  
  88.            }  
  89.        }          
  90.    }  
  91.      
  92.    /**
  93.     * 總經(jīng)理審批
  94.     * @param pass
  95.     */  
  96.    @SuppressWarnings("unchecked")  
  97.    protectedvoid approveByPresident(boolean pass){  
  98.           System.out.println("==FirstFlowProcessTest.approveByPresident()==");  
  99.            
  100.           Iterator
  101.            
  102.           for( ;it.hasNext(); ){  
  103.              
  104.                TaskInstance ti = it.next();  
  105.                  
  106.                if(ti.getActorId().equals("President")){  
  107.                    List
  108.                    for(Transition t : transitions){  
  109.                        System.out.println("----Transition" + t.getName());  
  110.                    }  
  111.                    assertEquals("President",ti.getActorId());  
  112.                    if(pass){  
  113.                         ti.end("總經(jīng)理審批通過(guò)");      
  114.                    }else{  
  115.                        ti.end("總經(jīng)理駁回");  
  116.                    }  
  117.                    return;  
  118.                }  
  119.           }  
  120.    }      
  121.    /**
  122.     * 打印任務(wù)記錄
  123.     */  
  124.    @SuppressWarnings("unchecked")  
  125.    protectedvoid checkTasks(){        
  126.        System.out.println("==FirstFlowProcessTest.checkTasks()==");  
  127.        Collection
  128.        System.out.println("====Process has task:====");  
  129.        for(TaskInstance ti : coll){  
  130.               System.out.println("=="+ti.getName()+"==");  
  131.               System.out.println("=="+ti.getActorId()+"==");  
  132.               System.out.println("=="+ti.getVariables().toString() +"==");  
  133.        }  
  134.        System.out.println("====end====");    
  135.    }      
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);        
    }    
    /**
     * 生成流程實(shí)例 
     */
    protected void createProcessInstance(String user){
        System.out.println("==FirstFlowProcessTest.createProcessInstance()==");
    assertNotNull("Definition should not be null", pdf);
        //生成實(shí)例
    	pi = pdf.createProcessInstance();
    	assertNotNull("processInstance should not be null", pi);
    	//設(shè)置流程發(fā)起人
    	pi.getContextInstance().createVariable("initiator", user);
    	//觸發(fā)流程轉(zhuǎn)向
    	pi.signal();
    }    
    /**
     * 填寫(xiě)提交申請(qǐng)單
     * @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();    	
    }    
    /**
     * 部門經(jīng)理審批
     * @param pass
     */    
    @SuppressWarnings("unchecked")
    protected void approveByManager(boolean pass){    	
        System.out.println("==FirstFlowProcessTest.approveByManager()==");        
        Iterator



該案例是在沒(méi)有數(shù)據(jù)庫(kù)支持的情況下,對(duì)報(bào)銷流程進(jìn)行運(yùn)行測(cè)試,測(cè)試邏輯如下:

1. 加載流程定義

Java代碼 jbpm學(xué)習(xí)
  1. ProcessDefinition.parseXmlResource("firstflow/processdefinition.xml")  
ProcessDefinition.parseXmlResource("firstflow/processdefinition.xml")

代碼說(shuō)明:
在沒(méi)有數(shù)據(jù)庫(kù)存儲(chǔ)的情況下,流程定義通過(guò)ProcessDefinition類直接從processdefinition.xml文件中解析加載。

2. 實(shí)例化流程對(duì)象

Java代碼 jbpm學(xué)習(xí)
  1. //生成實(shí)例  
  2. pi = pdf.createProcessInstance();  
  3. assertNotNull("processInstance should not be null", pi);  
  4. //設(shè)置流程發(fā)起人  
  5. pi.getContextInstance().createVariable("initiator", user);  
  6. //觸發(fā)流程轉(zhuǎn)向  
  7. pi.signal();  
      //生成實(shí)例
       pi = pdf.createProcessInstance();
      assertNotNull("processInstance should not be null", pi);
      //設(shè)置流程發(fā)起人
       pi.getContextInstance().createVariable("initiator", user);
      //觸發(fā)流程轉(zhuǎn)向
       pi.signal();

代碼說(shuō)明:
在獲得流程定義的實(shí)例后,可以用它生成流程實(shí)例,使用如下的語(yǔ)句:
pi = pdf.createProcessInstance();
流程實(shí)例擁有自己的ContextInstance環(huán)境變量對(duì)象。它實(shí)際上是一個(gè)HashMap,以key-value方式記錄了流程的上下文變量值,代碼中的
pi.getContextInstance().createVariable("initiator", user);就是向環(huán)境變量中添加一個(gè)key為initiator的對(duì)象。
每個(gè)流程實(shí)例都擁有自己Token令牌對(duì)象,主流程有自己的RootToken,子流程也擁有自己的子Token。父流程的Token和子流程的Token相互關(guān)聯(lián),形成Token樹(shù)。
Token對(duì)象表示流程運(yùn)行的當(dāng)前位置(運(yùn)行到哪個(gè)節(jié)點(diǎn)了)。通過(guò)對(duì)Token對(duì)象的signal()方法調(diào)用,可以使流程向下運(yùn)行。代碼中的 pi.signal();實(shí)際上是間接調(diào)用了pi.getRootToken().signal();它使得新建的流程繼續(xù)向下個(gè)節(jié)點(diǎn)(即借款申請(qǐng)單填 寫(xiě))進(jìn)發(fā)。

3. 員工發(fā)起借款申請(qǐng)

Java代碼 jbpm學(xué)習(xí)
  1. /**
  2. * 填寫(xiě)提交申請(qǐng)單
  3. * @param money
  4. */  
  5. protectedvoid submitApplication(int money){  
  6.         System.out.println("==FirstFlowProcessTest.submitApplication()==");  
  7.      
  8.    TaskInstance ti = (TaskInstance)pi.getTaskMgmtInstance().getTaskInstances().iterator() .next()          
  9.    System.out.println("ti.actor = " + ti.getActorId());  
  10.    ContextInstance ci = ti.getContextInstance();  
  11.    ci.setVariable("money",new Integer(money));  
  12.    ti.end();  
    /**
     * 填寫(xiě)提交申請(qǐng)單
     * @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();
}

代碼說(shuō)明:
在借款流程發(fā)起后,流程進(jìn)入了申請(qǐng)單填寫(xiě)階段。這個(gè)階段是個(gè)人工的任務(wù),需要用戶的介入。因此,對(duì)于要借款的用戶而言,首先是獲取填寫(xiě)申請(qǐng)單的任務(wù)實(shí)例:
    TaskInstance ti = (TaskInstance)pi.getTaskMgmtInstance().getTaskInstances().iterator() .next()        
在這個(gè)測(cè)試類中,由于沒(méi)有數(shù)據(jù)庫(kù)。對(duì)流程實(shí)例的引用是依靠了類的全局標(biāo)量pi。這里通過(guò)pi獲取全部的任務(wù)列表。實(shí)際上有且僅有一個(gè)任務(wù),就是我們剛剛發(fā)起的申請(qǐng)單填寫(xiě)任務(wù)。
接下來(lái),我們獲取流程的上下文變量,將申請(qǐng)借款的數(shù)額記錄在上下文變量中ContextInstance ci = ti.getContextInstance();
   ci.setVariable("money",new Integer(money));
最后,我們要結(jié)束當(dāng)前任務(wù),告訴流程繼續(xù)下行,調(diào)用ti.end();這個(gè)方法的本質(zhì)依然是調(diào)用了token.signal(),它選擇了一個(gè)默 認(rèn)的transition進(jìn)行轉(zhuǎn)向。這里要說(shuō)明的是signal方法有多態(tài)的實(shí)現(xiàn)signal(Transition transition),是可以指定具體轉(zhuǎn)向參數(shù)的。

4. 部門領(lǐng)導(dǎo)審批申請(qǐng)

Java代碼 jbpm學(xué)習(xí)
  1.     /**
  2.     * 部門經(jīng)理審批
  3.     * @param pass
  4.     */      
  5.    @SuppressWarnings("unchecked")  
  6.    protectedvoid approveByManager(boolean pass){        
  7.        System.out.println("==FirstFlowProcessTest.approveByManager()==");          
  8.        Iterator
  9.        for( ;it.hasNext(); ){            
  10.            TaskInstance ti = it.next();              
  11.            if(ti.getActorId().equals("DepartmentManager")){  
  12.                List
  13.                for(Transition t : transitions){  
  14.                    System.out.println("----Transition" + t.getName());  
  15.                }  
  16.                assertEquals("DepartmentManager",ti.getActorId());  
  17.                if(pass){  
  18.                     ti.end("部門經(jīng)理審批通過(guò)");          
  19.                }else{  
  20.                    ti.end("部門經(jīng)理駁回");  
  21.                }  
  22.                return;  
  23.            }  
  24.        }  
  25. }  
     /**
     * 部門經(jīng)理審批
     * @param pass
     */    
    @SuppressWarnings("unchecked")
    protected void approveByManager(boolean pass){    	
        System.out.println("==FirstFlowProcessTest.approveByManager()==");        
        Iterator

代碼說(shuō)明:
這里,流程進(jìn)入了部門經(jīng)理審批階段。由于沒(méi)有數(shù)據(jù)庫(kù)支持,我們只能采取遍歷任務(wù)列表,并比對(duì)委派者ID的方式來(lái)確定委派給部門經(jīng)理的任務(wù)實(shí)例。(在后面的基于數(shù)據(jù)庫(kù)的標(biāo)準(zhǔn)案例中,我們會(huì)看到如果根據(jù)用戶的ID來(lái)獲取分配給指定用戶的任務(wù))
ti.getActorId().equals("DepartmentManager") // 比對(duì)任務(wù)的委派人。
ti.getToken().getNode().getLeavingTransitions();//獲取任務(wù)在當(dāng)前節(jié)點(diǎn)上的所有轉(zhuǎn)向。
這里我們要特別指出的是ti.end("部門經(jīng)理審批通過(guò)")和ti.end("部門經(jīng)理駁回")這實(shí)際上調(diào)用token.signal(transition);來(lái)完成任務(wù)的轉(zhuǎn)向,從而使流程繼續(xù)。

5. 總經(jīng)理審批申請(qǐng)

Java代碼 jbpm學(xué)習(xí)
  1.     /**
  2.     * 總經(jīng)理審批
  3.     * @param pass
  4.     */  
  5.    @SuppressWarnings("unchecked")  
  6.    protectedvoid approveByPresident(boolean pass){  
  7.           System.out.println("==FirstFlowProcessTest.approveByPresident()==");  
  8.           Iterator
  9.            
  10.           for( ;it.hasNext(); ){                
  11.                TaskInstance ti = it.next();                  
  12.                if(ti.getActorId().equals("President")){  
  13.                    List
  14.                    for(Transition t : transitions){  
  15.                        System.out.println("----Transition" + t.getName());  
  16.                    }  
  17.                    assertEquals("President",ti.getActorId());  
  18.                    if(pass){  
  19.                         ti.end("總經(jīng)理審批通過(guò)");      
  20.                    }else{  
  21.                        ti.end("總經(jīng)理駁回");  
  22.                    }  
  23.                    return;  
  24.                }  
  25.           }  
  26. }  
     /**
     * 總經(jīng)理審批
     * @param pass
     */
    @SuppressWarnings("unchecked")
    protected void approveByPresident(boolean pass){
    	   System.out.println("==FirstFlowProcessTest.approveByPresident()=="); 
           Iterator

代碼說(shuō)明:
此步代碼同“部門經(jīng)理審批”代碼相似,不作更多說(shuō)明。

標(biāo)準(zhǔn)流程測(cè)試案例

該案例模擬了標(biāo)準(zhǔn)運(yùn)行環(huán)境中,基于關(guān)系型數(shù)據(jù)庫(kù)的jBPM系統(tǒng)是如何執(zhí)行流程的。
測(cè)試案例類:FirstFlowProcessDBTest.java

Java代碼 jbpm學(xué)習(xí)
  1. publicclass FirstFlowProcessDBTest {    
  2.    /*
  3.     * 初始化jBPM配置
  4.     * 包含對(duì)Hibernate的數(shù)據(jù)庫(kù)初始化
  5.     */  
  6.    static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();      
  7.    publicstaticvoid main(String[] args){  
  8.        FirstFlowProcessDBTest test = new FirstFlowProcessDBTest();  
  9.        test.test4000YuanApplication();  
  10.        test.test6000YuanApplication();  
  11.        test.test7000YuanApplication();  
  12.    }  
  13.      
  14.    publicvoid test4000YuanApplication(){  
  15.        ProcessInstance pi = createProcessInstance("linly");  
  16.        submitApplication("linly" , 4000);  
  17.        approveByManager(true);  
  18.        checkTasks(pi);  
  19.    }  
  20.    publicvoid test6000YuanApplication() {  
  21.        ProcessInstance pi = createProcessInstance("linly");  
  22.        submitApplication("linly" , 6000);  
  23.        approveByManager(true);  
  24.        approveByPresident(true);  
  25.        checkTasks(pi);  
  26.    }    
  27.    publicvoid test7000YuanApplication() {  
  28.        ProcessInstance pi = createProcessInstance("linly");  
  29.        submitApplication("linly" , 7000);  
  30.        approveByManager(true);  
  31.        approveByPresident(false);  
  32.        checkTasks(pi);  
  33.    }  
  34.    /**
  35.     * 生成流程實(shí)例
  36.     */  
  37.    protected ProcessInstance createProcessInstance(String user){  
  38.        System.out.println("==FirstFlowProcessTest.createProcessInstance()==");  
  39.        JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();  
  40.        try {  
  41.             GraphSession graphSession = jbpmContext.getGraphSession();  
  42.             /*
  43.              * 從數(shù)據(jù)庫(kù)獲取指定的流程定義
  44.              */  
  45.             ProcessDefinition pdf  = graphSession.findLatestProcessDefinition("simple");  
  46.             //生成流程實(shí)例  
  47.             ProcessInstance pi = pdf.createProcessInstance();  
  48.             //設(shè)置流程發(fā)起人  
  49.             pi.getContextInstance().createVariable("initiator", user);  
  50.             //觸發(fā)流程轉(zhuǎn)向  
  51.             pi.signal();  
  52.             /*
  53.              * 保存流程實(shí)例
  54.              */  
  55.             jbpmContext.save(pi);            
  56.             return pi;  
  57.        }finally{  
  58.            jbpmContext.close();  
  59.        }  
  60.    }  
  61.      
  62.    /**
  63.     * 填寫(xiě)提交申請(qǐng)單
  64.     * @param money
  65.     */  
  66.    @SuppressWarnings("unchecked")  
  67.    protectedvoid submitApplication(String actorId , int money){  
  68.        System.out.println("==FirstFlowProcessTest.submitApplication()==");  
  69.        JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();  
  70.        try {    
  71.            /*
  72.             *根據(jù)操作者ID,獲取屬于該操作者的任務(wù)集
  73.             */  
  74.            List
  75.            for(TaskInstance ti : taskInstances){  
  76.                System.out.println("ti.name = " + ti.getName());  
  77.                System.out.println("ti.actor = " + ti.getActorId());  
  78.                ContextInstance ci = ti.getContextInstance();  
  79.                ci.setVariable("money",new Integer(money));  
  80.                ti.end();  
  81.            }            
  82.        }finally{  
  83.            jbpmContext.close();      
  84.        }  
  85.    }  
  86.      
  87.    /**
  88.     * 部門經(jīng)理審批
  89.     * @param pass
  90.     */  
  91.    @SuppressWarnings("unchecked")  
  92.    protectedvoid approveByManager(boolean pass){        
  93.        System.out.println("==FirstFlowProcessTest.approveByManager()==");  
  94.        JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();  
  95.        try{  
  96.            List
  97.            for(TaskInstance ti : taskInstances){            
  98.                System.out.println("ti.name = " + ti.getName());  
  99.                System.out.println("ti.actor = " + ti.getActorId());  
  100.                 if(pass){  
  101.                     ti.end("部門經(jīng)理審批通過(guò)");          
  102.                }else{  
  103.                    ti.end("部門經(jīng)理駁回");  
  104.                }            
  105.            }  
  106.        }finally{  
  107.            jbpmContext.close();  
  108.        }  
  109.    }  
  110.      
  111.    /**
  112.     * 總經(jīng)理審批
  113.     * @param pass
  114.     */  
  115.    @SuppressWarnings("unchecked")  
  116.    protectedvoid approveByPresident(boolean pass){  
  117.        System.out.println("==FirstFlowProcessTest.approveByPresident()==");          
  118.        JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();  
  119.        try{  
  120.            List
  121.            for(TaskInstance ti : taskInstances){  
  122.                System.out.println("ti.name = " + ti.getName());  
  123.                System.out.println("ti.actor = " + ti.getActorId());  
  124.                 if(pass){  
  125.                     ti.end("總經(jīng)理審批通過(guò)");      
  126.                }else{  
  127.                    ti.end("總經(jīng)理駁回");  
  128.                }  
  129.            }  
  130.        }finally{  
  131.            jbpmContext.close();  
  132.        }  
  133.    }  
  134.      
  135.    /**
  136.     * 打印任務(wù)記錄
  137.     */  
  138.    @SuppressWarnings("unchecked")  
  139.    protectedvoid checkTasks(ProcessInstance pi){        
  140.        System.out.println("==FirstFlowProcessTest.checkTasks()==");  
  141.        JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();  
  142.        try{                      
  143.            List
  144.            System.out.println("====Process has task:====");      
  145.            for(TaskInstance ti : coll){      
  146.                   System.out.println("=="+ti.getName()+"==");    
  147.                   System.out.println("=="+ti.getActorId()+"==");    
  148.                   System.out.println("=="+ti.getVariables().toString() +"==");  
  149.            }    
  150.            System.out.println("====end====");  
  151.        }finally{  
  152.            jbpmContext.close();  
  153.        }  
  154.    }      
  155. }  
public class FirstFlowProcessDBTest {	
	/*
	 * 初始化jBPM配置
	 * 包含對(duì)Hibernate的數(shù)據(jù)庫(kù)初始化
	 */
    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);
	} 
    /**
     * 生成流程實(shí)例 
     */
    protected ProcessInstance createProcessInstance(String user){
        System.out.println("==FirstFlowProcessTest.createProcessInstance()==");
        JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
        try {
        	 GraphSession graphSession = jbpmContext.getGraphSession();
             /*
              * 從數(shù)據(jù)庫(kù)獲取指定的流程定義
              */
        	 ProcessDefinition pdf  = graphSession.findLatestProcessDefinition("simple");
        	 //生成流程實(shí)例
        	 ProcessInstance pi = pdf.createProcessInstance();
        	 //設(shè)置流程發(fā)起人
        	 pi.getContextInstance().createVariable("initiator", user);
        	 //觸發(fā)流程轉(zhuǎn)向
        	 pi.signal();
        	 /*
        	  * 保存流程實(shí)例 
        	  */
        	 jbpmContext.save(pi);        	 
        	 return pi;
        }finally{
        	jbpmContext.close();
        }
    }
    
    /**
     * 填寫(xiě)提交申請(qǐng)單
     * @param money
     */
    @SuppressWarnings("unchecked")
    protected void submitApplication(String actorId , int money){
        System.out.println("==FirstFlowProcessTest.submitApplication()=="); 
    	JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
	    try {  	
            /*
             *根據(jù)操作者ID,獲取屬于該操作者的任務(wù)集
向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI