Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add parsing for diagram labels in xml #3834

Merged
merged 3 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ public interface BpmnXMLConstants {
public static final String ATTRIBUTE_DI_SOURCE_DOCKER_Y = "sourceDockerY";
public static final String ATTRIBUTE_DI_TARGET_DOCKER_X = "targetDockerX";
public static final String ATTRIBUTE_DI_TARGET_DOCKER_Y = "targetDockerY";
public static final String ATTRIBUTE_DI_ROTATION = "rotation";

public static final String ELEMENT_DATA_OBJECT = "dataObject";
public static final String ATTRIBUTE_DATA_ID = "id";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,12 @@ protected static void createBpmnShape(BpmnModel model, String elementId, XMLStre
xtw.writeAttribute(ATTRIBUTE_DI_Y, String.valueOf(graphicInfo.getY()));
xtw.writeEndElement();

GraphicInfo labelGraphicInfo = model.getLabelGraphicInfo(elementId);

if (labelGraphicInfo != null && flowElement != null && StringUtils.isNotEmpty(flowElement.getName())) {
addLabelElement(labelGraphicInfo, xtw);
}

xtw.writeEndElement();
}

Expand Down Expand Up @@ -231,16 +237,23 @@ protected static void createBpmnEdge(BpmnModel model, String elementId, XMLStrea
}

if (labelGraphicInfo != null && hasName) {
xtw.writeStartElement(BPMNDI_PREFIX, ELEMENT_DI_LABEL, BPMNDI_NAMESPACE);
xtw.writeStartElement(OMGDC_PREFIX, ELEMENT_DI_BOUNDS, OMGDC_NAMESPACE);
xtw.writeAttribute(ATTRIBUTE_DI_HEIGHT, String.valueOf(labelGraphicInfo.getHeight()));
xtw.writeAttribute(ATTRIBUTE_DI_WIDTH, String.valueOf(labelGraphicInfo.getWidth()));
xtw.writeAttribute(ATTRIBUTE_DI_X, String.valueOf(labelGraphicInfo.getX()));
xtw.writeAttribute(ATTRIBUTE_DI_Y, String.valueOf(labelGraphicInfo.getY()));
xtw.writeEndElement();
xtw.writeEndElement();
addLabelElement(labelGraphicInfo, xtw);
}

xtw.writeEndElement();
}

