diff --git a/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/constants/BpmnXMLConstants.java b/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/constants/BpmnXMLConstants.java index 5e16277089a..9ad28d9f1da 100644 --- a/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/constants/BpmnXMLConstants.java +++ b/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/constants/BpmnXMLConstants.java @@ -41,6 +41,7 @@ public interface BpmnXMLConstants { public static final String ATTRIBUTE_ID = "id"; public static final String ATTRIBUTE_NAME = "name"; + public static final String ATTRIBUTE_ELEMENT_NAME = "element-name"; public static final String ATTRIBUTE_TYPE = "type"; public static final String ATTRIBUTE_EXPORTER = "exporter"; public static final String ATTRIBUTE_EXPORTER_VERSION = "exporterVersion"; diff --git a/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/BaseBpmnXMLConverter.java b/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/BaseBpmnXMLConverter.java index ad7967da6a0..673822dfff0 100644 --- a/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/BaseBpmnXMLConverter.java +++ b/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/BaseBpmnXMLConverter.java @@ -111,7 +111,9 @@ public void convertToBpmnModel(XMLStreamReader xtr, BpmnModel model, Process act FlowElement currentFlowElement = (FlowElement) parsedElement; currentFlowElement.setId(elementId); - currentFlowElement.setName(elementName); + if (currentFlowElement.getName() == null) { + currentFlowElement.setName(elementName); + } if (currentFlowElement instanceof FlowNode) { FlowNode flowNode = (FlowNode) currentFlowElement; @@ -167,7 +169,10 @@ public void convertToXML(XMLStreamWriter xtw, BaseElement baseElement, BpmnModel boolean didWriteExtensionStartElement = false; writeDefaultAttribute(ATTRIBUTE_ID, baseElement.getId(), xtw); if (baseElement instanceof FlowElement) { - writeDefaultAttribute(ATTRIBUTE_NAME, ((FlowElement) baseElement).getName(), xtw); + String name = ((FlowElement) baseElement).getName(); + if (!BpmnXMLUtil.containsNewLine(name)) { + writeDefaultAttribute(ATTRIBUTE_NAME, name, xtw); + } } if (baseElement instanceof FlowNode) { @@ -220,6 +225,8 @@ public void convertToXML(XMLStreamWriter xtw, BaseElement baseElement, BpmnModel xtw.writeCharacters(flowElement.getDocumentation()); xtw.writeEndElement(); } + + didWriteExtensionStartElement = BpmnXMLUtil.writeElementNameExtensionElement(flowElement, didWriteExtensionStartElement, xtw); } didWriteExtensionStartElement = writeExtensionChildElements(baseElement, didWriteExtensionStartElement, xtw); diff --git a/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/BpmnXMLConverter.java b/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/BpmnXMLConverter.java index 493f4180c0b..80d1c8ad8d8 100644 --- a/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/BpmnXMLConverter.java +++ b/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/BpmnXMLConverter.java @@ -619,6 +619,8 @@ protected void createXML(FlowElement flowElement, BpmnModel model, XMLStreamWrit boolean didWriteExtensionStartElement = FlowableListenerExport.writeListeners(subProcess, false, xtw); + didWriteExtensionStartElement = BpmnXMLUtil.writeElementNameExtensionElement(subProcess, didWriteExtensionStartElement, xtw); + didWriteExtensionStartElement = BpmnXMLUtil.writeExtensionElements(subProcess, didWriteExtensionStartElement, model.getNamespaces(), xtw); if (didWriteExtensionStartElement) { // closing extensions element diff --git a/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/SequenceFlowXMLConverter.java b/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/SequenceFlowXMLConverter.java index 52269c91884..5bf94cd8927 100644 --- a/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/SequenceFlowXMLConverter.java +++ b/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/SequenceFlowXMLConverter.java @@ -42,7 +42,6 @@ protected BaseElement convertXMLToElement(XMLStreamReader xtr, BpmnModel model) BpmnXMLUtil.addXMLLocation(sequenceFlow, xtr); sequenceFlow.setSourceRef(xtr.getAttributeValue(null, ATTRIBUTE_FLOW_SOURCE_REF)); sequenceFlow.setTargetRef(xtr.getAttributeValue(null, ATTRIBUTE_FLOW_TARGET_REF)); - sequenceFlow.setName(xtr.getAttributeValue(null, ATTRIBUTE_NAME)); sequenceFlow.setSkipExpression(xtr.getAttributeValue(null, ATTRIBUTE_FLOW_SKIP_EXPRESSION)); parseChildElements(getXMLElementName(), sequenceFlow, model, xtr); diff --git a/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/child/ElementNameParser.java b/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/child/ElementNameParser.java new file mode 100644 index 00000000000..8f12ce8ea48 --- /dev/null +++ b/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/child/ElementNameParser.java @@ -0,0 +1,38 @@ +/* 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.bpmn.converter.child; + +import javax.xml.stream.XMLStreamReader; + +import org.apache.commons.lang3.StringUtils; +import org.flowable.bpmn.model.BaseElement; +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.bpmn.model.FlowElement; + +public class ElementNameParser extends BaseChildElementParser { + + @Override + public String getElementName() { + return ATTRIBUTE_ELEMENT_NAME; + } + + @Override + public void parseChildElement(XMLStreamReader xtr, BaseElement parentElement, BpmnModel model) throws Exception { + String elementName = xtr.getElementText(); + if (StringUtils.isNotEmpty(elementName)) { + if (parentElement instanceof FlowElement) { + ((FlowElement) parentElement).setName(elementName.trim()); + } + } + } +} diff --git a/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/parser/ExtensionElementsParser.java b/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/parser/ExtensionElementsParser.java index e93562dcc03..33de43296ac 100644 --- a/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/parser/ExtensionElementsParser.java +++ b/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/parser/ExtensionElementsParser.java @@ -17,6 +17,7 @@ import javax.xml.stream.XMLStreamReader; import org.flowable.bpmn.constants.BpmnXMLConstants; +import org.flowable.bpmn.converter.child.ElementNameParser; import org.flowable.bpmn.converter.child.ExecutionListenerParser; import org.flowable.bpmn.converter.child.FlowableEventListenerParser; import org.flowable.bpmn.converter.util.BpmnXMLUtil; @@ -50,6 +51,8 @@ public void parse(XMLStreamReader xtr, List activeSubProcessList, Pr new FlowableEventListenerParser().parseChildElement(xtr, parentElement, model); } else if (ELEMENT_POTENTIAL_STARTER.equals(xtr.getLocalName())) { new PotentialStarterParser().parse(xtr, activeProcess); + } else if (ATTRIBUTE_ELEMENT_NAME.equals(xtr.getLocalName())) { + new ElementNameParser().parseChildElement(xtr, parentElement, model); } else { ExtensionElement extensionElement = BpmnXMLUtil.parseExtensionElement(xtr); parentElement.addExtensionElement(extensionElement); diff --git a/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/util/BpmnXMLUtil.java b/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/util/BpmnXMLUtil.java index 8aba4885172..87756a31200 100644 --- a/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/util/BpmnXMLUtil.java +++ b/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/util/BpmnXMLUtil.java @@ -37,6 +37,7 @@ import org.flowable.bpmn.converter.child.DataOutputAssociationParser; import org.flowable.bpmn.converter.child.DataStateParser; import org.flowable.bpmn.converter.child.DocumentationParser; +import org.flowable.bpmn.converter.child.ElementNameParser; import org.flowable.bpmn.converter.child.ErrorEventDefinitionParser; import org.flowable.bpmn.converter.child.EscalationEventDefinitionParser; import org.flowable.bpmn.converter.child.ExecutionListenerParser; @@ -65,6 +66,7 @@ import org.flowable.bpmn.model.BpmnModel; import org.flowable.bpmn.model.ExtensionAttribute; import org.flowable.bpmn.model.ExtensionElement; +import org.flowable.bpmn.model.FlowElement; import org.flowable.bpmn.model.GraphicInfo; import org.flowable.bpmn.model.IOParameter; @@ -104,6 +106,7 @@ public class BpmnXMLUtil implements BpmnXMLConstants { addGenericParser(new FlowNodeRefParser()); addGenericParser(new FlowableFailedjobRetryParser()); addGenericParser(new FlowableMapExceptionParser()); + addGenericParser(new ElementNameParser()); } private static void addGenericParser(BaseChildElementParser parser) { @@ -408,6 +411,22 @@ protected static void writeExtensionElement(ExtensionElement extensionElement, M xtw.writeEndElement(); } } + + public static boolean writeElementNameExtensionElement(FlowElement element, boolean didWriteExtensionStartElement, XMLStreamWriter xtw) throws Exception { + String name = element.getName(); + if (BpmnXMLUtil.containsNewLine(name)) { + if (!didWriteExtensionStartElement) { + xtw.writeStartElement(ELEMENT_EXTENSIONS); + didWriteExtensionStartElement = true; + } + + xtw.writeStartElement(FLOWABLE_EXTENSIONS_PREFIX, ATTRIBUTE_ELEMENT_NAME, FLOWABLE_EXTENSIONS_NAMESPACE); + xtw.writeCharacters(element.getName()); + xtw.writeEndElement(); + } + + return didWriteExtensionStartElement; + } public static boolean writeIOParameters(String elementName, List parameterList, boolean didWriteExtensionStartElement, XMLStreamWriter xtw) throws Exception { @@ -614,4 +633,8 @@ public static void parseLabelElement(XMLStreamReader xtr, BpmnModel model, Strin } } } + + public static boolean containsNewLine(String str) { + return str != null && str.contains("\n"); + } } diff --git a/modules/flowable-bpmn-converter/src/test/java/org/flowable/editor/language/xml/NameWithNewLineTest.java b/modules/flowable-bpmn-converter/src/test/java/org/flowable/editor/language/xml/NameWithNewLineTest.java new file mode 100644 index 00000000000..5831ec55309 --- /dev/null +++ b/modules/flowable-bpmn-converter/src/test/java/org/flowable/editor/language/xml/NameWithNewLineTest.java @@ -0,0 +1,87 @@ +/* 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 static org.flowable.bpmn.constants.BpmnXMLConstants.ATTRIBUTE_ELEMENT_NAME; + +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.bpmn.model.ExtensionElement; +import org.flowable.bpmn.model.FlowElement; +import org.flowable.bpmn.model.SubProcess; +import org.flowable.editor.language.xml.util.BpmnXmlConverterTest; + +class NameWithNewLineTest { + + @BpmnXmlConverterTest("nameWithNewLineTestProcess.bpmn") + void validateModel(BpmnModel model) { + FlowElement flowElement = model.getMainProcess().getFlowElement("startnoneevent1"); + assertThat(flowElement.getName()).isEqualTo("start\nevent"); + assertThat(flowElement.getExtensionElements().get(ATTRIBUTE_ELEMENT_NAME)).isNull(); + + flowElement = model.getMainProcess().getFlowElement("bpmnCatchEvent_12"); + assertThat(flowElement.getName()).isEqualTo("intermediate\nevent"); + assertThat(flowElement.getExtensionElements().get(ATTRIBUTE_ELEMENT_NAME)).isNull(); + + flowElement = model.getMainProcess().getFlowElement("bpmnGateway_14"); + assertThat(flowElement.getName()).isEqualTo("gate\nway"); + assertThat(flowElement.getExtensionElements().get(ATTRIBUTE_ELEMENT_NAME)).isNull(); + + flowElement = model.getMainProcess().getFlowElement("bpmnEndEvent_3"); + assertThat(flowElement.getName()).isEqualTo("end\nevent"); + assertThat(flowElement.getExtensionElements().get(ATTRIBUTE_ELEMENT_NAME)).isNull(); + + SubProcess subProcess = (SubProcess) model.getMainProcess().getFlowElement("bpmnStructure_1"); + assertThat(subProcess.getName()).isEqualTo("sub\nprocess"); + assertThat(flowElement.getExtensionElements().get(ATTRIBUTE_ELEMENT_NAME)).isNull(); + + flowElement = subProcess.getFlowElement("bpmnTask_5"); + assertThat(flowElement.getName()).isEqualTo("user\ntask"); + assertThat(flowElement.getExtensionElements().get(ATTRIBUTE_ELEMENT_NAME)).isNull(); + + flowElement = subProcess.getFlowElement("bpmnBoundaryEvent_10"); + assertThat(flowElement.getName()).isEqualTo("boundary\nevent"); + assertThat(flowElement.getExtensionElements().get(ATTRIBUTE_ELEMENT_NAME)).isNull(); + } + + @BpmnXmlConverterTest("nameWithoutNewLineTestProcess.bpmn") + void validateModelWithoutNewLines(BpmnModel model) { + FlowElement flowElement = model.getMainProcess().getFlowElement("startnoneevent1"); + assertThat(flowElement.getName()).isEqualTo("startevent"); + assertThat(flowElement.getExtensionElements().get(ATTRIBUTE_ELEMENT_NAME)).isNull(); + + flowElement = model.getMainProcess().getFlowElement("bpmnCatchEvent_12"); + assertThat(flowElement.getName()).isEqualTo("intermediateevent"); + assertThat(flowElement.getExtensionElements().get(ATTRIBUTE_ELEMENT_NAME)).isNull(); + + flowElement = model.getMainProcess().getFlowElement("bpmnGateway_14"); + assertThat(flowElement.getName()).isEqualTo("gateway"); + assertThat(flowElement.getExtensionElements().get(ATTRIBUTE_ELEMENT_NAME)).isNull(); + + flowElement = model.getMainProcess().getFlowElement("bpmnEndEvent_3"); + assertThat(flowElement.getName()).isEqualTo("endevent"); + assertThat(flowElement.getExtensionElements().get(ATTRIBUTE_ELEMENT_NAME)).isNull(); + + SubProcess subProcess = (SubProcess) model.getMainProcess().getFlowElement("bpmnStructure_1"); + assertThat(subProcess.getName()).isEqualTo("subprocess"); + assertThat(subProcess.getExtensionElements().get(ATTRIBUTE_ELEMENT_NAME)).isNull(); + + flowElement = subProcess.getFlowElement("bpmnTask_5"); + assertThat(flowElement.getName()).isEqualTo("usertask"); + assertThat(flowElement.getExtensionElements().get(ATTRIBUTE_ELEMENT_NAME)).isNull(); + + flowElement = subProcess.getFlowElement("bpmnBoundaryEvent_10"); + assertThat(flowElement.getName()).isEqualTo("boundaryevent"); + assertThat(flowElement.getExtensionElements().get(ATTRIBUTE_ELEMENT_NAME)).isNull(); + } +} diff --git a/modules/flowable-bpmn-converter/src/test/resources/nameWithNewLineTestProcess.bpmn b/modules/flowable-bpmn-converter/src/test/resources/nameWithNewLineTestProcess.bpmn new file mode 100644 index 00000000000..7f1612c775c --- /dev/null +++ b/modules/flowable-bpmn-converter/src/test/resources/nameWithNewLineTestProcess.bpmn @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + PT1H + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/flowable-bpmn-converter/src/test/resources/nameWithoutNewLineTestProcess.bpmn b/modules/flowable-bpmn-converter/src/test/resources/nameWithoutNewLineTestProcess.bpmn new file mode 100644 index 00000000000..5671059f18f --- /dev/null +++ b/modules/flowable-bpmn-converter/src/test/resources/nameWithoutNewLineTestProcess.bpmn @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + PT1H + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/CmmnXmlConstants.java b/modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/CmmnXmlConstants.java index 47179fce435..140759d18b2 100644 --- a/modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/CmmnXmlConstants.java +++ b/modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/CmmnXmlConstants.java @@ -104,6 +104,7 @@ public interface CmmnXmlConstants { String ATTRIBUTE_ID = "id"; String ATTRIBUTE_NAME = "name"; + String ATTRIBUTE_ELEMENT_NAME = "element-name"; String ATTRIBUTE_INITIATOR_VARIABLE_NAME = "initiatorVariableName"; String ATTRIBUTE_CASE_CANDIDATE_USERS = "candidateStarterUsers"; String ATTRIBUTE_CASE_CANDIDATE_GROUPS = "candidateStarterGroups"; diff --git a/modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/ExtensionElementsXMLConverter.java b/modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/ExtensionElementsXMLConverter.java index 4fb460d7647..1ae61f50b37 100644 --- a/modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/ExtensionElementsXMLConverter.java +++ b/modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/ExtensionElementsXMLConverter.java @@ -15,6 +15,7 @@ import static org.flowable.cmmn.converter.CmmnXmlConstants.ATTRIBUTE_CLASS; import static org.flowable.cmmn.converter.CmmnXmlConstants.ATTRIBUTE_DELEGATE_EXPRESSION; +import static org.flowable.cmmn.converter.CmmnXmlConstants.ATTRIBUTE_ELEMENT_NAME; import static org.flowable.cmmn.model.ImplementationType.IMPLEMENTATION_TYPE_CLASS; import static org.flowable.cmmn.model.ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION; @@ -28,6 +29,7 @@ import org.flowable.cmmn.model.AbstractFlowableHttpHandler; import org.flowable.cmmn.model.BaseElement; import org.flowable.cmmn.model.Case; +import org.flowable.cmmn.model.CaseElement; import org.flowable.cmmn.model.ChildTask; import org.flowable.cmmn.model.CmmnElement; import org.flowable.cmmn.model.CompletionNeutralRule; @@ -124,6 +126,8 @@ protected CmmnElement convert(XMLStreamReader xtr, ConversionHelper conversionHe } else if (CmmnXmlConstants.ELEMENT_VARIABLE_AGGREGATION.equals(xtr.getLocalName())) { readVariableAggregationDefinition(xtr, conversionHelper); + } else if (CmmnXmlConstants.ATTRIBUTE_ELEMENT_NAME.equals(xtr.getLocalName())) { + readElementName(xtr, conversionHelper); } else { ExtensionElement extensionElement = CmmnXmlUtil.parseExtensionElement(xtr); conversionHelper.getCurrentCmmnElement().addExtensionElement(extensionElement); @@ -463,6 +467,24 @@ protected void readVariableAggregationDefinition(XMLStreamReader xtr, Conversion } + protected void readElementName(XMLStreamReader xtr, ConversionHelper conversionHelper) { + CmmnElement currentCmmnElement = conversionHelper.getCurrentCmmnElement(); + + if (currentCmmnElement instanceof CaseElement) { + try { + String elementName = xtr.getElementText(); + + if (StringUtils.isNotEmpty(elementName)) { + ((CaseElement) currentCmmnElement).setName(elementName.trim()); + } + } catch (Exception e) { + throw new FlowableException("Error while reading " + ATTRIBUTE_ELEMENT_NAME + " extension element", e); + } + + } + + } + protected void readCommonXmlInfo(BaseElement baseElement, XMLStreamReader xtr) { baseElement.setId(xtr.getAttributeValue(null, CmmnXmlConstants.ATTRIBUTE_ID)); Location location = xtr.getLocation(); diff --git a/modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/PlanItemDefinitionXmlConverter.java b/modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/PlanItemDefinitionXmlConverter.java index ddbe05fdfb3..371a5b520a2 100644 --- a/modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/PlanItemDefinitionXmlConverter.java +++ b/modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/PlanItemDefinitionXmlConverter.java @@ -35,7 +35,8 @@ public BaseElement convertToCmmnModel(XMLStreamReader xtr, ConversionHelper conv if (parentStage != null) { parentStage.addPlanItemDefinition(planItemDefinition); } - } + } + return planItemDefinition; } diff --git a/modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/export/AbstractPlanItemDefinitionExport.java b/modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/export/AbstractPlanItemDefinitionExport.java index 44d6d93bf11..3752c48978b 100644 --- a/modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/export/AbstractPlanItemDefinitionExport.java +++ b/modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/export/AbstractPlanItemDefinitionExport.java @@ -67,7 +67,7 @@ protected void writePlanItemDefinitionStartElement(T planItemDefinition, XMLStre protected void writePlanItemDefinitionCommonAttributes(T planItemDefinition, XMLStreamWriter xtw) throws Exception { xtw.writeAttribute(ATTRIBUTE_ID, planItemDefinition.getId()); - if (StringUtils.isNotEmpty(planItemDefinition.getName())) { + if (StringUtils.isNotEmpty(planItemDefinition.getName()) && !CmmnXmlUtil.containsNewLine(planItemDefinition.getName())) { xtw.writeAttribute(ATTRIBUTE_NAME, planItemDefinition.getName()); } } @@ -98,8 +98,10 @@ protected boolean writePlanItemDefinitionCommonElements(CmmnModel model, T planI xtw.writeCharacters(planItemDefinition.getDocumentation()); xtw.writeEndElement(); } + + boolean didWriteExtensionStartElement = CmmnXmlUtil.writeElementNameExtensionElement(planItemDefinition, false, xtw); - return CmmnXmlUtil.writeExtensionElements(planItemDefinition, false, model.getNamespaces(), xtw); + return CmmnXmlUtil.writeExtensionElements(planItemDefinition, didWriteExtensionStartElement, model.getNamespaces(), xtw); } protected boolean writePlanItemDefinitionExtensionElements(CmmnModel model, T planItemDefinition, boolean didWriteExtensionElement, XMLStreamWriter xtw) throws Exception { diff --git a/modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/util/CmmnXmlUtil.java b/modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/util/CmmnXmlUtil.java index dde18db44f8..06c0f9b26ee 100644 --- a/modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/util/CmmnXmlUtil.java +++ b/modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/util/CmmnXmlUtil.java @@ -28,6 +28,7 @@ import org.apache.commons.lang3.StringUtils; import org.flowable.cmmn.converter.CmmnXmlConstants; import org.flowable.cmmn.model.BaseElement; +import org.flowable.cmmn.model.CaseElement; import org.flowable.cmmn.model.ExtensionAttribute; import org.flowable.cmmn.model.ExtensionElement; import org.flowable.cmmn.model.GraphicInfo; @@ -225,6 +226,22 @@ protected static void writeExtensionElement(ExtensionElement extensionElement, M } } + public static boolean writeElementNameExtensionElement(CaseElement element, boolean didWriteExtensionStartElement, XMLStreamWriter xtw) throws Exception { + String name = element.getName(); + if (containsNewLine(name)) { + if (!didWriteExtensionStartElement) { + xtw.writeStartElement(ELEMENT_EXTENSION_ELEMENTS); + didWriteExtensionStartElement = true; + } + + xtw.writeStartElement(FLOWABLE_EXTENSIONS_PREFIX, ATTRIBUTE_ELEMENT_NAME, FLOWABLE_EXTENSIONS_NAMESPACE); + xtw.writeCharacters(element.getName()); + xtw.writeEndElement(); + } + + return didWriteExtensionStartElement; + } + public static void writeCustomAttributes(Collection> attributes, XMLStreamWriter xtw, List... blackLists) throws XMLStreamException { writeCustomAttributes(attributes, xtw, new LinkedHashMap<>(), blackLists); } @@ -296,4 +313,8 @@ public static boolean isBlacklisted(ExtensionAttribute attribute, List + + + + + + + + + + + + + + + + + + + + + + + + + occur + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/flowable-cmmn-converter/src/test/resources/org/flowable/test/cmmn/converter/nameWithoutNewLineTestCase.cmmn b/modules/flowable-cmmn-converter/src/test/resources/org/flowable/test/cmmn/converter/nameWithoutNewLineTestCase.cmmn new file mode 100644 index 00000000000..a53c90175f5 --- /dev/null +++ b/modules/flowable-cmmn-converter/src/test/resources/org/flowable/test/cmmn/converter/nameWithoutNewLineTestCase.cmmn @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + occur + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file