posts - 18,  comments - 0,  trackbacks - 0

OSWORKFLOW基本概念                                      

1. 步骤、状态和动作

工作流要描述步骤 (step) 、步骤的状态 (status) 、各个步骤之间的关系以及执行各个步骤的条件和权限,每个步骤中可以含有一个或多个动作 (action) ,动作将会使一个步骤的状态发生改变。

对于一个执行的工作流来讲,步骤的切换是不可避免的。一个工作流在某一时刻会有一个或多个当前步骤,每个当前步骤都有一个状态值,当前步骤的状态值组成了工作流实例的状态值。一旦完成了一个步骤,那么这个步骤将不再是当前步骤(而是切换到一个新的步骤),通常一个新的当前步骤将随之建立起来,以保证工作流继续执行。完成了的步骤的最终状态值是用 old-status 属性指定的,这个状态值的设定将发生在切换到其他步骤之前。 old-status 的值可以是任意的,但在一般情况下,我们设置为 Finished

切换本身是一个动作( action )的执行结果。每个步骤可以含有多个动作,究竟要载入哪个动作是由最终用户、外部事件或者 triggerd 的自动调用决定的。随着动作的完成,一个特定的步骤切换也将发生。动作可以被限制在用户、用户组或当前状态。每一个动作都必须包含一个 unconditional result 0 个或多个 conditional results

所以,总体来说,一个工作流由多个步骤组成。每个步骤有一个当前状态(例如: Queued, Underway, or Finished ),一个步骤包含多个动作。每个步骤含有多个可以执行的动作。每个动作都有执行的条件,也有要执行的函数。动作包含有可以改变状态和当前工作流步骤的 results

2. Results, Joins, and Splits

(1) Unconditional Result

对于每一个动作来讲,必须存在一个 Unconditional Result 。一个 result 是一系列指令,这些指令将告诉 OSWorkFlow 下一个任务要做什么。这包括使工作流从一个状态切换到另一个状态。

(2) conditional Result

conditional Result unconditional Result 的一个扩展。它需要一个或多个 condition 子标签。第一个为 true conditional (使用 AND OR 类型),会指明发生切换的步骤,这个切换步骤的发生是由于某个用户执行了某个动作的结果导致的。

(3) 三种不同的 Results conditional or unconditional

 -- 一个新的、单一的步骤和状态的组合。

 -- 一个分裂成两个或多个步骤和状态的组合。

 -- 将这个和其他的切换组合成一个新的单一的步骤和状态的组合。

  每种不同的 result 对应了不同的 xml 描述,你可以阅读 http://www.opensymphony.com/osworkflow/workflow_2_6.dtd ,获取更多的信息。

  注意:通常,一个 split 或一个 join 不会再导致一个 split join 的发生。

单一步骤和状态的结果可以这样描述:

<unconditional-result old-status="Finished" step="2" status="Underway" owner="${someOwner}"/>

如果状态不是 Queued 的话,那么第三个必要条件就是新步骤的所有者( owner )。除了可以指明下一个状态的信息之外, result 也可以指定 validators post-functions ,这将在下面讨论。

从一个状态分裂成多个状态可以这样描述:

<unconditional-result split="1"/>

...

<splits>

  <split id="1">

    <unconditional-result old-status="Finished" step="2"

                          status="Underway" owner="${someOwner}"/>

    <unconditional-result old-status="Finished" step="2"

                          status="Underway" owner="${someOtherOwner}"/>

  </split>

</splits>

将多个状态合并为一个状态可以这样描述:

<!-- for step id 6 ->

<unconditional-result join="1"/>

...

<!- for step id 8 ->

<unconditional-result join="1"/>

...

