零全零美(www.zzgwt.com)
生活中的很多事情,并不像If...Else那么简单!
BlogJava
首页
新文章
联系
管理
posts - 96,comments - 52,trackbacks - 0
<
2008年11月
>
日
一
二
三
四
五
六
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
常用链接
我的随笔
我的评论
我的参与
最新评论
随笔分类
apache组件(4)
JavaScript(14)
jbpm(6)
oracle(5)
PL/SQL(1)
SEO(3)
tomcat(5)
ubuntu(16)
安全相关(26)
数据库
正则表达式(6)
设计模式(3)
随笔档案
2012年9月 (1)
2012年7月 (3)
2012年6月 (2)
2009年11月 (36)
2009年10月 (18)
2009年9月 (1)
2009年2月 (1)
2009年1月 (1)
2008年11月 (9)
2008年9月 (1)
2008年8月 (1)
2008年7月 (4)
2008年6月 (2)
2008年5月 (6)
2008年4月 (11)
友情链接
www.modaotea.com
茶艺培训 茶楼管理
www.website371.com
郑州做网站 郑州网站建设 郑州做网站公司 郑州网站优化 郑州网站制作
河南省大井科技有限公司(www.zzgwt.com)
搜索
积分与排名
积分 - 149902
排名 - 409
最新评论
1. re: 正则表达式学习笔记(1) 行的开始和结束、字符组、连字符、脱字符、用"."去匹配任意字符
赞
--性感电子
2. re: Apache httpd+Jk+Tomcat实现JAVA服务器配置全解析(1):基础环境搭建
什么嘛,我就是不懂这些才搜索的,我最需要的就是你省略的部分,如何配置安装,唉,又得继续找资料了。
--吐槽
3. re: JavaScript学习笔记(1)变量的生命周期
写的很好
--fwd
4. re: SELinux学习(1):Can't connect to MySQL server on 'ip' (13) 的解决方案
没玩过这东西啊呵呵
--台式万用表
5. re: [原创]巧用System.getProperty()编译现有工程的java文件
你不能用ANT吗?
--DB Compare Tool
[原创]JBPM源码解读之:Fork
Fork节点在整个JBPM流程运转过程中配合Join使用提供使多于一个的节点如:TaskNode、State等并行运行的作用,很可惜我们不能利用Fork提供的现有机制实现需求中经常遇到的并发子流程的效果,当然虽然JBPM并不支持并发子流程的机制,并不代表我们不能变通的实现,我将在另一篇文章中详细说明
我的并发子流程的实现方式
。
Fork类的注释中说:if this fork behaviour is not sufficient for your needs, consider writing your own custom TokenHandler.看来连JBPM开发小组也意识到Fork可能不能满足某些特殊的需求。注释中还说Fork节点有三种配置方式,我很奇怪为什么代码中只能找到两种:
1、without configuration : in that case the fork will launch one new sub-token over each of the leaving tranisions of the fork node.
2、a script : can be used to calculate a collection of transition names at runtime. if a script is configured, the script must have exactly one variable with 'write' access. that variable should be assigned a java.util.Collection in the script expression.
Fork类继承自Node并实现了Parsable接口。Fork类相对简单,他的私有成员变量只有一个:
1
/** */
/**
2
* a script that calculates the transitionNames at runtime.
3
*/
4
Script script
=
null
;
Fork中的Script可以在运行时对Fork节点选择Transition,所以在实际应用中可以
使用Fork+Script的方式进行多路路由选择
.但是有一点要特别注意:JBBM User Guide文档中说:the script in a fork is not persisted. script in fork might be removed in later versions of jPDL,原本以为这句话的前半句是说Script不会被持久化进数据库,实验了才知道其实Script还是被存进了数据库,这半句的意思应该是说"fork中的script不被坚持",JBPM开发小组要在新版本中放弃Script,我相信他们一定会提供更好的解决方案,让我们拭目以待。 Fork重写了Node类的read(Element forkElement, JpdlXmlReader jpdlReader)方法,其主要作用是解析JPDL中Fork节点Script的配置,并初始化自己的成员变量script。下面是execute(ExecutionContext executionContext)方法中的相关处理
1
Token token
=
executionContext.getToken();
2
//
声明离开转向的集合
3
Collection transitionNames
=
null
;
4
//
声明子Token容器
5
List forkedTokens
=
new
ArrayList();
6
7
//
如果没有Script,默认按照其父类Node的getLeavingTransitionsMap取得所有离开转向
8
if
(script
==
null
)
{
9
transitionNames
=
getLeavingTransitionsMap().keySet();
10
}
else
{
11
//
如果有Script,按照规范该Script应该返回一个Collection类型的数据,作为Fork的离开转向集合
12
Map outputMap
=
null
;
13
try
{
14
//
执行Script,得到返回的Collection数据
15
outputMap
=
script.eval(token);
16
}
catch
(Exception e)
{
17
this
.raiseException(e, executionContext);
18
}
19
if
(outputMap.size()
==
1
)
{
20
Object result
=
outputMap.values().iterator().next();
21
if
(result
instanceof
Collection)
{
22
transitionNames
=
(Collection) result;
23
}
24
}
25
if
(transitionNames
==
null
)
{
26
throw
new
JbpmException(
"
script for fork '
"
+
name
+
"
' should produce one collection (in one writable variable):
"
+
transitionNames);
27
}
28
}
下面让我们来看一下,Fork产生的子Token的命名方式:
1
/** */
/**
2
* 功能描述:为子Token取名字<BR>
3
*
@param
parent 父Token
4
*
@param
transitionName 离开转向的名字
5
*/
6
protected
String getTokenName(Token parent, String transitionName)
{
7
String tokenName
=
null
;
8
//
如果transitionName不为空
9
if
(transitionName
!=
null
)
{
10
//
如果父Tokehn中不存在以transitionName命名的子Token
11
if
(
!
parent.hasChild(transitionName))
{
12
//
以transitionName的名字为子Token命名
13
tokenName
=
transitionName;
14
}
else
{
15
//
如果已经存在则以transitionName+2的方式命名
16
int
i
=
2
;
17
tokenName
=
transitionName
+
Integer.toString(i);
18
//
如果加2之后依然存在,开始循环,直到父Token中不存在相同名称的子Token
19
while
(parent.hasChild(tokenName))
{
20
i
++
;
21
tokenName
=
transitionName
+
Integer.toString(i);
22
}
23
}
24
}
else
{
25
//
如果transitionName为空,则判但父Token中是否有子Token,如果有则以parent.getChildren().size() + 1法命名,
26
//
如果没有直接命名为1
27
int
size
=
(parent.getChildren()
!=
null
?
parent.getChildren().size()
+
1
:
1
);
28
tokenName
=
Integer.toString(size);
29
}
30
return
tokenName;
31
}
名字定好之后,Fork为每个离开转向分别创建了一个子Token,加入一开始创建的forkedTokens中。最后开始循环列表,执行Node的leave方法,并触发Node-leave事件
iter
=
forkedTokens.iterator();
while
(iter.hasNext())
{
ForkedToken forkedToken
=
(ForkedToken) iter.next();
Token childToken
=
forkedToken.token;
String leavingTransitionName
=
forkedToken.leavingTransitionName;
ExecutionContext childExecutionContext
=
new
ExecutionContext(childToken);
if
(leavingTransitionName
!=
null
)
{
leave(childExecutionContext, leavingTransitionName);
}
else
{
leave(childExecutionContext);
}
}
看了这段代码我们应该明白:Fork的Node-leave事件是会执行多遍的,具体要看产生的子Token的个数.至于ForkedToken类,其实是Fork的一个内被类,只起到一个普通Bean的作用.
到这里,Fork类的大体内容我们已经解读完毕,但是还有一点要注意的地方:
add some way of blocking the current token here and disable that blocking when the join reactivates this token Then an exception can be thrown by in case someone tries to signal a token that is waiting in a fork.Suspend and resume can NOT be used for this since that will also suspend any related timers, tasks and messages...So a separate kind of blocking should be created for this.
文章原创,转载请注明出处!
posted on 2008-11-05 16:41
零全零美
阅读(2092)
评论(0)
编辑
收藏
所属分类:
jbpm
新用户注册
刷新评论列表
只有注册用户
登录
后才能发表评论。
网站导航:
博客园
IT新闻
知识库
C++博客
博问
管理
相关文章:
[原创]巧用System.getProperty()编译现有工程的java文件
[原创]JBPM源码解读之:Join
[原创]JBPM实践之:并发子流程的实现
JBPM实践之:使用Fork中的Script实现多路路由选择
[原创]JBPM源码解读之:Fork
JBPM实践之:在流程图上高亮显示指定的任务节点