工作流系列(5.1)-Activiti流程文件解析功能架构设计

文章目录

    • 配置文件
    • BPMN2.0元素与Activiti的支持
      • 事件(Event)
      • 活动(Activity)
        • 任务(Task)
        • 子流程
      • 网关
      • 链接对象
    • 解析架构设计
      • 元素与转换
        • 转化器
        • 解析器

对于解析流程文件,Activiti使用的是流模式,在5.12.1之前使用的是推模式(SAX),而在此之后使用的拉模式(STAX)。

配置文件

之前也讲到,流程文件是通过XML文件配置的,如下所示:


<definitions id="definitions"
             targetNamespace="http://activiti.org/bpmn20"
             xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:activiti="http://activiti.org/bpmn">

  <process id="vacationRequest" name="Vacation request">

    <startEvent id="request" activiti:initiator="employeeName">
      <extensionElements>
        <activiti:formProperty id="numberOfDays" name="Number of days" type="long" value="1" required="true"/>
        <activiti:formProperty id="startDate" name="First day of holiday (dd-MM-yyy)" datePattern="dd-MM-yyyy hh:mm" type="date" required="true" />
        <activiti:formProperty id="vacationMotivation" name="Motivation" type="string" />
      extensionElements>
    startEvent>
    <sequenceFlow id="flow1" sourceRef="request" targetRef="handleRequest" />

    <userTask id="handleRequest" name="Handle vacation request" >
      <documentation>
        ${employeeName} would like to take ${numberOfDays} day(s) of vacation (Motivation: ${vacationMotivation}).
      documentation>
      <extensionElements>
         <activiti:formProperty id="vacationApproved" name="Do you approve this vacation" type="enum" required="true">
          <activiti:value id="true" name="Approve" />
          <activiti:value id="false" name="Reject" />
        activiti:formProperty>
        <activiti:formProperty id="managerMotivation" name="Motivation" type="string" />
      extensionElements>
      <potentialOwner>
        <resourceAssignmentExpression>
          <formalExpression>managementformalExpression>
        resourceAssignmentExpression>
      potentialOwner>
    userTask>
    <sequenceFlow id="flow2" sourceRef="handleRequest" targetRef="requestApprovedDecision" />

    <exclusiveGateway id="requestApprovedDecision" name="Request approved?" />
    <sequenceFlow id="flow3" sourceRef="requestApprovedDecision" targetRef="sendApprovalMail">
      <conditionExpression xsi:type="tFormalExpression">${vacationApproved == 'true'}conditionExpression>
    sequenceFlow>

    <task id="sendApprovalMail" name="Send confirmation e-mail" />
    <sequenceFlow id="flow4" sourceRef="sendApprovalMail" targetRef="theEnd1" />
    <endEvent id="theEnd1" />

    <sequenceFlow id="flow5" sourceRef="requestApprovedDecision" targetRef="adjustVacationRequestTask">
      <conditionExpression xsi:type="tFormalExpression">${vacationApproved == 'false'}conditionExpression>
    sequenceFlow>

    <userTask id="adjustVacationRequestTask" name="Adjust vacation request">
      <documentation>
        Your manager has disapproved your vacation request for ${numberOfDays} days.
        Reason: ${managerMotivation}
      documentation>
      <extensionElements>
        <activiti:formProperty id="numberOfDays" name="Number of days" value="${numberOfDays}" type="long" required="true"/>
        <activiti:formProperty id="startDate" name="First day of holiday (dd-MM-yyy)" value="${startDate}" datePattern="dd-MM-yyyy hh:mm" type="date" required="true" />
        <activiti:formProperty id="vacationMotivation" name="Motivation" value="${vacationMotivation}" type="string" />
        <activiti:formProperty id="resendRequest" name="Resend vacation request to manager?" type="enum" required="true">
          <activiti:value id="true" name="Yes" />
          <activiti:value id="false" name="No" />
        activiti:formProperty>
      extensionElements>
      <humanPerformer>
        <resourceAssignmentExpression>
          <formalExpression>${employeeName}formalExpression>
        resourceAssignmentExpression>
      humanPerformer>
    userTask>
    <sequenceFlow id="flow6" sourceRef="adjustVacationRequestTask" targetRef="resendRequestDecision" />

    <exclusiveGateway id="resendRequestDecision" name="Resend request?" />
    <sequenceFlow id="flow7" sourceRef="resendRequestDecision" targetRef="handleRequest">
      <conditionExpression xsi:type="tFormalExpression">${resendRequest == 'true'}conditionExpression>
    sequenceFlow>

     <sequenceFlow id="flow8" sourceRef="resendRequestDecision" targetRef="theEnd2">
      <conditionExpression xsi:type="tFormalExpression">${resendRequest == 'false'}conditionExpression>
    sequenceFlow>
    <endEvent id="theEnd2" />

  process>

definitions>

这只一个流程文件,摘自Activiti用户手册

BPMN2.0元素与Activiti的支持

对于BPMN元素的介绍,可以看 工作流系列(2)-BPMN简介。

Activiti对于BPMN元素的支持,只列出最基本的元素

事件(Event)

简单的介绍开始结束事件,其他的比如边界事件等暂不介绍

