一个Jbpm员工请假流程的实例
作者:吴大愚
Email:dywu_xa@sina.com
2006-10-26
适用于jbpm3.1版本
此实例包括的是一个员工请假审批的流程实例,和流程相关的代码以及相应的测试代码。此流程在Eclipse 3.1.2 ,JBoss-IDE 1.6环境下测试通过。
假设应用背景如下:
在某一公司中,部门员工要休假的话需要部门主管的批准。如果休假天数大于10天的话,在部门主管的同意后,还必须老板批准。如果是部门主管要休假只要老板批准即可。在休假被批准之前,申请人可以撤销休假申请。
每次休假申请结束之后,不管通过未通过或是否取消,都必须记录下来。主管在批复申请之后,系统要将批复结果Email给申请人。对于大于10天的申请,如果部门主管已批准同意而上级主管还未批准,这时申请人撤销申请后,系统应发Email通知部门主管申请已撤销。
<?xml version="1.0" encoding="UTF-8"?>
<process-definition
xmlns="urn:jbpm.org:jpdl-3.1" name="MyRequest">
<start-state name="SS_Request">
<transition name="" to="TN_WriteRequest"></transition>
</start-state>
<task-node name="TN_WriteRequest">
<task name="Task_WriteRequest">
<controller>
<variable name="dayCount" access="read,write,required"></variable>
</controller>
<assignment class="com.myrequest.task.WriteRequestAssignmentHandler"></assignment>
</task>
<transition name="Tr_WriteLeave" to="Fork_request">
<action name="Ac_WriteLeave" class="com.myrequest.action.WriteLeaveActionHandler"></action>
</transition>
</task-node>
<fork name="Fork_request">
<transition name="Tr_Cancel" to="TN_RequesterCancel"></transition>
<transition name="Tr_Request" to="Deci_IsChiefHere">
<action name="Ac_GetChiefState" class="com.myrequest.action.GetChiefStateActionHandler"></action>
</transition>
</fork>
<decision name="Deci_IsChiefHere">
<handler class="com.myrequest.decision.IsChiefHereDecisionHandler"/>
<transition name="Tr_Chief" to="TN_ChiefDecide"></transition>
<transition name="Tr_Boss" to="TN_BossDecide"></transition>
</decision>
<task-node name="TN_RequesterCancel">
<task name="Task_CancelRequest">
<assignment class="com.myrequest.task.CancelRequestAssignmentHandler"></assignment>
</task>
<transition name="Tr_RequestCancel" to="Join_Request">
<action name="Ac_RequestCancel" class="com.myrequest.action.RequestCancelActionHandler"></action>
</transition>
</task-node>
<task-node name="TN_ChiefDecide">
<task name="Task_ChiefDecide">
<assignment class="com.myrequest.task.ChiefDecideAssignmentHandler"></assignment>
</task>
<transition name="Tr_ChiefApprove" to="Deci_NeedBossDecide">
<action name="Ac_ChiefApprove" class="com.myrequest.action.ChiefApproveActionHandler"></action>
</transition>
<transition name="Tr_ChiefNotApprove" to="Join_Request">
<action name="Ac_ChiefNotApprove" class="com.myrequest.action.ChiefNotApproveActionHandler"></action>
</transition>
</task-node>
<join name="Join_Request">
<transition name="Tr_Join" to="Deci_DoSomething"></transition>
</join>
<decision name="Deci_NeedBossDecide">
<handler class="com.myrequest.decision.NeedBossDecideDecisionHandler"/>
<transition name="Tr_Need" to="TN_BossDecide"></transition>
<transition name="Tr_NotNeed" to="Join_Request">
<action name="Ac_NotNeed" class="com.myrequest.action.NotNeedActionHandler"></action>
</transition>
</decision>
<task-node name="TN_BossDecide">
<task name="Task_BossDecide">
<assignment class="com.myrequest.task.BossDecideAssignmentHandler"></assignment>
</task>
<transition name="Tr_BossApprove" to="Join_Request">
<action name="Ac_BossApprove" class="com.myrequest.action.BossApproveActionHandler"></action>
</transition>
<transition name="Tr_BossNotApprove" to="Join_Request">
<action name="Ac_BossNotApprove" class="com.myrequest.action.BossNotApproveActionHandler"></action>
</transition>
</task-node>
<decision name="Deci_DoSomething">
<handler class="com.myrequest.decision.DoSomethingDecisionHandler"/>
<transition name="Tr_Approve" to="ES_Finished">
<action name="Ac_Approve" class="com.myrequest.action.ApproveActionHandler"></action>
</transition>
<transition name="Tr_NotApprove" to="ES_Finished">
<action name="Ac_NotApprove" class="com.myrequest.action.NotApproveActionHandler"></action>
</transition>
<transition name="Tr_Cancel" to="ES_Finished">
<action name="Ac_Cancel" class="com.myrequest.action.CancelActionHandler"></action>
</transition>
</decision>
<end-state name="ES_Finished">
<event type="node-enter">
<action name="Ac_Finished" class="com.myrequest.action.FinishedActionHandler"></action>
</event>
</end-state>
</process-definition>
start-state的定义为SS_
end-state的定义为ES_
task-node的定义为TN_
fork的定义为Fork_
join的定义为Join_
task的定义为Task_
transition的定义为Tr_
action的定义为Ac_
join结点Join_Request,采用的是Discriminator模式,即只要有一个fork发出的分支到达join,流程就可以向下进行。
Join共有三中模式:
l 默认的是所有fork发出的分支都到达,流程才向下进行;
l 第二种就是Discriminator模式,只要有一个fork发出的分支到达join,流程就可以向下进行;
l 第三种是设置当有n个分支到达之后,流程就可以向下进行。
但jpdl语言在jbpm3.1版本中还不支持对第二,第三两种模式的设置。需要在流程实例化之后,来制定join的模式。具体如何实现,参见后面有关代码部分。
系统存在一个有关申请的状态。系统用流程变量RequestState来存储。共有五个状态。存储在com.myrequest.RequestState.java文件中。
在用户启动此请假流程,完成第一个填写请假申请的任务实例后,此状态置为REQUEST。在完成取消请求任务之后,状态改为CANCEL。等等,读者可以仔细阅读流程定义和对应的代码。
要说明的是所有的状态修改都在完成任务之后的边上执行Action中来修改的。这样虽然增加了很多Action,但是状态修改明确。但对于这样的简单问题,前台代码在实际任务完整之后,就可以调用修改此状态变量。此处将这些修改都放在Action里面,也有一定演示的含义。
在fork节点后,产生两个并行分支。其中一个TN_RequestCancel任务节点包含一个Task_CancelRequest的任务。当此分支执行到这里时,会把这个任务分配给启动流程的用户。在流程没有结束的时候,如果用户执行这个任务,就表示用户要取消请假申请。在这个取消申请的任务会修改请假状态,在此任务结束后,就会首先到达join节点。表示取消了此次申请操作。
本实例是在Eclipse 3.1.2 里面实现的。
l com.myrequest
n 存放流程的公共信息,包括:
n interface RequestState,用来存放请求状态的5种状态
n interface RequestVariable 存放流程实例的变量名
l com.myrequest.action
n 存放流程中所有的ActionHandler类
n 共有12个类,每个类对应流程中一个action的代码。
l com.myrequest.task
n 存放流程中所有的task的AssignmentHandler分配类
n 共有4个类,对应4个task
l com.myrequest.decision
n 存放流程中所有的decision节点的判断类
n 包括3个类,对应3个Decision节点
l com.myrequest
n 包含此流程的测试类 MyRequestProcessTest.java
l
因篇幅问题不能全部显示,请点此查看更多更全内容