Posted on 2007-10-11 16:51
dennis 阅读(557)
评论(0) 编辑 收藏 所属分类:
java 、
my open-source
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);