jPDL的扩展思考

基于自己目前对jBPM的了解,发现使用jBPM做为工作流引擎时流程可以通过jPDL很方便的定义和发布。主要的工作来自于界面的定制,因为觉得 想要做一个通用的jBPM界面简直是不可能(或者是我目前的思路有问题),每个流程的流程meta是没问题,比方说把transition定义为一个 button然后去调用webcontroller,但是业务meta就不行了,某个字段可能需要显示为一个dropdown而不是文本框。尽管jPDL designer可以生成form但也只能生成比较简单的文本框和按钮,而且是基于jsf。

偶然中发现了liferay中对jPDL的扩展恰好是我想要的,增加了表单数据类型的定义

每个node的变量定义为:
text:username
textarea:introduction
checkbox:married:yes,no

“liferayworkflow portletjbpm的变量定义经行了扩展,可以看到每个变量的名字都由多部分组成其中用冒号分隔,workflow portlet会根据变量的前缀自动为该变量生成html中的表单。”

现在扩展是扩展了,但是如果想要加入业务规则呢?试试另一种思路:业务数据是在流在工作流上的,那么在不同的流程阶段(phase)要满足不同的业 务规则。这里就有一个问题了,规则是应该作为流程的一部分还是作为数据的一部分,显然应该是流程的一部分。但流程怎么能够知道这些meta(某个数据在某 个节点上要怎么显示并满足哪些规则)呢 ?(其实这些东西早就有现成的产品了。比如PEGA)这个时候就又需要扩展jPDL了。

考虑怎么去扩展jPDL:每个流程应该有一个flowBean的model,他可能包含很多其他的业务数据对象,这样每个流程所要操作的数据就都在 这个flowBean里,而规则和显示则要定义到流程的每个节点。有点类似JPF(java page flow,weblogic portal用的webmvc)。

先想到这里,以后再补充。

jBPM中的assignment

ZhangV

在jbpm的流程定义文件(processdefinition.xml)中当定义一个task的assignment的时候有几种选择:

  • Swimlane
  • Pooled Actors
  • Expression
  • Actor
  • Handler

这里分别描述一下每种的用法,以及使用场景。使用场景的理解很重要,只有清楚每一种用法的所适合的情形,以及他们之间的相互转换才能说是真的“会用了”。

Swimlane
泳道是用来处理一个流程中的多个任务必须由同一个人来处理的机制。所以,当一个流程的第一个任务实例被创建到指定的泳道后,第一个任务实例中的执行人被保 存,该泳道中的后续任务的处理人都是第一个任务的处理人。所以一个泳道有一个人员被分配,并且泳道中的任务不需要再分配人员。这里是指这个流程中的参与者或者角色。在实际的业务系统中,他可能根本就不是一个业务角色,可能是一个外部应用,也可能是一个处理过程,或者是几个业务角色的结合。所以要清楚他是指“在该流程中”的角色。在jPDL的user guide中写的很清楚也反复强调 – “process role”。
通过在流程定义文件中定义:
<swimlane name=”leader”>
<assignment class=”com.modofo.engine.swimlane.LeaderSwimlane”></assignment>
</swimlane>
同样可以实现运行时的结合实际应用进行灵活的任务分配。这也是目前我看到的使用比较多的方式。

Actor
相当于设置TaskInstance的actorId属性,主要用于获取某个actor的所有任务列表。设置方法在定义中描述actor-id属性,或者调用TaskInstance.setActorId(String)方法,或者在AssignmentHandler中调用assignable.setActorId(String)方法。

Pooled Actors
用于定义所有的任务参与人(candidates for task instance)。在查找某个参与者可参与的任务时使用,其实就是一个actor的集合,jBPM通过TaskMgmtSession.findPooledTaskInstances(String actorId)或者TaskMgmtSession.findPooledTaskInstances(List actorIds) 来查找任务集合。
注意:actor的优先级比pooled actors要高,所以如果同时设置两者,那jBPM只会用actor来查找,而忽略pooled actors。

一句话: actor被用来获取某个参与者的个人任务列表,pooled actors用来获取某个参与者可以参与的所有任务列表,或者说组任务列表。
使用这个actor集合的初衷就是为了不让任务分配和角色体系耦合。流程定义中始终都是只有参与者的名称和集合,而不存在用户,角色和用户组的具体设计。而使用Expression就耦合了这些信息在流程定义里。

Expression
如果你使用jBPM的identity component的话。你可以使用表达式定义的任务分配模式。通常这个表达式的形式是:

<assignment expression=’previous –> group(hierarchy) –> member(boss)’ />
我看了之后也不是很清楚,group和member是jBPM的identity componenet的概念,这个表达的意思大概是:使用之前的actor,然后在hierarchy组,并且member(角色)是boss的所有actor。这种方法仅限于使用jBPM的IC时使用。

Handler

指定你自己的AssignmentHandler实现。该接口只有assign方法。这种任务分配方式主要用于运行时的任务分配,而不是hardcode到定义文件里。使用场景,如果不想让原本应用中的访问控制与jBPM耦合起来,就可以使用这种方法来将jBPM中的任务分配代理出来。当然更好的定义是用swimlane,这样可以让定义文件看起来不是很凌乱。