OSWorkFlow深入浅出(6)---Step2详解

来源:互联网 发布:点阵取模软件 编辑:程序博客网 时间:2024/06/17 10:52

在上一下节中,我们曾写道讲解了step的prefunction以及postfunction,其实都是标签层面的讲解,因为在后文中我们将要详细描述Function组建,这在osworkflow中占有非常重要的位置,上一节中还有两个step非常重要的概念,那就是split和join,我们在本节中详细说明。

先来说说split和join的作用是什么,我们不妨来看看如下的状态图。


通过上图可以看出当请假条直接上司审批之后,还需要两个部门领导人审批,只有两个领导审批通过之后,最终到最高领导处审批,最高领导审批通过才算成功!

通过上面的文字描述和图示,我们不难看出有两个非常重要的概念,那就是拆分和联合,也就是split和join,这种情况也是一个流程引擎中必须具备的功能。

针对上面的流程图,我们不难写出配置文件,配置文件如下所示!

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE workflow PUBLIC "-//OpenSymphony Group//DTD OSWorkflow 2.7//EN" "http://www.opensymphony.com/osworkflow/workflow_2_7.dtd"><workflow><initial-actions><action id="100" name="请假初始化"><results><unconditional-result old-status="Finished"status="Underway" step="1" owner="step" /></results></action></initial-actions><steps><step id="1" name="员工请假"><actions><action id="1" name="请假"><results><unconditional-result old-status="Finished"status="Underway" step="2" /></results></action></actions></step><step id="2" name="直接上司审批"><actions><action id="2" name="上司审批"><results><unconditional-result old-status="Finished"status="Underway" split="1" /></results></action></actions></step><step id="4" name="部门领导A审批"><actions><action id="4" name="领导A审批"><results><unconditional-result old-status="Finished"status="Underway" join="1" /></results></action></actions></step><step id="5" name="部门领导B审批"><actions><action id="5" name="领导B审批"><results><unconditional-result old-status="Finished"status="Underway" join="1" /></results></action></actions></step><step id="6" name="最高领导审批"><actions><action id="6" name="最高领导审批" finish="true"><results><unconditional-result old-status="Finished"status="Underway" step="6" /></results></action></actions></step></steps><splits><split id="1"><unconditional-result old-status="Finished"status="Underway" step="4" /><unconditional-result old-status="Finished"status="Underway" step="5" /></split></splits><joins><join id="1"><conditions type="AND"><condition type="beanshell"><arg name="script"><![CDATA["Finished".equals(jn.getStep(4).getStatus())                    && "Finished".equals(jn.getStep(5).getStatus())          ]]></arg></condition></conditions><unconditional-result old-status="Finished"status="Underway" step="6" /></join></joins></workflow>
 对照着上文中的描述,我们将xml写了出来,其中在joins中有一个非常重要的上下文常量,叫做jn,其中jn是JoinNodes对象的一个实例,在该示例中提供了若干个方法,其中有一个方法getStep,可以通过他获取step的实例对象,在后文中讲解源码的时候都会讲解到,耐心等待吧。

写完了配置文件,就直接单元测试呗,看看我们的流程是否行得通!

@Testpublic void testJoinAndSplit(){long id ;try {id = wf.initialize("joinsplit", 100, null);List currentSteps = wf.getCurrentSteps(id);/*系统初始化之后只有一个step可以执行,那就是step,也就是请假单发起的步骤*/Assert.assertEquals(1, currentSteps.size());Assert.assertEquals(1,((SimpleStep)currentSteps.get(0)).getId());/*执行请假申请流程*/wf.doAction(id, 1, Collections.EMPTY_MAP);/*接下来应该到直接上级*/currentSteps = wf.getCurrentSteps(id);Assert.assertEquals(1, currentSteps.size());/*直接上级的step为2*/Assert.assertEquals(2,((SimpleStep)currentSteps.get(0)).getId());/*获取执行历史*/List historySteps = wf.getHistorySteps(id);/*只有一个执行历史*/Assert.assertEquals(1, currentSteps.size());/*直接上级审批通过*/wf.doAction(id, 2, Collections.EMPTY_MAP);/*接下来应该到了两位部门领导哪里,因此需要执行的步骤应该有两个才对*/currentSteps = wf.getCurrentSteps(id);Assert.assertEquals(2, currentSteps.size());/*部门领导A审批*/wf.doAction(id, 4, Collections.EMPTY_MAP);/*部门领导B审批*/wf.doAction(id, 5, Collections.EMPTY_MAP);/*接下来应该到了最高领导哪里,因此需要执行的步骤应该有1个才对*/currentSteps = wf.getCurrentSteps(id);Assert.assertEquals(1, currentSteps.size());/*最高领导审批*/wf.doAction(id, 6, Collections.EMPTY_MAP);/*流程执行完毕*/Assert.assertEquals(WorkflowEntry.COMPLETED, wf.getEntryState(id));historySteps = wf.getHistorySteps(id);Assert.assertEquals(5, historySteps.size());} catch (InvalidActionException e) {e.printStackTrace();} catch (InvalidRoleException e) {e.printStackTrace();} catch (InvalidInputException e) {e.printStackTrace();} catch (InvalidEntryStateException e) {e.printStackTrace();} catch (WorkflowException e) {e.printStackTrace();}}

执行单元测试,顺利通过,并且我们的期望都得到了正确的验证,通过上面的例子,您是不是对join和split标签有了一个比较清楚的认识呢?如果不了解标签如何配置,我给您的建议是直接打开dtd文件,非常直观,如下所示

joins标签:

<!ELEMENT join (conditions, unconditional-result)><!ATTLIST joinid CDATA #REQUIRED><!--A list of join elements.Used in: workflow--><!ELEMENT joins (join*)>
Splits标签
<!ELEMENT split (unconditional-result+)><!ATTLIST splitid CDATA #REQUIRED><!--List of split elements.Used in: workflow--><!ELEMENT splits (split+)>
好了,本节的内容描述完毕!下节再见!