<joins>

  <join id="1">

    <conditions type="AND">

      <condition type="beanshell">

        <arg name="script">

          "Finished".equals(jn.getStep(6).getStatus()

          && "Finished".equals(jn.getStep(8).getStatus())

        </arg>

      </condition>

    </conditions>

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

  </join>

</joins>

上面的描述也许有点含糊,但是你最应该关注的是 condition 标签,它使用一个 "jn" 的变量,利用这个变量,你可以组成表达式来决定合并动作发生的条件。这个表达式的意思是说:“当 id=6 id=8 的步骤的状态都变成 Finished 的状态并且他们要发生的切换都是 join="1" 时,这个合并动作才发生”。

3. 外部函数

OSWorkFlow 为要定义和执行的外部业务逻辑定义了一个标准的解决方法。这是通过使用 "functions" 来实现的。 OSWorkFlow 有两种 function pre post step functions

Pre functions 是在流程的步骤发生切换之前执行的。一个例子是取得调用者名字的函数,将取得的调用者的名字作为要发生状态切换的 result 使用。另外一个例子是 pre-function 用来更新大多数的动作的最近调用者。这两个函数是做为标准的工具函数提供的,在实际的工作流中非常实用。

Post functions Pre functions 有着同样的适用范围,不同点在于 Post functions 是在状态发生变化之后执行的。一个典型的 Post functions 的例子是:在某个动作执行完毕后,给某些人发送电子邮件。例如:当一个文档处于 'research' 步骤,并且执行了 'markReadyForReview' 动作的时候,要发送邮件给所有的 reviewers

使用 Post functions Pre functions 可能有很多原因。一个是如果用户点击完成按钮两次而且发送了两次执行动作的指令,而且这个动作的 Pre function 会执行很长时间,那么这个长时间执行的函数可能会被执行多次,因为切换动作还没有发生,这时 OSWorkflow 会认为第二次执行动作是合理的。所以要将这个函数改变成 Post function 。一般情况下, Pre function 应该是简单的、能快速执行的函数。

函数可以定义在两个独立的位置:步骤 (step) 和动作 (action)

通常情况下, Post functions Pre functions 被定义在 action 中。在 action 中定义的 Pre-functions 是指在该动作发生之前要执行的函数。当工作流发生切换的时候,函数用来做某些事情,不管是发送 E_mail 也好,还是为以后的使用设置变量。

Post functions Pre functions 被定义在 step 中的时候,用途就有点不同了。在 step 中定义的 Pre-functions 是指在切换到这个 step 之前要执行

的函数。注意:这些函数将被应用到这个步骤的所有的切换,即使是由于这个步骤本身发起的切换,例如:在同一个步骤内,由 Queued 状态转移到 Underway 状态时,也将调用所有的 Pre functions 。与此相同,在 step 中的 Post functions 将在流程离开这个步骤之前。

4. Trigger Functions

Trigger Functions 与其他函数一样,不同点在于他们不是与一个动作相联系的。他们也是通过一个唯一的 ID 来标识。这些函数通常是运行在系统级用户或非正规用户的环境中。 Trigger functions 是通过 OSWorkflow API 来使用。

5. Validators

validator 是用来校验一个动作的输入的有效性的。如果输入符合条件,那么将执行这个动作。如果输入不符合条件,那么将抛出 InvalidInputException 异常。

6. Registers

A register 是一个辅助函数,这个函数可以返回一个对象,这个对象可以用在函数中去访问其他的普通对象,特别是出现在 workflow 中的实体。被注册的对象可以是任何类型,典型的注册对象的例子是: Document, Metadata, Issue, Task

下面是一个 registers 的例子:

<registers>

       <register name="doc" class="com.acme.DocumentRegister"/>

</registers>

...

<results>

       <result condition="doc.priority == 1" step="1" status="Underway"

                  owner="${someManager}"/>

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

</results>

...

7. Conditions

Conditions 就象 validators registers functions 一样,可以用不同的语言和技术来实现。 Conditions 可以用 AND OR 逻辑运算符来组织。 Conditions 通常是与 conditional results 联系的,只有当条件成立, result 才会执行。

Conditions 与函数很相似,唯一不同的是 Conditions 返回的是 boolean 值,而不是 void

8. Variable Interpolation

在所有的 functions conditions validators registers 中,可能要提供一系列的参数。这些参数将会被转化为参数 Map ,这将在后面讨论。同样,在 workflow 描述符中的 status old-status owner 标签也将被动态的解析成变量。一个变量是这样被识别的: ${foo} 。当 OSWorkflow 识别出这种格式的时候,它首先到 transientVars 中去找关键字为 foo 的对象,如果没有找到,那么就到 propertySet 中去找,如果也没找到,那么变量 foo 将被转换为一个空字串。

 

One thing of particular importance is that in the case of args, if the variable is the only argument, the argument will not be of type String, but instead whatever the variable type is. However, if the arg is a mix of characters and variables, the entire argument is converted to String no matter what. That means the two arguments below are very different in that foo is a Date object and bar is a String:

<arg name="foo">${someDate}</arg>

<arg name="bar"> ${someDate} </arg> <!-- 注意多余的空格 -->

9. Permissions and Restrictions

Permissions can be assigned to users and/or groups based on the state of the workflow instance. These permissions are unrelated to the functionality of the workflow engine, but they are useful to have for applications that implement OSWorkflow. For example, a document management system might have the permission name "file-write-permission" enabled for a particular group only during the "Document Edit" stage of the workflow. That way your application can use the API to determine if files can be modified or not. This is useful as there could be a number of states within the workflow where the "file-write-permission" is applicable, so instead of checking for specific steps or conditions, the check can simply be made for a particular permission.

 

10. Auto actions

有的时候,我们需要一些动作可以基于一些条件自动地执行。为了达到这个目的,你可以在 action 中加入 auto="true" 属性。流程将考察这个动作的条件和限制,如果条件符合,那么将执行这个动作。 Auto action 是由当前的调用者执行的,所以将对该动作的调用者执行权限检查。

11. Integrating with Abstract Entities

建议在你的核心实体中,例如 "Document" "Order" ,在内部创建一个新的属性: workflowId 。这样,当新的 "Document" "Order" 被创建的时候,它能够和一个 workflow 实例关联起来。那么,你的代码可以通过 OSWorkflow API 查找到这个 workflow 实例并且得到这个 workflow 的信息和动作。

12. Workflow Instance State

有的时候,为整个 workflow 实例指定一个状态是很有帮助的,它独立于流程的执行步骤。 OSWorkflow 提供一些 workflow 实例中可以包含的 "meta-states" 。这些 "meta-states" 可以是 CREATED, ACTIVATED, SUSPENDED, KILLED COMPLETED 。当一个工作流实例被创建的时候,它将处于 CREATED 状态。然后,只要一个动作被执行,它就会自动的变成 ACTIVATED 状态。如果调用者没有明确地改变实例的状态,工作流将一直保持这个状态直到工作流结束。当工作流不可能再执行任何其他的动作的时候,工作流将自动的变成 COMPLETED 状态。

 

然而,当工作流处于 ACTIVATED 状态的时候,调用者可以终止或挂起这个工作流(设置工作流的状态为 KILLED SUSPENDED )。一个终止了的工作流将不能再执行任何动作,而且将永远保持着终止状态。一个被挂起了的工作流会被冻结,他也不能执行任何的动作,除非它的状态再变成 ACTIVATED

posted on 2006-04-22 20:34 LORD BLOG 阅读(260) 评论(0)  编辑  收藏 所属分类: WorkFlow

只有注册用户登录后才能发表评论。


网站导航: