做一个带有分支的流向流程
在执行seperate状态的时候分成了200和400两种情况
描述文件的内容如下:
<? xml version="1.0" encoding="UTF-8"
?>
<
process
name
="fork"
xmlns
="http://jbpm.org/4.4/jpdl"
>
<
start
g
="237,28,48,48"
name
="start1"
>
<
transition
name
="to separate"
to
="separate"
g
="-71,-17"
/>
</
start
>
<
state
g
="210,153,92,52"
name
="separate"
>
<
transition
name
="to 200"
to
="200"
g
="-41,-17"
/>
<
transition
name
="to 400"
to
="400"
g
="-41,-17"
/>
</
state
>
<
state
g
="145,256,92,52"
name
="200"
>
<
transition
name
="to end1"
to
="end1"
g
="-47,-17"
/>
</
state
>
<
state
g
="306,255,92,52"
name
="400"
>
<
transition
name
="to end1"
to
="end1"
g
="-47,-17"
/>
</
state
>
<
end
g
="245,375,48,48"
name
="end1"
/>
</
process
>
测试代码如下:
public class
TestSperator
extends
JbpmTestCase {
String deploymentId;
protected
void
setUp()
throws
Exception {
super
.setUp();
deploymentId
=
repositoryService.createDeployment()
.addResourceFromClasspath(
"
com/jbpm/fork/fork.jpdl.xml
"
)
.deploy();
}
protected
void
tearDown()
throws
Exception {
repositoryService.deleteDeploymentCascade(deploymentId);
super
.tearDown();
}
public
void
testSeparate() {
ProcessInstance processInstance
=
executionService
.startProcessInstanceByKey(
"
fork
"
);
System.out.println(
"
流程实例Id:
"
+
processInstance.getId());
System.out.println(
"
流程定义Id:
"
+
processInstance.getProcessDefinitionId());
ProcessInstance instance
=
executionService.signalExecutionById(processInstance.getId());
//
判断当前是否位于state节点
System.out.println(
"
是否位于state节点:
"
+
instance.isActive(
"
separate
"
));
System.out.println(
"
向下执行...
"
);
ProcessInstance processInstance200
=
executionService.signalExecutionById(processInstance.getId(),
"
to 200
"
);
System.out.println(
"
当前流程是否位于200节点---->
"
+
processInstance200.isActive(
"
200
"
));
System.out.println(
"
当前流程是否结束---->
"
+
processInstance200.isEnded());
ProcessInstance endinstance
=
executionService.signalExecutionById(processInstance200.getId());
System.out.println(
"
当前流程是否结束---->
"
+
endinstance.isEnded());
}
}
执行流程的结果如下:
使流程向下执行
executionService.signalExecutionById();
该方法有多个重载:
ProcessInstance signalExecutionById(String executionId); |
注:当一个节点有多个分支时,若要通过signalExecutionById()方法将流程向下执行必须明确指出signalName即(transition的name属性所指的方向),否则流程不会向下执行,仍会停留在当前节点。因为jbpm不确定流程该流向那个方向。
接下来是一个decision的例子,这个是一个分支判断的节点,相当于我们程序中的switch case
下面画一个选择向左还是向右的例子
定义文件如下:
<? xml version="1.0" encoding="UTF-8" ?>
<
process
name
="decision"
xmlns
="http://jbpm.org/4.4/jpdl"
>
<
start
g
="246,30,48,48"
name
="start1"
>
<
transition
name
="to wait"
to
="wait"
g
="-47,-17"
/>
</
start
>
<
state
g
="231,112,92,52"
name
="wait"
>
<
transition
name
="to exclusive1"
to
="exclusive1"
g
="-83,-17"
/>
</
state
>
<
decision
g
="252,204,48,48"
name
="exclusive1"
>
<
transition
name
="to left"
to
="left"
g
="-47,-17"
>
<
condition
expr
="${coder=='left'}"
></
condition
>
</
transition
>
<
transition
name
="to right"
to
="right"
g
="-53,-17"
>
<
condition
expr
="${coder=='right'}"
></
condition
>
</
transition
>
</
decision
>
<
state
g
="175,295,92,52"
name
="left"
>
<
transition
name
="to end1"
to
="end1"
g
="-47,-17"
/>
</
state
>
<
state
g
="325,292,92,52"
name
="right"
>
<
transition
name
="to end1"
to
="end1"
g
="-47,-17"
/>
</
state
>
<
end
g
="268,370,48,48"
name
="end1"
/>
</
process
>
其中有几种方式可以处理流程的走向
第一种,内置条件
即在流程定义中设置每一个transition的子节点condition,并为每一个condition填充expr属性
形如:
<condition expr="${coder=='left'}"></condition>
对应的测试流程如下,需要增加
Map < String, String > map
=
new
HashMap
<
String, String
>
();
//
coder为流程定义中表达式的名称
map.put(
"
coder
"
,
"
left
"
);
ProcessInstance processInstance
=
executionService.startProcessInstanceByKey(
"
decision
"
,map);
如果map中order的值指定的有问题那么就会抛出异常
测试程序如下:
public class TestDecision extends JbpmTestCase {
String deploymentId;
protected
void
setUp()
throws
Exception {
super
.setUp();
deploymentId
=
repositoryService.createDeployment()
.addResourceFromClasspath(
"
com/jbpm/decision/decision.jpdl.xml
"
)
.deploy();
}
protected
void
tearDown()
throws
Exception {
repositoryService.deleteDeploymentCascade(deploymentId);
super
.tearDown();
}
public
void
testDescsion() {
Map
<
String, String
>
map
=
new
HashMap
<
String, String
>
();
//
coder为流程定义中表达式的名称
map.put(
"
coder
"
,
"
left
"
);
ProcessInstance processInstance
=
executionService.startProcessInstanceByKey(
"
decision
"
,map);
System.out.println(
"
流程实例Id:
"
+
processInstance.getId());
System.out.println(
"
流程定义Id:
"
+
processInstance.getProcessDefinitionId());
System.out.println(
"
是否位于state节点:
"
+
processInstance.isActive(
"
wait
"
));
ProcessInstance decisionInstance
=
executionService.signalExecutionById(processInstance.getId());
//
判断当前是否位于wait节点
System.out.println(
"
是否位于wait节点:
"
+
decisionInstance.isActive(
"
wait
"
));
System.out.println(
"
因为已经有值所以自动向下执行...
"
);
System.out.println(
"
是否位于left节点:
"
+
decisionInstance.isActive(
"
left
"
));
//
向下执行
ProcessInstance endinstance
=
executionService.signalExecutionById(decisionInstance.getId());
System.out.println(
"
当前流程是否结束---->
"
+
endinstance.isEnded());
}
}
执行结果如图所示:
因为在开始的时候指定了流程处理的方向,所以流程向left方向自动执行。
第二种,更像switch case
在decision节点上指定
<decision g="252,204,48,48" name="exclusive1" expr="${toWhere}">
修改代码为:
Map < String, String > map = new
HashMap
<
String, String
>
();
//
coder为流程定义中表达式的名称
map.put(
"
toWhere
"
,
"
to left
"
);
其它部分不变,可以看到结果和原来的相同。
第三种,配置handler子类
在流程定义中在decision节点内部配置<handler/>子节点,并设置该元素的class属性为你自己的类)该类实现了org.jbpm.api.jpdl.DecisionHandler.你需要重写
String decide(OpenExecution execution);方法即可,在该方法最终返回decision活动后的下一个transition的name属性的值。
修改配置文件
< decision g ="252,204,48,48" name ="exclusive1" >
<
handler
class
="com.jbpm.decision.HandlerDecision"
></
handler
>
<
transition
name
="to left"
to
="left"
g
="-47,-17"
>
</
transition
>
<
transition
name
="to right"
to
="right"
g
="-53,-17"
>
</
transition
>
</
decision
>
添加HandlerDecision并且实现DecisionHandler
代码如下:
@SuppressWarnings( " serial " ) public class HandlerDecision
implements
DecisionHandler {
@Override
public
String decide(OpenExecution execution) {
//
TODO Auto-generated method stub
String toWhere
=
execution.getVariable(
"
toWhere
"
).toString();
String result
=
null
;
if
(
"
left
"
.equals(toWhere)) {
result
=
"
to left
"
;
}
else
if
(
"
right
"
.equals(toWhere)) {
result
=
"
to right
"
;
}
return
result;
}
}
测试代码只需将map中的值进行简单修改即可
Map < String, String > map = new HashMap <
String, String
>
();
//
coder为流程定义中表达式的名称
map.put(
"
toWhere
"
,
"
left
"
);