Activiti工作流之獲取流程定義中所有的節點
阿新 • • 發佈:2019-01-09
初步設想實現一個部署完工作流之後,為UserTask節點動態分配任務執行者,或者在分支節點上新增進入條件的功能。為了實現這個功能需要解析流程定義檔案取出檔案中定義的所有節點。這裡有兩個方法可以實現此功能。
方法一(流程部署至伺服器上之後可使用):
該方法適用於流程部署至伺服器上之後,通過該方法可以簡單快速的獲取流程定義檔案中各個節點資訊。//<span style="font-family: Arial, Helvetica, sans-serif;">processDefinitionId</span><span style="font-family: Arial, Helvetica, sans-serif;"> 為流程定義Id,該Id可以通過多種方式獲得,如通過ProcessDefinitionQuery可以查詢一個ProcessDefinition物件,Task物件中也包含</span><span style="font-family: Arial, Helvetica, sans-serif;">processDefinitionId</span><span style="font-family: Arial, Helvetica, sans-serif;"> </span> BpmnModel model = repositoryService.getBpmnModel(processDefinitionId); if(model != null) { Collection<FlowElement> flowElements = model.getMainProcess().getFlowElements(); for(FlowElement e : flowElements) { System.out.println("flowelement id:" + e.getId() + " name:" + e.getName() + " class:" + e.getClass().toString()); } }
方法二 讀取流程定義檔案方式
該方法使用到了activiti的activiti-bpmn-converter-5.20.0.jar和activiti-bpmn-model-5.20.0.jar,用到了其中比較關鍵的一個類BpmnXMLConverter,該類將xml定義檔案解析成BpmnModel物件,使用BpmnModel的getMainProcess()獲取一個Process物件,該物件實際是一個繼承自BaseElement、FlowElementContainer的節點容器,通過getFlowElements()獲取當前流程定義檔案中所有的節點物件。 該方法的好處在於可以解析本地或者未部署至Activiti引擎中的流程定義檔案。<pre name="code" class="java">//import java.io.InputStream; //import java.io.InputStreamReader; //import javax.xml.stream.XMLInputFactory; //import javax.xml.stream.XMLStreamException; //import javax.xml.stream.XMLStreamReader; // //import org.activiti.bpmn.converter.BpmnXMLConverter; //import org.activiti.bpmn.model.BpmnModel; //import org.activiti.bpmn.model.FlowElement; InputStream resouceStream = this.getClass().getClassLoader().getResourceAsStream("leave-formkey.bpmn20.xml"); XMLInputFactory xif = XMLInputFactory.newInstance(); InputStreamReader in; XMLStreamReader xtr; try { in = new InputStreamReader(resouceStream, "UTF-8"); xtr = xif.createXMLStreamReader(in); BpmnModel model = new BpmnXMLConverter().convertToBpmnModel(xtr); Collection<FlowElement> flowElements = model.getMainProcess().getFlowElements(); for(FlowElement e : flowElements) { System.out.println("flowelement id:" + e.getId() + " name:" + e.getName() + " class:" + e.getClass().toString()); } } catch (XMLStreamException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); }
兩次測試列印結果如下:
flowelement id:startevent1 name:Start class:class org.activiti.bpmn.model.StartEvent flowelement id:deptLeaderAudit name:部門領導審批 class:class org.activiti.bpmn.model.UserTask flowelement id:exclusivegateway5 name:Exclusive Gateway class:class org.activiti.bpmn.model.ExclusiveGateway flowelement id:modifyApply name:調整申請 class:class org.activiti.bpmn.model.UserTask flowelement id:hrAudit name:人事審批 class:class org.activiti.bpmn.model.UserTask flowelement id:exclusivegateway6 name:Exclusive Gateway class:class org.activiti.bpmn.model.ExclusiveGateway flowelement id:reportBack name:銷假 class:class org.activiti.bpmn.model.UserTask flowelement id:endevent1 name:End class:class org.activiti.bpmn.model.EndEvent flowelement id:exclusivegateway7 name:Exclusive Gateway class:class org.activiti.bpmn.model.ExclusiveGateway flowelement id:flow2 name: class:class org.activiti.bpmn.model.SequenceFlow flowelement id:flow3 name: class:class org.activiti.bpmn.model.SequenceFlow flowelement id:flow4 name:不同意 class:class org.activiti.bpmn.model.SequenceFlow flowelement id:flow5 name:同意 class:class org.activiti.bpmn.model.SequenceFlow flowelement id:flow6 name: class:class org.activiti.bpmn.model.SequenceFlow flowelement id:flow7 name:同意 class:class org.activiti.bpmn.model.SequenceFlow flowelement id:flow8 name: class:class org.activiti.bpmn.model.SequenceFlow flowelement id:flow9 name:不同意 class:class org.activiti.bpmn.model.SequenceFlow flowelement id:flow10 name:重新申請 class:class org.activiti.bpmn.model.SequenceFlow flowelement id:flow11 name: class:class org.activiti.bpmn.model.SequenceFlow flowelement id:flow12 name:結束流程 class:class org.activiti.bpmn.model.SequenceFlow
流程定義檔案leave-formkey.bpmn20.xml:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="OFFICE">
<process id="leave-formkey" name="病事假申請">
<documentation>請假流程演示</documentation>
<startEvent id="startevent1" name="Start" activiti:initiator="applyUserId"></startEvent>
<userTask id="deptLeaderAudit" name="部門領導審批" activiti:assignee="${applyUserId}" activiti:formKey="leaveHandle.form"></userTask>
<exclusiveGateway id="exclusivegateway5" name="Exclusive Gateway"></exclusiveGateway>
<userTask id="modifyApply" name="調整申請" activiti:assignee="${applyUserId}" activiti:formKey="leaveApplyAgain.form"></userTask>
<userTask id="hrAudit" name="人事審批" activiti:assignee="${applyUserId}" activiti:formKey="leaveHandle.form"></userTask>
<exclusiveGateway id="exclusivegateway6" name="Exclusive Gateway"></exclusiveGateway>
<userTask id="reportBack" name="銷假" activiti:assignee="${applyUserId}" activiti:formKey="leaveHandle.form"></userTask>
<endEvent id="endevent1" name="End"></endEvent>
<exclusiveGateway id="exclusivegateway7" name="Exclusive Gateway"></exclusiveGateway>
<sequenceFlow id="flow2" name="" sourceRef="startevent1" targetRef="deptLeaderAudit"></sequenceFlow>
<sequenceFlow id="flow3" name="" sourceRef="deptLeaderAudit" targetRef="exclusivegateway5"></sequenceFlow>
<sequenceFlow id="flow4" name="不同意" sourceRef="exclusivegateway5" targetRef="modifyApply">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${deptLeaderPass == 'false'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow5" name="同意" sourceRef="exclusivegateway5" targetRef="hrAudit">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${deptLeaderPass == 'true'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow6" name="" sourceRef="hrAudit" targetRef="exclusivegateway6"></sequenceFlow>
<sequenceFlow id="flow7" name="同意" sourceRef="exclusivegateway6" targetRef="reportBack">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${hrPass == 'true'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow8" name="" sourceRef="reportBack" targetRef="endevent1"></sequenceFlow>
<sequenceFlow id="flow9" name="不同意" sourceRef="exclusivegateway6" targetRef="modifyApply">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${hrPass == 'false'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow10" name="重新申請" sourceRef="exclusivegateway7" targetRef="deptLeaderAudit">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${reApply == 'true'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow11" name="" sourceRef="modifyApply" targetRef="exclusivegateway7"></sequenceFlow>
<sequenceFlow id="flow12" name="結束流程" sourceRef="exclusivegateway7" targetRef="endevent1">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${reApply == 'false'}]]></conditionExpression>
</sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_leave-formkey">
<bpmndi:BPMNPlane bpmnElement="leave-formkey" id="BPMNPlane_leave-formkey">
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35" width="35" x="10" y="90"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="deptLeaderAudit" id="BPMNShape_deptLeaderAudit">
<omgdc:Bounds height="55" width="105" x="90" y="80"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="exclusivegateway5" id="BPMNShape_exclusivegateway5">
<omgdc:Bounds height="40" width="40" x="250" y="87"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="modifyApply" id="BPMNShape_modifyApply">
<omgdc:Bounds height="55" width="105" x="218" y="190"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="hrAudit" id="BPMNShape_hrAudit">
<omgdc:Bounds height="55" width="105" x="358" y="80"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="exclusivegateway6" id="BPMNShape_exclusivegateway6">
<omgdc:Bounds height="40" width="40" x="495" y="87"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="reportBack" id="BPMNShape_reportBack">
<omgdc:Bounds height="55" width="105" x="590" y="80"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35" width="35" x="625" y="283"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="exclusivegateway7" id="BPMNShape_exclusivegateway7">
<omgdc:Bounds height="40" width="40" x="250" y="280"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="45" y="107"></omgdi:waypoint>
<omgdi:waypoint x="90" y="107"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="195" y="107"></omgdi:waypoint>
<omgdi:waypoint x="250" y="107"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
<omgdi:waypoint x="270" y="127"></omgdi:waypoint>
<omgdi:waypoint x="270" y="190"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="11" width="100" x="10" y="0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">
<omgdi:waypoint x="290" y="107"></omgdi:waypoint>
<omgdi:waypoint x="358" y="107"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="11" width="100" x="-24" y="-17"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
<omgdi:waypoint x="463" y="107"></omgdi:waypoint>
<omgdi:waypoint x="495" y="107"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">
<omgdi:waypoint x="535" y="107"></omgdi:waypoint>
<omgdi:waypoint x="590" y="107"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="11" width="100" x="-22" y="-17"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8">
<omgdi:waypoint x="642" y="135"></omgdi:waypoint>
<omgdi:waypoint x="642" y="283"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9">
<omgdi:waypoint x="515" y="127"></omgdi:waypoint>
<omgdi:waypoint x="514" y="217"></omgdi:waypoint>
<omgdi:waypoint x="323" y="217"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="11" width="100" x="10" y="0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10">
<omgdi:waypoint x="250" y="300"></omgdi:waypoint>
<omgdi:waypoint x="142" y="299"></omgdi:waypoint>
<omgdi:waypoint x="142" y="135"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="11" width="100" x="10" y="0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11">
<omgdi:waypoint x="270" y="245"></omgdi:waypoint>
<omgdi:waypoint x="270" y="280"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12">
<omgdi:waypoint x="290" y="300"></omgdi:waypoint>
<omgdi:waypoint x="625" y="300"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="11" width="100" x="10" y="0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>