gpt4 book ai didi

Java - Camunda BPMN 模型 API : how to save valid xml?

转载 作者:行者123 更新时间:2023-12-04 12:25:39 29 4
gpt4 key购买 nike

我正在构建一些测试 BPMN 2.0 模型并将它们保存到 xml 文件,在一个 Java 项目中,按照官方提供的示例doc ,在本例中为示例 2。

我在我的 pom 中导入了 lib,如下所示:

<!-- https://mvnrepository.com/artifact/org.camunda.bpm.model/camunda-bpmn-model -->
<dependency>
<groupId>org.camunda.bpm.model</groupId>
<artifactId>camunda-bpmn-model</artifactId>
<version>7.10.0</version>
</dependency>

这是我的测试类,遵循示例 2:
import org.camunda.bpm.model.bpmn.Bpmn;
import org.camunda.bpm.model.bpmn.BpmnModelInstance;
import org.camunda.bpm.model.bpmn.instance.*;
import org.camunda.bpm.model.bpmn.instance.Process;

import java.io.File;
import java.io.IOException;

public class Test {
protected static <T extends BpmnModelElementInstance> T createElement(BpmnModelInstance modelInstance, BpmnModelElementInstance parentElement, String id, Class<T> elementClass) {
T element = modelInstance.newInstance(elementClass);
element.setAttributeValue("id", id, true);
parentElement.addChildElement(element);
return element;
}

public static SequenceFlow createSequenceFlow(BpmnModelInstance modelInstance, Process process, FlowNode from, FlowNode to) {
String identifier = from.getId() + "-" + to.getId();
SequenceFlow sequenceFlow = createElement(modelInstance, process, identifier, SequenceFlow.class);
process.addChildElement(sequenceFlow);
sequenceFlow.setSource(from);
from.getOutgoing().add(sequenceFlow);
sequenceFlow.setTarget(to);
to.getIncoming().add(sequenceFlow);
return sequenceFlow;
}

public static void main(String[] args) throws IOException {
// create an empty model
BpmnModelInstance modelInstance = Bpmn.createEmptyModel();
Definitions definitions = modelInstance.newInstance(Definitions.class);
definitions.setTargetNamespace("http://camunda.org/examples");
modelInstance.setDefinitions(definitions);

// create a process
Process process = modelInstance.newInstance(Process.class);
process.setId("process");
definitions.addChildElement(process);

// create elements
StartEvent startEvent = createElement(modelInstance, process, "start", StartEvent.class);
ParallelGateway fork = createElement(modelInstance, process, "fork", ParallelGateway.class);
ServiceTask task1 = createElement(modelInstance, process, "task1", ServiceTask.class);
task1.setName("Service Task");
UserTask task2 = createElement(modelInstance, process, "task2", UserTask.class);
task2.setName("User Task");
ParallelGateway join = createElement(modelInstance, process, "join", ParallelGateway.class);
EndEvent endEvent = createElement(modelInstance, process, "end", EndEvent.class);

// create flows
createSequenceFlow(modelInstance, process, startEvent, fork);
createSequenceFlow(modelInstance, process, fork, task1);
createSequenceFlow(modelInstance, process, fork, task2);
createSequenceFlow(modelInstance, process, task1, join);
createSequenceFlow(modelInstance, process, task2, join);
createSequenceFlow(modelInstance, process, join, endEvent);

// validate and write model to file
Bpmn.validateModel(modelInstance);
File file = new File("bpmn-model.bpmn.xml");
file.createNewFile();
Bpmn.writeModelToFile(file, modelInstance);
}
}

这里生成的BPMN 2.0 xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<definitions id="definitions_7b2df680-1d9c-4897-ba8b-a83548ab937f" targetNamespace="http://camunda.org/examples" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL">
<process id="process">
<startEvent id="start">
<outgoing>start-fork</outgoing>
</startEvent>
<parallelGateway id="fork">
<incoming>start-fork</incoming>
<outgoing>fork-task1</outgoing>
<outgoing>fork-task2</outgoing>
</parallelGateway>
<serviceTask id="task1" name="Service Task">
<incoming>fork-task1</incoming>
<outgoing>task1-join</outgoing>
</serviceTask>
<userTask id="task2" name="User Task">
<incoming>fork-task2</incoming>
<outgoing>task2-join</outgoing>
</userTask>
<parallelGateway id="join">
<incoming>task1-join</incoming>
<incoming>task2-join</incoming>
<outgoing>join-end</outgoing>
</parallelGateway>
<endEvent id="end">
<incoming>join-end</incoming>
</endEvent>
<sequenceFlow id="start-fork" sourceRef="start" targetRef="fork"/>
<sequenceFlow id="fork-task1" sourceRef="fork" targetRef="task1"/>
<sequenceFlow id="fork-task2" sourceRef="fork" targetRef="task2"/>
<sequenceFlow id="task1-join" sourceRef="task1" targetRef="join"/>
<sequenceFlow id="task2-join" sourceRef="task2" targetRef="join"/>
<sequenceFlow id="join-end" sourceRef="join" targetRef="end"/>
</process>
</definitions>