BPMN元素 Activiti 类 配置文件表示
开始事件 StartEvent
结束事件 EndEvent

活动(Activity)

活动包含任务、子流程

任务(Task)

只介绍常用的,当然还有其他的比如:业务规则任务、接受任务等

BPMN元素 Activiti 类 配置文件表示
用户任务 UserTask
服务任务 ServiceTask
手工任务 ManualTask

还有比如:脚本任务 ScriptTask

<scriptTask id="theScriptTask" name="Execute script" scriptFormat="groovy">
  <script>
    sum = 0
    for ( i in inputArray ) {
      sum += i
    }
  script>
scriptTask>

子流程

  • 嵌入子流程 subProcess
<subProcess id="subProcess">
  <startEvent id="subProcessStart" />
  ... other Sub-Process elements ...
  <endEvent id="subProcessEnd" />
 subProcess>
  • 调用子流程 callActivity
<callActivity id="callCheckCreditProcess" name="Check credit" calledElement="checkCreditProcess" />

网关

BPMN元素 Activiti 类 配置文件表示
并行网关 ParallelGateway
排他网关 ExclusiveGateway
包容网关 InclusiveGateway

链接对象

BPMN元素 Activiti 类 配置文件表示
顺序流 SequenceFlow

在顺序流中可以增加条件,比如

<sequenceFlow id="flow3" sourceRef="requestApprovedDecision" targetRef="sendApprovalMail">
      <conditionExpression xsi:type="tFormalExpression">${vacationApproved == 'true'}conditionExpression>
    sequenceFlow>

解析架构设计

Activiti的解析工作,就是将配置文件中的元素转换为对应的Java类,如果说Java类在对顶层,则配置文件就位于最底层,而在这两者中间就是转换器与解析器。
首先对于每一个元素都有公共的属性,比如id、name等,对于这些公共属性,我们可以将其提取到公共的方法中进行解析。但是每个元素都有自己独特的属性,所以Activiti为每一个元素都定义了解析器或转换器,以便当每个元素增添属性时,只需要修改特定的解析器就可以实现。

元素与转换

BpmnXMLConverter是转换的入口,它读取配置文件并进行循环解析,通过注册不同的转换器来转换不同的元素,而在转化器中通过自己解析或调用解析器解析元素,并最终构建BpmnModel对象。
很多元素都具有相同的构造,所以拥有一个公共的解析方式;拥有公共的扩展属性(ExtensionAttribute),这些使用同一个解析器循环处理。

转化器

元素 Java类 转换器 备注
endEvent EndEvent EndEventXMLConverter
startEvent StartEvent StartEventXMLConverter
businessRuleTask BusinessRuleTask BusinessRuleTaskXMLConverter
manualTask ManualTask ManualTaskXMLConverter
receiveTask ReceiveTask ReceiveTaskXMLConverter
scriptTask ScriptTask ScriptTaskXMLConverter
serviceTask ServiceTask ServiceTaskXMLConverter
sendTask SendTask SendTaskXMLConverter
userTask UserTask UserTaskXMLConverter
task Task TaskXMLConverter
callActivity CallActivity CallActivityXMLConverter
eventGateway EventGateway EventGatewayXMLConverter
exclusiveGateway ExclusiveGateway ExclusiveGatewayXMLConverter
inclusiveGateway InclusiveGateway InclusiveGatewayXMLConverter
parallelGateway ParallelGateway ParallelGatewayXMLConverter
complexGateway ComplexGateway ComplexGatewayXMLConverter
sequenceFlow SequenceFlow SequenceFlowXMLConverter
catchEvent CatchEvent CatchEventXMLConverter
throwEvent ThrowEvent ThrowEventXMLConverter
boundaryEvent BoundaryEvent BoundaryEventXMLConverter
textAnnotation TextAnnotation TextAnnotationXMLConverter
association Association AssociationXMLConverter
dataStoreReference DataStoreReference DataStoreReferenceXMLConverter
valuedDataObject ValuedDataObject ValuedDataObjectXMLConverter
alfrescoStartEvent AlfrescoStartEvent AlfrescoStartEventXMLConverter
alfrescoUserTask AlfrescoUserTask AlfrescoUserTaskXMLConverter

解析器

解析器所在包是org.activiti.bpmn.converter.childorg.activiti.bpmn.converter.parse

元素 Java类 解析器 备注
process Process ProcessParse
subProcess SubProcess SubProcessParser
bpmndi:BPMNEdge GraphicInfo BpmnEdgeParser 解析的是顺序流等线段图形位置等信息
bpmndi:BPMNShape GraphicInfo BpmnShapeParser 解析的是任务等非线段图形位置、宽高等信息
lane Lane LaneParser
pool Pool ParticipantParser
messageFlow MessageFlow MessageFlowParser
activiti:executionListener ExecutionListener ExecutionListenerParser 执行监听器
activiti:taskListener ActivitiListener TaskListenerParser 任务监听器解析
multiInstanceLoopCharacteristics MultiInstanceLoopCharacteristics MultiInstanceParser 解析包括loopCardinality、isSequential、completionCondition等信息

你可能感兴趣的:(Activiti学习)