org.jbpm.casemgmt.cmmn.xml.CaseHandler Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2017 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.casemgmt.cmmn.xml;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.drools.core.xml.BaseAbstractHandler;
import org.drools.core.xml.ExtensibleXmlParser;
import org.drools.core.xml.Handler;
import org.jbpm.casemgmt.cmmn.core.Definitions;
import org.jbpm.casemgmt.cmmn.core.FileItemDefinition;
import org.jbpm.casemgmt.cmmn.core.Role;
import org.jbpm.casemgmt.cmmn.core.SequenceFlow;
import org.jbpm.compiler.xml.ProcessBuildData;
import org.jbpm.process.core.ContextContainer;
import org.jbpm.process.core.context.exception.ActionExceptionHandler;
import org.jbpm.process.core.context.exception.CompensationScope;
import org.jbpm.process.core.context.exception.ExceptionScope;
import org.jbpm.process.core.event.EventFilter;
import org.jbpm.process.core.event.EventTypeFilter;
import org.jbpm.process.core.timer.Timer;
import org.jbpm.process.instance.impl.CancelNodeInstanceAction;
import org.jbpm.ruleflow.core.RuleFlowProcess;
import org.jbpm.workflow.core.Connection;
import org.jbpm.workflow.core.Constraint;
import org.jbpm.workflow.core.DroolsAction;
import org.jbpm.workflow.core.impl.ConnectionImpl;
import org.jbpm.workflow.core.impl.ConnectionRef;
import org.jbpm.workflow.core.impl.ConstraintImpl;
import org.jbpm.workflow.core.impl.DroolsConsequenceAction;
import org.jbpm.workflow.core.impl.ExtendedNodeImpl;
import org.jbpm.workflow.core.impl.NodeImpl;
import org.jbpm.workflow.core.node.ActionNode;
import org.jbpm.workflow.core.node.BoundaryEventNode;
import org.jbpm.workflow.core.node.ConstraintTrigger;
import org.jbpm.workflow.core.node.EndNode;
import org.jbpm.workflow.core.node.EventNode;
import org.jbpm.workflow.core.node.EventSubProcessNode;
import org.jbpm.workflow.core.node.EventTrigger;
import org.jbpm.workflow.core.node.FaultNode;
import org.jbpm.workflow.core.node.HumanTaskNode;
import org.jbpm.workflow.core.node.Split;
import org.jbpm.workflow.core.node.StartNode;
import org.jbpm.workflow.core.node.StateBasedNode;
import org.jbpm.workflow.core.node.StateNode;
import org.jbpm.workflow.core.node.Trigger;
import org.kie.api.definition.process.Node;
import org.kie.api.definition.process.NodeContainer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
public class CaseHandler extends BaseAbstractHandler implements Handler {
private static final Logger logger = LoggerFactory.getLogger(CaseHandler.class);
public static final String CONNECTIONS = "BPMN.Connections";
public static final String LINKS = "BPMN.ThrowLinks";
public static final String ASSOCIATIONS = "BPMN.Associations";
public static final String ERRORS = "BPMN.Errors";
public static final String ESCALATIONS = "BPMN.Escalations";
static final String PROCESS_INSTANCE_SIGNAL_EVENT = "kcontext.getProcessInstance().signalEvent(\"";
static final String RUNTIME_SIGNAL_EVENT = "kcontext.getKnowledgeRuntime().signalEvent(\"";
static final String RUNTIME_MANAGER_SIGNAL_EVENT = "((org.kie.api.runtime.manager.RuntimeManager)kcontext.getKnowledgeRuntime().getEnvironment().get(\"RuntimeManager\")).signalEvent(\"";
public CaseHandler() {
if ((this.validParents == null) && (this.validPeers == null)) {
this.validParents = new HashSet<>();
this.validParents.add(Definitions.class);
this.validPeers = new HashSet<>();
this.validPeers.add(null);
this.validPeers.add(RuleFlowProcess.class);
this.validPeers.add(FileItemDefinition.class);
this.allowNesting = false;
}
}
public Object start(final String uri,
final String localName,
final Attributes attrs,
final ExtensibleXmlParser parser) throws SAXException {
parser.startElementBuilder(localName, attrs);
String id = attrs.getValue("id");
String name = attrs.getValue("name");
String packageName = attrs.getValue("http://www.jboss.org/drools", "packageName");
String version = attrs.getValue("http://www.jboss.org/drools", "version");
RuleFlowProcess process = new RuleFlowProcess();
process.setAutoComplete(true);
process.setId(id);
if (name == null) {
name = id;
}
process.setName(name);
process.setType("RuleFlow");
if (packageName == null) {
packageName = "org.jbpm.cmmn";
}
process.setPackageName(packageName);
process.setDynamic(true);
process.setAutoComplete(false);
if (version != null) {
process.setVersion(version);
}
((ProcessBuildData) parser.getData()).addProcess(process);
// register the definitions object as metadata of process.
process.setMetaData("Definitions", parser.getParent());
// register cmmn imports as meta data of process
Object typedImports = ((ProcessBuildData) parser.getData()).getMetaData("CmmnImports");
if (typedImports != null) {
process.setMetaData("CmmnImports", typedImports);
}
// register item definitions as meta data of process
Object itemDefinitions = ((ProcessBuildData) parser.getData()).getMetaData("ItemDefinitions");
if (itemDefinitions != null) {
process.setMetaData("ItemDefinitions", itemDefinitions);
}
// for unique id's of nodes, start with one to avoid returning wrong nodes for dynamic nodes
parser.getMetaData().put("idGen", new AtomicInteger(1));
return process;
}
@SuppressWarnings("unchecked")
public Object end(final String uri,
final String localName,
final ExtensibleXmlParser parser) throws SAXException {
parser.endElementBuilder();
ProcessBuildData buildData = (ProcessBuildData) parser.getData();
Map roles = (Map) buildData.getMetaData("Roles");
RuleFlowProcess process = (RuleFlowProcess) parser.getCurrent();
List connections = (List) process.getMetaData(CONNECTIONS);
linkConnections(process, connections);
linkBoundaryEvents(process);
postProcessNodes(process, process, roles);
return process;
}
private static Node findNodeByIdOrUniqueIdInMetadata(NodeContainer nodeContainer, final String nodeRef, String errorMsg) {
Node node = null;
// try looking for a node with same "UniqueId" (in metadata)
for (Node containerNode : nodeContainer.getNodes()) {
if (nodeRef.equals(containerNode.getMetaData().get("UniqueId"))) {
node = containerNode;
break;
}
}
if (node == null) {
throw new IllegalArgumentException(errorMsg);
}
return node;
}
public Class> generateNodeFor() {
return RuleFlowProcess.class;
}
public static void linkConnections(NodeContainer nodeContainer, List connections) {
if (connections != null) {
for (SequenceFlow connection : connections) {
String sourceRef = connection.getSourceRef();
Node source = findNodeByIdOrUniqueIdInMetadata(nodeContainer, sourceRef, "Could not find source node for connection:" + sourceRef);
if (source instanceof EventNode) {
for (EventFilter eventFilter : ((EventNode) source).getEventFilters()) {
if (eventFilter instanceof EventTypeFilter) {
if ("Compensation".equals(((EventTypeFilter) eventFilter).getType())) {
// While this isn't explicitly stated in the spec,
// BPMN Method & Style, 2nd Ed. (Silver), states this on P. 131
throw new IllegalArgumentException(
"A Compensation Boundary Event can only be *associated* with a compensation activity via an Association, not via a Sequence Flow element.");
}
}
}
}
String targetRef = connection.getTargetRef();
Node target = findNodeByIdOrUniqueIdInMetadata(nodeContainer, targetRef, "Could not find target node for connection:" + targetRef);
Connection result = new ConnectionImpl(
source, NodeImpl.CONNECTION_DEFAULT_TYPE,
target, NodeImpl.CONNECTION_DEFAULT_TYPE);
result.setMetaData("bendpoints", connection.getBendpoints());
result.setMetaData("UniqueId", connection.getId());
if ("true".equals(System.getProperty("jbpm.enable.multi.con"))) {
NodeImpl nodeImpl = (NodeImpl) source;
Constraint constraint = buildConstraint(connection, nodeImpl);
if (constraint != null) {
nodeImpl.addConstraint(new ConnectionRef(connection.getId(), target.getId(), NodeImpl.CONNECTION_DEFAULT_TYPE),
constraint);
}
} else if (source instanceof Split) {
Split split = (Split) source;
Constraint constraint = buildConstraint(connection, split);
split.addConstraint(
new ConnectionRef(target.getId(), NodeImpl.CONNECTION_DEFAULT_TYPE),
constraint);
}
}
}
}
public static void linkBoundaryEvents(NodeContainer nodeContainer) {
for (Node node : nodeContainer.getNodes()) {
if (node instanceof EventNode) {
final String attachedTo = (String) node.getMetaData().get("AttachedTo");
if (attachedTo != null) {
for (EventFilter filter : ((EventNode) node).getEventFilters()) {
String type = ((EventTypeFilter) filter).getType();
Node attachedNode = findNodeByIdOrUniqueIdInMetadata(nodeContainer, attachedTo, "Could not find node to attach to: " + attachedTo);
//
if (!(attachedNode instanceof StateBasedNode) && !type.equals("Compensation")) {
throw new IllegalArgumentException("Boundary events are supported only on StateBasedNode, found node: " + attachedNode.getClass().getName() + " [" + attachedNode.getMetaData().get(
"UniqueId") +
"]");
}
if (type.startsWith("Escalation")) {
linkBoundaryEscalationEvent(nodeContainer, node, attachedTo, attachedNode);
} else if (type.startsWith("Error-")) {
linkBoundaryErrorEvent(nodeContainer, node, attachedTo, attachedNode);
} else if (type.startsWith("Timer-")) {
linkBoundaryTimerEvent(nodeContainer, node, attachedTo, attachedNode);
} else if (node.getMetaData().get("SignalName") != null || type.startsWith("Message-")) {
linkBoundarySignalEvent(nodeContainer, node, attachedTo, attachedNode);
} else if (type.startsWith("Condition-")) {
linkBoundaryConditionEvent(nodeContainer, node, attachedTo, attachedNode);
}
}
}
}
}
}
private static void linkBoundaryEscalationEvent(NodeContainer nodeContainer, Node node, String attachedTo, Node attachedNode) {
boolean cancelActivity = (Boolean) node.getMetaData().get("CancelActivity");
String escalationCode = (String) node.getMetaData().get("EscalationEvent");
String escalationStructureRef = (String) node.getMetaData().get("EscalationStructureRef");
ContextContainer compositeNode = (ContextContainer) attachedNode;
ExceptionScope exceptionScope = (ExceptionScope) compositeNode.getDefaultContext(ExceptionScope.EXCEPTION_SCOPE);
if (exceptionScope == null) {
exceptionScope = new ExceptionScope();
compositeNode.addContext(exceptionScope);
compositeNode.setDefaultContext(exceptionScope);
}
String variable = ((EventNode) node).getVariableName();
ActionExceptionHandler exceptionHandler = new ActionExceptionHandler();
DroolsConsequenceAction action = new DroolsConsequenceAction("java",
PROCESS_INSTANCE_SIGNAL_EVENT + "Escalation-" + attachedTo + "-" + escalationCode + "\", kcontext.getVariable(\"" + variable + "\"));");
exceptionHandler.setAction(action);
exceptionHandler.setFaultVariable(variable);
exceptionScope.setExceptionHandler(escalationCode, exceptionHandler);
if (escalationStructureRef != null) {
exceptionScope.setExceptionHandler(escalationStructureRef, exceptionHandler);
}
if (cancelActivity) {
List actions = ((EventNode) node).getActions(EndNode.EVENT_NODE_EXIT);
if (actions == null) {
actions = new ArrayList();
}
DroolsConsequenceAction cancelAction = new DroolsConsequenceAction("java", null);
cancelAction.setMetaData("Action", new CancelNodeInstanceAction(attachedTo));
actions.add(cancelAction);
((EventNode) node).setActions(EndNode.EVENT_NODE_EXIT, actions);
}
}
private static void linkBoundaryErrorEvent(NodeContainer nodeContainer, Node node, String attachedTo, Node attachedNode) {
ContextContainer compositeNode = (ContextContainer) attachedNode;
ExceptionScope exceptionScope = (ExceptionScope) compositeNode.getDefaultContext(ExceptionScope.EXCEPTION_SCOPE);
if (exceptionScope == null) {
exceptionScope = new ExceptionScope();
compositeNode.addContext(exceptionScope);
compositeNode.setDefaultContext(exceptionScope);
}
String errorCode = (String) node.getMetaData().get("ErrorEvent");
boolean hasErrorCode = (Boolean) node.getMetaData().get("HasErrorEvent");
String errorStructureRef = (String) node.getMetaData().get("ErrorStructureRef");
ActionExceptionHandler exceptionHandler = new ActionExceptionHandler();
String variable = ((EventNode) node).getVariableName();
DroolsConsequenceAction action = new DroolsConsequenceAction("java",
PROCESS_INSTANCE_SIGNAL_EVENT + "Error-" + attachedTo + "-" + errorCode + "\", kcontext.getVariable(\"" + variable + "\"));");
exceptionHandler.setAction(action);
exceptionHandler.setFaultVariable(variable);
exceptionScope.setExceptionHandler(hasErrorCode ? errorCode : null, exceptionHandler);
if (errorStructureRef != null) {
exceptionScope.setExceptionHandler(errorStructureRef, exceptionHandler);
}
List actions = ((EventNode) node).getActions(EndNode.EVENT_NODE_EXIT);
if (actions == null) {
actions = new ArrayList();
}
DroolsConsequenceAction cancelAction = new DroolsConsequenceAction("java", null);
cancelAction.setMetaData("Action", new CancelNodeInstanceAction(attachedTo));
actions.add(cancelAction);
((EventNode) node).setActions(EndNode.EVENT_NODE_EXIT, actions);
}
private static void linkBoundaryTimerEvent(NodeContainer nodeContainer, Node node, String attachedTo, Node attachedNode) {
boolean cancelActivity = (Boolean) node.getMetaData().get("CancelActivity");
StateBasedNode compositeNode = (StateBasedNode) attachedNode;
String timeDuration = (String) node.getMetaData().get("TimeDuration");
String timeCycle = (String) node.getMetaData().get("TimeCycle");
String timeDate = (String) node.getMetaData().get("TimeDate");
Timer timer = new Timer();
if (timeDuration != null) {
timer.setDelay(timeDuration);
timer.setTimeType(Timer.TIME_DURATION);
compositeNode.addTimer(timer, new DroolsConsequenceAction("java",
PROCESS_INSTANCE_SIGNAL_EVENT + "Timer-" + attachedTo + "-" + timeDuration + "-" + node.getId() + "\", kcontext.getNodeInstance().getId());"));
} else if (timeCycle != null) {
int index = timeCycle.indexOf("###");
if (index != -1) {
String period = timeCycle.substring(index + 3);
timeCycle = timeCycle.substring(0, index);
timer.setPeriod(period);
}
timer.setDelay(timeCycle);
timer.setTimeType(Timer.TIME_CYCLE);
compositeNode.addTimer(timer, new DroolsConsequenceAction("java",
PROCESS_INSTANCE_SIGNAL_EVENT + "Timer-" + attachedTo + "-" + timeCycle + (timer.getPeriod() == null ? "" : "###" + timer.getPeriod()) + "-" + node
.getId() +
"\", kcontext.getNodeInstance().getId());"));
} else if (timeDate != null) {
timer.setDate(timeDate);
timer.setTimeType(Timer.TIME_DATE);
compositeNode.addTimer(timer, new DroolsConsequenceAction("java",
PROCESS_INSTANCE_SIGNAL_EVENT + "Timer-" + attachedTo + "-" + timeDate + "-" + node.getId() + "\", kcontext.getNodeInstance().getId());"));
}
if (cancelActivity) {
List actions = ((EventNode) node).getActions(EndNode.EVENT_NODE_EXIT);
if (actions == null) {
actions = new ArrayList();
}
DroolsConsequenceAction cancelAction = new DroolsConsequenceAction("java", null);
cancelAction.setMetaData("Action", new CancelNodeInstanceAction(attachedTo));
actions.add(cancelAction);
((EventNode) node).setActions(EndNode.EVENT_NODE_EXIT, actions);
}
}
private static void linkBoundarySignalEvent(NodeContainer nodeContainer, Node node, String attachedTo, Node attachedNode) {
boolean cancelActivity = (Boolean) node.getMetaData().get("CancelActivity");
if (cancelActivity) {
List actions = ((EventNode) node).getActions(EndNode.EVENT_NODE_EXIT);
if (actions == null) {
actions = new ArrayList();
}
DroolsConsequenceAction action = new DroolsConsequenceAction("java", null);
action.setMetaData("Action", new CancelNodeInstanceAction(attachedTo));
actions.add(action);
((EventNode) node).setActions(EndNode.EVENT_NODE_EXIT, actions);
}
}
private static void linkBoundaryConditionEvent(NodeContainer nodeContainer, Node node, String attachedTo, Node attachedNode) {
String processId = ((RuleFlowProcess) nodeContainer).getId();
String eventType = "RuleFlowStateEvent-" + processId + "-" + ((EventNode) node).getUniqueId() + "-" + attachedTo;
((EventTypeFilter) ((EventNode) node).getEventFilters().get(0)).setType(eventType);
boolean cancelActivity = (Boolean) node.getMetaData().get("CancelActivity");
if (cancelActivity) {
List actions = ((EventNode) node).getActions(EndNode.EVENT_NODE_EXIT);
if (actions == null) {
actions = new ArrayList();
}
DroolsConsequenceAction action = new DroolsConsequenceAction("java", null);
action.setMetaData("Action", new CancelNodeInstanceAction(attachedTo));
actions.add(action);
((EventNode) node).setActions(EndNode.EVENT_NODE_EXIT, actions);
}
}
private void postProcessNodes(RuleFlowProcess process, NodeContainer container, Map roles) {
List eventSubProcessHandlers = new ArrayList();
for (Node node : container.getNodes()) {
if (node instanceof HumanTaskNode) {
if (roles != null) {
HumanTaskNode humanTaskNode = (HumanTaskNode) node;
Role performer = roles.get(humanTaskNode.getWork().getParameter("ActorId"));
if (performer != null) {
humanTaskNode.getWork().setParameter("ActorId", performer.getName());
}
}
}
if (node instanceof StateNode) {
StateNode stateNode = (StateNode) node;
String condition = (String) stateNode.getMetaData("Condition");
Constraint constraint = new ConstraintImpl();
constraint.setConstraint(condition);
constraint.setType("rule");
for (org.kie.api.definition.process.Connection connection : stateNode.getDefaultOutgoingConnections()) {
stateNode.setConstraint(connection, constraint);
}
} else if (node instanceof NodeContainer) {
// prepare event sub process
if (node instanceof EventSubProcessNode) {
EventSubProcessNode eventSubProcessNode = (EventSubProcessNode) node;
Node[] nodes = eventSubProcessNode.getNodes();
for (Node subNode : nodes) {
// avoids cyclomatic complexity
if (subNode == null || !(subNode instanceof StartNode)) {
continue;
}
List triggers = ((StartNode) subNode).getTriggers();
if (triggers == null) {
continue;
}
for (Trigger trigger : triggers) {
if (trigger instanceof EventTrigger) {
final List filters = ((EventTrigger) trigger).getEventFilters();
for (EventFilter filter : filters) {
if (filter instanceof EventTypeFilter) {
eventSubProcessNode.addEvent((EventTypeFilter) filter);
String type = ((EventTypeFilter) filter).getType();
if (type.startsWith("Error-") || type.startsWith("Escalation")) {
String faultCode = (String) subNode.getMetaData().get("FaultCode");
String replaceRegExp = "Error-|Escalation-";
final String signalType = type;
ExceptionScope exceptionScope = (ExceptionScope) ((ContextContainer) eventSubProcessNode.getNodeContainer()).getDefaultContext(ExceptionScope.EXCEPTION_SCOPE);
if (exceptionScope == null) {
exceptionScope = new ExceptionScope();
((ContextContainer) eventSubProcessNode.getNodeContainer()).addContext(exceptionScope);
((ContextContainer) eventSubProcessNode.getNodeContainer()).setDefaultContext(exceptionScope);
}
String faultVariable = null;
if (trigger.getInAssociations() != null && !trigger.getInAssociations().isEmpty()) {
faultVariable = trigger.getInAssociations().get(0).getTarget();
}
ActionExceptionHandler exceptionHandler = new ActionExceptionHandler();
DroolsConsequenceAction action = new DroolsConsequenceAction("java", PROCESS_INSTANCE_SIGNAL_EVENT + signalType + "\", " + (faultVariable == null ? "null"
: "kcontext.getVariable(\"" + faultVariable + "\")") + ");");
exceptionHandler.setAction(action);
exceptionHandler.setFaultVariable(faultVariable);
if (faultCode != null) {
String trimmedType = type.replaceFirst(replaceRegExp, "");
exceptionScope.setExceptionHandler(trimmedType, exceptionHandler);
eventSubProcessHandlers.add(trimmedType);
} else {
exceptionScope.setExceptionHandler(faultCode, exceptionHandler);
}
}
}
}
} else if (trigger instanceof ConstraintTrigger) {
ConstraintTrigger constraintTrigger = (ConstraintTrigger) trigger;
if (constraintTrigger.getConstraint() != null) {
String processId = ((RuleFlowProcess) container).getId();
String type = "RuleFlowStateEventSubProcess-Event-" + processId + "-" + eventSubProcessNode.getUniqueId();
EventTypeFilter eventTypeFilter = new EventTypeFilter();
eventTypeFilter.setType(type);
eventSubProcessNode.addEvent(eventTypeFilter);
}
}
}
}
}
postProcessNodes(process, (NodeContainer) node, roles);
} else if (node instanceof EndNode) {
handleIntermediateOrEndThrowCompensationEvent((EndNode) node);
} else if (node instanceof ActionNode) {
handleIntermediateOrEndThrowCompensationEvent((ActionNode) node);
} else if (node instanceof EventNode) {
final EventNode eventNode = (EventNode) node;
if (!(eventNode instanceof BoundaryEventNode) && eventNode.getDefaultIncomingConnections().size() == 0) {
throw new IllegalArgumentException("Event node '" + node.getName() + "' [" + node.getId() + "] has no incoming connection");
}
}
}
// process fault node to disable terminate parent if there is event subprocess handler
for (Node node : container.getNodes()) {
if (node instanceof FaultNode) {
FaultNode faultNode = (FaultNode) node;
if (eventSubProcessHandlers.contains(faultNode.getFaultName())) {
faultNode.setTerminateParent(false);
}
}
}
}
private static Constraint buildConstraint(SequenceFlow connection, NodeImpl node) {
if (connection.getExpression() == null) {
return null;
}
Constraint constraint = new ConstraintImpl();
String defaultConnection = (String) node.getMetaData("Default");
if (defaultConnection != null && defaultConnection.equals(connection.getId())) {
constraint.setDefault(true);
}
if (connection.getName() != null) {
constraint.setName(connection.getName());
} else {
constraint.setName("");
}
if (connection.getType() != null) {
constraint.setType(connection.getType());
} else {
constraint.setType("code");
}
if (connection.getLanguage() != null) {
constraint.setDialect(connection.getLanguage());
}
if (connection.getExpression() != null) {
constraint.setConstraint(connection.getExpression());
}
constraint.setPriority(connection.getPriority());
return constraint;
}
protected void handleIntermediateOrEndThrowCompensationEvent(ExtendedNodeImpl throwEventNode) {
if (throwEventNode.getMetaData("compensation-activityRef") != null) {
String activityRef = (String) throwEventNode.getMetaData().remove("compensation-activityRef");
NodeContainer nodeParent = (NodeContainer) throwEventNode.getNodeContainer();
if (nodeParent instanceof EventSubProcessNode) {
boolean compensationEventSubProcess = false;
List startTriggers = ((EventSubProcessNode) nodeParent).findStartNode().getTriggers();
CESP_CHECK: for (Trigger trigger : startTriggers) {
if (trigger instanceof EventTrigger) {
for (EventFilter filter : ((EventTrigger) trigger).getEventFilters()) {
if (((EventTypeFilter) filter).getType().equals("Compensation")) {
compensationEventSubProcess = true;
break CESP_CHECK;
}
}
}
}
if (compensationEventSubProcess) {
// BPMN2 spec, p. 252, p. 248: intermediate and end compensation event visibility scope
nodeParent = (NodeContainer) ((NodeImpl) nodeParent).getNodeContainer();
}
}
String parentId;
if (nodeParent instanceof RuleFlowProcess) {
parentId = ((RuleFlowProcess) nodeParent).getId();
} else {
parentId = (String) ((NodeImpl) nodeParent).getMetaData("UniqueId");
}
String compensationEvent;
if (activityRef.length() == 0) {
// general/implicit compensation
compensationEvent = CompensationScope.IMPLICIT_COMPENSATION_PREFIX + parentId;
} else {
// specific compensation
compensationEvent = activityRef;
}
DroolsConsequenceAction compensationAction = new DroolsConsequenceAction("java",
PROCESS_INSTANCE_SIGNAL_EVENT + "Compensation\", \"" + compensationEvent + "\");");
if (throwEventNode instanceof ActionNode) {
((ActionNode) throwEventNode).setAction(compensationAction);
} else if (throwEventNode instanceof EndNode) {
List actions = new ArrayList();
actions.add(compensationAction);
((EndNode) throwEventNode).setActions(EndNode.EVENT_NODE_ENTER, actions);
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy