首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > PowerDesigner >

第 六 章 jPDL

2012-08-27 
第 6 章 jPDL这章将会解释用来描述流程定义的 jPDL文件格式。jDPL是jBPM的突出的流程语言。jPDL的目标 是尽

第 6 章 jPDL

这章将会解释用来描述流程定义的 jPDL文件格式。jDPL是jBPM的突出的流程语言。jPDL的目标 是尽量精简和尽可能的开发者友好,在提供所有你期望 从BPM流程语言中获得功能的同时。

jPDL的schema文件包含了比这个文档中更多的属性和元素。 这个文档解释了jPDL中稳定的被支持的部分。 试验性的、不支持的jPDL特性可以在开发者指南中找到。

下面是一个jPDL流程文件的例子:

6.1.?process流程处理

顶级元素(element)是流程处理定义。

表?6.1.?process流程处理的属性

属性类型默认值是否必须描述name名称文本?必须在与用户交互时, 作为流程名字显示的一个名字或是标签。key键字母或数字,下划线如果省略,key中的非字母和非数字的字符会被替换为 下划线。可选(optional)用来辨别不同的流程定义。 拥有同一个key的流程会有多个版本。 对于所有已发布的流程版本,key-name这种组合都必须是 完全一样的。version版本整型比已部署的key相同的流程版本号高1, 如果还没有与之相同的key的流程被部署,那么版本就从1开始。可选流程的版本号

表?6.2.?process流程的元素

元素个数描述description描述0个或1个描述文本activities活动至少1个流程中会有很多活动, 至少要有1个是启动的活动。
?

6.2.?控制流程Activities活动

6.2.1.?start启动

说明一个流程的实例从哪里开始。 在一个流程里必须有一个开始节点。 一个流程必须至少拥有一个开始节点。 开始节点必须有一个向外的流向,这个流向会在流程启动的时候执行。

已知的限制:直到现在, 一个流程处理只能有一个启动节点(start)。

表?6.3.?start启动的属性

属性类型默认值是否必须描述name名称文本?可选活动的名字,在启动活动没有内部的转移(transition)时, name名称是可选的。

表?6.4.?start启动的元素

元素个数描述transition转移1向外的转移
?

6.2.2.?State状态节点

一个等待状态节点。 流程处理的流向会在外部触发器调用提供的API之前一直等待。 状态节点和其他的活动不一样, 它没有其他任何属性或元素。

6.2.2.1.?序列状态节点

让我们看一个用序列连接状态 和转移的例子。

第 六 章 jPDL

图?6.1.?序列状态节点


下列代码将启动一个流向:

6.2.2.2.?可选择的状态节点

在第2个状态节点的例子里, 我们将演示如何使用状态节点实现 路径的选择。

第 六 章 jPDL

图?6.2.?状态节点中的选择


让我们在这个流程处理定义里启动一个新的流程实例。

6.2.3.?decision决定节点

在多个选择中选择一条路径。也可以当做是一个决定。 一个决定活动拥有很多个向外的转移。当一个流向到达一个决定活动时, 会自动执行并决定交给哪个向外的转移。

一个决定节点应该配置成下面三个方式之一。

6.2.3.1.?decision决定条件

decision中会运行并判断每一个transition里的判断条件。 当遇到一个嵌套条件是true或者没有设置判断条件的转移, 那么转移就会被运行。

表?6.5.?exclusive.transition.condition 属性

属性类型默认值是否必须?描述exprexpression?required必须将被运行的 指定脚本langexpression language从脚本引擎配置里得到的默认代表性语言(default-expression-language)可选指定expr中执行的 脚本语言的种类

例子:

第 六 章 jPDL

图?6.3.?流程处理的决定条件例子


<condition expr="#{content=="good"}" />    </transition>    <transition to="try again">      <condition expr="#{content=="not so good"}" />    </transition>    <transition to="give up" />  </decision>  <state name="submit document" />  <state name="try again" />  <state name="give up" /></process>

在使用good content启动一个流程之后

submit document活动会变成活动的

6.2.3.2.?decision expression唯一性表达式

decision表达式返回类型为字符串的 向外转移的名字。

表?6.6.?决定属性

属性类型默认值是否必须?描述exprexpression?required必须将被运行的指定 脚本langexpression language从脚本引擎配置里得到的默认指定的脚本语言(default-expression-language)可选指定expr中执行的脚本语言的 种类。

例子:

第 六 章 jPDL

图?6.4.?流程处理的决定表达式例子


expr="#{content}" >    <transition name="good" to="submit document"  />    <transition name="bad"  to="try again"  />    <transition name="ugly" to="give up"  />  </decision>  <state name="submit document"  />  <state name="try again"  />  <state name="give up"  /></process>

当你使用good content启动一个新的流程实例,代码如下:

submit document活动。

参考实例中的单元测试,获得其他场景。

6.2.3.3.?Decision handler决定处理器

唯一性管理是继承了DecisionHandler接口的java类。 决定处理器负责选择 向外转移。

