OSWorkflow使用问答

1.         从哪儿可以得到OSWorkflow的有关工作流定义的资料?

答:下载之后,在OSWorkflow的docs目录下会有一些dtd文件。其中workflow_2_7.dtd就是2.7的工作流xml使用的dtd。在这个文件中,作者使用注释详细说明了每个元素的含义和作用。

2.         简单的描述一下OSWorkflow工作流定义的特点?
答: OSWorkflow把工作流视为一组关联的Step,通过执行与Step相关的Action,实现从一个Step到另一个Step的转换。从而引起工作 流状态的转换,推动工作的前进。目前OSWorkflow并不支持子流程,这一点可以从它的dtd文件看出来。另一个主要的特点就是脚本(如 beanshell)的支持,OSWorkflow的主要组件,如function、validator等,都支持使用脚本来编程。
3.         如何定义顺序结构?
答:Step1到Step2的转换,可以这样来看:在Step1上执行了一个Action,这个Action的结果是转向到Step2。因此,可以描述成:

<steps>

      <step name="Step1" id="1">

                <actions>

                         <action name="Step1_Action" id="11">

                                  <results>

                                            <unconditional-result old-status="Finished" status="Waiting" step="2"/>

                                  </results>

                         </action>

                </actions>

      </step>

      <step name="Step2" id="2">

        ......

      </step>

<steps>
注意,在OSWorkflow中基本上都是使用id,而不是name。对于status和old-status,前者表示转向到Step2后的状态值(Step2的状态),后者表示离开Step1后状态值(Step1的状态)。
另外,当转向的Step是类似于<step name="end" id="2"/>时,则流程会自动终止。当转向的Step中包含的Action集合中存在一个auto属性为true的action时,转向之后Action自动触发。如:

<step name="Step2" id="2">

    <actions>

        <action name="Step2_Action" id="21" auto="true">

            <results>

                <unconditional-result old-status="Finished" status="Ready1" split="100"/>

            </results>

        </action>

    </actions>

</step>

进入Step2后,Step2_Action将自动执行。

4.         如何定义并行工作中的Split和Join?
答:在状态机中表示并行工作的存在着2个特别的元素:分拆和合并。在 OSWorkflow中与之对应的则是:<split>和< join>。从Step2分拆成2个并行任务(Step31,Step32),再合并并转向Step4。可以如此理解:在Step2上执行一个 Action,其结果会导致Step31和Step32的产生;分别执行Step31和Step32的Action,转向合并点;合并点判断Step31 和Step32都完成后,那么转向Step4。因此,可以描述为:

<steps>

......

<step name="Step2" id="2">

    <actions>

        <action name="Step2_Action" id="21">

            <results>

                <unconditional-result old-status="Finished" status="Ready1" split="100"/>

            </results>

        </action>

    </actions>

</step>

<step name="Split_Step" id="31">

    <actions>

        <action name="Split_Step_Action" id="311">

            <results>

                <unconditional-result old-status="finished" status="Ready2" join="200"/>

            </results>

        </action>

    </actions>

</step>

<step name="Split_Step" id="32">

    <actions>

        <action name="Split_Step_Action" id="321">

            <results>

                <unconditional-result old-status="finished" status="Ready3" join="200"/>

            </results>

        </action>

    </actions>

</step>

<step name="Join_Step" id="4">

    ......

</step>

</steps>

<splits>

<split id="100">

    <unconditional-result old-status="finished" status="Ready5" step="31" />

    <unconditional-result old-status="finished" status="Ready6" step="32" />

</split>

</splits>

<joins>

<join id="200">

    <conditions>

        <condition type="beanshell">

            <arg name="script">

                "finished".equals( jn.getStep(31).getStatus())

              &amp;&amp;"finished".equals( jn.getStep(32).getStatus());

            </arg>

        </condition>

    </conditions>

    <unconditional-result old-status="finished" status="Ready7" step="4" />

</join>

</joins>

注意:<steps>、<splits> 和<joins>可以理解为<step>、< split>和<join>对应的集合。关键是<result>(或<unconditional- result>),使得这些离散的建立了关联,确定了状态转换的目标。

5.         如何建立分支和循环结构?
答:对于循环结构可以由分支结构来模拟,让我们主要来看看分支结构的实现。通常有2种方法:
-          使用外部程序,因为状态改变是Action的结果,而每个Step可以有多个Action。通过在外部程序中决定使用哪个Action,可以达到分支的效果。这个方法的本质实际是将分支判断放到外部程序中。如:

<steps>

      <step name="Step1" id="1">

                <actions>

                         <action name="Step1_Action1" id="11">

                                  <results>

                                            <unconditional-result old-status="Finished" status="Waiting" step="2"/>

                                  </results>

                         </action>

            <action name="Step1_Action2" id="12">

                                  <results>

                                            <unconditional-result old-status="Finished" status="Waiting" step="3"/>

                                  </results>

                         </action>

                </actions>

      </step>

      <step name="Step2" id="2">

        ......

      </step>

    <step name="Step3" id="3">

        ......

      </step>

<steps>
       当处于Step1时,在外部程序如果调用action11,那么下一步就是Step2;如果是action12,下一步就是Step3。
-          使用带条件的结果,相对于上个方法而言,这个是使用OSWorkflow的内部机制。当然,内部条件使用的数据仍然还是由外部调用决定的。如:

