diff --git a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/BaseBpmnXMLConverter.java b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/BaseBpmnXMLConverter.java index 48a8cc7966e0f9d96c45b7042c9da6d5918dfafa..876d4e010d8dee10a4ab149abeb039b7bb2468bf 100644 --- a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/BaseBpmnXMLConverter.java +++ b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/BaseBpmnXMLConverter.java @@ -21,23 +21,6 @@ import javax.xml.stream.XMLStreamWriter; import org.activiti.bpmn.constants.BpmnXMLConstants; import org.activiti.bpmn.converter.child.BaseChildElementParser; -import org.activiti.bpmn.converter.child.CancelEventDefinitionParser; -import org.activiti.bpmn.converter.child.CompensateEventDefinitionParser; -import org.activiti.bpmn.converter.child.ConditionExpressionParser; -import org.activiti.bpmn.converter.child.DataInputAssociationParser; -import org.activiti.bpmn.converter.child.DataOutputAssociationParser; -import org.activiti.bpmn.converter.child.DocumentationParser; -import org.activiti.bpmn.converter.child.ErrorEventDefinitionParser; -import org.activiti.bpmn.converter.child.ExecutionListenerParser; -import org.activiti.bpmn.converter.child.FieldExtensionParser; -import org.activiti.bpmn.converter.child.FormPropertyParser; -import org.activiti.bpmn.converter.child.IOSpecificationParser; -import org.activiti.bpmn.converter.child.MessageEventDefinitionParser; -import org.activiti.bpmn.converter.child.MultiInstanceParser; -import org.activiti.bpmn.converter.child.SignalEventDefinitionParser; -import org.activiti.bpmn.converter.child.TaskListenerParser; -import org.activiti.bpmn.converter.child.TerminateEventDefinitionParser; -import org.activiti.bpmn.converter.child.TimerEventDefinitionParser; import org.activiti.bpmn.converter.export.ActivitiListenerExport; import org.activiti.bpmn.converter.export.MultiInstanceExport; import org.activiti.bpmn.converter.util.BpmnXMLUtil; @@ -47,8 +30,6 @@ import org.activiti.bpmn.model.BaseElement; import org.activiti.bpmn.model.BpmnModel; import org.activiti.bpmn.model.ErrorEventDefinition; import org.activiti.bpmn.model.EventDefinition; -import org.activiti.bpmn.model.ExtensionAttribute; -import org.activiti.bpmn.model.ExtensionElement; import org.activiti.bpmn.model.FlowElement; import org.activiti.bpmn.model.FormProperty; import org.activiti.bpmn.model.FormValue; @@ -75,34 +56,9 @@ public abstract class BaseBpmnXMLConverter implements BpmnXMLConstants { protected BpmnModel model; protected Process activeProcess; protected Map childElementParsers = new HashMap(); - private static Map genericChildParserMap = new HashMap(); protected boolean didWriteExtensionStartElement = false; - static { - addGenericParser(new CancelEventDefinitionParser()); - addGenericParser(new CompensateEventDefinitionParser()); - addGenericParser(new ConditionExpressionParser()); - addGenericParser(new DataInputAssociationParser()); - addGenericParser(new DataOutputAssociationParser()); - addGenericParser(new DocumentationParser()); - addGenericParser(new ErrorEventDefinitionParser()); - addGenericParser(new ExecutionListenerParser()); - addGenericParser(new FieldExtensionParser()); - addGenericParser(new FormPropertyParser()); - addGenericParser(new IOSpecificationParser()); - addGenericParser(new MessageEventDefinitionParser()); - addGenericParser(new MultiInstanceParser()); - addGenericParser(new SignalEventDefinitionParser()); - addGenericParser(new TaskListenerParser()); - addGenericParser(new TerminateEventDefinitionParser()); - addGenericParser(new TimerEventDefinitionParser()); - } - - private static void addGenericParser(BaseChildElementParser parser) { - genericChildParserMap.put(parser.getElementName(), parser); - } - public void convertToBpmnModel(XMLStreamReader xtr, BpmnModel model, Process activeProcess, List activeSubProcessList) throws Exception { @@ -203,19 +159,7 @@ public abstract class BaseBpmnXMLConverter implements BpmnXMLConstants { writeExtensionChildElements(baseElement, xtw); didWriteExtensionStartElement = writeListeners(baseElement, xtw); - - if (baseElement.getExtensionElements().size() > 0) { - if (didWriteExtensionStartElement == false) { - xtw.writeStartElement(ELEMENT_EXTENSIONS); - didWriteExtensionStartElement = true; - } - Map namespaceMap = new HashMap(); - for (List extensionElements : baseElement.getExtensionElements().values()) { - for (ExtensionElement extensionElement : extensionElements) { - writeExtensionElement(extensionElement, namespaceMap, xtw); - } - } - } + didWriteExtensionStartElement = BpmnXMLUtil.writeExtensionElements(baseElement, didWriteExtensionStartElement, xtw); if (didWriteExtensionStartElement) { xtw.writeEndElement(); @@ -245,71 +189,10 @@ public abstract class BaseBpmnXMLConverter implements BpmnXMLConstants { protected void parseChildElements(String elementName, BaseElement parentElement, XMLStreamReader xtr) throws Exception { Map childParsers = new HashMap(); - childParsers.putAll(genericChildParserMap); if (childElementParsers != null) { childParsers.putAll(childElementParsers); } - - boolean inExtensionElements = false; - boolean readyWithChildElements = false; - while (readyWithChildElements == false && xtr.hasNext()) { - xtr.next(); - if (xtr.isStartElement()) { - if (ELEMENT_EXTENSIONS.equals(xtr.getLocalName())) { - inExtensionElements = true; - } else if (childParsers.containsKey(xtr.getLocalName())) { - childParsers.get(xtr.getLocalName()).parseChildElement(xtr, parentElement, model); - } else if (inExtensionElements) { - ExtensionElement extensionElement = parseExtensionElement(xtr); - parentElement.addExtensionElement(extensionElement); - } - - } else if (xtr.isEndElement()) { - if (ELEMENT_EXTENSIONS.equals(xtr.getLocalName())) { - inExtensionElements = false; - } else if (elementName.equalsIgnoreCase(xtr.getLocalName())) { - readyWithChildElements = true; - } - } - } - } - - protected ExtensionElement parseExtensionElement(XMLStreamReader xtr) throws Exception { - ExtensionElement extensionElement = new ExtensionElement(); - extensionElement.setName(xtr.getLocalName()); - if (StringUtils.isNotEmpty(xtr.getNamespaceURI())) { - extensionElement.setNamespace(xtr.getNamespaceURI()); - } - if (StringUtils.isNotEmpty(xtr.getPrefix())) { - extensionElement.setNamespacePrefix(xtr.getPrefix()); - } - - for (int i = 0; i < xtr.getAttributeCount(); i++) { - ExtensionAttribute extensionAttribute = new ExtensionAttribute(); - extensionAttribute.setName(xtr.getAttributeLocalName(i)); - extensionAttribute.setValue(xtr.getAttributeValue(i)); - extensionAttribute.setNamespace(xtr.getAttributeNamespace(i)); - if (StringUtils.isNotEmpty(xtr.getAttributePrefix(i))) { - extensionAttribute.setNamespacePrefix(xtr.getAttributePrefix(i)); - } - extensionElement.addAttribute(extensionAttribute); - } - - boolean readyWithExtensionElement = false; - while (readyWithExtensionElement == false && xtr.hasNext()) { - xtr.next(); - if (xtr.isCharacters()) { - if (StringUtils.isNotEmpty(xtr.getText().trim())) { - extensionElement.setElementText(xtr.getText().trim()); - } - } else if (xtr.isStartElement()) { - ExtensionElement childExtensionElement = parseExtensionElement(xtr); - extensionElement.addChildElement(childExtensionElement); - } else if (xtr.isEndElement() && extensionElement.getName().equalsIgnoreCase(xtr.getLocalName())) { - readyWithExtensionElement = true; - } - } - return extensionElement; + BpmnXMLUtil.parseChildElements(elementName, parentElement, xtr, childParsers, model); } protected boolean parseAsync(XMLStreamReader xtr) { @@ -353,69 +236,6 @@ public abstract class BaseBpmnXMLConverter implements BpmnXMLConstants { // To XML converter convenience methods - protected void writeExtensionElement(ExtensionElement extensionElement, Map namespaceMap, XMLStreamWriter xtw) throws Exception { - if (StringUtils.isNotEmpty(extensionElement.getName())) { - Map localNamespaceMap = new HashMap(); - if (StringUtils.isNotEmpty(extensionElement.getNamespace())) { - if (StringUtils.isNotEmpty(extensionElement.getNamespacePrefix())) { - xtw.writeStartElement(extensionElement.getNamespacePrefix(), extensionElement.getName(), extensionElement.getNamespace()); - - if (namespaceMap.containsKey(extensionElement.getNamespacePrefix()) == false || - namespaceMap.get(extensionElement.getNamespacePrefix()).equals(extensionElement.getNamespace()) == false) { - - xtw.writeNamespace(extensionElement.getNamespacePrefix(), extensionElement.getNamespace()); - namespaceMap.put(extensionElement.getNamespacePrefix(), extensionElement.getNamespace()); - localNamespaceMap.put(extensionElement.getNamespacePrefix(), extensionElement.getNamespace()); - } - } else { - xtw.writeStartElement(extensionElement.getNamespace(), extensionElement.getName()); - } - } else { - xtw.writeStartElement(extensionElement.getName()); - } - - for (List attributes : extensionElement.getAttributes().values()) { - for (ExtensionAttribute attribute : attributes) { - if (StringUtils.isNotEmpty(attribute.getName()) && attribute.getValue() != null) { - if (StringUtils.isNotEmpty(attribute.getNamespace())) { - if (StringUtils.isNotEmpty(attribute.getNamespacePrefix())) { - - if (namespaceMap.containsKey(attribute.getNamespacePrefix()) == false || - namespaceMap.get(attribute.getNamespacePrefix()).equals(attribute.getNamespace()) == false) { - - xtw.writeNamespace(attribute.getNamespacePrefix(), attribute.getNamespace()); - namespaceMap.put(attribute.getNamespacePrefix(), attribute.getNamespace()); - } - - xtw.writeAttribute(attribute.getNamespacePrefix(), attribute.getNamespace(), attribute.getName(), attribute.getValue()); - } else { - xtw.writeAttribute(attribute.getNamespace(), attribute.getName(), attribute.getValue()); - } - } else { - xtw.writeAttribute(attribute.getName(), attribute.getValue()); - } - } - } - } - - if (extensionElement.getElementText() != null) { - xtw.writeCharacters(extensionElement.getElementText()); - } else { - for (List childElements : extensionElement.getChildElements().values()) { - for (ExtensionElement childElement : childElements) { - writeExtensionElement(childElement, namespaceMap, xtw); - } - } - } - - for (String prefix : localNamespaceMap.keySet()) { - namespaceMap.remove(prefix); - } - - xtw.writeEndElement(); - } - } - protected String convertToDelimitedString(List stringList) { return BpmnXMLUtil.convertToDelimitedString(stringList); } @@ -496,7 +316,10 @@ public abstract class BaseBpmnXMLConverter implements BpmnXMLConstants { protected void writeTimerDefinition(TimerEventDefinition timerDefinition, XMLStreamWriter xtw) throws Exception { xtw.writeStartElement(ELEMENT_EVENT_TIMERDEFINITION); - + boolean didWriteExtensionStartElement = BpmnXMLUtil.writeExtensionElements(timerDefinition, false, xtw); + if (didWriteExtensionStartElement) { + xtw.writeEndElement(); + } if (StringUtils.isNotEmpty(timerDefinition.getTimeDate())) { xtw.writeStartElement(ATTRIBUTE_TIMER_DATE); xtw.writeCharacters(timerDefinition.getTimeDate()); @@ -518,7 +341,11 @@ public abstract class BaseBpmnXMLConverter implements BpmnXMLConstants { protected void writeSignalDefinition(SignalEventDefinition signalDefinition, XMLStreamWriter xtw) throws Exception { xtw.writeStartElement(ELEMENT_EVENT_SIGNALDEFINITION); - writeDefaultAttribute(ATTRIBUTE_SIGNAL_REF, signalDefinition.getSignalRef(), xtw); + writeDefaultAttribute(ATTRIBUTE_SIGNAL_REF, signalDefinition.getSignalRef(), xtw); + boolean didWriteExtensionStartElement = BpmnXMLUtil.writeExtensionElements(signalDefinition, false, xtw); + if (didWriteExtensionStartElement) { + xtw.writeEndElement(); + } xtw.writeEndElement(); } @@ -541,18 +368,30 @@ public abstract class BaseBpmnXMLConverter implements BpmnXMLConstants { } } } - writeDefaultAttribute(ATTRIBUTE_MESSAGE_REF, messageRef, xtw); + writeDefaultAttribute(ATTRIBUTE_MESSAGE_REF, messageRef, xtw); + boolean didWriteExtensionStartElement = BpmnXMLUtil.writeExtensionElements(messageDefinition, false, xtw); + if (didWriteExtensionStartElement) { + xtw.writeEndElement(); + } xtw.writeEndElement(); } protected void writeErrorDefinition(ErrorEventDefinition errorDefinition, XMLStreamWriter xtw) throws Exception { xtw.writeStartElement(ELEMENT_EVENT_ERRORDEFINITION); - writeDefaultAttribute(ATTRIBUTE_ERROR_REF, errorDefinition.getErrorCode(), xtw); + writeDefaultAttribute(ATTRIBUTE_ERROR_REF, errorDefinition.getErrorCode(), xtw); + boolean didWriteExtensionStartElement = BpmnXMLUtil.writeExtensionElements(errorDefinition, false, xtw); + if (didWriteExtensionStartElement) { + xtw.writeEndElement(); + } xtw.writeEndElement(); } protected void writeTerminateDefinition(TerminateEventDefinition terminateDefinition, XMLStreamWriter xtw) throws Exception { xtw.writeStartElement(ELEMENT_EVENT_TERMINATEDEFINITION); + boolean didWriteExtensionStartElement = BpmnXMLUtil.writeExtensionElements(terminateDefinition, false, xtw); + if (didWriteExtensionStartElement) { + xtw.writeEndElement(); + } xtw.writeEndElement(); } diff --git a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/BpmnXMLConverter.java b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/BpmnXMLConverter.java index 8282d1cb5f812a61fda833b05a9ab6ad7357979a..9f2cdb106627f035c5214dd05a6e77bee3511958 100644 --- a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/BpmnXMLConverter.java +++ b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/BpmnXMLConverter.java @@ -39,7 +39,6 @@ import org.activiti.bpmn.constants.BpmnXMLConstants; import org.activiti.bpmn.converter.alfresco.AlfrescoStartEventXMLConverter; import org.activiti.bpmn.converter.alfresco.AlfrescoUserTaskXMLConverter; import org.activiti.bpmn.converter.child.DocumentationParser; -import org.activiti.bpmn.converter.child.ExecutionListenerParser; import org.activiti.bpmn.converter.child.IOSpecificationParser; import org.activiti.bpmn.converter.child.MultiInstanceParser; import org.activiti.bpmn.converter.export.ActivitiListenerExport; @@ -51,6 +50,7 @@ import org.activiti.bpmn.converter.export.ProcessExport; import org.activiti.bpmn.converter.export.SignalAndMessageDefinitionExport; import org.activiti.bpmn.converter.parser.BpmnEdgeParser; import org.activiti.bpmn.converter.parser.BpmnShapeParser; +import org.activiti.bpmn.converter.parser.ExtensionElementsParser; import org.activiti.bpmn.converter.parser.ImportParser; import org.activiti.bpmn.converter.parser.InterfaceParser; import org.activiti.bpmn.converter.parser.ItemDefinitionParser; @@ -60,6 +60,7 @@ import org.activiti.bpmn.converter.parser.PotentialStarterParser; import org.activiti.bpmn.converter.parser.ProcessParser; import org.activiti.bpmn.converter.parser.SignalParser; import org.activiti.bpmn.converter.parser.SubProcessParser; +import org.activiti.bpmn.converter.util.BpmnXMLUtil; import org.activiti.bpmn.converter.util.InputStreamProvider; import org.activiti.bpmn.exceptions.XMLException; import org.activiti.bpmn.model.Activity; @@ -313,6 +314,7 @@ public class BpmnXMLConverter implements BpmnXMLConstants { pool.setId(xtr.getAttributeValue(null, ATTRIBUTE_ID)); pool.setName(xtr.getAttributeValue(null, ATTRIBUTE_NAME)); pool.setProcessRef(xtr.getAttributeValue(null, ATTRIBUTE_PROCESS_REF)); + BpmnXMLUtil.parseChildElements(ELEMENT_PARTICIPANT, pool, xtr, model); model.getPools().add(pool); } @@ -327,7 +329,7 @@ public class BpmnXMLConverter implements BpmnXMLConstants { new PotentialStarterParser().parse(xtr, activeProcess); } else if (ELEMENT_LANE.equals(xtr.getLocalName())) { - new LaneParser().parse(xtr, activeProcess); + new LaneParser().parse(xtr, activeProcess, model); } else if (ELEMENT_DOCUMENTATION.equals(xtr.getLocalName())) { @@ -339,32 +341,24 @@ public class BpmnXMLConverter implements BpmnXMLConstants { } new DocumentationParser().parseChildElement(xtr, parentElement, model); + } else if (ELEMENT_EXTENSIONS.equals(xtr.getLocalName())) { + new ExtensionElementsParser().parse(xtr, activeSubProcessList, activeProcess, model); + } else if (ELEMENT_SUBPROCESS.equals(xtr.getLocalName())) { - new SubProcessParser().parse(xtr, activeSubProcessList, activeProcess); } else if (ELEMENT_TRANSACTION.equals(xtr.getLocalName())) { - new SubProcessParser().parse(xtr, activeSubProcessList, activeProcess); } else if (ELEMENT_DI_SHAPE.equals(xtr.getLocalName())) { - new BpmnShapeParser().parse(xtr, model); } else if (ELEMENT_DI_EDGE.equals(xtr.getLocalName())) { - new BpmnEdgeParser().parse(xtr, model); - } else if (activeSubProcessList.size() == 0 && ELEMENT_EXECUTION_LISTENER.equals(xtr.getLocalName())) { - - new ExecutionListenerParser().parseChildElement(xtr, activeProcess, model); - } else { - if (activeSubProcessList.size() > 0 && ELEMENT_EXECUTION_LISTENER.equalsIgnoreCase(xtr.getLocalName())) { - new ExecutionListenerParser().parseChildElement(xtr, activeSubProcessList.get(activeSubProcessList.size() - 1), model); - - } else if (activeSubProcessList.size() > 0 && ELEMENT_MULTIINSTANCE.equalsIgnoreCase(xtr.getLocalName())) { + if (activeSubProcessList.size() > 0 && ELEMENT_MULTIINSTANCE.equalsIgnoreCase(xtr.getLocalName())) { new MultiInstanceParser().parseChildElement(xtr, activeSubProcessList.get(activeSubProcessList.size() - 1), model); diff --git a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/CompensateEventDefinitionParser.java b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/CompensateEventDefinitionParser.java index bf5c0912a4d2c366223177b2c846b79bd2a24bf0..74e57db9f52880a7fc5887b21fd187270cede06d 100644 --- a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/CompensateEventDefinitionParser.java +++ b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/CompensateEventDefinitionParser.java @@ -40,6 +40,8 @@ public class CompensateEventDefinitionParser extends BaseChildElementParser { eventDefinition.setWaitForCompletion(Boolean.parseBoolean(xtr.getAttributeValue(null, ATTRIBUTE_COMPENSATE_WAITFORCOMPLETION))); } + BpmnXMLUtil.parseChildElements(ELEMENT_EVENT_COMPENSATEDEFINITION, eventDefinition, xtr, model); + ((Event) parentElement).getEventDefinitions().add(eventDefinition); } } diff --git a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/ErrorEventDefinitionParser.java b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/ErrorEventDefinitionParser.java index 79ee1347befdf67f656f6825c922924587a89af9..b03c256ddef07f9657379a658efe2cc91224a37d 100644 --- a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/ErrorEventDefinitionParser.java +++ b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/ErrorEventDefinitionParser.java @@ -41,6 +41,8 @@ public class ErrorEventDefinitionParser extends BaseChildElementParser { model.addProblem("errorRef is required for an error event", xtr); } + BpmnXMLUtil.parseChildElements(ELEMENT_EVENT_ERRORDEFINITION, eventDefinition, xtr, model); + ((Event) parentElement).getEventDefinitions().add(eventDefinition); } } diff --git a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/FlowNodeRefParser.java b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/FlowNodeRefParser.java new file mode 100644 index 0000000000000000000000000000000000000000..db0d243499e644fbe84ebb7c8f165d8f10a140b1 --- /dev/null +++ b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/FlowNodeRefParser.java @@ -0,0 +1,36 @@ +/* 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.activiti.bpmn.converter.child; + +import javax.xml.stream.XMLStreamReader; + +import org.activiti.bpmn.model.BaseElement; +import org.activiti.bpmn.model.BpmnModel; +import org.activiti.bpmn.model.Lane; + +/** + * @author Tijs Rademakers + */ +public class FlowNodeRefParser extends BaseChildElementParser { + + public String getElementName() { + return ATTRIBUTE_FLOWNODE_REF; + } + + public void parseChildElement(XMLStreamReader xtr, BaseElement parentElement, BpmnModel model) throws Exception { + if (parentElement instanceof Lane == false) return; + + Lane lane = (Lane) parentElement; + lane.getFlowReferences().add(xtr.getElementText()); + } +} diff --git a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/MessageEventDefinitionParser.java b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/MessageEventDefinitionParser.java index a758f43721b618720bc06a0fb15d1797a2f645f0..52a81f3794eeacae0c0a265afc48bf7908b9dee4 100644 --- a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/MessageEventDefinitionParser.java +++ b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/MessageEventDefinitionParser.java @@ -54,6 +54,9 @@ public class MessageEventDefinitionParser extends BaseChildElementParser { model.addProblem("Invalid 'messageRef': no message with id '" + eventDefinition.getMessageRef() + "' found.", xtr); } } + + BpmnXMLUtil.parseChildElements(ELEMENT_EVENT_MESSAGEDEFINITION, eventDefinition, xtr, model); + ((Event) parentElement).getEventDefinitions().add(eventDefinition); } } diff --git a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/SignalEventDefinitionParser.java b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/SignalEventDefinitionParser.java index 881bb3577037b5286342c0790f4a1476a3dfa242..fb813980b07cf1134b1780254ea0e6b6ff532f98 100644 --- a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/SignalEventDefinitionParser.java +++ b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/SignalEventDefinitionParser.java @@ -44,6 +44,8 @@ public class SignalEventDefinitionParser extends BaseChildElementParser { model.addProblem("signalEventDefinition does not have required property 'signalRef'", xtr); } + BpmnXMLUtil.parseChildElements(ELEMENT_EVENT_SIGNALDEFINITION, eventDefinition, xtr, model); + ((Event) parentElement).getEventDefinitions().add(eventDefinition); } } diff --git a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/TerminateEventDefinitionParser.java b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/TerminateEventDefinitionParser.java index bdfef42115dafe861878f3f707e90302105e0a33..b8481a06268d40aa96dd4b4fa95a6970e6375b38 100644 --- a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/TerminateEventDefinitionParser.java +++ b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/TerminateEventDefinitionParser.java @@ -35,6 +35,9 @@ public class TerminateEventDefinitionParser extends BaseChildElementParser { TerminateEventDefinition eventDefinition = new TerminateEventDefinition(); BpmnXMLUtil.addXMLLocation(eventDefinition, xtr); + + BpmnXMLUtil.parseChildElements(ELEMENT_EVENT_TERMINATEDEFINITION, eventDefinition, xtr, model); + ((Event) parentElement).getEventDefinitions().add(eventDefinition); } } diff --git a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/TimeCycleParser.java b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/TimeCycleParser.java new file mode 100644 index 0000000000000000000000000000000000000000..bfd027590af07d8c0b189d64a759095eb4f9f593 --- /dev/null +++ b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/TimeCycleParser.java @@ -0,0 +1,36 @@ +/* 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.activiti.bpmn.converter.child; + +import javax.xml.stream.XMLStreamReader; + +import org.activiti.bpmn.model.BaseElement; +import org.activiti.bpmn.model.BpmnModel; +import org.activiti.bpmn.model.TimerEventDefinition; + +/** + * @author Tijs Rademakers + */ +public class TimeCycleParser extends BaseChildElementParser { + + public String getElementName() { + return ATTRIBUTE_TIMER_CYCLE; + } + + public void parseChildElement(XMLStreamReader xtr, BaseElement parentElement, BpmnModel model) throws Exception { + if (parentElement instanceof TimerEventDefinition == false) return; + + TimerEventDefinition eventDefinition = (TimerEventDefinition) parentElement; + eventDefinition.setTimeCycle(xtr.getElementText()); + } +} diff --git a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/TimeDateParser.java b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/TimeDateParser.java new file mode 100644 index 0000000000000000000000000000000000000000..ad841a302955f8dcbe18943022f0f73b72d3cc92 --- /dev/null +++ b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/TimeDateParser.java @@ -0,0 +1,36 @@ +/* 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.activiti.bpmn.converter.child; + +import javax.xml.stream.XMLStreamReader; + +import org.activiti.bpmn.model.BaseElement; +import org.activiti.bpmn.model.BpmnModel; +import org.activiti.bpmn.model.TimerEventDefinition; + +/** + * @author Tijs Rademakers + */ +public class TimeDateParser extends BaseChildElementParser { + + public String getElementName() { + return ATTRIBUTE_TIMER_DATE; + } + + public void parseChildElement(XMLStreamReader xtr, BaseElement parentElement, BpmnModel model) throws Exception { + if (parentElement instanceof TimerEventDefinition == false) return; + + TimerEventDefinition eventDefinition = (TimerEventDefinition) parentElement; + eventDefinition.setTimeDate(xtr.getElementText()); + } +} diff --git a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/TimeDurationParser.java b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/TimeDurationParser.java new file mode 100644 index 0000000000000000000000000000000000000000..d60d30f285c0b478dc19dff81a6932f679e2b1f2 --- /dev/null +++ b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/TimeDurationParser.java @@ -0,0 +1,36 @@ +/* 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.activiti.bpmn.converter.child; + +import javax.xml.stream.XMLStreamReader; + +import org.activiti.bpmn.model.BaseElement; +import org.activiti.bpmn.model.BpmnModel; +import org.activiti.bpmn.model.TimerEventDefinition; + +/** + * @author Tijs Rademakers + */ +public class TimeDurationParser extends BaseChildElementParser { + + public String getElementName() { + return ATTRIBUTE_TIMER_DURATION; + } + + public void parseChildElement(XMLStreamReader xtr, BaseElement parentElement, BpmnModel model) throws Exception { + if (parentElement instanceof TimerEventDefinition == false) return; + + TimerEventDefinition eventDefinition = (TimerEventDefinition) parentElement; + eventDefinition.setTimeDuration(xtr.getElementText()); + } +} diff --git a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/TimerEventDefinitionParser.java b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/TimerEventDefinitionParser.java index 3fd232a0e7d1b4170ea2b248e5161f67669c8597..a4bdb72d468128a64340f190f54b4bf9a51b36f9 100644 --- a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/TimerEventDefinitionParser.java +++ b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/child/TimerEventDefinitionParser.java @@ -34,28 +34,7 @@ public class TimerEventDefinitionParser extends BaseChildElementParser { TimerEventDefinition eventDefinition = new TimerEventDefinition(); BpmnXMLUtil.addXMLLocation(eventDefinition, xtr); - try { - while (xtr.hasNext()) { - xtr.next(); - if (xtr.isStartElement() && ATTRIBUTE_TIMER_DURATION.equalsIgnoreCase(xtr.getLocalName())) { - eventDefinition.setTimeDuration(xtr.getElementText()); - break; - - } else if (xtr.isStartElement() && ATTRIBUTE_TIMER_DATE.equalsIgnoreCase(xtr.getLocalName())) { - eventDefinition.setTimeDate(xtr.getElementText()); - break; - - } else if (xtr.isStartElement() && ATTRIBUTE_TIMER_CYCLE.equalsIgnoreCase(xtr.getLocalName())) { - eventDefinition.setTimeCycle(xtr.getElementText()); - break; - - } else if (xtr.isEndElement() && ELEMENT_EVENT_TIMERDEFINITION.equalsIgnoreCase(xtr.getLocalName())) { - break; - } - } - } catch (Exception e) { - LOGGER.warn("Error parsing timer event definition", e); - } + BpmnXMLUtil.parseChildElements(ELEMENT_EVENT_TIMERDEFINITION, eventDefinition, xtr, model); ((Event) parentElement).getEventDefinitions().add(eventDefinition); } diff --git a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/export/ProcessExport.java b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/export/ProcessExport.java index abeee5808ae1b90588e51cdf14a25ffdb6f01ce9..2ac7a7ef73196877d8f6b6a0d65ded521de2ba6c 100644 --- a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/export/ProcessExport.java +++ b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/export/ProcessExport.java @@ -49,8 +49,10 @@ public class ProcessExport implements BpmnXMLConstants { xtw.writeEndElement(); } - boolean wroteListener = ActivitiListenerExport.writeListeners(process, false, xtw); - if (wroteListener) { + boolean didWriteExtensionStartElement = ActivitiListenerExport.writeListeners(process, false, xtw); + didWriteExtensionStartElement = BpmnXMLUtil.writeExtensionElements(process, didWriteExtensionStartElement, xtw); + + if (didWriteExtensionStartElement) { // closing extensions element xtw.writeEndElement(); } diff --git a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/parser/ExtensionElementsParser.java b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/parser/ExtensionElementsParser.java new file mode 100644 index 0000000000000000000000000000000000000000..ed36a78f07c7eb62104158b26db1edccd5226eba --- /dev/null +++ b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/parser/ExtensionElementsParser.java @@ -0,0 +1,60 @@ +/* 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.activiti.bpmn.converter.parser; + +import java.util.List; + +import javax.xml.stream.XMLStreamReader; + +import org.activiti.bpmn.constants.BpmnXMLConstants; +import org.activiti.bpmn.converter.child.ExecutionListenerParser; +import org.activiti.bpmn.converter.util.BpmnXMLUtil; +import org.activiti.bpmn.model.BaseElement; +import org.activiti.bpmn.model.BpmnModel; +import org.activiti.bpmn.model.ExtensionElement; +import org.activiti.bpmn.model.Process; +import org.activiti.bpmn.model.SubProcess; + +/** + * @author Tijs Rademakers + */ +public class ExtensionElementsParser implements BpmnXMLConstants { + + public void parse(XMLStreamReader xtr, List activeSubProcessList, Process activeProcess, BpmnModel model) throws Exception { + BaseElement parentElement = null; + if (activeSubProcessList.size() > 0) { + parentElement = activeSubProcessList.get(activeSubProcessList.size() - 1); + + } else { + parentElement = activeProcess; + } + + boolean readyWithChildElements = false; + while (readyWithChildElements == false && xtr.hasNext()) { + xtr.next(); + if (xtr.isStartElement()) { + if (ELEMENT_EXECUTION_LISTENER.equals(xtr.getLocalName())) { + new ExecutionListenerParser().parseChildElement(xtr, activeProcess, model); + } else { + ExtensionElement extensionElement = BpmnXMLUtil.parseExtensionElement(xtr); + parentElement.addExtensionElement(extensionElement); + } + + } else if (xtr.isEndElement()) { + if (ELEMENT_EXTENSIONS.equals(xtr.getLocalName())) { + readyWithChildElements = true; + } + } + } + } +} diff --git a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/parser/ItemDefinitionParser.java b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/parser/ItemDefinitionParser.java index c5872d3587912d1a9de9fdc400be4fcd1d6af092..3ee0000810fb91bd92370b8a67a013849e0c8a00 100644 --- a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/parser/ItemDefinitionParser.java +++ b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/parser/ItemDefinitionParser.java @@ -45,6 +45,7 @@ public class ItemDefinitionParser implements BpmnXMLConstants { item.setStructureRef(structureRef); item.setItemKind(xtr.getAttributeValue(null, ATTRIBUTE_ITEM_KIND)); + BpmnXMLUtil.parseChildElements(ELEMENT_ITEM_DEFINITION, item, xtr, model); model.addItemDefinition(itemDefinitionId, item); } } diff --git a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/parser/LaneParser.java b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/parser/LaneParser.java index 65bd894334396b3797ac8921e61bbf353ce27c00..be0145661dd1f62547d764a024f37d2df4ce7a3e 100644 --- a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/parser/LaneParser.java +++ b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/parser/LaneParser.java @@ -16,6 +16,7 @@ import javax.xml.stream.XMLStreamReader; import org.activiti.bpmn.constants.BpmnXMLConstants; import org.activiti.bpmn.converter.util.BpmnXMLUtil; +import org.activiti.bpmn.model.BpmnModel; import org.activiti.bpmn.model.Lane; import org.activiti.bpmn.model.Process; @@ -24,21 +25,13 @@ import org.activiti.bpmn.model.Process; */ public class LaneParser implements BpmnXMLConstants { - public void parse(XMLStreamReader xtr, Process activeProcess) throws Exception { + public void parse(XMLStreamReader xtr, Process activeProcess, BpmnModel model) throws Exception { Lane lane = new Lane(); BpmnXMLUtil.addXMLLocation(lane, xtr); lane.setId(xtr.getAttributeValue(null, ATTRIBUTE_ID)); lane.setName(xtr.getAttributeValue(null, ATTRIBUTE_NAME)); lane.setParentProcess(activeProcess); activeProcess.getLanes().add(lane); - - while (xtr.hasNext()) { - xtr.next(); - if (xtr.isStartElement() && ATTRIBUTE_FLOWNODE_REF.equalsIgnoreCase(xtr.getLocalName())) { - lane.getFlowReferences().add(xtr.getElementText()); - } else if(xtr.isEndElement() && ELEMENT_LANE.equalsIgnoreCase(xtr.getLocalName())) { - break; - } - } + BpmnXMLUtil.parseChildElements(ELEMENT_LANE, lane, xtr, model); } } diff --git a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/parser/MessageParser.java b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/parser/MessageParser.java index 1810fda0fa41aaa414fb6ff7609520c92bfba709..82bd6d57f215594c708223b21afbfd2750c9193a 100644 --- a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/parser/MessageParser.java +++ b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/parser/MessageParser.java @@ -32,6 +32,7 @@ public class MessageParser implements BpmnXMLConstants { String itemRef = parseItemRef(xtr.getAttributeValue(null, ATTRIBUTE_ITEM_REF), model); Message message = new Message(messageId, messageName, itemRef); BpmnXMLUtil.addXMLLocation(message, xtr); + BpmnXMLUtil.parseChildElements(ELEMENT_MESSAGE, message, xtr, model); model.addMessage(message); } } diff --git a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/parser/SignalParser.java b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/parser/SignalParser.java index 36de45c7187d05841fbba928450758402ba8edab..b63e54aa61d20525204c8b17024c92fb009be8e7 100644 --- a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/parser/SignalParser.java +++ b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/parser/SignalParser.java @@ -52,6 +52,7 @@ public class SignalParser implements BpmnXMLConstants { } BpmnXMLUtil.addXMLLocation(signal, xtr); + BpmnXMLUtil.parseChildElements(ELEMENT_SIGNAL, signal, xtr, model); model.addSignal(signal); } } diff --git a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/util/BpmnXMLUtil.java b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/util/BpmnXMLUtil.java index 525b2802795e786dd59cd4127c3d38766f6742f7..daf53101ad7eda1e63a38ec0e2d370989b72f53d 100644 --- a/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/util/BpmnXMLUtil.java +++ b/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter/util/BpmnXMLUtil.java @@ -2,18 +2,75 @@ package org.activiti.bpmn.converter.util; import java.text.StringCharacterIterator; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.xml.stream.Location; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; import org.activiti.bpmn.constants.BpmnXMLConstants; +import org.activiti.bpmn.converter.child.BaseChildElementParser; +import org.activiti.bpmn.converter.child.CancelEventDefinitionParser; +import org.activiti.bpmn.converter.child.CompensateEventDefinitionParser; +import org.activiti.bpmn.converter.child.ConditionExpressionParser; +import org.activiti.bpmn.converter.child.DataInputAssociationParser; +import org.activiti.bpmn.converter.child.DataOutputAssociationParser; +import org.activiti.bpmn.converter.child.DocumentationParser; +import org.activiti.bpmn.converter.child.ErrorEventDefinitionParser; +import org.activiti.bpmn.converter.child.ExecutionListenerParser; +import org.activiti.bpmn.converter.child.FieldExtensionParser; +import org.activiti.bpmn.converter.child.FlowNodeRefParser; +import org.activiti.bpmn.converter.child.FormPropertyParser; +import org.activiti.bpmn.converter.child.IOSpecificationParser; +import org.activiti.bpmn.converter.child.MessageEventDefinitionParser; +import org.activiti.bpmn.converter.child.MultiInstanceParser; +import org.activiti.bpmn.converter.child.SignalEventDefinitionParser; +import org.activiti.bpmn.converter.child.TaskListenerParser; +import org.activiti.bpmn.converter.child.TerminateEventDefinitionParser; +import org.activiti.bpmn.converter.child.TimeCycleParser; +import org.activiti.bpmn.converter.child.TimeDateParser; +import org.activiti.bpmn.converter.child.TimeDurationParser; +import org.activiti.bpmn.converter.child.TimerEventDefinitionParser; import org.activiti.bpmn.model.BaseElement; +import org.activiti.bpmn.model.BpmnModel; +import org.activiti.bpmn.model.ExtensionAttribute; +import org.activiti.bpmn.model.ExtensionElement; import org.activiti.bpmn.model.GraphicInfo; import org.apache.commons.lang3.StringUtils; public class BpmnXMLUtil implements BpmnXMLConstants { + + private static Map genericChildParserMap = new HashMap(); + + static { + addGenericParser(new CancelEventDefinitionParser()); + addGenericParser(new CompensateEventDefinitionParser()); + addGenericParser(new ConditionExpressionParser()); + addGenericParser(new DataInputAssociationParser()); + addGenericParser(new DataOutputAssociationParser()); + addGenericParser(new DocumentationParser()); + addGenericParser(new ErrorEventDefinitionParser()); + addGenericParser(new ExecutionListenerParser()); + addGenericParser(new FieldExtensionParser()); + addGenericParser(new FormPropertyParser()); + addGenericParser(new IOSpecificationParser()); + addGenericParser(new MessageEventDefinitionParser()); + addGenericParser(new MultiInstanceParser()); + addGenericParser(new SignalEventDefinitionParser()); + addGenericParser(new TaskListenerParser()); + addGenericParser(new TerminateEventDefinitionParser()); + addGenericParser(new TimerEventDefinitionParser()); + addGenericParser(new TimeDateParser()); + addGenericParser(new TimeCycleParser()); + addGenericParser(new TimeDurationParser()); + addGenericParser(new FlowNodeRefParser()); + } + + private static void addGenericParser(BaseChildElementParser parser) { + genericChildParserMap.put(parser.getElementName(), parser); + } public static void addXMLLocation(BaseElement element, XMLStreamReader xtr) { Location location = xtr.getLocation(); @@ -27,6 +84,80 @@ public class BpmnXMLUtil implements BpmnXMLConstants { graphicInfo.setXmlColumnNumber(location.getColumnNumber()); } + public static void parseChildElements(String elementName, BaseElement parentElement, XMLStreamReader xtr, BpmnModel model) throws Exception { + parseChildElements(elementName, parentElement, xtr, null, model); + } + + public static void parseChildElements(String elementName, BaseElement parentElement, XMLStreamReader xtr, + Map childParsers, BpmnModel model) throws Exception { + + if (childParsers == null) { + childParsers = new HashMap(); + } + childParsers.putAll(genericChildParserMap); + + boolean inExtensionElements = false; + boolean readyWithChildElements = false; + while (readyWithChildElements == false && xtr.hasNext()) { + xtr.next(); + if (xtr.isStartElement()) { + if (ELEMENT_EXTENSIONS.equals(xtr.getLocalName())) { + inExtensionElements = true; + } else if (childParsers.containsKey(xtr.getLocalName())) { + childParsers.get(xtr.getLocalName()).parseChildElement(xtr, parentElement, model); + } else if (inExtensionElements) { + ExtensionElement extensionElement = BpmnXMLUtil.parseExtensionElement(xtr); + parentElement.addExtensionElement(extensionElement); + } + + } else if (xtr.isEndElement()) { + if (ELEMENT_EXTENSIONS.equals(xtr.getLocalName())) { + inExtensionElements = false; + } else if (elementName.equalsIgnoreCase(xtr.getLocalName())) { + readyWithChildElements = true; + } + } + } + } + + public static ExtensionElement parseExtensionElement(XMLStreamReader xtr) throws Exception { + ExtensionElement extensionElement = new ExtensionElement(); + extensionElement.setName(xtr.getLocalName()); + if (StringUtils.isNotEmpty(xtr.getNamespaceURI())) { + extensionElement.setNamespace(xtr.getNamespaceURI()); + } + if (StringUtils.isNotEmpty(xtr.getPrefix())) { + extensionElement.setNamespacePrefix(xtr.getPrefix()); + } + + for (int i = 0; i < xtr.getAttributeCount(); i++) { + ExtensionAttribute extensionAttribute = new ExtensionAttribute(); + extensionAttribute.setName(xtr.getAttributeLocalName(i)); + extensionAttribute.setValue(xtr.getAttributeValue(i)); + extensionAttribute.setNamespace(xtr.getAttributeNamespace(i)); + if (StringUtils.isNotEmpty(xtr.getAttributePrefix(i))) { + extensionAttribute.setNamespacePrefix(xtr.getAttributePrefix(i)); + } + extensionElement.addAttribute(extensionAttribute); + } + + boolean readyWithExtensionElement = false; + while (readyWithExtensionElement == false && xtr.hasNext()) { + xtr.next(); + if (xtr.isCharacters()) { + if (StringUtils.isNotEmpty(xtr.getText().trim())) { + extensionElement.setElementText(xtr.getText().trim()); + } + } else if (xtr.isStartElement()) { + ExtensionElement childExtensionElement = parseExtensionElement(xtr); + extensionElement.addChildElement(childExtensionElement); + } else if (xtr.isEndElement() && extensionElement.getName().equalsIgnoreCase(xtr.getLocalName())) { + readyWithExtensionElement = true; + } + } + return extensionElement; + } + public static void writeDefaultAttribute(String attributeName, String value, XMLStreamWriter xtw) throws Exception { if (StringUtils.isNotEmpty(value) && "null".equalsIgnoreCase(value) == false) { xtw.writeAttribute(attributeName, value); @@ -39,6 +170,85 @@ public class BpmnXMLUtil implements BpmnXMLConstants { } } + public static boolean writeExtensionElements(BaseElement baseElement, boolean didWriteExtensionStartElement, XMLStreamWriter xtw) throws Exception { + if (baseElement.getExtensionElements().size() > 0) { + if (didWriteExtensionStartElement == false) { + xtw.writeStartElement(ELEMENT_EXTENSIONS); + didWriteExtensionStartElement = true; + } + Map namespaceMap = new HashMap(); + for (List extensionElements : baseElement.getExtensionElements().values()) { + for (ExtensionElement extensionElement : extensionElements) { + writeExtensionElement(extensionElement, namespaceMap, xtw); + } + } + } + return didWriteExtensionStartElement; + } + + protected static void writeExtensionElement(ExtensionElement extensionElement, Map namespaceMap, XMLStreamWriter xtw) throws Exception { + if (StringUtils.isNotEmpty(extensionElement.getName())) { + Map localNamespaceMap = new HashMap(); + if (StringUtils.isNotEmpty(extensionElement.getNamespace())) { + if (StringUtils.isNotEmpty(extensionElement.getNamespacePrefix())) { + xtw.writeStartElement(extensionElement.getNamespacePrefix(), extensionElement.getName(), extensionElement.getNamespace()); + + if (namespaceMap.containsKey(extensionElement.getNamespacePrefix()) == false || + namespaceMap.get(extensionElement.getNamespacePrefix()).equals(extensionElement.getNamespace()) == false) { + + xtw.writeNamespace(extensionElement.getNamespacePrefix(), extensionElement.getNamespace()); + namespaceMap.put(extensionElement.getNamespacePrefix(), extensionElement.getNamespace()); + localNamespaceMap.put(extensionElement.getNamespacePrefix(), extensionElement.getNamespace()); + } + } else { + xtw.writeStartElement(extensionElement.getNamespace(), extensionElement.getName()); + } + } else { + xtw.writeStartElement(extensionElement.getName()); + } + + for (List attributes : extensionElement.getAttributes().values()) { + for (ExtensionAttribute attribute : attributes) { + if (StringUtils.isNotEmpty(attribute.getName()) && attribute.getValue() != null) { + if (StringUtils.isNotEmpty(attribute.getNamespace())) { + if (StringUtils.isNotEmpty(attribute.getNamespacePrefix())) { + + if (namespaceMap.containsKey(attribute.getNamespacePrefix()) == false || + namespaceMap.get(attribute.getNamespacePrefix()).equals(attribute.getNamespace()) == false) { + + xtw.writeNamespace(attribute.getNamespacePrefix(), attribute.getNamespace()); + namespaceMap.put(attribute.getNamespacePrefix(), attribute.getNamespace()); + } + + xtw.writeAttribute(attribute.getNamespacePrefix(), attribute.getNamespace(), attribute.getName(), attribute.getValue()); + } else { + xtw.writeAttribute(attribute.getNamespace(), attribute.getName(), attribute.getValue()); + } + } else { + xtw.writeAttribute(attribute.getName(), attribute.getValue()); + } + } + } + } + + if (extensionElement.getElementText() != null) { + xtw.writeCharacters(extensionElement.getElementText()); + } else { + for (List childElements : extensionElement.getChildElements().values()) { + for (ExtensionElement childElement : childElements) { + writeExtensionElement(childElement, namespaceMap, xtw); + } + } + } + + for (String prefix : localNamespaceMap.keySet()) { + namespaceMap.remove(prefix); + } + + xtw.writeEndElement(); + } + } + public static List parseDelimitedList(String s) { List result = new ArrayList(); if (StringUtils.isNotEmpty(s)) { diff --git a/modules/activiti-bpmn-converter/src/test/java/org/activiti/editor/language/xml/CustomExtensionsConverterTest.java b/modules/activiti-bpmn-converter/src/test/java/org/activiti/editor/language/xml/CustomExtensionsConverterTest.java index c719e3a5f33b079dce3012a54a9351afd5152f1d..d3782588e99ad7af64dbfe5d202a6944475461f3 100644 --- a/modules/activiti-bpmn-converter/src/test/java/org/activiti/editor/language/xml/CustomExtensionsConverterTest.java +++ b/modules/activiti-bpmn-converter/src/test/java/org/activiti/editor/language/xml/CustomExtensionsConverterTest.java @@ -9,6 +9,7 @@ import java.util.List; import java.util.Map; import org.activiti.bpmn.model.ActivitiListener; +import org.activiti.bpmn.model.BoundaryEvent; import org.activiti.bpmn.model.BpmnModel; import org.activiti.bpmn.model.ExtensionAttribute; import org.activiti.bpmn.model.ExtensionElement; @@ -16,12 +17,13 @@ import org.activiti.bpmn.model.FieldExtension; import org.activiti.bpmn.model.FlowElement; import org.activiti.bpmn.model.ImplementationType; import org.activiti.bpmn.model.ServiceTask; +import org.activiti.bpmn.model.TimerEventDefinition; import org.junit.Test; public class CustomExtensionsConverterTest extends AbstractConverterTest { @Test - public void connvertXMLToModel() throws Exception { + public void convertXMLToModel() throws Exception { BpmnModel bpmnModel = readXMLFile(); validateModel(bpmnModel); } @@ -39,6 +41,11 @@ public class CustomExtensionsConverterTest extends AbstractConverterTest { } private void validateModel(BpmnModel model) { + List listeners = model.getMainProcess().getExecutionListeners(); + validateExecutionListeners(listeners); + Map> extensionElementMap = model.getMainProcess().getExtensionElements(); + validateExtensionElements(extensionElementMap); + FlowElement flowElement = model.getMainProcess().getFlowElement("servicetask"); assertNotNull(flowElement); assertTrue(flowElement instanceof ServiceTask); @@ -56,7 +63,22 @@ public class CustomExtensionsConverterTest extends AbstractConverterTest { assertEquals("testField2", field.getFieldName()); assertEquals("${test}", field.getExpression()); - List listeners = serviceTask.getExecutionListeners(); + listeners = serviceTask.getExecutionListeners(); + validateExecutionListeners(listeners); + + extensionElementMap = serviceTask.getExtensionElements(); + validateExtensionElements(extensionElementMap); + + assertEquals(1, serviceTask.getBoundaryEvents().size()); + BoundaryEvent boundaryEvent = serviceTask.getBoundaryEvents().get(0); + assertEquals("timerEvent", boundaryEvent.getId()); + assertEquals(1, boundaryEvent.getEventDefinitions().size()); + assertTrue(boundaryEvent.getEventDefinitions().get(0) instanceof TimerEventDefinition); + extensionElementMap = boundaryEvent.getEventDefinitions().get(0).getExtensionElements(); + validateExtensionElements(extensionElementMap); + } + + protected void validateExecutionListeners(List listeners) { assertEquals(3, listeners.size()); ActivitiListener listener = (ActivitiListener) listeners.get(0); assertTrue(ImplementationType.IMPLEMENTATION_TYPE_CLASS.equals(listener.getImplementationType())); @@ -70,8 +92,9 @@ public class CustomExtensionsConverterTest extends AbstractConverterTest { assertTrue(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equals(listener.getImplementationType())); assertEquals("${delegateExpression}", listener.getImplementation()); assertEquals("start", listener.getEvent()); - - Map> extensionElementMap = serviceTask.getExtensionElements(); + } + + protected void validateExtensionElements(Map> extensionElementMap ) { assertEquals(1, extensionElementMap.size()); List extensionElements = extensionElementMap.get("test"); diff --git a/modules/activiti-bpmn-converter/src/test/java/org/activiti/editor/language/xml/InCompleteSignalConverterTest.java b/modules/activiti-bpmn-converter/src/test/java/org/activiti/editor/language/xml/InCompleteSignalConverterTest.java index f373247054aee09a9d129aef7cf986a58c42db6b..a7b67dd797fdbb45d9ebfbeb20f2d0b0c3880a50 100644 --- a/modules/activiti-bpmn-converter/src/test/java/org/activiti/editor/language/xml/InCompleteSignalConverterTest.java +++ b/modules/activiti-bpmn-converter/src/test/java/org/activiti/editor/language/xml/InCompleteSignalConverterTest.java @@ -33,6 +33,5 @@ public class InCompleteSignalConverterTest extends AbstractConverterTest { List problems = model.getProblems(); assertNotNull(problems); assertEquals(1, problems.size()); - System.out.println(problems.get(0)); } } diff --git a/modules/activiti-bpmn-converter/src/test/resources/customextensionsmodel.bpmn b/modules/activiti-bpmn-converter/src/test/resources/customextensionsmodel.bpmn index 4a56effb96998330a218792619d4190085aea08f..53b4e658cefc9552fa9bad5330fff4b547305fbc 100644 --- a/modules/activiti-bpmn-converter/src/test/resources/customextensionsmodel.bpmn +++ b/modules/activiti-bpmn-converter/src/test/resources/customextensionsmodel.bpmn @@ -4,6 +4,19 @@ 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="http://www.activiti.org/test"> + + + + + + + test + + + + + + @@ -23,6 +36,21 @@ + + + + + + test + + + + + + + ${cronExpression} + + diff --git a/modules/activiti-engine/src/test/java/org/activiti/examples/task/StandaloneTaskTest.java b/modules/activiti-engine/src/test/java/org/activiti/examples/task/StandaloneTaskTest.java index 7c8c16b4f89c07526c4a45a05c12158a0d319a35..12df5c7510b069380ea500cb26449f324b698e23 100644 --- a/modules/activiti-engine/src/test/java/org/activiti/examples/task/StandaloneTaskTest.java +++ b/modules/activiti-engine/src/test/java/org/activiti/examples/task/StandaloneTaskTest.java @@ -48,15 +48,21 @@ public class StandaloneTaskTest extends PluggableActivitiTestCase { taskService.addCandidateUser(taskId, "kermit"); taskService.addCandidateUser(taskId, "gonzo"); - // Retrieve task list for jbarrez + // Retrieve task list for kermit List tasks = taskService.createTaskQuery().taskCandidateUser("kermit").list(); assertEquals(1, tasks.size()); assertEquals("testTask", tasks.get(0).getName()); - // Retrieve task list for tbaeyens + // Retrieve task list for gonzo tasks = taskService.createTaskQuery().taskCandidateUser("gonzo").list(); assertEquals(1, tasks.size()); assertEquals("testTask", tasks.get(0).getName()); + + task.setName("Update name"); + taskService.saveTask(task); + tasks = taskService.createTaskQuery().taskCandidateUser("kermit").list(); + assertEquals(1, tasks.size()); + assertEquals("Update name", tasks.get(0).getName()); // Claim task taskService.claim(taskId, "kermit");