今天终于完成了struts+hibernate+spring的一个简单的WF事例, 又看了chenjin同志的BLOG"jbpm 使用日记5 一个简单会签示例",觉得需要记录下来:
以下例子中 采用了jbpm console 的几个示例用户
项目提交人 : ernie .
主管审批 : bert
会签 : ernie , bert , grover
老板审批 : grover
正常流程: 项目金额 >= 500W RMB
提交项目 --> 主管审批 --> 会签 --> 老板审批 --> 审批通过(结束)
正常流程: 项目金额 < 500W RMB
提交项目 --> 主管审批 --> 会签 --> 审批通过(结束)
其中主管审批, 会签, 老板审批 , 不通过, 全部退回给项目提交人修改.
会签中: 所有人全通过, 则通过. 任何一人不通过, 停止其他会签任务.退回给提交人.
流程定义如下:
代码
- <?xml
version="1.0" encoding="UTF-8"?> -
- <process-definition
xmlns="urn:jbpm.org:jpdl-3.1" -
name="tc_prj_approval"> -
-
<swimlane name="initiator" /> -
-
<!-- 项目提交人 --> -
<swimlane name="requester"> -
<assignment expression="user(ernie)" /> -
</swimlane> -
-
<!-- 主管 --> -
<swimlane name="chief"> -
<assignment expression="user(bert)" /> -
</swimlane> -
-
<!-- 老板 --> -
<swimlane name="boss"> -
<assignment expression="user(grover)" /> -
</swimlane> -
-
<!-- 会签人 --><!-- 原来可以用这些方式实现用户组,从CosingerAssiHandler 类中去加载用户.--> -
<swimlane name="cosinger"> -
<assignment class="net.chenj.jbpm.sample.CosingerAssiHandler"> -
</assignment> -
</swimlane> -
<start-state name="start"> -
<task name="tc_prj_newprj" swimlane="initiator"></task> -
<transition name="to_submit" to="tc_prj_submit"></transition> -
</start-state> -
<task-node name="tc_prj_submit"> -
<task name="tc_prj_submit"></task> -
<transition name="to_chiefapprove" to="tc_prj_chiefapprove"></transition> -
</task-node> -
<task-node name="tc_prj_chiefapprove"> -
<task name="tc_prj_chiefapprove"></task> -
<transition name="approve" to="tc_prj_countersign"></transition> -
<transition name="disapprove" to="tc_prj_submit"></transition> -
</task-node> -
<task-node name="tc_prj_countersign" signal="last-wait" -
create-tasks="false"> <!-- 不让流程创建task,使用event去手工创建task,这里一次创建了三个task --> -
<task name="tc_prj_countersign"> -
<event type="task-end"> -
<action -
class="net.chenj.jbpm.sample.TaskEndCountersign"> <!-- 如果随便哪个会签人拒绝了申请,将停掉其他二个task. --> -
</action> -
</event> -
-
</task> -
-
<event type="node-enter"> -
<action name="createInstance" -
class="net.chenj.jbpm.sample.CreateTaskInstanceCountersign"> -
</action> -
</event> -
-
<transition name="approve" to="amount_decision"></transition> -
<transition name="disapprove" to="tc_prj_submit"></transition> -
</task-node> -
<decision name="amount_decision"> -
<transition name="to_bossapprove" to="tc_prj_bossapprove"></transition> -
<transition name="to_end" to="end1"></transition> -
</decision> -
<task-node name="tc_prj_bossapprove"> -
<task name="tc_prj_bossapprove"></task> -
<transition name="approve" to="end1"></transition> -
<transition name="disapprove" to="tc_prj_submit"> -
<condition>#{amount >= 500}</condition> -
</transition> -
</task-node> -
<end-state name="end1"></end-state> - </process-definition>
-
会签swimlane class
代码
- package
net.chenj.jbpm.sample; -
- import
org.jbpm.graph.exe.*; - import
org.jbpm.taskmgmt.def.*; - import
org.jbpm.taskmgmt.exe.Assignable; -
- public
class CosingerAssiHandler implements AssignmentHandler { -
-
private static final long serialVersionUID = 1L; -
-
public void assign(Assignable assignable, ExecutionContext executionContext) { -
// 从数据库或者ldap 读取会签人设置 -
String[] a = { "ernie", "bert", "grover" }; -
assignable.setPooledActors(a); -
} -
- }
-
创建会签任务实现类
代码
- package
net.chenj.jbpm.sample; -
- import
org.jbpm.graph.def.ActionHandler; - import
org.jbpm.graph.exe.ExecutionContext; - import
org.jbpm.graph.exe.Token; - import
org.jbpm.graph.node.TaskNode; - import
org.jbpm.taskmgmt.def.Task; - import
org.jbpm.taskmgmt.exe.TaskMgmtInstance; -
- public
class CreateTaskInstanceCountersign implements ActionHandler { -
-
private static final long serialVersionUID = 1L; -
-
public void execute(ExecutionContext executionContext) throws Exception { -
-
Token token = executionContext.getToken(); -
TaskMgmtInstance tmi = executionContext.getTaskMgmtInstance(); -
TaskNode taskNode = (TaskNode) executionContext.getNode(); -
Task task = taskNode.getTask("tc_prj_countersign"); -
// 从数据库或者ldap 读取会签人设置创建任务实例 -
tmi.createTaskInstance(task, token).setActorId("ernie"); -
tmi.createTaskInstance(task, token).setActorId("bert"); -
tmi.createTaskInstance(task, token).setActorId("grover"); -
-
} -
- }
结束不通过时结束其他会签任务实现
代码
- package
net.chenj.jbpm.sample; -
- import
java.util.Collection; - import
java.util.Iterator; - import
org.jbpm.graph.def.ActionHandler; - import
org.jbpm.graph.exe.ExecutionContext; - import
org.jbpm.taskmgmt.exe.TaskInstance; - import
org.jbpm.taskmgmt.exe.TaskMgmtInstance; -
- public
class TaskEndCountersign implements ActionHandler { -
-
private static final long serialVersionUID = 1L; -
-
public void execute(ExecutionContext executionContext) throws Exception { -
-
-
boolean isDisapprove = Boolean.valueOf((String) executionContext -
.getVariable("isDisapprove")); -
// 如果有一个任务实例拒绝通过则结束除当前任务实例外其他任务实例 -
if (isDisapprove) { -
TaskMgmtInstance tmi = executionContext.getTaskMgmtInstance(); -
TaskInstance ti = executionContext.getTaskInstance(); -
final String actorId = ti.getActorId(); -
Collection c = tmi.getSignallingTasks(executionContext); -
for (Iterator it = c.iterator(); it.hasNext();) { -
TaskInstance task = (TaskInstance) it.next(); -
if (!(actorId.equals(task.getActorId())) && (!task.hasEnded())) { -
task.end("disapprove"); -
} -
} -
} -
-
} -
- }
感谢 tomkoo提供了会签的实现思路.