osworkflow问答

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

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

2.         简单的描述一下OSWorkflow工作流定义的特点?

答:OSWorkflow把工作流视为一组关联的Step,通过执行与Step相关的Action,实现从一个Step到另一个Step的转换。从而引起工作流状态的转换,推动工作的前进。目前OSWorkflow并不支持子流程,这一点可以从它的dtd文件看出来。另一个主要的特点就是脚本(如beanshell)的支持,OSWorkflow的主要组件,如functionvalidator等,都支持使用脚本来编程。

3.         如何定义顺序结构?

答:Step1Step2的转换,可以这样来看:在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。对于statusold-status,前者表示转向到Step2后的状态值(Step2的状态),后者表示离开Step1后状态值(Step1的状态)。

另外,当转向的Step是类似于<step name="end" id="2"/>时,则流程会自动终止。当转向的Step中包含的Action集合中存在一个auto属性为trueaction时,转向之后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.         如何定义并行工作中的SplitJoin

答:在状态机中表示并行工作的存在着2个特别的元素:分拆和合并。在OSWorkflow中与之对应的则是:<split><join>。从Step2分拆成2个并行任务(Step31Step32),再合并并转向Step4。可以如此理解:在Step2上执行一个Action,其结果会导致Step31Step32的产生;分别执行Step31Step32Action,转向合并点;合并点判断Step31Step32都完成后,那么转向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;

}

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

6.         如何实现自定义的功能?

答:OSWorkflow在工作流描述文件中提供了自定义功能的地方:

-          function,主要在状态改变时发生作用,如状态改变时发送电子邮件通知。对应的元素<function>,用于<pre-functions><post-functions>中。针对<step><action>都可以使用,pre-function是进入<step><action>时起作用;post-functions是离开时起作用。例子:

-          condition,自定义条件,如执行action的所需要的条件,在<conditions>中定义。针对<join>< restrict-to ><result>起作用。如果在<conditions>包含<conditions>,表示内嵌条件。

-          validator,自定义验证,如验证参数或流程的状态,在<validators>中定义。针对<action><result><unconditional-result>起作用。

-          register,为工作流的组件,如function,提供了存取另一个实体的方便操作。可以理解为这个实体的创建工厂,在<registers>中定义。针对工作流的其他组件都起作用。

上述组件都支持三种类型的定义:Java-basedbeanshellbsf,使用方法基本一致。以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提供了一些内置的对象(对于脚本,直接在脚本中按下面的名字使用即可):

-          transientVars,临时变量Map,包括:register、用户输入和当前的工作流上下文等信息。

-          args,在文件的<arg>中定义的参数Map

-          propertySet,用于持久化的变量。

-          jncom.opensymphony.workflow.JoinNodes,表示合并的步骤集合。

上述对象,前三个可以使用在前面列出的所有组件中使用。最后一个主要在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是初始化时得到的流程id11<action>id,这个id应该是全局唯一的;最后一个参数,是用来给OSWorkflow传递参数用的外部输入。

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

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

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

9.         如何查询工作流?

答:主要的类型:

-          获得当前步骤和历史步骤列表:WorkflowgetCurrentStepsgetHistorySteps

-          获得当前可用的actionWorkflowgetAvailableActions

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值