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

简介: 做一个带有分支的流向流程 在执行seperate状态的时候分成了200和400两种情况 描述文件的内容如下: View Code 测试代码如下: View Code public class TestSperator extends JbpmTest...

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

img_3b573ba83dfd68789eb02dfa6a86992f.png

在执行seperate状态的时候分成了200和400两种情况

描述文件的内容如下:

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif View Code
 
  
<? 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 >

测试代码如下:

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif View Code
 
  
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());


}
}

执行流程的结果如下:

img_f165a9857698ff692548957fadb55375.gif

使流程向下执行

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

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

img_ad8fb47bbcb8362c72d50d8742b44005.gif

定义文件如下:

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif View Code
 
  
<? 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>

对应的测试流程如下,需要增加

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif View Code
 
  
Map < String, String > map = new HashMap < String, String > ();
// coder为流程定义中表达式的名称
map.put( " coder " , " left " );

ProcessInstance processInstance
= executionService.startProcessInstanceByKey( " decision " ,map);

如果map中order的值指定的有问题那么就会抛出异常

测试程序如下:

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif View Code
 
  
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());

}
}

执行结果如图所示:

img_7093156a5186bd293ed8e1d913a41b10.gif

因为在开始的时候指定了流程处理的方向,所以流程向left方向自动执行。

第二种,更像switch case

在decision节点上指定

<decision g="252,204,48,48" name="exclusive1" expr="${toWhere}">

修改代码为:

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif View Code
 
  
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属性的值。

修改配置文件

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif View Code
 
  
< 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

代码如下:

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif View Code
 
  
@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 " );
执行测试,得到的流程和之前完全相同。


目录
相关文章
LeetCode 102. 二叉树的层序遍历 Binary Tree Level Order Traversal
LeetCode 102. 二叉树的层序遍历 Binary Tree Level Order Traversal
UVA122 树的层次遍历 Trees on the level
UVA122 树的层次遍历 Trees on the level
【1115】Counting Nodes in a BST (30分)【BST建树 DFS】
【1115】Counting Nodes in a BST (30分)【BST建树 DFS】 【1115】Counting Nodes in a BST (30分)【BST建树 DFS】
115 0