in jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/ProcessHandler.java [712:817]
private static void checkBoundaryEventCompensationHandler(Association association, Node source, Node target) {
// check that
// - event node is boundary event node
if (!(source instanceof BoundaryEventNode)) {
throw new ProcessParsingValidationException("(Compensation) activities may only be associated with Boundary Event Nodes (not with" +
source.getClass().getSimpleName() + " nodes [node " + source.getUniqueId() + "].");
}
BoundaryEventNode eventNode = (BoundaryEventNode) source;
// - event node has compensationEvent
List<EventFilter> eventFilters = eventNode.getEventFilters();
boolean compensationCheckPassed = false;
if (eventFilters != null) {
for (EventFilter filter : eventFilters) {
if (filter instanceof EventTypeFilter) {
String type = ((EventTypeFilter) filter).getType();
if (type != null && type.equals("Compensation")) {
compensationCheckPassed = true;
}
}
}
}
if (!compensationCheckPassed) {
throw new ProcessParsingValidationException("An Event [" + eventNode.getUniqueId()
+ "] linked from an association [" + association.getId()
+ "] must be a (Boundary) Compensation Event.");
}
// - boundary event node is attached to the correct type of node?
/**
* Tasks:
* business: RuleSetNode
* manual: WorkItemNode
* receive: WorkItemNode
* script: ActionNode
* send: WorkItemNode
* service: WorkItemNode
* task: WorkItemNode
* user: HumanTaskNode
*/
String attachedToId = eventNode.getAttachedToNodeId();
Node attachedToNode = null;
for (Node node : eventNode.getParentContainer().getNodes()) {
if (attachedToId.equals(node.getUniqueId())) {
attachedToNode = node;
break;
}
}
if (attachedToNode == null) {
throw new ProcessParsingValidationException("Boundary Event [" + eventNode.getUniqueId()
+ "] is not attached to a node [" + attachedToId + "] that can be found.");
}
if (!(attachedToNode instanceof RuleSetNode
|| attachedToNode instanceof WorkItemNode
|| attachedToNode instanceof ActionNode
|| attachedToNode instanceof HumanTaskNode
|| attachedToNode instanceof CompositeNode
|| attachedToNode instanceof SubProcessNode)) {
throw new ProcessParsingValidationException("Compensation Boundary Event [" + eventNode.getUniqueId()
+ "] must be attached to a task or sub-process.");
}
// - associated node is a task or subProcess
compensationCheckPassed = false;
if (target instanceof WorkItemNode || target instanceof HumanTaskNode
|| target instanceof CompositeContextNode || target instanceof SubProcessNode) {
compensationCheckPassed = true;
} else if (target instanceof ActionNode) {
Object nodeTypeObj = ((ActionNode) target).getMetaData("NodeType");
if (nodeTypeObj != null && nodeTypeObj.equals("ScriptTask")) {
compensationCheckPassed = true;
}
}
if (!compensationCheckPassed) {
throw new ProcessParsingValidationException("An Activity ["
+ ((NodeImpl) target).getUniqueId() +
"] associated with a Boundary Compensation Event must be a Task or a (non-Event) Sub-Process");
}
// - associated node does not have outgoingConnections of it's own
compensationCheckPassed = true;
NodeImpl targetNode = (NodeImpl) target;
Map<String, List<org.kie.api.definition.process.Connection>> connectionsMap = targetNode.getOutgoingConnections();
ConnectionImpl outgoingConnection = null;
for (String connectionType : connectionsMap.keySet()) {
List<org.kie.api.definition.process.Connection> connections = connectionsMap.get(connectionType);
if (connections != null && !connections.isEmpty()) {
for (org.kie.api.definition.process.Connection connection : connections) {
Object hiddenObj = connection.getMetaData().get("hidden");
if (hiddenObj != null && ((Boolean) hiddenObj)) {
continue;
}
outgoingConnection = (ConnectionImpl) connection;
compensationCheckPassed = false;
break;
}
}
}
if (!compensationCheckPassed) {
throw new ProcessParsingValidationException("A Compensation Activity ["
+ targetNode.getUniqueId()
+ "] may not have any outgoing connection ["
+ (String) outgoingConnection.getUniqueId() + "]");
}
}