<step name="Step2" id="2">

    <actions>

        <action name="Step2_Action" id="21">

            <results>

               <result old-status="Finished" status="Ready1" step="5">

                    <conditions>

                        <condition type="beanshell">

                            <arg name="script">

                                null== transientVars.get("flag");

                            </arg>

                        </condition>

                    </conditions>

                </result>

                <unconditional-result old-status="Finished" status="Ready1" split="100"/>

            </results>

        </action>                     

    </actions>

</step>
       上述描述相当于:
       if(){
              转向step5;
       }else{
              转向split100;
}

从OSWorkflow 的DTD中,可以知道<results>的有关资料:<!ELEMENT results (result*, unconditional-result)>。当有多个带条件的result时,满足条件的第一个<result>起作用,当没有条 件满足时< unconditional-result >起作用。

6.         如何实现自定义的功能?
答:OSWorkflow在工作流描述文件中提供了自定义功能的地方:
-          ,主要在状态改变时发生作用,如状态改变时发送电子邮件通知。对应的元素<function>,用于<pre- functions>和<post-functions>中。针对<step>和<action>都可以使 用,pre-function是进入<step>或<action>时起作用;post-functions是离开时起作用。例 子:function
-          ,自定义条件,如执行action的所需要的条件,在<conditions>中定义。针对<join>、< restrict-to >和<result>起作用。如果在<conditions>包含<conditions>,表示内嵌条件。 condition
-          ,自定义验证,如验证参数或流程的状态,在<validators>中定义。针对<action>、<result>和<unconditional-result>起作用。validator
-          ,为工作流的组件,如function,提供了存取另一个实体的方便操作。可以理解为这个实体的创建工厂,在<registers>中定义。针对工作流的其他组件都起作用。register
上述组件都支持三种类型的定义:Java-based、beanshell和bsf,使用方法基本一致。以function为例:

<function type="beanshell">

<arg name="script">

    System.out.println("prefunction 2 of action 11");

</arg>

</function>

<function type="class">

    <!-- 实现类,参见javadoc -->

    <arg name="class.name">

workflow.Prefunction1OfStep1

</arg>

    <arg name="msg">foxgem is ok!</arg>

</function>

同时OSWorkflow还提供了对应的一些预置组件,请参见相关的javadoc。为了方便数据的交互,OSWorkflow提供了一些内置的对象(对于脚本,直接在脚本中按下面的名字使用即可):
-          ,临时变量Map,包括:register、用户输入和当前的工作流上下文等信息。transientVars
-          ,在文件的<arg>中定义的参数Map。args
-          ,用于持久化的变量。propertySet
-          ,com.opensymphony.workflow.JoinNodes,表示合并的步骤集合。jn

上述对象,前三个可以使用在前面列出的所有组件中使用。最后一个主要在join中定义的conditions中使用,见前例。

7.         外部程序如何使用OSWorkflow?
答:外部程序使用OSWorkflow的基本步骤:
1)        定义工作流文件,并配置。OSWorkflow的配置文件基本上是三个层次:
osworkflow.xml,配置osworkflow的全局信息。如创建工厂,持久化机制等。
    workflows.xml,指明工作流文件的集合
         具体workflow定义,定义具体的工作流描述。
2)        创建工作流:Workflow flow= new BasicWorkflow("tester");。
3)        初始化指定的工作流。
//最后一个参数,可以传进一些数据供OSWorkflow的组件使用
long id= flow.initialize( "mytest", 1, null);
其中 mytest,是在workflows.xml中定义的名字,对应具体的工作流定义文件。在OSWorkflow中有一组特定的Action,< initial-actions>,它的目的就是用来初始化流程的。典型的<initial-actions>定义如下:

<initial-actions>

      <action name="Start Workflow" id="1">

                <results>

                         <unconditional-result old-status="Finished" status="Queued" step="1"/>

                 </results>

      </action>

      <action name="Another Entry" id="2">

                <results>

                         <unconditional-result old-status="Finished" status="Underway" step="2"/>

                </results>

      </action>

</initial-actions>

这其中的每个Action代表了不同的流程启动点。

4)        执行指定的动作,完成流程状态的切换。flow.doAction( flowid, 11, null);。其中flowid是初始化时得到的流程id;11是<action>的id,这个id应该是全局唯一的;最后一个参数,是用来 给OSWorkflow传递参数用的外部输入。

以上就是OSWorkflow的基本使用,实际上最常用的就是2个方法:initialize和doAction。对于其他的方法和对象,请参见对应的javadoc。

8.         如何将持久化机制用于流程数据?

答:对于持久化的支持,OSWorkflow提供了WorkflowStore接 口,可以让使用者自己实现自定义的持久化机制。对于数据库,使用 JDBCStore即可。关于JDBCStore的配置主要集中于osworkflow.xml中,具体的配置方法,参见文档:1.4 Persistence Options。

9.         如何查询工作流?
答:主要的类型:
-          获得当前步骤和历史步骤列表:Workflow的getCurrentSteps和getHistorySteps。
-          获得当前可用的action:Workflow的getAvailableActions。

-          自定义查询:首先构造WorkflowExpressionQuery,然后使用Workflow的query。具体例子参见:文档5.4 Queries。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值