handler的内容元素 可以在第?6.7?节 “用户代码”中找到。

下面是一个决定使用DecisionHandler的流程处理例子:

第 六 章 jPDL

图?6.5.?流程处理的exclusive管理例子


下面是ContentEvalation类:

6.2.4.?concurrency并发

流程的并发路径可以使用?fork?和?join?活动来建模。下面的表格描述了?join?的属性;fork没有特别的属性。

表?6.7.?join属性:

属性类型默认值是否必须?描述multiplicity整数或表达式传入转移的数目可选在这个join活动之前需要到达的执行的数目, 然后一个执行 会沿着join的单独的外向转移向外执行。lockmode{none, read, upgrade, upgrade_nowait, write}upgrade可选hibernate的锁定模式,应用在上级执行, 来防止两个还没到达join的同步事务看到对方, 这会导致死锁。

6.2.4.1.?使用?fork实现并行分支

fork?活动允许将一个单独的流程路径分成 两个或多个分支,这些流程分支可以同步执行。

第 六 章 jPDL第 六 章 jPDL

图?6.6.?流程处理的并发例子


<fork name="fork">      <transition to="send invoice" />      <transition to="load truck"/>      <transition to="print shipping documents" />   </fork>   <state name="send invoice" >      <transition to="final join" />   </state>   <state name="load truck" >      <transition to="shipping join" />   </state>   <state name="print shipping documents">      <transition to="shipping join" />   </state>   <join name="shipping join" >      <transition to="drive truck to destination" />   </join>   <state name="drive truck to destination" >      <transition to="final join" />   </state>   <join name="final join" >      <transition to="end"/>   </join>   <end name="end" /></process>

6.2.5.?end结束

结束流向

6.2.5.1.?end process instance结束流程处理实例

默认情况下,结束活动会终结已完成流程处理实例。 因此在流程处理实例中, 仍然在活动的多个并发(concurrent)流向(concurrent) 也会结束。

第 六 章 jPDL

图?6.7.?结束活动


新的流程处理实例一创建便会直接结束。

6.2.5.2.?end execution结束流向

只有流向到达结束(end)活动时会结束流程处理实例, 并且其他并发流向会放弃活动。 我们可以设置属性ends="execution" 来达到这种状况。

表?6.8.?end execution属性

属性类型默认值是否必须描述ends{processinstance|execution}processinstanceoptional可选流向路径到达end活动 整个流程处理实例就会结束。
?

6.2.5.3.?end multiple多个结束

一个流程处理可以有多个end events, 这样就很容易显示出流程处理实例的不同结果。示例:

第 六 章 jPDL

图?6.8.?多个end events


如果你启动一个流向并使用下面的代码将它执行到get return code等待状态, 流向便会以bad request的end 活动(event)结束

6.2.5.4.?end State结束状态

流向(execution)可以以不同的状态结束。可以用其他的方式列出流程处理实例的结果。 可以用end event的状态属性或者end-cancel 和end-error表示。

表?6.9.?end execution 属性

属性类型默认值是否必须描述stateString?可选状态分配给流向

参考下面流程的例子。

第 六 章 jPDL

图?6.9.?不同的结束状态


这时,如果我们启动一个流向并使用下面的代码将流向执行到get return code等待状态, 流向会以取消状态(cancel state)结束。

和上面一样,使用值为200或500会让流向 分别以comleted或者error states结束。

6.2.6.?task

在任务组件中,为一个人创建一个任务。

6.2.6.1.?任务分配者

一个简单的任务会被分配给一个指定的用户

表?6.10.?任务属性:

属性类型默认值是否必填描述assignee表达式?可选用户id引用的用户 负责完成任务。
第 六 章 jPDL

图?6.10.?任务分配者示例流程


assignee="#{order.owner}">     <transition to="wait" />  </task>  <state name="wait" /></process>

这个流程演示了任务分配的两个方面。第一,?assignee用来指示用户, 负责完成任务的人。分配人是一个任务中的字符串属性 引用一个用户。

第二,这个属性默认会当做表达式来执行。 在这里任务被分配给#{order.owner}。 这意味着首先使用order这个名字查找一个对象。 其中一个查找对象的地方是这个任务对应的流程变量。 然后getOwner()方法会用来 获得用户id, 引用的用户负责完成这个任务。

这就是我们例子中使用到得Order类:

johndoe的任务列表可以像下面这样获得。

assignee="johndoe"。 在这里,任务会被分配给johndoe。

6.2.6.2.?task候选人

任务可能被分配给一组用户。 其中的一个用户应该接受这个任务并完成它。

表?6.11.?任务属性:

属性类型默认值是否必填描述candidate-groups表达式?可选一个使用逗号分隔的组id列表。 所有组内的用户将会成为这个任务的 候选人。candidate-users表达式?可选一个使用逗号分隔的用户id列表。 所有的用户将会成为这个任务的候选人。
第 六 章 jPDL

图?6.11.?任务候选人示例流程


这是一个使用任务候选人的示例流程:

