use of org.kie.api.definition.process.Connection in project jbpm by kiegroup.
the class JoinInstance method internalTrigger.
public void internalTrigger(final NodeInstance from, String type) {
if (!org.jbpm.workflow.core.Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
throw new IllegalArgumentException("An ActionNode only accepts default incoming connections!");
}
final Join join = getJoin();
switch(join.getType()) {
case Join.TYPE_XOR:
triggerCompleted();
break;
case Join.TYPE_AND:
Integer count = (Integer) this.triggers.get(from.getNodeId());
if (count == null) {
this.triggers.put(from.getNodeId(), 1);
} else {
this.triggers.put(from.getNodeId(), count.intValue() + 1);
}
if (checkAllActivated()) {
decreaseAllTriggers();
triggerCompleted();
}
break;
case Join.TYPE_DISCRIMINATOR:
boolean triggerCompleted = triggers.isEmpty();
triggers.put(from.getNodeId(), new Integer(1));
if (checkAllActivated()) {
resetAllTriggers();
}
if (triggerCompleted) {
triggerCompleted();
}
break;
case Join.TYPE_N_OF_M:
count = (Integer) this.triggers.get(from.getNodeId());
if (count == null) {
this.triggers.put(from.getNodeId(), 1);
} else {
this.triggers.put(from.getNodeId(), count.intValue() + 1);
}
int counter = 0;
for (final Connection connection : getJoin().getDefaultIncomingConnections()) {
if (this.triggers.get(connection.getFrom().getId()) != null) {
counter++;
}
}
String n = join.getN();
Integer number = null;
if (n.startsWith("#{") && n.endsWith("}")) {
n = n.substring(2, n.length() - 1);
VariableScopeInstance variableScopeInstance = (VariableScopeInstance) resolveContextInstance(VariableScope.VARIABLE_SCOPE, n);
if (variableScopeInstance == null) {
throw new IllegalArgumentException("Could not find variable " + n + " when executing join.");
}
Object value = variableScopeInstance.getVariable(n);
if (value instanceof Number) {
number = ((Number) value).intValue();
} else {
throw new IllegalArgumentException("Variable " + n + " did not return a number when executing join: " + value);
}
} else {
number = new Integer(n);
}
if (counter >= number) {
resetAllTriggers();
triggerCompleted();
}
break;
case Join.TYPE_OR:
NodeInstanceContainer nodeInstanceContainer = (NodeInstanceContainer) getNodeInstanceContainer();
boolean activePathExists = existsActiveDirectFlow(nodeInstanceContainer, getJoin());
if (!activePathExists) {
triggerCompleted();
}
break;
default:
throw new IllegalArgumentException("Illegal join type " + join.getType());
}
}
use of org.kie.api.definition.process.Connection in project jbpm by kiegroup.
the class JoinInstance method checkNodes.
private boolean checkNodes(Set<Long> vistedNodes, Node startAt, Node currentNode, Node lookFor) {
if (currentNode == null) {
// for dynamic/ad hoc task there is no node
return false;
}
List<Connection> connections = currentNode.getOutgoingConnections(org.jbpm.workflow.core.Node.CONNECTION_DEFAULT_TYPE);
// special handling for XOR split as it usually is used for arbitrary loops
if (currentNode instanceof Split && ((Split) currentNode).getType() == Split.TYPE_XOR) {
if (vistedNodes.contains(startAt.getId())) {
return false;
}
for (Connection conn : connections) {
Set<Long> xorCopy = new HashSet<Long>(vistedNodes);
Node nextNode = conn.getTo();
if (nextNode == null) {
continue;
} else {
xorCopy.add(nextNode.getId());
if (nextNode.getId() != lookFor.getId()) {
checkNodes(xorCopy, currentNode, nextNode, lookFor);
}
}
if (xorCopy.contains(lookFor.getId())) {
vistedNodes.addAll(xorCopy);
return true;
}
}
} else {
for (Connection conn : connections) {
Node nextNode = conn.getTo();
if (nextNode == null) {
continue;
} else {
if (vistedNodes.contains(nextNode.getId())) {
// we have already been here so let's continue
continue;
}
if (nextNode.getId() == lookFor.getId()) {
// we found the node that we are looking for, add it and continue to find out other parts
// as it could be part of a loop
vistedNodes.add(nextNode.getId());
continue;
}
vistedNodes.add(nextNode.getId());
if (startAt.getId() == nextNode.getId()) {
return true;
} else {
boolean nestedCheck = checkNodes(vistedNodes, startAt, nextNode, lookFor);
if (nestedCheck) {
return true;
}
}
}
}
}
return false;
}
use of org.kie.api.definition.process.Connection in project jbpm by kiegroup.
the class SplitInstance method executeStrategy.
protected void executeStrategy(Split split, String type) {
// TODO make different strategies for each type
switch(split.getType()) {
case Split.TYPE_AND:
triggerCompleted(org.jbpm.workflow.core.Node.CONNECTION_DEFAULT_TYPE, true);
break;
case Split.TYPE_XOR:
List<Connection> outgoing = split.getDefaultOutgoingConnections();
int priority = Integer.MAX_VALUE;
Connection selected = null;
for (final Iterator<Connection> iterator = outgoing.iterator(); iterator.hasNext(); ) {
final Connection connection = (Connection) iterator.next();
ConstraintEvaluator constraint = (ConstraintEvaluator) split.getConstraint(connection);
if (constraint != null && constraint.getPriority() < priority && !constraint.isDefault()) {
try {
if (constraint.evaluate(this, connection, constraint)) {
selected = connection;
priority = constraint.getPriority();
}
} catch (RuntimeException e) {
throw new RuntimeException("Exception when trying to evaluate constraint " + constraint.getName() + " in split " + split.getName(), e);
}
}
}
((NodeInstanceContainer) getNodeInstanceContainer()).removeNodeInstance(this);
if (selected == null) {
for (final Iterator<Connection> iterator = outgoing.iterator(); iterator.hasNext(); ) {
final Connection connection = (Connection) iterator.next();
if (split.isDefault(connection)) {
selected = connection;
break;
}
}
}
if (selected == null) {
throw new IllegalArgumentException("XOR split could not find at least one valid outgoing connection for split " + getSplit().getName());
}
if (!hasLoop(selected.getTo(), split)) {
setLevel(1);
((NodeInstanceContainer) getNodeInstanceContainer()).setCurrentLevel(1);
}
triggerConnection(selected);
break;
case Split.TYPE_OR:
((NodeInstanceContainer) getNodeInstanceContainer()).removeNodeInstance(this);
outgoing = split.getDefaultOutgoingConnections();
boolean found = false;
List<NodeInstanceTrigger> nodeInstances = new ArrayList<NodeInstanceTrigger>();
List<Connection> outgoingCopy = new ArrayList<Connection>(outgoing);
while (!outgoingCopy.isEmpty()) {
priority = Integer.MAX_VALUE;
Connection selectedConnection = null;
ConstraintEvaluator selectedConstraint = null;
for (final Iterator<Connection> iterator = outgoingCopy.iterator(); iterator.hasNext(); ) {
final Connection connection = (Connection) iterator.next();
ConstraintEvaluator constraint = (ConstraintEvaluator) split.getConstraint(connection);
if (constraint != null && constraint.getPriority() < priority && !constraint.isDefault()) {
priority = constraint.getPriority();
selectedConnection = connection;
selectedConstraint = 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 (getProcessInstance().getState() != ProcessInstance.STATE_ACTIVE) {
return;
}
triggerNodeInstance(nodeInstance.getNodeInstance(), nodeInstance.getToType());
}
if (!found) {
for (final Iterator<Connection> iterator = outgoing.iterator(); iterator.hasNext(); ) {
final Connection connection = (Connection) iterator.next();
ConstraintEvaluator constraint = (ConstraintEvaluator) split.getConstraint(connection);
if (constraint != null && constraint.isDefault() || split.isDefault(connection)) {
triggerConnection(connection);
found = true;
break;
}
}
}
if (!found) {
throw new IllegalArgumentException("OR split could not find at least one valid outgoing connection for split " + getSplit().getName());
}
break;
case Split.TYPE_XAND:
((org.jbpm.workflow.instance.NodeInstanceContainer) getNodeInstanceContainer()).removeNodeInstance(this);
Node node = getNode();
List<Connection> connections = null;
if (node != null) {
connections = node.getOutgoingConnections(type);
}
if (connections == null || connections.isEmpty()) {
((org.jbpm.workflow.instance.NodeInstanceContainer) getNodeInstanceContainer()).nodeInstanceCompleted(this, type);
} else {
ExclusiveGroupInstance groupInstance = new ExclusiveGroupInstance();
org.kie.api.runtime.process.NodeInstanceContainer parent = getNodeInstanceContainer();
if (parent instanceof ContextInstanceContainer) {
((ContextInstanceContainer) parent).addContextInstance(ExclusiveGroup.EXCLUSIVE_GROUP, groupInstance);
} else {
throw new IllegalArgumentException("An Exclusive AND is only possible if the parent is a context instance container");
}
Map<org.jbpm.workflow.instance.NodeInstance, String> nodeInstancesMap = new HashMap<org.jbpm.workflow.instance.NodeInstance, String>();
for (Connection connection : connections) {
nodeInstancesMap.put(followConnection(connection), connection.getToType());
}
for (NodeInstance nodeInstance : nodeInstancesMap.keySet()) {
groupInstance.addNodeInstance(nodeInstance);
}
for (Map.Entry<org.jbpm.workflow.instance.NodeInstance, String> entry : nodeInstancesMap.entrySet()) {
// stop if this process instance has been aborted / completed
if (getProcessInstance().getState() != ProcessInstance.STATE_ACTIVE) {
return;
}
boolean hidden = false;
if (getNode().getMetaData().get("hidden") != null) {
hidden = true;
}
InternalKnowledgeRuntime kruntime = getProcessInstance().getKnowledgeRuntime();
if (!hidden) {
((InternalProcessRuntime) kruntime.getProcessRuntime()).getProcessEventSupport().fireBeforeNodeLeft(this, kruntime);
}
((org.jbpm.workflow.instance.NodeInstance) entry.getKey()).trigger(this, entry.getValue());
if (!hidden) {
((InternalProcessRuntime) kruntime.getProcessRuntime()).getProcessEventSupport().fireAfterNodeLeft(this, kruntime);
}
}
}
break;
default:
throw new IllegalArgumentException("Illegal split type " + split.getType());
}
}
use of org.kie.api.definition.process.Connection in project jbpm by kiegroup.
the class CompositeNodeInstance method internalTrigger.
public void internalTrigger(final org.kie.api.runtime.process.NodeInstance from, String type) {
super.internalTrigger(from, type);
// if node instance was cancelled, abort
if (getNodeInstanceContainer().getNodeInstance(getId()) == null) {
return;
}
CompositeNode.NodeAndType nodeAndType = getCompositeNode().internalGetLinkedIncomingNode(type);
if (nodeAndType != null) {
List<Connection> connections = nodeAndType.getNode().getIncomingConnections(nodeAndType.getType());
for (Iterator<Connection> iterator = connections.iterator(); iterator.hasNext(); ) {
Connection connection = iterator.next();
if ((connection.getFrom() instanceof CompositeNode.CompositeNodeStart) && (from == null || ((CompositeNode.CompositeNodeStart) connection.getFrom()).getInNode().getId() == from.getNodeId())) {
NodeInstance nodeInstance = getNodeInstance(connection.getFrom());
((org.jbpm.workflow.instance.NodeInstance) nodeInstance).trigger(null, nodeAndType.getType());
return;
}
}
} else {
// try to search for start nodes
boolean found = false;
for (Node node : getCompositeNode().getNodes()) {
if (node instanceof StartNode) {
StartNode startNode = (StartNode) node;
if (startNode.getTriggers() == null || startNode.getTriggers().isEmpty()) {
NodeInstance nodeInstance = getNodeInstance(startNode);
((org.jbpm.workflow.instance.NodeInstance) nodeInstance).trigger(null, null);
found = true;
}
}
}
if (found) {
return;
}
}
if (isLinkedIncomingNodeRequired()) {
throw new IllegalArgumentException("Could not find start for composite node: " + type);
}
}
use of org.kie.api.definition.process.Connection in project jbpm by kiegroup.
the class NodeInstanceImpl method triggerNodeInstance.
protected void triggerNodeInstance(org.jbpm.workflow.instance.NodeInstance nodeInstance, String type) {
boolean hidden = false;
if (getNode().getMetaData().get("hidden") != null) {
hidden = true;
}
InternalKnowledgeRuntime kruntime = getProcessInstance().getKnowledgeRuntime();
if (!hidden) {
((InternalProcessRuntime) kruntime.getProcessRuntime()).getProcessEventSupport().fireBeforeNodeLeft(this, kruntime);
}
// trigger next node
nodeInstance.trigger(this, type);
Collection<Connection> outgoing = getNode().getOutgoingConnections(type);
for (Connection conn : outgoing) {
if (conn.getTo().getId() == nodeInstance.getNodeId()) {
this.metaData.put("OutgoingConnection", conn.getMetaData().get("UniqueId"));
break;
}
}
if (!hidden) {
((InternalProcessRuntime) kruntime.getProcessRuntime()).getProcessEventSupport().fireAfterNodeLeft(this, kruntime);
}
}
Aggregations