轉自小小冰 http://blog.csdn.net/kellerdu/archive/2004/11/08/172247.aspx
-----------------------------------------------------------------------
-------
-------
-------
--
示例:
在某一公司中,部門員工要休假的話需要部門主管的批準。如果休假天數大于10天的話,在部門主管的同意后,還必須上級主管批準。如果是部門主管要休假只要上級主管批準即可。在休假被批準之前,申請人可以撤銷休假申請。
每
個員工還有多少天休假必須管理起來,在員工提交休假申請時要檢查申請天數是否超過可用天數。申請批準后,要在可用天數里減去申請天數。每次休假申請結束之
后,不管通過未通過或是否取消,都必須記錄下來。主管在批復申請之后,系統要將批復結果Email給申請人。對于大于10天的申請,如果部門主管已批準同
意而上級主管還未批準,這時申請人撤銷申請后,系統應發Email通知部門主管申請已撤銷。
processdefinition.xml如下:
??1?<?xml?version="1.0"?encoding="UTF-8"?>
??2?<!--?edited?with?XMLSPY?v2004?rel.?3?U?(http://www.xmlspy.com)?by?keller?(zju)?-->
??3?<!DOCTYPE?process-definition?PUBLIC
??4?????"-//jBpm/jBpm?Mapping?DTD?2.0//EN"
??5?????"http://jbpm.org/dtd/processdefinition-2.0.dtd">
??6?<process-definition??name="RequestLeave">
??7??<swimlane?name="requester">
??8???<description>申請者</description>
??9??</swimlane>
?10??<swimlane?name="chief">
?11???<description>部門主管</description>
?12???<delegation?class="kellerdu.jbpm.delegation.ChiefSwimlane"/>
?13??</swimlane>
?14??<swimlane?name="boss">
?15???<description>上級主管</description>
?16???<delegation?class="kellerdu.jbpm.delegation.BossSwimlane"/>
?17??</swimlane>
?18??<start-state?name="request"?swimlane="requester">
?19???<transition?to="BeginRequest"/>
?20??</start-state>
?21??<fork?name="BeginRequest">
?22???<transition?to="RequesterCancel"/>
?23???<transition?to="IsChief"/>
?24??</fork>
?25??<decision?name="IsChief">
?26???<delegation?class="kellerdu.jbpm.delegation.ChiefDecision"/>
?27???<transition?name="BossApprove"??to="BossApprove"/>
?28???<transition?name="ChiefApprove"??to="ChiefApprove"/>
?29??</decision>
?30??<state?name="RequesterCancel">
?31???<assignment?swimlane="requester"/>
?32???<transition?name="cancel"?to="Decided">
?33????<action>
?34?????<!--?將請假的狀態改變為“取消”-->
?35?????<delegation?class="kellerdu.jbpm.action.RequestCancel"/>
?36????</action>
?37???</transition>
?38??</state>
?39??<state?name="ChiefApprove">
?40???<assignment?swimlane="chief"/>
?41???<transition?name="approve"?to="NeedBossApprove">
?42????<action>
?43?????<!--?將請假的狀態改變為“主管批準”-->
?44?????<delegation?class="kellerdu.jbpm.action.ChiefApprove"/>
?45????</action>
?46???</transition>
?47???<transition?name="disapprove"?to="Decided">
?48????<action>
?49?????<!--?將請假的狀態改變為“主管否決”-->
?50?????<delegation?class="kellerdu.jbpm.action.ChiefDisapprove"/>
?51????</action>
?52???</transition>
?53??</state>
?54??<state?name="BossApprove">
?55???<assignment?swimlane="boss"/>
?56???<transition?name="approve"?to="Decided">
?57????<action>
?58?????<!--?將請假的狀態改變為“老板批準”-->
?59?????<delegation?class="kellerdu.jbpm.action.BossApprove"/>
?60????</action>
?61???</transition>
?62???<transition?name="disapprove"?to="Decided">
?63????<action>
?64?????<!--?將請假的狀態改變為“老板否決”-->
?65?????<delegation?class="kellerdu.jbpm.action.BossDisapprove"/>
?66????</action>
?67???</transition>
?68??</state>
?69??<decision?name="NeedBossApprove">
?70???<!--?請假天數大于10天的要老板批準??-->
?71???<delegation?class="kellerdu.jbpm.delegation.NeedBossApproveDecision"/>
?72???<transition?name="need"?to="BossApprove"/>
?73???<transition?name="notNeed"?to="Decided"/>
?74??</decision>
?75??<join?name="Decided">
?76???<description>有一個先到達即進行父Token</description>
?77???<delegation?class="kellerdu.jbpm.delegation.DecidedJoin"/>
?78???<transition?to="DoSomething"/>
?79??</join>
?80??<decision?name="DoSomething">
?81???<description>
?82?????根據請求的狀態決定。
?83?????(1)“主管或者老板批準”-‘approve’:修改員工休假的總天數,設定發給用戶E-Mail的信息。
?84?????(2)“主管或者老板否決”-“disapprove”:設定發給用戶E-Mail的信息。
?85?????(3)“撤銷”-"cancel"-設定發給用戶E-Mail的信息。如果主管批準,要發給主管消息說明已經撤銷。
?86?????</description>
?87???<delegation?class="kellerdu.jbpm.delegation.DoSomethingDecision"/>
?88???<transition?name="disapprove"?to="Finished">
?89????<action>
?90?????<delegation?class="kellerdu.jbpm.action.Disapprove"/>
?91????</action>
?92???</transition>
?93???<transition?name="approve"?to="Finished">
?94????<action>
?95?????<delegation?class="kellerdu.jbpm.action.Approve"/>
?96????</action>
?97???</transition>
?98???<transition?name="cancel"?to="Finished">
?99????<action>
100?????<delegation?class="kellerdu.jbpm.action.Cancel"/>
101????</action>
102???</transition>
103??</decision>
104??<end-state?name="Finished"/>
105??<action?event-type="process-end">
106???<!--?發送E-Mail消息給申請者,記錄請假日志?-->
107???<delegation?class="kellerdu.jbpm.action.ProcessEndAction"/>
108??</action>
109?</process-definition>
Action指明的是當前狀態要執行的一些額外的操作,如記錄log、發郵件等。
(1)Swimline的delegation要做的就是判別當前Actor的身份。
?1?package?kellerdu.jbpm.delegation;
?2?
?3?import?org.jbpm.delegation.*;
?4?import?kellerdu.jbpm.LogsFactory;
?5?import?org.apache.commons.logging.Log;
?6?
?7?public?class?BossSwimlane?implements?AssignmentHandler?{
?8?????public?BossSwimlane()?{
?9?????}
10?
11?????/**
12??????*?當前的狀態有哪個actor來具體負責處理,選擇是老板的actor來處理。
13??????*
14??????*?如果王林是老板,那么他請假可以用他的名稱來開始一個請假流程,當他檢查他需要批示的
15??????*?請假時,使用actorId=boss來找出所有的批示。這時selectActor返回的值就是一個常量“boss”
16??????*
17??????*
18??????*?@param?assignmentContext?AssignmentContext
19??????*?@return?String
20??????*?@todo?Implement?this?org.jbpm.delegation.AssignmentHandler?method
21??????*/
22?????public?String?selectActor(AssignmentContext?assignmentContext)?{
23?????????Log?log?=?LogsFactory.getLogInstance(this.getClass());
24?????????log.info("任務分配給老板");
25?????????return?"boss";
26?????}
27?}
28?
?1?package?kellerdu.jbpm.delegation;
?2?
?3?import?org.jbpm.delegation.*;
?4?import?kellerdu.jbpm.LogsFactory;
?5?import?org.apache.commons.logging.Log;
?6?
?7?public?class?ChiefSwimlane?implements?AssignmentHandler?{
?8?????public?ChiefSwimlane()?{
?9?????}
10?????/**
11??????*?selectActor
12??????*?@see?BossSwimlane
13??????*
14??????*?@param?assignmentContext?AssignmentContext
15??????*?@return?String
16??????*?@todo?Implement?this?org.jbpm.delegation.AssignmentHandler?method
17??????*/
18?????public?String?selectActor(AssignmentContext?assignmentContext)?{
19????????Log?log?=?LogsFactory.getLogInstance(this.getClass());
20?????????log.info("任務分配給上級主管");
21????????return?"chief";
22?????}
23?}
(二)Decision
?1?package?kellerdu.jbpm.delegation;
?2?
?3?import?org.jbpm.delegation.*;
?4?import?kellerdu.jbpm.LogsFactory;
?5?import?org.apache.commons.logging.Log;
?6?import?kellerdu.jbpm.Constants;
?7?
?8?public?class?ChiefDecision?implements?DecisionHandler?{
?9?????public?ChiefDecision()?{
10?????}
11?
12?????/**
13??????*?判斷是否需要主管批準,決定下一個要進行的transition
14??????*
15??????*?@param?executionContext?ExecutionContext
16??????*?@return?String
17??????*?@todo?Implement?this?org.jbpm.delegation.DecisionHandler?method
18??????*/
19?????public?String?decide(ExecutionContext?executionContext)?{
20?????????Log?log=LogsFactory.getLogInstance(this.getClass());
21?????????String?ac=(String)executionContext.getVariable(Constants.USER_NAME);
22?????????if(ac!=null&&(ac.equals("dali")||ac.equals("wang"))){
23?????????????log.info(ac+"需要老板批準!");
24?????????????return?"BossApprove";
25?????????}else{
26?????????????log.info(ac+"需要先經主管批準");
27?????????????return?"ChiefApprove";
28?????????}
29?????}
30?}
(三)fork
?1?package?kellerdu.jbpm.delegation;
?2?
?3?import?org.jbpm.*;
?4?import?org.jbpm.delegation.*;
?5?import?org.jbpm.model.execution.*;
?6?import?java.util.*;
?7?
?8?public?class?DecidedJoin?implements?JoinHandler?{
?9?????public?DecidedJoin()?{
10?????}
11?
12?????/**
13??????*?fork,只要一個分支到達,即可進行下一步操作,同時取消其它同時進行的分支。
14??????*?這里就是用戶如果取消,請假就取消。如果用戶請假批準,則用戶不能取消。
15??????*
16??????*?@param?forkContext?ForkContext
17??????*?@throws?ExecutionException
18??????*?@todo?Implement?this?org.jbpm.delegation.ForkHandler?method
19??????*/
20?????public?void?join(JoinContext?joinContext)?throws?ExecutionException?{
21?????????Iterator?it=joinContext.getConcurrentTokens().values().iterator();
22?????????Token?arrivingToken?=?joinContext.getToken();
23?????????while(it.hasNext()){
24?????????????Token?to=(Token)it.next();
25?????????????if(to.getId().equals(arrivingToken.getId())){
26?????????????????//取消其它執行的Token
27?????????????????joinContext.getExecutionService().cancelToken(to.getId());
28?????????????}
29?????????}
30??????????//?reactivate?the?parent?token.
31???????????joinContext.reactivateToken(?arrivingToken.getParent()?);
32?????}
33?}
(一)? 開始一個請假流程
??1???????//user是請假人的actorId
?2????????ExecutionService?es=JbpmServiceFactory.getInstance().openExecutionService(user);
?3?????????HashMap?vs=new?HashMap();
?4????????//一些參數
?5?????????vs.put(Constants.REQUEST_STATUS,String.valueOf(0));
?6?????????vs.put(Constants.REQUEST_RETURN_INFO,"No?info!");
?7?????????vs.put(Constants.USER_NAME,EncodeTransfer.toISO(user));
?8?????????vs.put(Constants.REQUEST_DAYS,String.valueOf(rea.getDays()));
?9?????????try?{
10????????????//開啟請假流程
11?????????????es.startProcessInstance(Constants.WORK_NAME,?vs);
12?????????????log.info("["+user+"]"+"申請假期開始!請假"+rea.getDays()+"天!");
13?????????????return?am.findForward("main");
14?????????}?catch?(ExecutionException?ex)?{
15?????????????ex.printStackTrace();
16?????????????log.error("請假進程無法開始!");
17?????????????return?am.findForward("error");
18?????????}finally{
19?????????????es.close();
20?????????}
(二)當前執行任務
?對于部門經理或者老板,找到要處理的請假。?1??????String?actorId?=?(String)?req.getSession().getAttribute(Constants.USER);
?2?????????????if(actorId.equals("wang")){
?3?????????????????actorId="boss";
?4?????????????}else?if(actorId.equals("bigli")){
?5?????????????????actorId="chief";
?6?????????????}
?7?????????????//?get?the?execution?service
?8?????????????ExecutionService?executionService?=?JbpmServiceFactory.getInstance().
?9?????????????????????????????????????????????????openExecutionService(actorId);
10?
11?????????????//?get?the?tasklist?from?jbpm?for?user
12?????????????List?tasks?=?new?ArrayList();
13?????????????//?add?the?jbpm?tasks
14?????????????tasks.addAll(executionService.getTaskList(actorId));
15?????????????//?put?the?tasklist?into?the?form
16?????????????mf.setTasks(tasks);
17?????????????//?get?the?tasklist?from?jbpm?for?user
18?????????????List?definitions?=?new?ArrayList();
19?????????????//?add?the?jbpm?definitions
20?????????????definitions.addAll(executionService.getLatestDefinitions());
21?????????????//?put?the?tasklist?into?the?form
22?????????????mf.setRequests(definitions);
23?????????????//?close?the?execution?service
24?????????????executionService.close();
25?????????????req.getSession().setAttribute("mainForm",mf);
26?????????????log.debug("任務:?"?+?tasks);
27?????????????log.debug("當前可以執行的請求:?"?+?definitions);
28?
(三)處理請假
?1??????????String?actorId?=?(String)?reqrest.getSession().getAttribute(Constants.
?2?????????????????????USER);
?3?????????????Long?tokenId=new?Long(req.getParameter("tokenId"));
?4?????????????//?get?the?execution?service
?5?????????????ExecutionService?executionService?=?JbpmServiceFactory.getInstance().
?6?????????????????????????????????????????????????openExecutionService(actorId);
?7?????????????Map?hm=executionService.getVariables(tokenId);//變量
?8?????????????String?act=req.getParameter("action");//進行轉換的transition
?9?????????????executionService.endOfState(tokenId,hm,act);
10?????????????executionService.close();