JBPM4.4(2)-state结点和decision结点
做一个带有分支的流向流程
在执行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); //若在流程定义某一个节点没有分支时(只有一个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
下面画一个选择向左还是向右的例子
定义文件如下:
<?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");
执行测试,得到的流程和之前完全相同。
- 关于 devbridge-autocomplete 插件多选操作的实现方法
- node-sass 安装失败的解决措施
- JavaMelody监控SQL
- 关于jboss的线程问题+java.lang.outofmemoryError
- 《了不起的 nodejs》中 TwitterWeb 案例 bug 解决
- java.lang.ClassNotFoundException与java.lang.NoClassDefFoundError的区别
- 【java开发系列】—— Tomcat编译报错
- java.lang.NoClassDefFoundError: org/aopalliance/aop/Advice
- 《像计算机科学家一样思考Java》—— 读后总结
- 记录安装oracle的那些事(三)之oracle Database R2安装
- Elasticsearch Javascript API增删改查
- Oracle二三事之 Oracle SPARC SuperCluster的九大技术优势
- 两个 viewports 的故事-第二部分
- 通过 JS 实现简单的拖拽功能并且可以在特定元素上禁止拖拽
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android Parcelable接口使用方法详解
- 假期结束了,撸一篇技术和大伙分享下吧!
- Android AIDL实现跨进程通信的示例代码
- Android中SharedPreferences简单使用实例
- 功能强大的Android滚动控件RecyclerView
- Android使用 Retrofit 2.X 上传多文件和多表单示例
- Android状态栏白底黑字的示例代码
- Android使用ViewPager实现顶部tabbar切换界面
- Android 中ScrollView与ListView冲突问题的解决办法
- Android数据库操作工具类分享
- Android使用RadioGroup实现底部导航栏
- Android 中Fragment与Activity通讯的详解
- Android常用控件ImageSwitcher使用方法详解
- Android实现阅读进度记忆功能
- Android 控制ScrollView滚动的实例详解