做一个带有分支的流向流程

JBPM4.4(2)-state结点和decision结点_System

在执行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());


}
}




执行流程的结果如下:

JBPM4.4(2)-state结点和decision结点_System_02

使流程向下执行

executionService.signalExecutionById();

该方法有多个重载:

ProcessInstance signalExecutionById(String executionId);
//若在流程定义某一个节点没有分支时(只有一个transition时),调用此方法,可将流程继续向下执行 executionId为流程实例Id
ProcessInstance signalExecutionById(String executionId, String signalName);
//若在流程定义某一个节点有多个分支时(有多个transition时),调用此方法,可将流程沿着transition所指的方向向下执行
executionId为流程实例Id, signalName为流程定义中transition节点的name属性的值
ProcessInstance signalExecutionById(String executionId, String signalName, Map<String, ?> parameters);
用于将流程沿着signalName方向(transition的name属性所指的方向)向下继续执行,在执行的过程中顺便传递参数parameters
ProcessInstance signalExecutionById(String executionId, Map<String, ?> parameters);
用于将流程向下继续执行,在执行的过程中顺便传递参数parameters

注:当一个节点有多个分支时,若要通过signalExecutionById()方法将流程向下执行必须明确指出signalName即(transition的name属性所指的方向),否则流程不会向下执行,仍会停留在当前节点。因为jbpm不确定流程该流向那个方向。

接下来是一个decision的例子,这个是一个分支判断的节点,相当于我们程序中的switch case

下面画一个选择向左还是向右的例子

JBPM4.4(2)-state结点和decision结点_JBPM4.42-state结点和dec_03

定义文件如下:

 

<?    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());

}
}


执行结果如图所示:

JBPM4.4(2)-state结点和decision结点_System_04

因为在开始的时候指定了流程处理的方向,所以流程向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
"
);