2007-10-11
写一个简单的工作流(二)
hoho,今天完成了选择路由的实现,完成了配置文件的读写和解析,流程定义文件还是决定采用xml文件,不过与其他工作流引擎采用的xml完全不同,因为是基于petri网的,因此引入了place的概念,比如下面这个4个节点的顺序路由的流程:
并行路由和选择路由引入了and-split,and-join,or-split,or-join四种transition,比如and-split,它就有多个输出place:
Place和Transition都有条件,用于决定操作是否执行,Transition额外指定了驱动的资源,这一点非常重要,资源可能是用户、用户组、某个时间点定时事件、特定消息等等。初步有个想法写一个GUI的流程定义工具,不过我对GUI编程了解有限,先暂时推后了。
今天额外发现的一个好处就是,引入Place之后,我可以轻易地将不同的流程连接起来组织成一个更复杂的流程,仅仅是需要修改各个流程的开始和结束的节点的输入输出库所,从而实现了层次化的Petri网,,类似代码:
xml 代码
- <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:
xml 代码
- <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额外指定了驱动的资源,这一点非常重要,资源可能是用户、用户组、某个时间点定时事件、特定消息等等。初步有个想法写一个GUI的流程定义工具,不过我对GUI编程了解有限,先暂时推后了。
今天额外发现的一个好处就是,引入Place之后,我可以轻易地将不同的流程连接起来组织成一个更复杂的流程,仅仅是需要修改各个流程的开始和结束的节点的输入输出库所,从而实现了层次化的Petri网,,类似代码:
java 代码
- 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);
发表评论
我的留言簿
-
你好,看过你关于自定义classloader的回帖,想问问几个问题:
  ...
-- by llp20_2000
最近加入圈子
最新评论
-
Ruby Tip——读文件
花花公子 写道IO.read("test.log")嗯,这个方法我是知道的,我前 ...
-- by dennis_zane -
Ruby Tip——读文件
IO.read("test.log")
-- by 花花公子 -
一封邮件
咋我没收到呢....
-- by yangzhihuan -
漂亮的代码
说得比较深.看的时候,觉得句句都正中心坎.看完之后,好像没啥收获.还是要自己试过 ...
-- by yangzhihuan -
广州opensource camp小记
貌似你那件open source camp的T-shirt背后很多广告滴说.
-- by yangzhihuan







评论排行榜