尽管使用验证方法,但在尝试使用 Camunda Modeler 应用程序和 bpmn.io 显示 BPMN 时,生成的 xml 似乎无效。 .

这个例子有什么问题,因此我的代码有什么问题?
如何使生成的 xml 有效?由于 bpmn 2.0 是一个标准,我对这个问题也有点惊讶。

最佳答案

我终于通过切换到流畅的模型构建器 API 使其工作,遵循这个 https://blog.camunda.com/post/2014/02/the-new-camunda-bpmn-model-api/

这是我更新的测试类:

import org.camunda.bpm.model.bpmn.Bpmn;
import org.camunda.bpm.model.bpmn.BpmnModelInstance;
import org.camunda.bpm.model.bpmn.GatewayDirection;

import java.io.File;
import java.io.IOException;

public class Test {
public static void main(String[] args) throws IOException {
BpmnModelInstance modelInstance = Bpmn.createProcess()
.name("BPMN API Invoice Process")
.executable()
.startEvent()
.name("Invoice received")
.camundaFormKey("embedded:app:forms/start-form.html")
.userTask()
.name("Assign Approver")
.camundaFormKey("embedded:app:forms/assign-approver.html")
.camundaAssignee("demo")
.userTask()
.id("approveInvoice")
.name("Approve Invoice")
.camundaFormKey("embedded:app:forms/approve-invoice.html")
.camundaAssignee("${approver}")
.exclusiveGateway()
.name("Invoice approved?")
.gatewayDirection(GatewayDirection.Diverging)
.condition("yes", "${approved}")
.userTask()
.name("Prepare Bank Transfer")
.camundaFormKey("embedded:app:forms/prepare-bank-transfer.html")
.camundaCandidateGroups("accounting")
.serviceTask()
.name("Archive Invoice")
.endEvent()
.name("Invoice processed")
.moveToLastGateway()
.condition("no", "${!approved}")
.userTask()
.name("Review Invoice")
.camundaFormKey("embedded:app:forms/review-invoice.html")
.camundaAssignee("demo")
.exclusiveGateway()
.name("Review successful?")
.gatewayDirection(GatewayDirection.Diverging)
.condition("no", "${!clarified}")
.endEvent()
.name("Invoice not processed")
.moveToLastGateway()
.condition("yes", "${clarified}")
.connectTo("approveInvoice")
.done();

// validate and write model to file
Bpmn.validateModel(modelInstance);
File file = new File("bpmn-model.bpmn.xml");
file.createNewFile();

String bpmnString = Bpmn.convertToString(modelInstance);
System.out.println("bpmnString");
System.out.println(bpmnString);

Bpmn.writeModelToFile(file, modelInstance);
}
}

