http://www.blogjava.net/jbpm/archive/2007/10/15/153036.html
一个简单的会签实例
作者:tomkoo
以下例子中 采用了jbpm console 的几个实例用户
项目提交人 : ernie .
主管审批 : bert
会签 : ernie , bert , grover
老板审批 : grover
正常流程: 项目金额 >= 500W RMB
提交项目 --> 主管审批 --> 会签 --> 老板审批 --> 审批通过(结束)
正常流程: 项目金额 < 500W RMB
提交项目 --> 主管审批 --> 会签 --> 审批通过(结束)
其中主管审批, 会签, 老板审批 , 不通过, 全部退回给项目提交人修改.
会签中: 所有人全通过, 则通过. 任何一人不通过, 停止其他会签任务.退回给提交人.
流程定义如下:
1. <?xml version="1.0" encoding="UTF-8"?>
2.
3. <process-definition xmlns="urn:jbpm.org:jpdl-3.1"
4. name="tc_prj_approval">
5.
6. <swimlane name="initiator" />
7.
8. <!项目提交人 >
9. <swimlane name="requester">
10. <assignment expression="user(ernie)" />
11. </swimlane>
12.
13. <! 主管 >
14. <swimlane name="chief">
15. <assignment expression="user(bert)" />
16. </swimlane>
17.
18. <!老板 >
19. <swimlane name="boss">
20. <assignment expression="user(grover)" />
21. </swimlane>
22.
23. <!会签人 >
24. <swimlane name="cosinger">
25. <assignment class="net.chenj.jbpm.sample.CosingerAssiHandler">
26. </assignment>
27. </swimlane>
28. <start-state name="start">
29. <task name="tc_prj_newprj" swimlane="initiator"></task>
30. <transition name="to_submit" to="tc_prj_submit"></transition>
31. </start-state>
32. <task-node name="tc_prj_submit">
33. <task name="tc_prj_submit"></task>
34. <transition name="to_chiefapprove" to="tc_prj_chiefapprove"></transition>
35. </task-node>
36. <task-node name="tc_prj_chiefapprove">
37. <task name="tc_prj_chiefapprove"></task>
38. <transition name="approve" to="tc_prj_countersign"></transition>
39. <transition name="disapprove" to="tc_prj_submit"></transition>
40. </task-node>
41. <task-node name="tc_prj_countersign" signal="last-wait"
42. create-tasks="false">
43. <task name="tc_prj_countersign">
44. <event type="task-end">
45. <action
46. class="net.chenj.jbpm.sample.TaskEndCountersign">
47. </action>
48. </event>
49.
50. </task>
51.
52. <event type="node-enter">
53. <action name="createInstance"
54. class="net.chenj.jbpm.sample.CreateTaskInstanceCountersign">
55. </action>
56. </event>
57.
58. <transition name="approve" to="amount_decision"></transition>
59. <transition name="disapprove" to="tc_prj_submit"></transition>
60. </task-node>
61. <decision name="amount_decision">
62. <transition name="to_bossapprove" to="tc_prj_bossapprove"></transition>
63. <transition name="to_end" to="end1"></transition>
64. </decision>
65. <task-node name="tc_prj_bossapprove">
66. <task name="tc_prj_bossapprove"></task>
67. <transition name="approve" to="end1"></transition>
68. <transition name="disapprove" to="tc_prj_submit">
69. <condition>#{amount >= 500}</condition>
70. </transition>
71. </task-node>
72. <end-state name="end1"></end-state>
73. </process-definition>
74.
会签swimlane class
1. package net.chenj.jbpm.sample;
2.
3. import org.jbpm.graph.exe.*;
4. import org.jbpm.taskmgmt.def.*;
5. import org.jbpm.taskmgmt.exe.Assignable;
6.
7. public class CosingerAssiHandler implements AssignmentHandler {
8.
9. private static final long serialVersionUID = 1L;
10.
11. public void assign(Assignable assignable, ExecutionContext executionContext) {
12. // 从数据库或者ldap 读取会签人设置
13. String[] a = { "ernie", "bert", "grover" };
14. assignable.setPooledActors(a);
15. }
16.
17. }
18.
创建会签任务实现类
1. package net.chenj.jbpm.sample;
2.
3. import org.jbpm.graph.def.ActionHandler;
4. import org.jbpm.graph.exe.ExecutionContext;
5. import org.jbpm.graph.exe.Token;
6. import org.jbpm.graph.node.TaskNode;
7. import org.jbpm.taskmgmt.def.Task;
8. import org.jbpm.taskmgmt.exe.TaskMgmtInstance;
9.
10. public class CreateTaskInstanceCountersign implements ActionHandler {
11.
12. private static final long serialVersionUID = 1L;
13.
14. public void execute(ExecutionContext executionContext) throws Exception {
15.
16. Token token = executionContext.getToken();
17. TaskMgmtInstance tmi = executionContext.getTaskMgmtInstance();
18. TaskNode taskNode = (TaskNode) executionContext.getNode();
19. Task task = taskNode.getTask("tc_prj_countersign");
20. // 从数据库或者ldap 读取会签人设置创建任务实例
21. tmi.createTaskInstance(task, token).setActorId("ernie");
22. tmi.createTaskInstance(task, token).setActorId("bert");
23. tmi.createTaskInstance(task, token).setActorId("grover");
24.
25. }
26.
27. }
结束不通过时结束其他会签任务实现
1. package net.chenj.jbpm.sample;
2.
3. import java.util.Collection;
4. import java.util.Iterator;
5. import org.jbpm.graph.def.ActionHandler;
6. import org.jbpm.graph.exe.ExecutionContext;
7. import org.jbpm.taskmgmt.exe.TaskInstance;
8. import org.jbpm.taskmgmt.exe.TaskMgmtInstance;
9.
10. public class TaskEndCountersign implements ActionHandler {
11.
12. private static final long serialVersionUID = 1L;
13.
14. public void execute(ExecutionContext executionContext) throws Exception {
15.
16.
17. boolean isDisapprove = Boolean.valueOf((String) executionContext
18. .getVariable("isDisapprove"));
19. // 如果有一个任务实例拒绝通过则结束除当前任务实例外其他任务实例
20. if (isDisapprove) {
21. TaskMgmtInstance tmi = executionContext.getTaskMgmtInstance();
22. TaskInstance ti = executionContext.getTaskInstance();
23. final String actorId = ti.getActorId();
24. Collection c = tmi.getSignallingTasks(executionContext);
25. for (Iterator it = c.iterator(); it.hasNext();) {
26. TaskInstance task = (TaskInstance) it.next();
27. if (!(actorId.equals(task.getActorId())) && (!task.hasEnded())) {
28. task.end("disapprove");
29. }
30. }
31. }
32.
33. }
34.
35. }
task-node"主管会计复核"则是我们需要进行会签的节点。在这个节点我们设置了几个重要的属性:
1) signal="last-wait",这个属性决定了该节点将在完成该节点内的所有Task的TaskInstance以后才会进入下一个节点。)
2) create-tasks="false",这个属性决定了在进入该节点的时候,不会自动为该节点的任何Task创建任何的TaskInstance。因为我们需要根据会签的人员来自己创建TaskInstance。
1. <
eventtype="node-enter">
进入流程节点的时候,执行ActionHandler类com.sky.plugin.jbpm.def.DynamicCreateTaskInstance,用来动态生成TaskInstance。
2. <
eventtype="
task-end">
Task结束的时候调用com.sky.plugin.jbpm.def.ConuntersignActionHandler进行会签处理。判断会签路径来决定会签的执行和走向。
参考文章
http://linliangyi2007.javaeye.com/blog/176356
http://tomkoo.javaeye.com/blog/24690
http://cache.baidu.com/c?m=9d78d513d99405f804ab837e7c509c244e4380127a84914c68d5e35f93124c403731bfed3365505adc9f3a2143b8482ff7ed7337721420c0c39bcc198af0c53f2fff76692f01c41c539504afca4322ca2b&p=9174c64ad1830ac308e2957e1e55&user=baidu