又有客户提出自由流需求,真晕,自由流不就等于没流程吗?还是劝他定个流程吧,上系统了不就是规范公司的流程吗?呵呵
虽然客户赞同我们的说法,不过私下来还是讨论尝试了对自由流的控制.最早的一个想法是建立几个孤立的没有联系的节点.让客户选择下一步要去的节点,(相当于选择转向).程序根据选择,创建这个节点上的任务.客户操作完任务,程序在负责关上这个任务.
这样是可以达到效果的.不过就是太不 'jbpm' 了.因为把流程的流转环境被去掉了.所以又想了个'jbpm'点的方法.要想从一个节点到另一个节点.必然要有'转向'连接两个节点.自由流不能在流程没跑起来前知道每个节点的下 一步到哪.只能在运行过程中知道,那我们就当知道的时候在创建两个节点间的转向呗.看看下面的测试代码
package org.jbpm.tutorial.action;
import junit.framework.TestCase;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.def.Transition;
import org.jbpm.graph.exe.ProcessInstance;
public class FreeProcessTest extends TestCase {
public void testTransitionAction() {
ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
"<process-definition>" +
" <start-state>" +
" <transition to='a' />" +
" </start-state>" +
" <state name='a'>" +
" </state>" +
" <state name='b'>" +
" <transition to='c'/>" +
" </state>" +
" <state name='c'>" +
" </state>" +
" <end-state name='end' />" +
"</process-definition>"
);
// 创建流程实例
ProcessInstance processInstance =
new ProcessInstance(processDefinition);
// 流转一步到节点a
processInstance.signal();
assertSame(processDefinition.getNode("a"),
processInstance.getRootToken().getNode());
//假定客户要从a到c,动态创建a到c的转向
Transition leavingTransition=new Transition("a to c");//构建一个a到c的转向
//指定该转向的目的节点是c
leavingTransition.setTo(processInstance.getProcessDefinition().getNode("c"));
//为当前节点添加这个转向.
processInstance.getRootToken().getNode().addLeavingTransition(leavingTransition);
//调用这个转向流转流程
processInstance.signal("a to c");
//删除这个临时创建的转向
processInstance.getRootToken().getNode().removeLeavingTransition(leavingTransition);
//测试是否到达c节点了
assertSame(processDefinition.getNode("c"),
processInstance.getRootToken().getNode());
// 假定客户要从c到b,动态创建c到b的转向
leavingTransition=new Transition("c to b");
leavingTransition.setTo(processInstance.getProcessDefinition().getNode("b"));
processInstance.getRootToken().getNode().addLeavingTransition(leavingTransition);
processInstance.signal("c to b");
processInstance.getRootToken().getNode().removeLeavingTransition(leavingTransition);
assertSame(processDefinition.getNode("b"),
processInstance.getRootToken().getNode());
// 假定客户要从b到c,不用动态创建,已经定义了
processInstance.signal();
assertSame(processDefinition.getNode("c"),
processInstance.getRootToken().getNode());
// 假定客户要从c到end,动态创建c到end的转向
leavingTransition=new Transition("c to end");
leavingTransition.setTo(processInstance.getProcessDefinition().getNode("end"));
processInstance.getRootToken().getNode().addLeavingTransition(leavingTransition);
processInstance.signal("c to end");
processInstance.getRootToken().getNode().removeLeavingTransition(leavingTransition);
assertSame(processDefinition.getNode("end"),
processInstance.getRootToken().getNode());
}
}
测试通过!这个够'jbpm'了吧.
分享到:
相关推荐
利用Kubernetes的动态资源调度功能和集群的动态伸缩特性,可以在需要进行压力测试时启动测试节点,在测试结束后释放资源给其他业务,甚至通过集群扩容和缩容临时为压力测试提供更多计算资源。这种方案不仅提高了硬件...
- **内存分配**: 使用malloc或calloc函数在堆区动态分配内存,为新创建的节点分配空间。 - **输入输出**: 使用printf和scanf函数进行输入输出操作,分别对应输出和输入格式化数据。 - **算法实现**: 根据中序遍历...
在“数据结构实验一”中,你可能需要实现这两种链表数据结构,包括它们的基本操作函数,如创建链表、插入节点、删除节点、打印链表等。这将帮助你理解链表的工作原理以及如何在实际编程中应用它们。在实现过程中,你...
假设测试环境中选择了两台服务器(192.168.1.237 和 192.168.1.238),每台服务器上创建 3 个节点。具体步骤如下: 1. 在 `/usr/local/` 下创建集群目录: ```bash mkdir redis_cluster mkdir 7000 7001 7002 ...
在ROS中,你可以创建一个节点来实现这个算法,订阅当前车辆位置,发布转向角。 7. **LQR算法**: LQR算法用于横向路径跟踪,它是一个控制理论中的经典方法,通过最小化一个二次型性能指标来优化控制输入。在ROS中...
在C语言中,链表操作包括创建新节点、插入节点、删除节点和遍历节点等。链表的灵活性使其在处理动态数据,比如随机数序列时特别有用,因为它可以在不预先知道数据量的情况下高效地工作。 总的来说,这个压缩包提供...
2. 动态加载:TreePanel支持异步加载,即在用户滚动或展开节点时动态获取子节点数据,这有助于减少页面初始化时的数据量。 3. 节点操作:可以添加、删除、移动和编辑TreePanel中的节点,实现丰富的交互功能。 4. ...
在ROS 5.21版本中,“限速脚本生成”是一个关键功能,它允许用户为机器人移动平台创建自定义的速度限制策略。这个功能对于确保机器人的安全运行至关重要,尤其是在人机共融的环境中。 首先,我们要理解ROS中的节点...
5. **Gazebo ROS模拟**:在Gazebo中,你可以创建各种环境,包括静态和动态的障碍物,以及不同的地形,以测试机器人的导航性能。通过ROS接口,Gazebo可以接收和发送传感器数据,与ROS的其他节点进行通信。 6. **ROS...
在实践中,首先创建一个100到200个VM的测试环境,以验证和测试设计的可行性。选择XenServer作为Hypervisor的原因在于其商业支持、稳定性和与CloudStack的深度集成。由于两者都是Citrix的产品,它们之间的兼容性和...
4. 集群扩展与维护:集群可以动态添加或删除节点,调整槽位分布,以适应数据量的变化。 5. 集群监控:使用`redis-cli`的`CLUSTER`命令集,如`CLUSTER NODES`查看集群状态,`CLUSTER SLOTS`查看槽位分配。 以上就是...
- **ASK 转向/MOVED 转向机制**:客户端请求被重定向至正确的节点以获取或存储数据。 ##### 1.2 Redis Cluster 架构 - **节点间互联**:所有节点通过 PING-PONG 机制相互通信,使用二进制协议以提高传输效率。 - *...
在实验中,学生需要实现插入节点(在指定位置或末尾)和删除节点(按值或位置)的功能,这有助于理解链表的动态特性。 实验二,二叉树操作,涉及二叉树的创建、遍历和查找等。二叉树是一种特殊的树结构,每个节点...
- 使用 `new WebFXLoadTree("根节点名称", "XML数据源路径")` 创建一个动态加载数据的树对象。 - 调用 `write()` 方法将树写入页面。 - 此时,树中的数据将从指定的 XML 文件中动态加载。 #### 3. XML 文件结构 - ...
在编程领域,可变长数组(也称为动态数组)和字典树(又称Trie树或前缀树)是两种非常重要的数据结构。它们在不同的场景下有着广泛的应用,尤其在处理大量数据时能展现出高效的性能。 首先,我们来详细讨论可变长...
每个链表节点包含两部分:数据和指向下一个节点的指针。在C++中,我们可以使用结构体或类来定义链表节点。例如: ```cpp struct ListNode { int data; ListNode* next; }; ``` 创建链表通常涉及插入新节点。插入...
4. **网络配置**:创建和配置CANoe中的网络,定义节点ID、帧类型以及与其他CANoe组件的交互方式。 5. **诊断配置**:设置VH6501的诊断功能,例如故障注入、数据读写等,以满足特定测试需求。 接下来,我们将焦点...
节点是执行特定任务的独立程序,话题用于节点间的数据传输,服务允许节点之间进行请求-响应交互,参数服务器则用来存储全局配置信息。 2. **Gazebo仿真环境**:Gazebo是一款强大的3D仿真工具,它能模拟真实的物理...
但在链栈中,每个元素(或者说节点)包含两部分:数据域和指针域。数据域用于存储元素值,而指针域则指向下一个元素。在链栈中,栈顶元素由一个特殊的节点——头节点标识,其指针域指向栈中下一个元素。插入(压栈)...
本文将详细介绍这两个库的核心概念、主要功能以及它们之间的关系。 DOM4J,全称是Dynamic Object Model for Java,是一个非常灵活且功能强大的Java XML API。它不仅提供了对XML文档的全面支持,包括读取、写入、...