Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.jbpm.bpmn2.xml.BoundaryEventHandler Maven / Gradle / Ivy
/**
* Copyright 2010 Red Hat, Inc. and/or its affiliates.
*
* 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.jbpm.bpmn2.xml;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.drools.compiler.compiler.xml.XmlDumper;
import org.drools.core.xml.ExtensibleXmlParser;
import org.jbpm.bpmn2.core.Error;
import org.jbpm.bpmn2.core.Escalation;
import org.jbpm.bpmn2.core.ItemDefinition;
import org.jbpm.bpmn2.core.Message;
import org.jbpm.bpmn2.core.Signal;
import org.jbpm.compiler.xml.ProcessBuildData;
import org.jbpm.process.core.event.EventFilter;
import org.jbpm.process.core.event.EventTransformerImpl;
import org.jbpm.process.core.event.EventTypeFilter;
import org.jbpm.process.core.event.NonAcceptingEventTypeFilter;
import org.jbpm.process.core.impl.DataTransformerRegistry;
import org.jbpm.ruleflow.core.RuleFlowProcess;
import org.jbpm.workflow.core.Node;
import org.jbpm.workflow.core.NodeContainer;
import org.jbpm.workflow.core.node.BoundaryEventNode;
import org.jbpm.workflow.core.node.EventNode;
import org.jbpm.workflow.core.node.Transformation;
import org.kie.api.runtime.process.DataTransformer;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
public class BoundaryEventHandler extends AbstractNodeHandler {
private DataTransformerRegistry transformerRegistry = DataTransformerRegistry.get();
protected Node createNode(Attributes attrs) {
return new BoundaryEventNode();
}
@SuppressWarnings("unchecked")
public Class generateNodeFor() {
return BoundaryEventNode.class;
}
public Object end(final String uri, final String localName,
final ExtensibleXmlParser parser) throws SAXException {
final Element element = parser.endElementBuilder();
Node node = (Node) parser.getCurrent();
String attachedTo = element.getAttribute("attachedToRef");
Attr cancelActivityAttr = element.getAttributeNode("cancelActivity");
boolean cancelActivity = Boolean.parseBoolean(cancelActivityAttr.getValue());
// determine type of event definition, so the correct type of node can be generated
org.w3c.dom.Node xmlNode = element.getFirstChild();
while (xmlNode != null) {
String nodeName = xmlNode.getNodeName();
if ("escalationEventDefinition".equals(nodeName)) {
// reuse already created EventNode
handleEscalationNode(node, element, uri, localName, parser, attachedTo, cancelActivity);
break;
} else if ("errorEventDefinition".equals(nodeName)) {
// reuse already created EventNode
handleErrorNode(node, element, uri, localName, parser, attachedTo, cancelActivity);
break;
} else if ("timerEventDefinition".equals(nodeName)) {
// reuse already created EventNode
handleTimerNode(node, element, uri, localName, parser, attachedTo, cancelActivity);
break;
} else if ("compensateEventDefinition".equals(nodeName)) {
// reuse already created EventNode
handleCompensationNode(node, element, uri, localName, parser, attachedTo, cancelActivity);
break;
} else if ("signalEventDefinition".equals(nodeName)) {
// reuse already created EventNode
handleSignalNode(node, element, uri, localName, parser, attachedTo, cancelActivity);
break;
} else if ("conditionalEventDefinition".equals(nodeName)) {
handleConditionNode(node, element, uri, localName, parser, attachedTo, cancelActivity);
break;
} else if ("messageEventDefinition".equals(nodeName)) {
handleMessageNode(node, element, uri, localName, parser, attachedTo, cancelActivity);
break;
}
xmlNode = xmlNode.getNextSibling();
}
NodeContainer nodeContainer = (NodeContainer) parser.getParent();
nodeContainer.addNode(node);
((ProcessBuildData) parser.getData()).addNode(node);
return node;
}
@SuppressWarnings("unchecked")
protected void handleEscalationNode(final Node node, final Element element, final String uri,
final String localName, final ExtensibleXmlParser parser, final String attachedTo,
final boolean cancelActivity) throws SAXException {
super.handleNode(node, element, uri, localName, parser);
BoundaryEventNode eventNode = (BoundaryEventNode) node;
eventNode.setMetaData("AttachedTo", attachedTo);
/**
* TODO: because of how we process bpmn2/xml files, we can't tell
* if the cancelActivity attribute is set to false or not
* (because we override with the xsd settings)
* BPMN2 spec, p. 255, Escalation row:
* "In contrast to an Error, an Escalation by default is assumed to not abort
* the Activity to which the boundary Event is attached."
*/
eventNode.setMetaData("CancelActivity", cancelActivity);
eventNode.setAttachedToNodeId(attachedTo);
org.w3c.dom.Node xmlNode = element.getFirstChild();
while (xmlNode != null) {
String nodeName = xmlNode.getNodeName();
if ("dataOutput".equals(nodeName)) {
String id = ((Element) xmlNode).getAttribute("id");
String outputName = ((Element) xmlNode).getAttribute("name");
dataOutputs.put(id, outputName);
} else if ("dataOutputAssociation".equals(nodeName)) {
readDataOutputAssociation(xmlNode, eventNode);
} else if ("escalationEventDefinition".equals(nodeName)) {
String escalationRef = ((Element) xmlNode).getAttribute("escalationRef");
if (escalationRef != null && escalationRef.trim().length() > 0) {
Map escalations = (Map)
((ProcessBuildData) parser.getData()).getMetaData(ProcessHandler.ESCALATIONS);
if (escalations == null) {
throw new IllegalArgumentException("No escalations found");
}
Escalation escalation = escalations.get(escalationRef);
if (escalation == null) {
throw new IllegalArgumentException("Could not find escalation " + escalationRef);
}
List eventFilters = new ArrayList();
EventTypeFilter eventFilter = new EventTypeFilter();
String type = escalation.getEscalationCode();
eventFilter.setType("Escalation-" + attachedTo + "-" + type);
eventFilters.add(eventFilter);
eventNode.setEventFilters(eventFilters);
eventNode.setMetaData("EscalationEvent", type);
} else {
throw new UnsupportedOperationException("General escalation is not yet supported.");
}
}
xmlNode = xmlNode.getNextSibling();
}
}
@SuppressWarnings("unchecked")
protected void handleErrorNode(final Node node, final Element element, final String uri,
final String localName, final ExtensibleXmlParser parser, final String attachedTo,
final boolean cancelActivity) throws SAXException {
super.handleNode(node, element, uri, localName, parser);
BoundaryEventNode eventNode = (BoundaryEventNode) node;
eventNode.setMetaData("AttachedTo", attachedTo);
eventNode.setAttachedToNodeId(attachedTo);
org.w3c.dom.Node xmlNode = element.getFirstChild();
while (xmlNode != null) {
String nodeName = xmlNode.getNodeName();
if ("dataOutput".equals(nodeName)) {
String id = ((Element) xmlNode).getAttribute("id");
String outputName = ((Element) xmlNode).getAttribute("name");
dataOutputs.put(id, outputName);
} else if ("dataOutputAssociation".equals(nodeName)) {
readDataOutputAssociation(xmlNode, eventNode);
} else if ("errorEventDefinition".equals(nodeName)) {
String errorRef = ((Element) xmlNode).getAttribute("errorRef");
if (errorRef != null && errorRef.trim().length() > 0) {
List errors = (List) ((ProcessBuildData) parser.getData()).getMetaData("Errors");
if (errors == null) {
throw new IllegalArgumentException("No errors found");
}
Error error = null;
for( Error listError : errors ) {
if( errorRef.equals(listError.getId()) ) {
error = listError;
}
}
if (error == null) {
throw new IllegalArgumentException("Could not find error " + errorRef);
}
String type = error.getErrorCode();
boolean hasErrorCode = true;
if (type == null) {
type = error.getId();
hasErrorCode = false;
}
String structureRef = error.getStructureRef();
if (structureRef != null) {
Map itemDefs = (Map)((ProcessBuildData)
parser.getData()).getMetaData("ItemDefinitions");
if (itemDefs.containsKey(structureRef)) {
structureRef = itemDefs.get(structureRef).getStructureRef();
}
}
List eventFilters = new ArrayList();
EventTypeFilter eventFilter = new EventTypeFilter();
eventFilter.setType("Error-" + attachedTo + "-" + type);
eventFilters.add(eventFilter);
eventNode.setEventFilters(eventFilters);
eventNode.setMetaData("ErrorEvent", type);
eventNode.setMetaData("HasErrorEvent", hasErrorCode);
eventNode.setMetaData("ErrorStructureRef", structureRef);
}
}
xmlNode = xmlNode.getNextSibling();
}
}
protected void handleTimerNode(final Node node, final Element element, final String uri,
final String localName, final ExtensibleXmlParser parser, final String attachedTo,
final boolean cancelActivity) throws SAXException {
super.handleNode(node, element, uri, localName, parser);
BoundaryEventNode eventNode = (BoundaryEventNode) node;
eventNode.setMetaData("AttachedTo", attachedTo);
eventNode.setMetaData("CancelActivity", cancelActivity);
eventNode.setAttachedToNodeId(attachedTo);
org.w3c.dom.Node xmlNode = element.getFirstChild();
while (xmlNode != null) {
String nodeName = xmlNode.getNodeName();
if ("timerEventDefinition".equals(nodeName)) {
String timeDuration = null;
String timeCycle = null;
String timeDate = null;
String language = "";
org.w3c.dom.Node subNode = xmlNode.getFirstChild();
while (subNode instanceof Element) {
String subNodeName = subNode.getNodeName();
if ("timeDuration".equals(subNodeName)) {
timeDuration = subNode.getTextContent();
break;
} else if ("timeCycle".equals(subNodeName)) {
timeCycle = subNode.getTextContent();
language = ((Element) subNode).getAttribute("language");
break;
} else if ("timeDate".equals(subNodeName)) {
timeDate = subNode.getTextContent();
break;
}
subNode = subNode.getNextSibling();
}
if (timeDuration != null && timeDuration.trim().length() > 0) {
List eventFilters = new ArrayList();
EventTypeFilter eventFilter = new EventTypeFilter();
eventFilter.setType("Timer-" + attachedTo + "-" + timeDuration);
eventFilters.add(eventFilter);
eventNode.setEventFilters(eventFilters);
eventNode.setMetaData("TimeDuration", timeDuration);
} else if (timeCycle != null && timeCycle.trim().length() > 0) {
List eventFilters = new ArrayList();
EventTypeFilter eventFilter = new EventTypeFilter();
eventFilter.setType("Timer-" + attachedTo + "-" + timeCycle);
eventFilters.add(eventFilter);
eventNode.setEventFilters(eventFilters);
eventNode.setMetaData("TimeCycle", timeCycle);
eventNode.setMetaData("Language", language);
} else if (timeDate != null && timeDate.trim().length() > 0) {
List eventFilters = new ArrayList();
EventTypeFilter eventFilter = new EventTypeFilter();
eventFilter.setType("Timer-" + attachedTo + "-" + timeDate);
eventFilters.add(eventFilter);
eventNode.setEventFilters(eventFilters);
eventNode.setMetaData("TimeDate", timeDate);
}
}
xmlNode = xmlNode.getNextSibling();
}
}
protected void handleCompensationNode(final Node node, final Element element, final String uri,
final String localName, final ExtensibleXmlParser parser, final String attachedTo,
final boolean cancelActivity) throws SAXException {
BoundaryEventNode eventNode = (BoundaryEventNode) parser.getCurrent();
super.handleNode(node, element, uri, localName, parser);
NodeList childs = element.getChildNodes();
for (int i = 0; i < childs.getLength(); i++) {
if (childs.item(i) instanceof Element) {
Element el = (Element) childs.item(i);
if ("compensateEventDefinition".equalsIgnoreCase(el.getNodeName())) {
String activityRef = el.getAttribute("activityRef");
if( activityRef != null && activityRef.length() > 0 ) {
logger.warn("activityRef value [" + activityRef + "] on Boundary Event '" + eventNode.getMetaData("UniqueId")
+ "' ignored per the BPMN2 specification.");
}
}
}
}
eventNode.setMetaData("AttachedTo", attachedTo);
eventNode.setAttachedToNodeId(attachedTo);
// 1. Find the parent (sub-)process
NodeContainer parentContainer = (NodeContainer) parser.getParent();
// 2. Add the event filter (never fires, purely for dumping purposes)
EventTypeFilter eventFilter = new NonAcceptingEventTypeFilter();
eventFilter.setType("Compensation");
List eventFilters = new ArrayList();
eventNode.setEventFilters(eventFilters);
eventFilters.add(eventFilter);
// 3. Add compensation scope (with key/id: attachedTo)
ProcessHandler.addCompensationScope((RuleFlowProcess) parser.getParent(RuleFlowProcess.class), eventNode, parentContainer, attachedTo);
}
protected void handleSignalNode(final Node node, final Element element,
final String uri, final String localName,
final ExtensibleXmlParser parser, final String attachedTo,
final boolean cancelActivity) throws SAXException {
super.handleNode(node, element, uri, localName, parser);
BoundaryEventNode eventNode = (BoundaryEventNode) node;
eventNode.setMetaData("AttachedTo", attachedTo);
eventNode.setMetaData("CancelActivity", cancelActivity);
eventNode.setAttachedToNodeId(attachedTo);
org.w3c.dom.Node xmlNode = element.getFirstChild();
while (xmlNode != null) {
String nodeName = xmlNode.getNodeName();
if ("dataOutput".equals(nodeName)) {
String id = ((Element) xmlNode).getAttribute("id");
String outputName = ((Element) xmlNode).getAttribute("name");
dataOutputs.put(id, outputName);
} if ("dataOutputAssociation".equals(nodeName)) {
readDataOutputAssociation(xmlNode, eventNode);
} else if ("signalEventDefinition".equals(nodeName)) {
String type = ((Element) xmlNode).getAttribute("signalRef");
if (type != null && type.trim().length() > 0) {
Map signals = (Map) ((ProcessBuildData) parser
.getData()).getMetaData("Signals");
if (signals != null && signals.containsKey(type)) {
Signal signal = signals.get(type);
type = signal.getName();
if (type == null) {
throw new IllegalArgumentException("Signal definition must have a name attribute");
}
}
List eventFilters = new ArrayList();
EventTypeFilter eventFilter = new EventTypeFilter();
eventFilter.setType(type);
eventFilters.add(eventFilter);
eventNode.setEventFilters(eventFilters);
eventNode.setScope("external");
eventNode.setMetaData("SignalName", type);
}
}
xmlNode = xmlNode.getNextSibling();
}
}
protected void handleConditionNode(final Node node, final Element element,
final String uri, final String localName,
final ExtensibleXmlParser parser, final String attachedTo,
final boolean cancelActivity) throws SAXException {
super.handleNode(node, element, uri, localName, parser);
BoundaryEventNode eventNode = (BoundaryEventNode) node;
eventNode.setMetaData("AttachedTo", attachedTo);
eventNode.setMetaData("CancelActivity", cancelActivity);
eventNode.setAttachedToNodeId(attachedTo);
org.w3c.dom.Node xmlNode = element.getFirstChild();
while (xmlNode != null) {
String nodeName = xmlNode.getNodeName();
if ("dataOutput".equals(nodeName)) {
String id = ((Element) xmlNode).getAttribute("id");
String outputName = ((Element) xmlNode).getAttribute("name");
dataOutputs.put(id, outputName);
} else if ("dataOutputAssociation".equals(nodeName)) {
readDataOutputAssociation(xmlNode, eventNode);
} else if ("conditionalEventDefinition".equals(nodeName)) {
org.w3c.dom.Node subNode = xmlNode.getFirstChild();
while (subNode != null) {
String subnodeName = subNode.getNodeName();
if ("condition".equals(subnodeName)) {
eventNode.setMetaData("Condition", xmlNode.getTextContent());
List eventFilters = new ArrayList();
EventTypeFilter eventFilter = new EventTypeFilter();
eventFilter.setType("Condition-" + attachedTo);
eventFilters.add(eventFilter);
eventNode.setScope("external");
eventNode.setEventFilters(eventFilters);
break;
}
subNode = subNode.getNextSibling();
}
}
xmlNode = xmlNode.getNextSibling();
}
}
protected void handleMessageNode(final Node node, final Element element,
final String uri, final String localName,
final ExtensibleXmlParser parser, final String attachedTo,
final boolean cancelActivity) throws SAXException {
super.handleNode(node, element, uri, localName, parser);
BoundaryEventNode eventNode = (BoundaryEventNode) node;
eventNode.setMetaData("AttachedTo", attachedTo);
eventNode.setMetaData("CancelActivity", cancelActivity);
eventNode.setAttachedToNodeId(attachedTo);
org.w3c.dom.Node xmlNode = element.getFirstChild();
while (xmlNode != null) {
String nodeName = xmlNode.getNodeName();
if ("dataOutput".equals(nodeName)) {
String id = ((Element) xmlNode).getAttribute("id");
String outputName = ((Element) xmlNode).getAttribute("name");
dataOutputs.put(id, outputName);
} else if ("dataOutputAssociation".equals(nodeName)) {
readDataOutputAssociation(xmlNode, eventNode);
} else if ("messageEventDefinition".equals(nodeName)) {
String messageRef = ((Element) xmlNode).getAttribute("messageRef");
Map messages = (Map) ((ProcessBuildData) parser
.getData()).getMetaData("Messages");
if (messages == null) {
throw new IllegalArgumentException("No messages found");
}
Message message = messages.get(messageRef);
if (message == null) {
throw new IllegalArgumentException("Could not find message " + messageRef);
}
eventNode.setMetaData("MessageType", message.getType());
List eventFilters = new ArrayList();
EventTypeFilter eventFilter = new EventTypeFilter();
eventFilter.setType("Message-" + messageRef);
eventFilters.add(eventFilter);
eventNode.setScope("external");
eventNode.setEventFilters(eventFilters);
}
xmlNode = xmlNode.getNextSibling();
}
}
protected void readDataOutputAssociation(org.w3c.dom.Node xmlNode, EventNode eventNode) {
// sourceRef
org.w3c.dom.Node subNode = xmlNode.getFirstChild();
String from = subNode.getTextContent();
// targetRef
subNode = subNode.getNextSibling();
String to = subNode.getTextContent();
// transformation
Transformation transformation = null;
subNode = subNode.getNextSibling();
if (subNode != null && "transformation".equals(subNode.getNodeName())) {
String lang = subNode.getAttributes().getNamedItem("language").getNodeValue();
String expression = subNode.getTextContent();
DataTransformer transformer = transformerRegistry.find(lang);
if (transformer == null) {
throw new IllegalArgumentException("No transformer registered for language " + lang);
}
transformation = new Transformation(lang, expression, dataOutputs.get(from));
eventNode.setMetaData("Transformation", transformation);
eventNode.setEventTransformer(new EventTransformerImpl(transformation));
}
eventNode.setVariableName(to);
}
public void writeNode(Node node, StringBuilder xmlDump, int metaDataType) {
EventNode eventNode = (EventNode) node;
String attachedTo = (String) eventNode.getMetaData("AttachedTo");
if (attachedTo != null) {
String type = ((EventTypeFilter) eventNode.getEventFilters().get(0)).getType();
if (type.startsWith("Escalation-")) {
type = type.substring(attachedTo.length() + 12);
boolean cancelActivity = (Boolean) eventNode.getMetaData("CancelActivity");
writeNode("boundaryEvent", eventNode, xmlDump, metaDataType);
xmlDump.append("attachedToRef=\"" + attachedTo + "\" ");
if (!cancelActivity) {
xmlDump.append("cancelActivity=\"false\" ");
}
xmlDump.append(">" + EOL);
writeExtensionElements(node, xmlDump);
xmlDump.append(" " + EOL);
endNode("boundaryEvent", xmlDump);
} else if (type.startsWith("Error-")) {
type = type.substring(attachedTo.length() + 7);
writeNode("boundaryEvent", eventNode, xmlDump, metaDataType);
xmlDump.append("attachedToRef=\"" + attachedTo + "\" ");
xmlDump.append(">" + EOL);
writeExtensionElements(node, xmlDump);
writeVariableName(eventNode, xmlDump);
String errorId = getErrorIdForErrorCode(type, eventNode);
xmlDump.append(" " + EOL);
endNode("boundaryEvent", xmlDump);
} else if (type.startsWith("Timer-")) {
type = type.substring(attachedTo.length() + 7);
boolean cancelActivity = (Boolean) eventNode.getMetaData("CancelActivity");
writeNode("boundaryEvent", eventNode, xmlDump, metaDataType);
xmlDump.append("attachedToRef=\"" + attachedTo + "\" ");
if (!cancelActivity) {
xmlDump.append("cancelActivity=\"false\" ");
}
xmlDump.append(">" + EOL);
writeExtensionElements(node, xmlDump);
String duration = (String) eventNode.getMetaData("TimeDuration");
String cycle = (String) eventNode.getMetaData("TimeCycle");
String date = (String) eventNode.getMetaData("TimeDate");
if (duration != null && cycle != null) {
String lang = (String) eventNode.getMetaData("Language");
String language = "";
if (lang != null && !lang.isEmpty()) {
language = "language=\""+lang + "\" ";
}
xmlDump.append(
" " + EOL +
" " + XmlDumper.replaceIllegalChars(duration) + " " + EOL +
" " + XmlDumper.replaceIllegalChars(cycle) + " " + EOL +
" " + EOL);
} else if (duration != null) {
xmlDump.append(
" " + EOL +
" " + XmlDumper.replaceIllegalChars(duration) + " " + EOL +
" " + EOL);
} else if (date != null) {
xmlDump.append(
" " + EOL +
" " + XmlDumper.replaceIllegalChars(date) + " " + EOL +
" " + EOL);
} else {
String lang = (String) eventNode.getMetaData("Language");
String language = "";
if (lang != null && !lang.isEmpty()) {
language = "language=\""+lang + "\" ";
}
xmlDump.append(
" " + EOL +
" " + XmlDumper.replaceIllegalChars(cycle) + " " + EOL +
" " + EOL);
}
endNode("boundaryEvent", xmlDump);
} else if (type.equals("Compensation")) {
writeNode("boundaryEvent", eventNode, xmlDump, metaDataType);
xmlDump.append("attachedToRef=\"" + attachedTo + "\" ");
xmlDump.append(">" + EOL);
writeExtensionElements(node, xmlDump);
xmlDump.append(" " + EOL);
endNode("boundaryEvent", xmlDump);
} else if (node.getMetaData().get("SignalName") != null) {
boolean cancelActivity = (Boolean) eventNode.getMetaData("CancelActivity");
writeNode("boundaryEvent", eventNode, xmlDump, metaDataType);
xmlDump.append("attachedToRef=\"" + attachedTo + "\" ");
if (!cancelActivity) {
xmlDump.append("cancelActivity=\"false\" ");
}
xmlDump.append(">" + EOL);
writeExtensionElements(node, xmlDump);
xmlDump.append(" "+ EOL);
endNode("boundaryEvent", xmlDump);
} else if (node.getMetaData().get("Condition") != null) {
boolean cancelActivity = (Boolean) eventNode.getMetaData("CancelActivity");
writeNode("boundaryEvent", eventNode, xmlDump, metaDataType);
xmlDump.append("attachedToRef=\"" + attachedTo + "\" ");
if (!cancelActivity) {
xmlDump.append("cancelActivity=\"false\" ");
}
xmlDump.append(">" + EOL);
writeExtensionElements(node, xmlDump);
xmlDump.append(" "+ EOL);
xmlDump.append(" " + eventNode.getMetaData("Condition") +" "+ EOL);
xmlDump.append(" "+ EOL);
endNode("boundaryEvent", xmlDump);
} else if (type.startsWith("Message-")) {
type = type.substring(8);
writeNode("boundaryEvent", eventNode, xmlDump, metaDataType);
xmlDump.append("attachedToRef=\"" + attachedTo + "\" ");
xmlDump.append(">" + EOL);
writeExtensionElements(node, xmlDump);
xmlDump.append(" " + EOL);
endNode("boundaryEvent", xmlDump);
}
}
}
}