- 浏览: 57573 次
- 来自: ...
最新评论
-
rebellan:
太感谢楼主的分享精神了,搞了好久的会签 被楼主点通了,谢谢
使用JBPM实现动态会签 -
zhumaohua:
使用JBPM实现动态会签 -
pppppp:
没有,之前没有出现过这种情况,使用terracotta才出现的 ...
terracotta在hibernate应用上的严重问题 -
daquan198163:
是不是你让sessionfactory新建表了
terracotta在hibernate应用上的严重问题 -
llandyl:
问题已经解决。是测试程序测试方法不对造成的。
使用JBPM实现动态会签
目前有很多实现动态会签的文章,但是给人感觉不是很优雅,下面介绍一种实现方式。
1、流程定义文件:
xml 代码
- < process-definition
- xmlns = "urn:jbpm.org:jpdl-3.1" name = "foreach" >
- < start-state name = "start" >
- < task name = "one" >
- </ task >
- < transition name = "a" to = "foreachf" > </ transition >
- </ start-state >
- < node name = "foreachf" >
- < action class = "com.framework.workflow.jbpm.ForEachFork" >
- < foreach > #{bpm_assignees} </ foreach >
- < var > reviewer </ var >
- </ action >
- < transition name = "review" to = "review" > </ transition >
- </ node >
- < task-node name = "review" >
- < task name = "reviewTask" >
- < assignment class = "com.framework.workflow.jbpm.DefaultAssignment" >
- < actor > #{reviewer} </ actor >
- </ assignment >
- </ task >
- < transition name = "reject" to = "endreview" >
- < action class = "com.framework.workflow.jbpm.JoinEndForkedTokens" />
- </ transition >
- < transition name = "approve" to = "endreview" > </ transition >
- </ task-node >
- < join name = "endreview" >
- < transition name = "toend" to = "end1" > </ transition >
- </ join >
- < end-state name = "end1" > </ end-state >
- </ process-definition >
在这里我们从node节点动态生成任务节点,会签时当有一个是reject时便结束所有节点。
2、动态派生ForEachFork代码:
java 代码
- public class ForEachFork implements ActionHandler
- {
- private Element foreach;
- private String var;
- //测试数据
- private static Map map = new HashMap();
- static {
- List list = new ArrayList();
- list.add("1234" );
- list.add("2345" );
- list.add("3456" );
- map.put("bpm_assignees" , list);
- }
- /**
- *
- 为每个元素创建一个分支
- *
- * @param executionContext
- * @throws Exception
- */
- @SuppressWarnings ( "unchecked" )
- public void execute( final ExecutionContext executionContext)
- throws Exception
- {
- if (foreach == null )
- {
- throw new WorkflowException( "forEach has not been provided" );
- }
- List forEachColl = null ;
- String forEachCollStr = foreach.getTextTrim();
- if (forEachCollStr != null )
- {
- if (forEachCollStr.startsWith( "#{" ))
- {
- String expression = forEachCollStr.substring(2 , forEachCollStr.length() - 1 );
- forEachColl = (List)map.get(expression);
- }
- }
- if (var == null || var.length() == 0 )
- {
- throw new WorkflowException( "forEach variable name has not been provided" );
- }
- //
- // 创建分支
- //
- Token rootToken = executionContext.getToken();
- Node node = executionContext.getNode();
- List forkTransitions = new ArrayList();
- // 为每一个元素创建一个token
- for ( int i = 0 ; i < node.getLeavingTransitions().size(); i++)
- {
- Transition transition = (Transition) node.getLeavingTransitions().get(i);
- for ( int iVar = 0 ; iVar < forEachColl.size(); iVar++)
- {
- // 为每一个新token创建一个path
- String tokenName = getTokenName(rootToken, transition.getName(), iVar);
- Token loopToken = new Token(rootToken, tokenName);
- loopToken.setTerminationImplicit(true );
- executionContext.getJbpmContext().getSession().save(loopToken);
- //赋予一个新变量
- final ExecutionContext newExecutionContext = new ExecutionContext(loopToken);
- newExecutionContext.getContextInstance().createVariable(var, forEachColl.get(iVar), loopToken);
- // 记录下每一transition
- ForkedTransition forkTransition = new ForkedTransition();
- forkTransition.executionContext = newExecutionContext;
- forkTransition.transition = transition;
- forkTransitions.add(forkTransition);
- }
- }
- //
- // 转向下一个节点
- //
- for (ForkedTransition forkTransition : forkTransitions)
- {
- node.leave(forkTransition.executionContext, forkTransition.transition);
- }
- }
- /**
- *
- 获得分支token name
- *
- * @param parent
- * @param transitionName
- * @return
- */
- protected String getTokenName(Token parent, String transitionName, int loopIndex)
- {
- String tokenName = null ;
- if (transitionName != null )
- {
- if (!parent.hasChild(transitionName))
- {
- tokenName = transitionName;
- }
- else
- {
- int i = 2 ;
- tokenName = transitionName + Integer.toString(i);
- while (parent.hasChild(tokenName))
- {
- i++;
- tokenName = transitionName + Integer.toString(i);
- }
- }
- }
- else
- {
- // 没有转向
- int size = ( parent.getChildren()!= null ? parent.getChildren().size()+ 1 : 1 );
- tokenName = Integer.toString(size);
- }
- return tokenName + "." + loopIndex;
- }
- /**
- * Fork Transition
- */
- private class ForkedTransition
- {
- private ExecutionContext executionContext;
- private Transition transition;
- }
- }
在具体应用中需要灵活的根据业务逻辑需要派生所需要的分支。
3、DefaultAssignment
进行简单的权限操作,这里面主要是将#{reviewer}值作为actorId进行设置
4、JoinEndForkedTokens结束所有节点
java 代码
- public class JoinEndForkedTokens implements ActionHandler
- {
- public JoinEndForkedTokens()
- {
- }
- /* (non-Javadoc)
- * @see org.jbpm.graph.def.ActionHandler#execute(org.jbpm.graph.exe.ExecutionContext)
- */
- public void execute(ExecutionContext executionContext)
- {
- Token token = executionContext.getToken().getParent();
- Map childTokens = token.getActiveChildren();
- for (Object childToken : childTokens.values())
- {
- cancelToken(executionContext, (Token)childToken);
- }
- }
- /**
- *
- 取消 token
- *
- * @param executionContext
- * @param token
- */
- protected void cancelToken(ExecutionContext executionContext, Token token)
- {
- Map childTokens = token.getActiveChildren();
- for (Object childToken : childTokens.values())
- {
- cancelToken(executionContext, (Token)childToken);
- }
- if (!token.hasEnded())
- {
- token.end(true );
- }
- cancelTokenTasks(executionContext, token);
- }
- /**
- *
- 结束token关联的任务
- *
- * @param executionContext
- * @param token
- */
- protected void cancelTokenTasks(ExecutionContext executionContext, Token token)
- {
- TaskMgmtInstance tms = executionContext.getTaskMgmtInstance();
- Collection tasks = tms.getUnfinishedTasks(token);
- for (Object task : tasks)
- {
- TaskInstance taskInstance = (TaskInstance)task;
- if (taskInstance.isBlocking())
- {
- taskInstance.setBlocking(false );
- }
- if (taskInstance.isSignalling())
- {
- taskInstance.setSignalling(false );
- }
- if (!taskInstance.hasEnded())
- {
- taskInstance.end();
- }
- }
- }
- }
结束所有分支节点任务,流向结束节点。
评论
4 楼
rebellan
2008-07-18
太感谢楼主的分享精神了,搞了好久的会签 被楼主点通了,谢谢
3 楼
zhumaohua
2008-02-21
2 楼
llandyl
2007-12-04
问题已经解决。是测试程序测试方法不对造成的。
1 楼
llandyl
2007-12-03
如果将流程定义文件修改,变成两次调用生成<node name="foreachf">就会有错误,而不是直接结束。
错误出现在 executionContext.getJbpmContext().getSession().save(loopToken);
。通过跟踪发现,是executionContext.getJbpmContext()为空。即报Caused by: java.lang.NullPointerException的错误。
这个问题困扰我几天了。一致没有解决。
不知那位有过此情况下的情况,望告知。谢谢!
错误出现在 executionContext.getJbpmContext().getSession().save(loopToken);
。通过跟踪发现,是executionContext.getJbpmContext()为空。即报Caused by: java.lang.NullPointerException的错误。
这个问题困扰我几天了。一致没有解决。
不知那位有过此情况下的情况,望告知。谢谢!
发表评论
-
几个不错的基于erlang的项目,先标记一下,有时间研究一下
2008-11-27 13:39 1125Scalaris 、 couchDB 、 Rabbitmq -
dojo combobox的autocomplete不支持中文检索问题的解决办法
2008-04-24 19:48 2103只需要修改ComboBox.js文件, 将if(evt.ctr ... -
terracotta在hibernate应用上的严重问题
2008-01-15 15:10 1273在原有的一个hibernate应用上,使用terracotta ... -
Lighttpd轻量级的web server
2007-04-18 06:20 1027lighttpd和apache一样是开源的,与apache相比 ... -
memcached高性能的分布式内存缓存
2007-04-18 06:58 1358当今对于网站的功能要求越来越高,生成静态文件的方式已经无法满足 ... -
memcached安装及使用
2007-04-18 07:58 20491、安装下载memcached 及libevent(memca ... -
构建在lucene之上搜索引擎框架
2007-04-19 05:23 2413Compass和Hibernate Search都是构建在lu ... -
MYsql查询缓存介绍
2007-04-24 01:38 1369看到一篇介绍 Mysql查询缓存的文章,标记一下。 -
困扰已久的链接参数带中文接收时变乱码的问题
2007-04-26 08:02 1568一直怀疑是jboss或者是seam框架自身的问题,却把tomc ... -
Hibernate shard介绍
2007-04-27 03:37 6894hibernate shards源自google的 ... -
Top10 J2EE性能问题
2007-05-02 08:44 120410、过多的日志开销9、不正确的应用服务器配置8、不恰当的使用 ... -
Memcached性能测试
2007-05-02 09:32 2740以1w个对象的get,set,delete三种操作进行测试当对 ... -
几个优秀的java测试套件
2007-06-01 01:55 1732三种单元测试套件:JUnit 、TestNG 、p-unitJ ... -
tapestry4.1.2怪异的问题
2007-07-03 06:52 1051环境tomcat6:如果应用名称和web.xml配置的serv ... -
RedHat Developer Studio初试
2007-08-27 02:15 1706试用了一下RedHat Developer Studio的be ...
相关推荐
本文将深入探讨jbpm4.3如何实现会签功能,并分享相关的源码和工具使用。 1. jbpm4.3概述: jbpm4.3是jbpm的一个较旧版本,但仍然包含许多工作流管理的核心特性,如流程定义、任务分配、事件处理等。它基于Java平台...
解压并运行这个示例,可以更深入地理解JBPM4.3和Spring如何协同工作以实现会签功能。 总之,这个JBPM4.3与Spring的会签实例展示了如何在企业级应用中有效地管理和控制业务流程。通过学习和实践这样的实例,开发者...
在JBPM4.4中,实现会签功能通常需要以下几个步骤: 1. **设计流程模型**:使用BPMN(Business Process Modeling Notation)语言或JBPM提供的图形化工具(如jBPM Designer)设计流程模型,定义会签节点。在这个节点...
在实现会签时,我们可以创建一个custom节点,然后在其中编写Java代码或者使用脚本来处理会签逻辑,包括分配任务给审批人、处理审批结果以及根据需要进行加签或减签操作。 加签功能是在流程运行过程中,根据业务需求...
本文将深入探讨如何在jbPM中实现会签以及加签、减签功能,并提供相关实践指导。 1. **会签概念与实现** 会签是指在流程中设置一个环节,需要多个参与者依次或同时进行审批。jbPM通过定义工作流模型,利用task节点...
在本教程中,我们将深入探讨jbpm中的会签和串签功能,以及如何进行流程部署、启动流程、任务提交、查询已办和待办任务。 首先,让我们了解流程部署的概念。在jbpm中,流程部署是将一个流程定义文件(通常是.bpmn或....
jbpm-3_2_2-Api jbpm 著名工作流引擎
在jbpm中,"fork & join"机制是实现并行处理和流程控制的关键概念,尤其在处理会签(多个审批人同时参与审批)等场景时显得尤为重要。 "fork"在jbpm中指的是流程分支,当流程到达一个fork节点时,流程会分裂为多个...
在jbpm中实现会签,主要涉及到以下几个关键知识点: 1. **工作流模型**:jbpm使用BPMN(Business Process Model and Notation)标准来定义流程模型。BPMN提供了一套图形化的符号,用于描绘业务流程,其中包括并行...
在阅读《jBPM4工作流应用开发指南.pdf》这本书时,你可以学习到如何使用jbpm4的API进行流程设计、部署和执行,以及如何进行流程实例的查询和管理。书中可能还会涉及如何处理异常、分支和合并逻辑,以及如何进行流程...
本主题聚焦于"工作流开发会签两套方案(Java源代码实现)",我们将深入探讨两种Java实现会签功能的方法,并结合JBPM(Java Business Process Management)框架,为你揭示如何高效地构建这样的系统。 首先,我们需要...
使用jBPM4提供的图形化工具(例如,eclipse的jbpm4 designer插件)创建流程定义文件(.bpmn2或.xml)。流程图可以通过拖放活动节点(如开始、结束、任务、会签等)来构建,并通过连接线定义它们之间的流转关系。 ##...
【jbpm工作流程详解】 jbpm,全称为Java Business Process ...尽管在应对某些特定的中国业务场景时可能需要额外的定制,但通过对其特性和机制的深入理解,开发者可以有效利用jbpm实现符合中国国情的流程自动化。
给新手学习使用,不会让你失望" 提示我们,该示例项目是为初学者准备的,通过简洁明了的代码和注释,帮助他们快速理解和掌握JBPM如何实现会签功能。这意味着文件内容可能包括了基础的JBPM配置、工作流定义、会签节点...
3. **网关**:用于控制流程的分支和合并,如并行网关实现任务并行执行,决策网关根据条件决定流程走向。 4. **连接线**:指示流程的流转路径,可能带有条件表达式,决定何时从一个活动转移到另一个。 5. **结束事件*...
例如,创建草稿任务、并发任务、会签任务等,这些都是通过控制类在流程图执行过程中动态生成的。 4. **流程监控与调试**:jbpm提供了监控和调试工具,可以帮助开发者跟踪流程实例的执行状态,找出潜在的问题并进行...
1. **流程定义**:代码可能会定义一个流程实例,其中包含并行网关来实现会签。并行网关将任务分支到不同的参与者,每个参与者完成自己的签署后,所有分支必须汇合,流程才能继续。 2. **任务监听器**:为了跟踪各个...