diff --git a/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/export/MultiInstanceExport.java b/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/export/MultiInstanceExport.java index 3448ceb208931eae6697165cd50b43fa6d609552..c242f6bb70d5cdab7ec274f59cc72220593fa325 100644 --- a/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/export/MultiInstanceExport.java +++ b/modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/export/MultiInstanceExport.java @@ -32,6 +32,8 @@ public class MultiInstanceExport implements BpmnXMLConstants { if (activity.getLoopCharacteristics() != null) { MultiInstanceLoopCharacteristics multiInstanceObject = activity.getLoopCharacteristics(); CollectionHandler handler = multiInstanceObject.getHandler(); + boolean didWriteExtensionStartElement = false; + if (StringUtils.isNotEmpty(multiInstanceObject.getLoopCardinality()) || StringUtils.isNotEmpty(multiInstanceObject.getInputDataItem()) || StringUtils.isNotEmpty(multiInstanceObject.getCompletionCondition()) || StringUtils.isNotEmpty(multiInstanceObject.getCollectionString())) { @@ -44,21 +46,12 @@ public class MultiInstanceExport implements BpmnXMLConstants { if (StringUtils.isNotEmpty(multiInstanceObject.getElementVariable())) { BpmnXMLUtil.writeQualifiedAttribute(ATTRIBUTE_MULTIINSTANCE_VARIABLE, multiInstanceObject.getElementVariable(), xtw); } - if (StringUtils.isNotEmpty(multiInstanceObject.getLoopCardinality())) { - xtw.writeStartElement(ELEMENT_MULTIINSTANCE_CARDINALITY); - xtw.writeCharacters(multiInstanceObject.getLoopCardinality()); - xtw.writeEndElement(); - } - if (StringUtils.isNotEmpty(multiInstanceObject.getCompletionCondition())) { - xtw.writeStartElement(ELEMENT_MULTIINSTANCE_CONDITION); - xtw.writeCharacters(multiInstanceObject.getCompletionCondition()); - xtw.writeEndElement(); - } - // check for collection element handler + // check for collection element handler extension first since process validation is order-dependent if (handler != null) { // start extensions xtw.writeStartElement(ELEMENT_EXTENSIONS); + didWriteExtensionStartElement = true; // start collection element xtw.writeStartElement(FLOWABLE_EXTENSIONS_NAMESPACE, ELEMENT_MULTIINSTANCE_COLLECTION); @@ -84,17 +77,29 @@ public class MultiInstanceExport implements BpmnXMLConstants { } - // check for extension elements + // check for other custom extension elements Map> extensions = multiInstanceObject.getExtensionElements(); if (!extensions.isEmpty()) { - BpmnXMLUtil.writeExtensionElements(multiInstanceObject, handler != null, model.getNamespaces(), xtw); + didWriteExtensionStartElement = BpmnXMLUtil.writeExtensionElements(multiInstanceObject, didWriteExtensionStartElement, model.getNamespaces(), xtw); + } + + // end extensions element + if (didWriteExtensionStartElement) { + xtw.writeEndElement(); } - // end extensions element - if (handler != null) { - xtw.writeEndElement(); - } + if (StringUtils.isNotEmpty(multiInstanceObject.getLoopCardinality())) { + xtw.writeStartElement(ELEMENT_MULTIINSTANCE_CARDINALITY); + xtw.writeCharacters(multiInstanceObject.getLoopCardinality()); + xtw.writeEndElement(); + } + if (StringUtils.isNotEmpty(multiInstanceObject.getCompletionCondition())) { + xtw.writeStartElement(ELEMENT_MULTIINSTANCE_CONDITION); + xtw.writeCharacters(multiInstanceObject.getCompletionCondition()); + xtw.writeEndElement(); + } + // end multi-instance element xtw.writeEndElement(); } } diff --git a/modules/flowable-bpmn-converter/src/test/resources/multiinstancemodel2.bpmn b/modules/flowable-bpmn-converter/src/test/resources/multiinstancemodel2.bpmn index 14a36d2482ad26886b7ed319a99b4773a8c263d9..f1f93149b5ca6c667c02abf0616cb88911e971e7 100644 --- a/modules/flowable-bpmn-converter/src/test/resources/multiinstancemodel2.bpmn +++ b/modules/flowable-bpmn-converter/src/test/resources/multiinstancemodel2.bpmn @@ -41,6 +41,7 @@ ${potentialOwnerList} + ${nrOfInstances==2}