天天看點

寫一個簡單的工作流(二)

  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" />

            <place id="3" />

    <node name="calc" id="2" resource="user">

            <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>

            class="net.rubyeye.insect.workflow.test.calculatehandler" />

            <place id="4" />

    <node type="end" name="hello" id="3">

            <place id="5" />

</workflow>

并行路由和選擇路由引入了and-split,and-join,or-split,or-join四種transition,比如and-split,它就有多個輸出place:

<node name="split" type="and-split" id="1" resource="user">

   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