工作流系列(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类转换器备注
endEventEndEventEndEventXMLConverter
startEventStartEventStartEventXMLConverter
businessRuleTaskBusinessRuleTaskBusinessRuleTaskXMLConverter
manualTaskManualTaskManualTaskXMLConverter
receiveTaskReceiveTaskReceiveTaskXMLConverter
scriptTaskScriptTaskScriptTaskXMLConverter
serviceTaskServiceTaskServiceTaskXMLConverter
sendTaskSendTaskSendTaskXMLConverter
userTaskUserTaskUserTaskXMLConverter
taskTaskTaskXMLConverter
callActivityCallActivityCallActivityXMLConverter
eventGatewayEventGatewayEventGatewayXMLConverter
exclusiveGatewayExclusiveGatewayExclusiveGatewayXMLConverter
inclusiveGatewayInclusiveGatewayInclusiveGatewayXMLConverter
parallelGatewayParallelGatewayParallelGatewayXMLConverter
complexGatewayComplexGatewayComplexGatewayXMLConverter
sequenceFlowSequenceFlowSequenceFlowXMLConverter
catchEventCatchEventCatchEventXMLConverter
throwEventThrowEventThrowEventXMLConverter
boundaryEventBoundaryEventBoundaryEventXMLConverter
textAnnotationTextAnnotationTextAnnotationXMLConverter
associationAssociationAssociationXMLConverter
dataStoreReferenceDataStoreReferenceDataStoreReferenceXMLConverter
valuedDataObjectValuedDataObjectValuedDataObjectXMLConverter
alfrescoStartEventAlfrescoStartEventAlfrescoStartEventXMLConverter
alfrescoUserTaskAlfrescoUserTaskAlfrescoUserTaskXMLConverter
解析器

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

元素Java类解析器备注
processProcessProcessParse
subProcessSubProcessSubProcessParser
bpmndi:BPMNEdgeGraphicInfoBpmnEdgeParser解析的是顺序流等线段图形位置等信息
bpmndi:BPMNShapeGraphicInfoBpmnShapeParser解析的是任务等非线段图形位置、宽高等信息
laneLaneLaneParser
poolPoolParticipantParser
messageFlowMessageFlowMessageFlowParser
activiti:executionListenerExecutionListenerExecutionListenerParser执行监听器
activiti:taskListenerActivitiListenerTaskListenerParser任务监听器解析
multiInstanceLoopCharacteristicsMultiInstanceLoopCharacteristicsMultiInstanceParser解析包括loopCardinality、isSequential、completionCondition等信息
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值