hoho,今天完成了选择路由的实现,完成了配置文件的读写和解析,流程定义文件还是决定采用xml文件,不过与其他工作流引擎采用的xml完全不同,因为是基于petri网的,因此引入了place的概念,比如下面这个4个节点的顺序路由的流程:
<
workflow
maxCases
="100"
>
<
node
type
="start"
name
="start"
id
="0"
>
<
inputs
>
<
place
id
="1"
/>
</
inputs
>
<
outputs
>
<
place
id
="2"
/>
</
outputs
>
</
node
>
<
node
name
="hello"
id
="1"
resource
="user"
>
<
conditions
type
="and"
>
<
condition
class
="net.rubyeye.insect.workflow.impl.NullHandler"
value
="false"
variable-name
="name"
/>
</
conditions
>
<
handler
class
="net.rubyeye.insect.workflow.test.HelloWorldHandler"
/>
<
inputs
>
<
place
id
="2"
/>
</
inputs
>
<
outputs
>
<
place
id
="3"
/>
</
outputs
>
</
node
>
<
node
name
="calc"
id
="2"
resource
="user"
>
<
conditions
type
="and"
>
<
condition
variable-name
="num"
>
<
exp
>
<![CDATA[
num<=1000
]]>
</
exp
>
</
condition
>
<
conditions
type
="or"
>
<
condition
variable-name
="num"
>
<
exp
>
<![CDATA[
num>=10
]]>
</
exp
>
</
condition
>
<
condition
class
="net.rubyeye.insect.workflow.impl.NullHandler"
value
="false"
variable-name
="name"
/>
</
conditions
>
</
conditions
>
<
handler
class
="net.rubyeye.insect.workflow.test.CalculateHandler"
/>
<
inputs
>
<
place
id
="3"
/>
</
inputs
>
<
outputs
>
<
place
id
="4"
/>
</
outputs
>
</
node
>
<
node
type
="end"
name
="hello"
id
="3"
>
<
inputs
>
<
place
id
="4"
/>
</
inputs
>
<
outputs
>
<
place
id
="5"
/>
</
outputs
>
</
node
>
</
workflow
>
并行路由和选择路由引入了and-split,and-join,or-split,or-join四种transition,比如and-split,它就有多个输出place:
<
node
name
="split"
type
="and-split"
id
="1"
resource
="user"
>
<
inputs
>
<
place
id
="2"
/>
</
inputs
>
<
outputs
>
<
place
id
="3"
/>
<
place
id
="4"
/>
</
outputs
>
</
node
>
Place和Transition都有条件,用于决定操作是否执行,Transition额外指定了驱动的资源以及回调的handler,这一点非常重要,资源可能是用户、用户组、某个时间点定时事件、特定消息等等。
今天额外发现的一个好处就是,引入Place之后,我可以轻易地将不同的流程连接起来组织成一个更复杂的流程,仅仅是需要修改各个流程的开始和结束的节点的输入输出库所,从而实现了层次化的Petri网,,类似代码:
WorkFlow sequence
=
wm.getWorkFlow(
"
sequence
"
); WorkFlow concurrency
=
wm.getWorkFlow(
"
concurrency
"
); WorkFlow choose
=
wm.getWorkFlow(
"
choose
"
);
//
组合流程
composite
=
new
WorkFlow(); composite.setName(
"
composite
"
); composite.setId(
100
); wm.saveWorkFlow(composite);
//
修改开始结束节点的输入输出库所
sequence.getEnd().setType(TransitionType.NORMAL); sequence.getEnd().setOutputs(concurrency.getStart().getInputs()); concurrency.getEnd().setType(TransitionType.NORMAL); concurrency.getEnd().setOutputs(choose.getStart().getInputs()); composite.setStart(sequence.getStart()); composite.setEnd(choose.getEnd()); List
<
Transition
>
transitions
=
new
ArrayList
<
Transition
>
(); transitions.addAll(sequence.getTransitions()); transitions.addAll(concurrency.getTransitions()); transitions.addAll(choose.getTransitions()); composite.setTransitions(transitions);
文章转自庄周梦蝶 ,原文发布时间2007-10-11