protected static void addLabelElement(GraphicInfo labelGraphicInfo, XMLStreamWriter xtw) throws Exception {
xtw.writeStartElement(BPMNDI_PREFIX, ELEMENT_DI_LABEL, BPMNDI_NAMESPACE);
if (labelGraphicInfo.getRotation() > 0) {
xtw.writeAttribute(FLOWABLE_EXTENSIONS_NAMESPACE, ATTRIBUTE_DI_ROTATION, String.valueOf(labelGraphicInfo.getRotation()));
}
xtw.writeStartElement(OMGDC_PREFIX, ELEMENT_DI_BOUNDS, OMGDC_NAMESPACE);
xtw.writeAttribute(ATTRIBUTE_DI_HEIGHT, String.valueOf(labelGraphicInfo.getHeight()));
xtw.writeAttribute(ATTRIBUTE_DI_WIDTH, String.valueOf(labelGraphicInfo.getWidth()));
xtw.writeAttribute(ATTRIBUTE_DI_X, String.valueOf(labelGraphicInfo.getX()));
xtw.writeAttribute(ATTRIBUTE_DI_Y, String.valueOf(labelGraphicInfo.getY()));
xtw.writeEndElement();
xtw.writeEndElement();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,7 @@ public void parse(XMLStreamReader xtr, BpmnModel model) throws Exception {
while (xtr.hasNext()) {
xtr.next();
if (xtr.isStartElement() && ELEMENT_DI_LABEL.equalsIgnoreCase(xtr.getLocalName())) {
while (xtr.hasNext()) {
xtr.next();
if (xtr.isStartElement() && ELEMENT_DI_BOUNDS.equalsIgnoreCase(xtr.getLocalName())) {
GraphicInfo graphicInfo = new GraphicInfo();
BpmnXMLUtil.addXMLLocation(graphicInfo, xtr);
graphicInfo.setX(Double.valueOf(xtr.getAttributeValue(null, ATTRIBUTE_DI_X)).intValue());
graphicInfo.setY(Double.valueOf(xtr.getAttributeValue(null, ATTRIBUTE_DI_Y)).intValue());
graphicInfo.setWidth(Double.valueOf(xtr.getAttributeValue(null, ATTRIBUTE_DI_WIDTH)).intValue());
graphicInfo.setHeight(Double.valueOf(xtr.getAttributeValue(null, ATTRIBUTE_DI_HEIGHT)).intValue());
model.addLabelGraphicInfo(id, graphicInfo);
break;
} else if (xtr.isEndElement() && ELEMENT_DI_LABEL.equalsIgnoreCase(xtr.getLocalName())) {
break;
}
}
BpmnXMLUtil.parseLabelElement(xtr, model, id);

} else if (xtr.isStartElement() && ELEMENT_DI_WAYPOINT.equalsIgnoreCase(xtr.getLocalName())) {
GraphicInfo graphicInfo = new GraphicInfo();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,16 @@ public void parse(XMLStreamReader xtr, BpmnModel model) throws Exception {
BpmnXMLUtil.addXMLLocation(graphicInfo, xtr);
while (xtr.hasNext()) {
xtr.next();
if (xtr.isStartElement() && ELEMENT_DI_BOUNDS.equalsIgnoreCase(xtr.getLocalName())) {
if (xtr.isStartElement() && ELEMENT_DI_LABEL.equalsIgnoreCase(xtr.getLocalName())) {
BpmnXMLUtil.parseLabelElement(xtr, model, id);

} else if (xtr.isStartElement() && ELEMENT_DI_BOUNDS.equalsIgnoreCase(xtr.getLocalName())) {
graphicInfo.setX(Double.valueOf(xtr.getAttributeValue(null, ATTRIBUTE_DI_X)));
graphicInfo.setY(Double.valueOf(xtr.getAttributeValue(null, ATTRIBUTE_DI_Y)));
graphicInfo.setWidth(Double.valueOf(xtr.getAttributeValue(null, ATTRIBUTE_DI_WIDTH)));
graphicInfo.setHeight(Double.valueOf(xtr.getAttributeValue(null, ATTRIBUTE_DI_HEIGHT)));

model.addGraphicInfo(id, graphicInfo);
break;
} else if (xtr.isEndElement() && ELEMENT_DI_SHAPE.equalsIgnoreCase(xtr.getLocalName())) {
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -589,4 +589,29 @@ public static boolean isBlacklisted(ExtensionAttribute attribute, List<Extension
}
return false;
}

public static void parseLabelElement(XMLStreamReader xtr, BpmnModel model, String BpmnElementId) throws Exception {
GraphicInfo labelGraphicInfo = new GraphicInfo();
BpmnXMLUtil.addXMLLocation(labelGraphicInfo, xtr);

if (xtr.getAttributeValue(null, ATTRIBUTE_DI_ROTATION) != null
&& !xtr.getAttributeValue(null, ATTRIBUTE_DI_ROTATION).isEmpty()) {
labelGraphicInfo.setRotation(Double.valueOf(xtr.getAttributeValue(null, ATTRIBUTE_DI_ROTATION)).intValue());
}

while (xtr.hasNext()) {
xtr.next();
if (xtr.isStartElement() && ELEMENT_DI_BOUNDS.equalsIgnoreCase(xtr.getLocalName())) {

labelGraphicInfo.setX(Double.valueOf(xtr.getAttributeValue(null, ATTRIBUTE_DI_X)).intValue());
labelGraphicInfo.setY(Double.valueOf(xtr.getAttributeValue(null, ATTRIBUTE_DI_Y)).intValue());
labelGraphicInfo.setWidth(Double.valueOf(xtr.getAttributeValue(null, ATTRIBUTE_DI_WIDTH)).intValue());
labelGraphicInfo.setHeight(Double.valueOf(xtr.getAttributeValue(null, ATTRIBUTE_DI_HEIGHT)).intValue());
model.addLabelGraphicInfo(BpmnElementId, labelGraphicInfo);
break;
} else if (xtr.isEndElement() && ELEMENT_DI_LABEL.equalsIgnoreCase(xtr.getLocalName())) {
break;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.flowable.editor.language.xml;

import static org.assertj.core.api.Assertions.assertThat;

import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.GraphicInfo;
import org.flowable.editor.language.xml.util.BpmnXmlConverterTest;

class LabelDiagramConverterTest {

@BpmnXmlConverterTest("labelProcess.bpmn")
void validateModel(BpmnModel bpmnModel) {
assertThat(bpmnModel.getLabelLocationMap().size()).isEqualTo(2);

// Test start event label
GraphicInfo labelGraphicInfo = bpmnModel.getLabelGraphicInfo("startnoneevent1");
assertThat(labelGraphicInfo).isNotNull();
assertThat(labelGraphicInfo.getX()).isEqualTo(419.0);
assertThat(labelGraphicInfo.getY()).isEqualTo(250.0);
assertThat(labelGraphicInfo.getWidth()).isEqualTo(41.0);
assertThat(labelGraphicInfo.getHeight()).isEqualTo(18.0);
assertThat(labelGraphicInfo.getRotation()).isEqualTo(0);

// Test sequence flow label
GraphicInfo labelGraphicInfo2 = bpmnModel.getLabelGraphicInfo("bpmnSequenceFlow_2");
assertThat(labelGraphicInfo2).isNotNull();
assertThat(labelGraphicInfo2.getX()).isEqualTo(845.0);
assertThat(labelGraphicInfo2.getY()).isEqualTo(181.0);
assertThat(labelGraphicInfo2.getWidth()).isEqualTo(85.0);
assertThat(labelGraphicInfo2.getHeight()).isEqualTo(18.0);
assertThat(labelGraphicInfo2.getRotation()).isEqualTo(90.0);

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?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:xsd="http://www.w3.org/2001/XMLSchema" xmlns:flowable="http://flowable.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" xmlns:design="http://flowable.org/design" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://flowable.org/test" design:palette="flowable-work-process-palette">
<process id="LabelProcess" name="nodeLabel" isExecutable="true" flowable:candidateStarterGroups="flowableUser">
<extensionElements>
<design:stencilid><![CDATA[BPMNDiagram]]></design:stencilid>
<design:creationdate><![CDATA[2024-01-30T11:47:37.150Z]]></design:creationdate>
<design:modificationdate><![CDATA[2024-01-30T13:57:17.503Z]]></design:modificationdate>
</extensionElements>
<userTask id="bpmnTask_1" name="User task" flowable:assignee="${initiator}" flowable:formFieldValidation="false">
<extensionElements>
<flowable:task-candidates-type><![CDATA[all]]></flowable:task-candidates-type>
<design:stencilid><![CDATA[FormTask]]></design:stencilid>
<design:stencilsuperid><![CDATA[Task]]></design:stencilsuperid>
</extensionElements>
</userTask>
<startEvent id="startnoneevent1" name="adcdef" flowable:initiator="initiator" flowable:formFieldValidation="false">
<extensionElements>
<flowable:work-form-field-validation><![CDATA[false]]></flowable:work-form-field-validation>
<design:stencilid><![CDATA[StartNoneEvent]]></design:stencilid>
<design:display_ref_in_diagram><![CDATA[true]]></design:display_ref_in_diagram>
</extensionElements>
</startEvent>
<endEvent id="bpmnEndEvent_1">
<extensionElements>
<design:stencilid><![CDATA[EndNoneEvent]]></design:stencilid>
</extensionElements>
</endEvent>
<sequenceFlow id="bpmnSequenceFlow_3" sourceRef="bpmnTask_1" targetRef="bpmnEndEvent_1">
<extensionElements>
<design:stencilid><![CDATA[SequenceFlow]]></design:stencilid>
</extensionElements>
</sequenceFlow>
<sequenceFlow id="bpmnSequenceFlow_2" name="ghijkl" sourceRef="startnoneevent1" targetRef="bpmnTask_1">
<extensionElements>
<design:stencilid><![CDATA[SequenceFlow]]></design:stencilid>
<design:labelrotation><![CDATA[0]]></design:labelrotation>
<design:display_ref_in_diagram><![CDATA[true]]></design:display_ref_in_diagram>
</extensionElements>
</sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_nodeLabel">
<bpmndi:BPMNPlane bpmnElement="LabelProcess" id="BPMNPlane_LabelProcess">
<bpmndi:BPMNShape bpmnElement="bpmnTask_1" id="BPMNShape_bpmnTask_1">
<omgdc:Bounds height="80.0" width="100.0" x="968.0" y="235.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="startnoneevent1" id="BPMNShape_startnoneevent1">
<omgdc:Bounds height="30.0" width="30.0" x="680.0" y="260.0"></omgdc:Bounds>
<bpmndi:BPMNLabel flowable:rotation="">
<omgdc:Bounds height="18.0" width="41.0" x="419.0" y="250.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="bpmnEndEvent_1" id="BPMNShape_bpmnEndEvent_1">
<omgdc:Bounds height="28.0" width="28.0" x="1226.0" y="261.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="bpmnSequenceFlow_3" id="BPMNEdge_bpmnSequenceFlow_3" flowable:sourceDockerX="50.0" flowable:sourceDockerY="40.0" flowable:targetDockerX="14.0" flowable:targetDockerY="14.0">
<omgdi:waypoint x="1068.0" y="275.0"></omgdi:waypoint>
<omgdi:waypoint x="1226.0" y="275.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="bpmnSequenceFlow_2" id="BPMNEdge_bpmnSequenceFlow_2" flowable:sourceDockerX="15.0" flowable:sourceDockerY="15.0" flowable:targetDockerX="50.0" flowable:targetDockerY="40.0">
<omgdi:waypoint x="710.0" y="275.0"></omgdi:waypoint>
<omgdi:waypoint x="968.0" y="275.0"></omgdi:waypoint>
<bpmndi:BPMNLabel flowable:rotation="90.0">
<omgdc:Bounds height="18.0" width="85.0" x="845.0" y="181.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class GraphicInfo {
protected Boolean expanded;
protected int xmlRowNumber;
protected int xmlColumnNumber;
protected double rotation;

public GraphicInfo() {}

Expand Down Expand Up @@ -104,6 +105,14 @@ public void setXmlColumnNumber(int xmlColumnNumber) {
this.xmlColumnNumber = xmlColumnNumber;
}

public double getRotation() {
return rotation;
}

public void setRotation(double rotation) {
this.rotation = rotation;
}

public boolean equals(GraphicInfo ginfo) {
if (this.getX() != ginfo.getX()) {
return false;
Expand All @@ -117,6 +126,9 @@ public boolean equals(GraphicInfo ginfo) {
if (this.getWidth() != ginfo.getWidth()) {
return false;
}
if (this.getRotation() != ginfo.getRotation()) {
return false;
}

// check for zero value in case we are comparing model value to BPMN DI value
// model values do not have xml location information
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,26 @@ public boolean hasChildElements() {

@Override
protected BaseElement convert(XMLStreamReader xtr, ConversionHelper conversionHelper) {
GraphicInfo graphicInfo = new GraphicInfo();
// If this Bounds element is in a Label element, there will be a currentLabelGraphicInfo available
GraphicInfo graphicInfo = null;
if (conversionHelper.getCurrentLabelGraphicInfo() != null) {
graphicInfo = conversionHelper.getCurrentLabelGraphicInfo();

if (conversionHelper.getCurrentDiEdge() != null) {
conversionHelper.getCurrentDiEdge().setLabelGraphicInfo(graphicInfo);
} else if (conversionHelper.getCurrentDiShape() != null) {
conversionHelper.getCurrentDiShape().setLabelGraphicInfo(graphicInfo);
}
} else {
graphicInfo = new GraphicInfo();
conversionHelper.getCurrentDiShape().setGraphicInfo(graphicInfo);
}

graphicInfo.setX(Double.valueOf(xtr.getAttributeValue(null, CmmnXmlConstants.ATTRIBUTE_DI_X)));
graphicInfo.setY(Double.valueOf(xtr.getAttributeValue(null, CmmnXmlConstants.ATTRIBUTE_DI_Y)));
graphicInfo.setWidth(Double.valueOf(xtr.getAttributeValue(null, CmmnXmlConstants.ATTRIBUTE_DI_WIDTH)));
graphicInfo.setHeight(Double.valueOf(xtr.getAttributeValue(null, CmmnXmlConstants.ATTRIBUTE_DI_HEIGHT)));

conversionHelper.getCurrentDiShape().setGraphicInfo(graphicInfo);

return graphicInfo;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,10 @@ protected BaseElement convert(XMLStreamReader xtr, ConversionHelper conversionHe

return diEdge;
}

@Override
protected void elementEnd(XMLStreamReader xtr, ConversionHelper conversionHelper) {
conversionHelper.setCurrentDiEdge(null);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.flowable.cmmn.converter;

import javax.xml.stream.XMLStreamReader;

import org.flowable.cmmn.model.BaseElement;
import org.flowable.cmmn.model.GraphicInfo;

public class CmmnDiLabelXmlConverter extends BaseCmmnXmlConverter {

@Override
public String getXMLElementName() {
return CmmnXmlConstants.ELEMENT_DI_LABEL;
}

@Override
public boolean hasChildElements() {
return false;
}

@Override
protected BaseElement convert(XMLStreamReader xtr, ConversionHelper conversionHelper) {
GraphicInfo labelGraphicInfo = new GraphicInfo();

if (xtr.getAttributeValue(null, CmmnXmlConstants.ATTRIBUTE_DI_ROTATION) != null
&& !xtr.getAttributeValue(null, CmmnXmlConstants.ATTRIBUTE_DI_ROTATION).isEmpty()) {
labelGraphicInfo.setRotation(Double.valueOf(xtr.getAttributeValue(null, CmmnXmlConstants.ATTRIBUTE_DI_ROTATION)).intValue());
}

conversionHelper.setCurrentLabelGraphicInfo(labelGraphicInfo);

return labelGraphicInfo;
}

@Override
protected void elementEnd(XMLStreamReader xtr, ConversionHelper conversionHelper) {
conversionHelper.setCurrentLabelGraphicInfo(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,10 @@ protected BaseElement convert(XMLStreamReader xtr, ConversionHelper conversionHe

return diShape;
}

@Override
protected void elementEnd(XMLStreamReader xtr, ConversionHelper conversionHelper) {
conversionHelper.setCurrentDiShape(null);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -243,5 +243,6 @@ public interface CmmnXmlConstants {
String ATTRIBUTE_DI_HEIGHT = "height";
String ATTRIBUTE_DI_X = "x";
String ATTRIBUTE_DI_Y = "y";
String ATTRIBUTE_DI_ROTATION = "rotation";

}
Loading
Loading