in jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceImpl.java [307:431]
public void triggerCompleted(String type, boolean remove) {
leaveTime = new Date();
org.kie.api.definition.process.Node node = getNode();
if (node != null) {
String uniqueId = node.getUniqueId();
if (uniqueId == null) {
uniqueId = ((NodeImpl) node).getUniqueId();
}
((WorkflowProcessInstanceImpl) processInstance).addCompletedNodeId(uniqueId);
((WorkflowProcessInstanceImpl) processInstance).getIterationLevels().remove(uniqueId);
}
// if node instance was cancelled, or containing container instance was cancelled
if ((getNodeInstanceContainer().getNodeInstance(getStringId()) == null)
|| (((org.jbpm.workflow.instance.NodeInstanceContainer) getNodeInstanceContainer()).getState() != STATE_ACTIVE)) {
return;
}
if (remove) {
((org.jbpm.workflow.instance.NodeInstanceContainer) getNodeInstanceContainer())
.removeNodeInstance(this);
}
List<Connection> connections = null;
if (node != null) {
if (WORKFLOW_PARAM_MULTIPLE_CONNECTIONS.get(getProcessInstance().getProcess()) && !((NodeImpl) node).getConstraints().isEmpty()) {
int priority;
connections = ((NodeImpl) node).getDefaultOutgoingConnections();
boolean found = false;
List<NodeInstanceTrigger> nodeInstances =
new ArrayList<>();
List<Connection> outgoingCopy = new ArrayList<>(connections);
while (!outgoingCopy.isEmpty()) {
priority = Integer.MAX_VALUE;
Connection selectedConnection = null;
ConstraintEvaluator selectedConstraint = null;
for (final Connection connection : outgoingCopy) {
Collection<Constraint> constraints = ((NodeImpl) node).getConstraints(connection);
if (constraints != null) {
for (Constraint constraint : constraints) {
if (constraint instanceof ConstraintEvaluator && constraint.getPriority() < priority
&& !constraint.isDefault()) {
priority = constraint.getPriority();
selectedConnection = connection;
selectedConstraint = (ConstraintEvaluator) constraint;
}
}
}
}
if (selectedConstraint == null) {
break;
}
if (selectedConstraint.evaluate(this,
selectedConnection,
selectedConstraint)) {
nodeInstances.add(new NodeInstanceTrigger(followConnection(selectedConnection), selectedConnection.getToType()));
found = true;
}
outgoingCopy.remove(selectedConnection);
}
for (NodeInstanceTrigger nodeInstance : nodeInstances) {
// stop if this process instance has been aborted / completed
if (((org.jbpm.workflow.instance.NodeInstanceContainer) getNodeInstanceContainer()).getState() != STATE_ACTIVE) {
return;
}
triggerNodeInstance(nodeInstance.getNodeInstance(), nodeInstance.getToType());
}
if (!found) {
for (final Connection connection : connections) {
Collection<Constraint> constraints = ((NodeImpl) node).getConstraints(connection);
if (constraints != null) {
for (Constraint constraint : constraints) {
if (constraint.isDefault()) {
triggerConnection(connection);
found = true;
break;
}
}
}
if (found) {
break;
}
}
}
if (!found) {
throw new IllegalArgumentException("Uncontrolled flow node could not find at least one valid outgoing connection " + getNode().getName());
}
return;
} else {
connections = node.getOutgoingConnections(type);
}
}
if (connections == null || connections.isEmpty()) {
boolean hidden = false;
org.kie.api.definition.process.Node currentNode = getNode();
if (currentNode != null && currentNode.getMetaData().get(HIDDEN) != null) {
hidden = true;
}
InternalKnowledgeRuntime kruntime = getProcessInstance().getKnowledgeRuntime();
if (!hidden) {
((InternalProcessRuntime) kruntime.getProcessRuntime())
.getProcessEventSupport().fireBeforeNodeLeft(this, kruntime);
}
// notify container
((org.jbpm.workflow.instance.NodeInstanceContainer) getNodeInstanceContainer())
.nodeInstanceCompleted(this, type);
if (!hidden) {
((InternalProcessRuntime) kruntime.getProcessRuntime())
.getProcessEventSupport().fireAfterNodeLeft(this, kruntime);
}
} else {
Map<org.jbpm.workflow.instance.NodeInstance, String> nodeInstances = new HashMap<>();
for (Connection connection : connections) {
nodeInstances.put(followConnection(connection), connection.getToType());
}
for (Map.Entry<org.jbpm.workflow.instance.NodeInstance, String> nodeInstance : nodeInstances.entrySet()) {
// stop if this process instance has been aborted / completed
if (((org.jbpm.workflow.instance.NodeInstanceContainer) getNodeInstanceContainer()).getState() != STATE_ACTIVE) {
return;
}
triggerNodeInstance(nodeInstance.getKey(), nodeInstance.getValue());
}
}
}