candidate-groups="sales-dept">     <transition to="wait" />  </task>  <state name="wait"/></process>        

在启动之后,一个任务会被创建。这个任务不显示在任何人的个人任务列表中。 下面的任务列表会是空的。

sales-dept组成员的 分组任务列表中。

在我们的例子中,sales-dept有两个成员:johndoe和joesmoe

candidate-users属性 可以用来处理用逗号分隔的一系列用户id。?candidate-users属性可以和其他分配选项结合使用。

6.2.6.3.?任务分配处理器

一个AssignmentHandler可以通过编程方式来计算 一个任务的分配人和候选人。

AssignmentHandler extends Serializable {  /** sets the actorId and candidates for the given assignable. */  void assign(Assignable assignable, OpenExecution execution) throws Exception;}

Assignable是任务和泳道的通用接口。 所以任务分配处理器可以使用在任务, 也可以用在泳道中(参考后面的内容)。

assignment-handler是任务元素的一个子元素。 它指定用户代码对象。所以assignment-handler的属性和元素 都来自第?6.7?节 “用户代码”

让我们看一下任务分配的例子流程。

第 六 章 jPDL

图?6.12.?任务分配处理器的示例流程


<assignment-handler />      </field>    </assignment-handler>    <transition to="wait" />  </task>  <state name="wait" g="255,16,88,52" /></process>

引用的类AssignTask看起来像这样:

TaskAssignmentHandler的新流程实例 会立即让新流程实例运行到任务节点。 一个新review任务被创建,在这个时候?AssignTask的分配处理器被调用。这将设置johndoe为分配人。 所以John Doe将在他自己的任务列表中找到这个任务。

6.2.6.4.?任务泳道

一个流程中的多任务应该被分配给同一个用户或换选人。 一个流程中的多任务可以分配给一个单独的泳道。 流程实例将记得换选人和用户,在泳道中执行的第一个任务。 任务序列在同一个泳道中将被分配给 这些用户和候选人。

一个泳道也可以当做一个流程规则。 在一些情况下, 这可能与身份组件中的权限角色相同。 但是实际上它们并不是同一个东西。

表?6.12.?任务属性:

属性类型默认值是否必填描述swimlane泳道(字符串)?可选引用一个定义在流程中的泳道

泳道可以被声明在流程元素中:

表?6.13.?泳道属性:

属性类型默认值是否必填描述name泳道(字符串)?必填泳道名称。 这个名称将被任务泳道属性中引用。assignee表达式?可选用户id引用的用户 负责完成这个任务。candidate-groups表达式?可选一个使用逗号分隔的组id列表。 所有组中的人将作为这个任务的这个泳道中的 候选人。candidate-users表达式?可选一个使用逗号分隔的用户id列表。 所有的用户将作为这个任务的这个泳道中的 候选人。
第 六 章 jPDL

图?6.13.?任务泳道示例流程


任务泳道示例是下面这个流程文件:

<swimlane name="sales representative"            candidate-groups="sales-dept" />  <start>    <transition to="enter order data" />  </start>  <task name="enter order data"        swimlane="sales representative">    <transition to="calculate quote"/>  </task>  <task      name="calculate quote"      swimlane="sales representative">  </task></process>

在这个例子中,我们在身份组件中 创建了下面的信息:

johndoe将成为?enter order data的一个候选人。还是像上一个流程候选人例子一样, John Doe可以像这样接收任务:

johndoe成为任务的分配人。 直到任务与泳道sales representative关联, 分配人johndoe也会关联到泳道中 作为分配人。

接下来,John Doe可以像下面这样完成任务:

calculate quote。 这个任务也关联着泳道。因此, 任务会分配给johndoe。 初始化分配的候选人用户和候选人组也会从泳道复制给任务。 这里所指的用户johndoe?会释放任务,返回它给其他候选人。

6.2.6.5.?任务变量

任务可以读取,更新流程变量。 稍后任务可以选择定义任务本地流程变量。 任务变量是任务表单的一个很重要的部分。 任务表单显示来自任务和流程实例的数据。 然后从用户一侧录入的数据会转换成设置的任务变量。

获得任务变量就像这样:

6.2.6.6.?在任务中支持e-mail

可以为分配人提供一个提醒, 当一个任务添加到他们的列表时,以及在特定的时间间隔进行提醒。 每个email信息都是根据一个模板生成出来的。模板可以在内部指定, 或者在配置文件中的?process-engine-context部分指定。

表?6.14.?task元素

元素数目描述notification0..1让一个任务被分配的时候发送一个提醒消息。 如果没有引用模板,也没有提供内部的模板, mail会使用task-notification名字的模板。reminder0..1根据指定的时间间隔发送提醒信息。 如果没有引用模板,也没有提供内部模板, mail会使用task-reminder名字的模板。

表?6.15.?notification属性

属性类型默认值是否必填描述continue{sync | async | exclusive}sync可选指定在发送提醒邮件后, 是不是产生一个异步执行。

表?6.16.?reminder属性:

热点排行