工作流系列(5.1)-Activiti流程文件解析功能架構設計


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

配置文件

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

<?xml version="1.0" encoding="UTF-8" ?>
<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>management</formalExpression>
        </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簡介。
Alt text

Activiti對於BPMN元素的支持,只列出最基本的元素

事件(Event)

簡單的介紹開始結束事件,其他的比如邊界事件等暫不介紹

BPMN元素 Activiti 類 配置文件表示
開始事件 StartEvent <startEvent id="startevent1" name="開始"></startEvent>
結束事件 EndEvent <endEvent id="endevent1" name="結束"></endEvent>

活動(Activity)

活動包含任務、子流程

任務(Task)

只介紹常用的,當然還有其他的比如:業務規則任務、接受任務等

BPMN元素 Activiti 類 配置文件表示
用戶任務 UserTask <userTask id="fillForm" name="填寫表單" />
服務任務 ServiceTask <serviceTask id="print" activiti:expression="#{printer.printMessage}" />
手工任務 ManualTask <manualTask id="myManualTask" name="Call client for more information" />

還有比如:腳本任務 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 <parallelGateway id="myParallelGateway" />
排他網關 ExclusiveGateway <exclusiveGateway id="exclusiveGw" name="Exclusive Gateway" />
包容網關 InclusiveGateway <inclusiveGateway id="myInclusiveGateway" />

鏈接對象

BPMN元素 Activiti 類 配置文件表示
順序流 SequenceFlow <sequenceFlow id="flow1" sourceRef="theStart" targetRef="theTask" />

在順序流中可以增加條件,比如

<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等信息
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章