这是生成的xml:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<definitions xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="definitions_3bd3e094-3e53-4644-af0c-1a048653920c" targetNamespace="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL">
<process id="process_e14ca74e-6095-4a2b-bced-debcb3b37954" isExecutable="true" name="BPMN API Invoice Process">
<startEvent camunda:formKey="embedded:app:forms/start-form.html" id="startEvent_e8daa33a-af99-4b7a-87ee-200b0e7bedcd" name="Invoice received">
<outgoing>sequenceFlow_cb28e7e5-ebc0-4f27-b8b2-24403ab87ce3</outgoing>
</startEvent>
<userTask camunda:assignee="demo" camunda:formKey="embedded:app:forms/assign-approver.html" id="userTask_029f48b9-de24-4292-af49-845e81fdcc4b" name="Assign Approver">
<incoming>sequenceFlow_cb28e7e5-ebc0-4f27-b8b2-24403ab87ce3</incoming>
<outgoing>sequenceFlow_57a81fcd-fb35-42cd-afca-7c4c7914936d</outgoing>
</userTask>
<sequenceFlow id="sequenceFlow_cb28e7e5-ebc0-4f27-b8b2-24403ab87ce3" sourceRef="startEvent_e8daa33a-af99-4b7a-87ee-200b0e7bedcd" targetRef="userTask_029f48b9-de24-4292-af49-845e81fdcc4b"/>
<userTask camunda:assignee="${approver}" camunda:formKey="embedded:app:forms/approve-invoice.html" id="approveInvoice" name="Approve Invoice">
<incoming>sequenceFlow_57a81fcd-fb35-42cd-afca-7c4c7914936d</incoming>
<incoming>sequenceFlow_6987bcb8-5f6a-467b-9b25-e21b90dd0d4d</incoming>
<outgoing>sequenceFlow_1fe15a36-427e-4000-8fc7-50b8925ea1e5</outgoing>
</userTask>
<sequenceFlow id="sequenceFlow_57a81fcd-fb35-42cd-afca-7c4c7914936d" sourceRef="userTask_029f48b9-de24-4292-af49-845e81fdcc4b" targetRef="approveInvoice"/>
<exclusiveGateway gatewayDirection="Diverging" id="exclusiveGateway_b66a0444-2889-4cae-ac78-c1f65405ba0b" name="Invoice approved?">
<incoming>sequenceFlow_1fe15a36-427e-4000-8fc7-50b8925ea1e5</incoming>
<outgoing>sequenceFlow_9156c1d4-f756-447b-a384-e3bf17c43ff4</outgoing>
<outgoing>sequenceFlow_29bab2ba-6108-4731-94c3-93a6955d1946</outgoing>
</exclusiveGateway>
<sequenceFlow id="sequenceFlow_1fe15a36-427e-4000-8fc7-50b8925ea1e5" sourceRef="approveInvoice" targetRef="exclusiveGateway_b66a0444-2889-4cae-ac78-c1f65405ba0b"/>
<sequenceFlow id="sequenceFlow_9156c1d4-f756-447b-a384-e3bf17c43ff4" name="yes" sourceRef="exclusiveGateway_b66a0444-2889-4cae-ac78-c1f65405ba0b" targetRef="userTask_79a63b4f-96a7-43d7-aab3-e8e0e83769e5">
<conditionExpression id="conditionExpression_13d7607b-d7e7-4fa4-a364-aeabff28a0f1">${approved}</conditionExpression>
</sequenceFlow>
<userTask camunda:candidateGroups="accounting" camunda:formKey="embedded:app:forms/prepare-bank-transfer.html" id="userTask_79a63b4f-96a7-43d7-aab3-e8e0e83769e5" name="Prepare Bank Transfer">
<incoming>sequenceFlow_9156c1d4-f756-447b-a384-e3bf17c43ff4</incoming>
<outgoing>sequenceFlow_b82e04ab-a0cc-4969-989a-1ec64d74d990</outgoing>
</userTask>
<serviceTask id="serviceTask_9d976f99-f8fb-4705-ae6d-a606758111f4" name="Archive Invoice">
<incoming>sequenceFlow_b82e04ab-a0cc-4969-989a-1ec64d74d990</incoming>
<outgoing>sequenceFlow_f0f99688-25b1-417e-9a5d-0d17503cb3ba</outgoing>
</serviceTask>
<sequenceFlow id="sequenceFlow_b82e04ab-a0cc-4969-989a-1ec64d74d990" sourceRef="userTask_79a63b4f-96a7-43d7-aab3-e8e0e83769e5" targetRef="serviceTask_9d976f99-f8fb-4705-ae6d-a606758111f4"/>
<endEvent id="endEvent_affc9949-819a-4b79-98bd-0f2fd844d014" name="Invoice processed">
<incoming>sequenceFlow_f0f99688-25b1-417e-9a5d-0d17503cb3ba</incoming>
</endEvent>
<sequenceFlow id="sequenceFlow_f0f99688-25b1-417e-9a5d-0d17503cb3ba" sourceRef="serviceTask_9d976f99-f8fb-4705-ae6d-a606758111f4" targetRef="endEvent_affc9949-819a-4b79-98bd-0f2fd844d014"/>
<sequenceFlow id="sequenceFlow_29bab2ba-6108-4731-94c3-93a6955d1946" name="no" sourceRef="exclusiveGateway_b66a0444-2889-4cae-ac78-c1f65405ba0b" targetRef="userTask_7b955191-5741-44df-b7ba-d154ddfbe616">
<conditionExpression id="conditionExpression_ce06d35f-8638-4699-802b-7f1b94732f46">${!approved}</conditionExpression>
</sequenceFlow>
<userTask camunda:assignee="demo" camunda:formKey="embedded:app:forms/review-invoice.html" id="userTask_7b955191-5741-44df-b7ba-d154ddfbe616" name="Review Invoice">
<incoming>sequenceFlow_29bab2ba-6108-4731-94c3-93a6955d1946</incoming>
<outgoing>sequenceFlow_74d95e16-7907-4000-9ffb-cdba8c3ddde4</outgoing>
</userTask>
<exclusiveGateway gatewayDirection="Diverging" id="exclusiveGateway_5aa645c5-a5e7-4453-8498-8462092b85b1" name="Review successful?">
<incoming>sequenceFlow_74d95e16-7907-4000-9ffb-cdba8c3ddde4</incoming>
<outgoing>sequenceFlow_3bf21b37-c534-4541-b84f-03d3fe05c989</outgoing>
<outgoing>sequenceFlow_6987bcb8-5f6a-467b-9b25-e21b90dd0d4d</outgoing>
</exclusiveGateway>
<sequenceFlow id="sequenceFlow_74d95e16-7907-4000-9ffb-cdba8c3ddde4" sourceRef="userTask_7b955191-5741-44df-b7ba-d154ddfbe616" targetRef="exclusiveGateway_5aa645c5-a5e7-4453-8498-8462092b85b1"/>
<sequenceFlow id="sequenceFlow_3bf21b37-c534-4541-b84f-03d3fe05c989" name="no" sourceRef="exclusiveGateway_5aa645c5-a5e7-4453-8498-8462092b85b1" targetRef="endEvent_68057c88-fa46-43cc-a93c-774b26be7b50">
<conditionExpression id="conditionExpression_8bb43e50-dd2f-40ba-9cc9-91a69813a835">${!clarified}</conditionExpression>
</sequenceFlow>
<endEvent id="endEvent_68057c88-fa46-43cc-a93c-774b26be7b50" name="Invoice not processed">
<incoming>sequenceFlow_3bf21b37-c534-4541-b84f-03d3fe05c989</incoming>
</endEvent>
<sequenceFlow id="sequenceFlow_6987bcb8-5f6a-467b-9b25-e21b90dd0d4d" name="yes" sourceRef="exclusiveGateway_5aa645c5-a5e7-4453-8498-8462092b85b1" targetRef="approveInvoice">
<conditionExpression id="conditionExpression_c3fb4bcf-905a-47dd-84cf-6cfe1980ca2e">${clarified}</conditionExpression>
</sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_946186ab-976d-40e2-9ed2-4672566340a2">
<bpmndi:BPMNPlane bpmnElement="process_e14ca74e-6095-4a2b-bced-debcb3b37954" id="BPMNPlane_78d2c2b7-e5e7-414f-abae-0dcddaefbdfd">
<bpmndi:BPMNShape bpmnElement="startEvent_e8daa33a-af99-4b7a-87ee-200b0e7bedcd" id="BPMNShape_2da46013-859f-418a-8612-25bd57aabb52">
<dc:Bounds height="36.0" width="36.0" x="100.0" y="100.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="userTask_029f48b9-de24-4292-af49-845e81fdcc4b" id="BPMNShape_79fd4553-cfb0-4740-b4fe-093d1c96474b">
<dc:Bounds height="80.0" width="100.0" x="186.0" y="78.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_cb28e7e5-ebc0-4f27-b8b2-24403ab87ce3" id="BPMNEdge_77315869-b425-4daf-85b6-6121867d91bc">
<di:waypoint x="136.0" y="118.0"/>
<di:waypoint x="186.0" y="118.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="approveInvoice" id="BPMNShape_b54e1244-b4fb-4e70-8c0d-4b76eb2798b0">
<dc:Bounds height="80.0" width="100.0" x="336.0" y="78.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_57a81fcd-fb35-42cd-afca-7c4c7914936d" id="BPMNEdge_dfa41f0e-273b-4d62-b8b8-ef9286b24f7d">
<di:waypoint x="286.0" y="118.0"/>
<di:waypoint x="336.0" y="118.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="exclusiveGateway_b66a0444-2889-4cae-ac78-c1f65405ba0b" id="BPMNShape_bc1af4c3-ef1f-4c26-a42c-b1c2982bf35c" isMarkerVisible="true">
<dc:Bounds height="50.0" width="50.0" x="486.0" y="93.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_1fe15a36-427e-4000-8fc7-50b8925ea1e5" id="BPMNEdge_9e81a730-2822-4c70-8061-9bbecf05022d">
<di:waypoint x="436.0" y="118.0"/>
<di:waypoint x="486.0" y="118.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="userTask_79a63b4f-96a7-43d7-aab3-e8e0e83769e5" id="BPMNShape_8c455164-1097-43ca-814f-6d601735b27a">
<dc:Bounds height="80.0" width="100.0" x="586.0" y="78.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_9156c1d4-f756-447b-a384-e3bf17c43ff4" id="BPMNEdge_47ba6c2b-fd10-4faf-8ee9-cbe019282080">
<di:waypoint x="536.0" y="118.0"/>
<di:waypoint x="586.0" y="118.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="serviceTask_9d976f99-f8fb-4705-ae6d-a606758111f4" id="BPMNShape_d2e257f4-4c63-44e6-a8ab-d3179a83682c">
<dc:Bounds height="80.0" width="100.0" x="736.0" y="78.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_b82e04ab-a0cc-4969-989a-1ec64d74d990" id="BPMNEdge_e5727f31-71a0-4f03-8a9d-7aca2cd9999a">
<di:waypoint x="686.0" y="118.0"/>
<di:waypoint x="736.0" y="118.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="endEvent_affc9949-819a-4b79-98bd-0f2fd844d014" id="BPMNShape_4a1b2f6f-6929-4fd7-b6cf-9f49410242d7">
<dc:Bounds height="36.0" width="36.0" x="886.0" y="100.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_f0f99688-25b1-417e-9a5d-0d17503cb3ba" id="BPMNEdge_28346c07-6da9-41d2-bcf2-76a9583ea933">
<di:waypoint x="836.0" y="118.0"/>
<di:waypoint x="886.0" y="118.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="userTask_7b955191-5741-44df-b7ba-d154ddfbe616" id="BPMNShape_1c62b32d-2c17-48b0-bbc7-ac0074c97e62">
<dc:Bounds height="80.0" width="100.0" x="586.0" y="208.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_29bab2ba-6108-4731-94c3-93a6955d1946" id="BPMNEdge_40c826c8-638d-4cd2-b9a1-ccdfa9a5ee6e">
<di:waypoint x="511.0" y="143.0"/>
<di:waypoint x="511.0" y="248.0"/>
<di:waypoint x="586.0" y="248.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="exclusiveGateway_5aa645c5-a5e7-4453-8498-8462092b85b1" id="BPMNShape_36d66f18-3b46-4fde-9342-3ccd8d0f838d" isMarkerVisible="true">
<dc:Bounds height="50.0" width="50.0" x="736.0" y="223.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_74d95e16-7907-4000-9ffb-cdba8c3ddde4" id="BPMNEdge_257a94d2-a5f6-4a88-9503-f5b9fd65cc7e">
<di:waypoint x="686.0" y="248.0"/>
<di:waypoint x="736.0" y="248.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="endEvent_68057c88-fa46-43cc-a93c-774b26be7b50" id="BPMNShape_2dff264a-5f15-44d9-ba38-b962be76ea74">
<dc:Bounds height="36.0" width="36.0" x="836.0" y="230.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_3bf21b37-c534-4541-b84f-03d3fe05c989" id="BPMNEdge_0a149725-d17c-4b6f-b7db-7854d0a27b00">
<di:waypoint x="786.0" y="248.0"/>
<di:waypoint x="836.0" y="248.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_6987bcb8-5f6a-467b-9b25-e21b90dd0d4d" id="BPMNEdge_8b25f14c-9653-42ab-a57f-48fc07bd7ee8">
<di:waypoint x="761.0" y="273.0"/>
<di:waypoint x="761.0" y="118.0"/>
<di:waypoint x="336.0" y="118.0"/>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>

通过与上面的 xml 进行比较,我注意到一些新的 <bpmndi ...>之前不存在的元素。

关于Java - Camunda BPMN 模型 API : how to save valid xml?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53634916/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com