use of org.kie.api.definition.process.Node in project jbpm by kiegroup.
the class CompensationEventListener method signalEvent.
/**
* When signaling compensation, you can do that in 1 of 2 ways:
* 1. signalEvent("Compensation", <node-with-compensation-handler-id>)
* This is specific compensation, that only possibly triggers the compensation handler
* attached to the node referred to by the <node-with-compensation-handler-id>.
* 2. signalEvent("Compensation", "implicit:" + <node-container-containing-compensation-scope-id> )
* This is implicit or general compensation, in which you trigger all visible compensation handlers
* (in the proper order, etc.) in the (sub-)process referred to by
* the <node-container-containing-compensation-scope-id>.
*/
public void signalEvent(String compensationType, Object activityRefStr) {
if (activityRefStr == null || !(activityRefStr instanceof String)) {
throw new WorkflowRuntimeException(null, getProcessInstance(), "Compensation can only be triggered with String events, not an event of type " + activityRefStr == null ? "null" : activityRefStr.getClass().getSimpleName());
}
// 1. parse the activity ref (is it general or specific compensation?)
String activityRef = (String) activityRefStr;
String toCompensateNodeId = activityRef;
boolean generalCompensation = false;
if (activityRef.startsWith(IMPLICIT_COMPENSATION_PREFIX)) {
toCompensateNodeId = activityRef.substring(IMPLICIT_COMPENSATION_PREFIX.length());
generalCompensation = true;
}
org.jbpm.process.core.Process process = (org.jbpm.process.core.Process) instance.getProcess();
// 2. for specific compensation: find the node that will be compensated
// for general compensation: find the compensation scope container that contains all the visible compensation handlers
Node toCompensateNode = null;
ContextContainer compensationScopeContainer = null;
if (generalCompensation) {
if (toCompensateNodeId.equals(instance.getProcessId())) {
compensationScopeContainer = process;
} else {
compensationScopeContainer = (ContextContainer) findNode(toCompensateNodeId);
}
} else {
toCompensateNode = findNode(toCompensateNodeId);
}
// c. handle the exception (which also cleans up the generated node instances)
if (toCompensateNode != null || compensationScopeContainer != null) {
CompensationScope compensationScope = null;
if (compensationScopeContainer != null) {
compensationScope = (CompensationScope) compensationScopeContainer.getDefaultContext(COMPENSATION_SCOPE);
} else {
compensationScope = (CompensationScope) ((NodeImpl) toCompensateNode).resolveContext(COMPENSATION_SCOPE, toCompensateNodeId);
}
assert compensationScope != null : "Compensation scope for node [" + toCompensateNodeId + "] could not be found!";
CompensationScopeInstance scopeInstance;
if (compensationScope.getContextContainerId().equals(process.getId())) {
// process level compensation
scopeInstance = (CompensationScopeInstance) instance.getContextInstance(compensationScope);
} else {
// nested compensation
Stack<NodeInstance> generatedInstances;
if (toCompensateNode == null) {
// logic is the same if it's specific or general
generatedInstances = createNodeInstanceContainers((Node) compensationScopeContainer, true);
} else {
generatedInstances = createNodeInstanceContainers(toCompensateNode, false);
}
NodeInstance nodeInstanceContainer = generatedInstances.peek();
scopeInstance = ((CompensationScopeInstance) ((ContextInstanceContainer) nodeInstanceContainer).getContextInstance(compensationScope));
scopeInstance.addCompensationInstances(generatedInstances);
}
scopeInstance.handleException(activityRef, null);
}
}
use of org.kie.api.definition.process.Node in project jbpm by kiegroup.
the class NodeInstanceImpl method cancel.
public void cancel() {
nodeInstanceContainer.removeNodeInstance(this);
boolean hidden = false;
Node node = getNode();
if (node != null && node.getMetaData().get("hidden") != null) {
hidden = true;
}
if (!hidden) {
InternalKnowledgeRuntime kruntime = getProcessInstance().getKnowledgeRuntime();
((InternalProcessRuntime) kruntime.getProcessRuntime()).getProcessEventSupport().fireAfterNodeLeft(this, kruntime);
}
}
use of org.kie.api.definition.process.Node in project jbpm by kiegroup.
the class WorkflowProcessInstanceImpl method signalEvent.
@SuppressWarnings("unchecked")
public void signalEvent(String type, Object event) {
logger.debug("Signal {} received with data {} in process instance {}", type, event, getId());
synchronized (this) {
if (getState() != ProcessInstance.STATE_ACTIVE) {
return;
}
if ("timerTriggered".equals(type)) {
TimerInstance timer = (TimerInstance) event;
if (timer.getId() == slaTimerId) {
handleSLAViolation();
// no need to pass the event along as it was purely for SLA tracking
return;
}
}
if ("slaViolation".equals(type)) {
handleSLAViolation();
// no need to pass the event along as it was purely for SLA tracking
return;
}
List<NodeInstance> currentView = new ArrayList<NodeInstance>(this.nodeInstances);
try {
this.activatingNodeIds = new ArrayList<String>();
List<EventListener> listeners = eventListeners.get(type);
if (listeners != null) {
for (EventListener listener : listeners) {
listener.signalEvent(type, event);
}
}
listeners = externalEventListeners.get(type);
if (listeners != null) {
for (EventListener listener : listeners) {
listener.signalEvent(type, event);
}
}
for (Node node : getWorkflowProcess().getNodes()) {
if (node instanceof EventNodeInterface) {
if (((EventNodeInterface) node).acceptsEvent(type, event, (e) -> resolveVariable(e))) {
if (node instanceof EventNode && ((EventNode) node).getFrom() == null) {
EventNodeInstance eventNodeInstance = (EventNodeInstance) getNodeInstance(node);
eventNodeInstance.signalEvent(type, event);
} else {
if (node instanceof EventSubProcessNode && ((resolveVariables(((EventSubProcessNode) node).getEvents()).contains(type)))) {
EventSubProcessNodeInstance eventNodeInstance = (EventSubProcessNodeInstance) getNodeInstance(node);
eventNodeInstance.signalEvent(type, event);
}
if (node instanceof DynamicNode && type.equals(((DynamicNode) node).getActivationEventName())) {
DynamicNodeInstance dynamicNodeInstance = (DynamicNodeInstance) getNodeInstance(node);
dynamicNodeInstance.signalEvent(type, event);
} else {
List<NodeInstance> nodeInstances = getNodeInstances(node.getId(), currentView);
if (nodeInstances != null && !nodeInstances.isEmpty()) {
for (NodeInstance nodeInstance : nodeInstances) {
((EventNodeInstanceInterface) nodeInstance).signalEvent(type, event);
}
}
}
}
}
}
}
if (((org.jbpm.workflow.core.WorkflowProcess) getWorkflowProcess()).isDynamic()) {
for (Node node : getWorkflowProcess().getNodes()) {
if (type.equals(node.getName()) && node.getIncomingConnections().isEmpty()) {
NodeInstance nodeInstance = getNodeInstance(node);
if (event != null) {
Map<String, Object> dynamicParams = new HashMap<>();
if (event instanceof Map) {
dynamicParams.putAll((Map<String, Object>) event);
} else {
dynamicParams.put("Data", event);
}
((org.jbpm.workflow.instance.NodeInstance) nodeInstance).setDynamicParameters(dynamicParams);
}
((org.jbpm.workflow.instance.NodeInstance) nodeInstance).trigger(null, NodeImpl.CONNECTION_DEFAULT_TYPE);
}
}
}
} finally {
if (this.activatingNodeIds != null) {
this.activatingNodeIds.clear();
this.activatingNodeIds = null;
}
}
}
}
use of org.kie.api.definition.process.Node in project jbpm by kiegroup.
the class WorkflowProcessInstanceUpgrader method getNodeId.
private static String getNodeId(Node[] nodes, String nodeName, boolean unique) {
Stack<Node> nodeStack = new Stack<Node>();
for (Node node : nodes) {
nodeStack.push(node);
}
Node match = null;
while (!nodeStack.isEmpty()) {
Node topNode = nodeStack.pop();
if (topNode.getName().compareTo(nodeName) == 0) {
match = topNode;
break;
}
if (topNode instanceof NodeContainer) {
for (Node node : ((NodeContainer) topNode).getNodes()) {
nodeStack.push(node);
}
}
}
if (match == null) {
throw new IllegalArgumentException("No node with name " + nodeName);
}
String id = "";
if (unique) {
while (!(match.getNodeContainer() instanceof Process)) {
id = ":" + match.getId() + id;
match = (Node) match.getNodeContainer();
}
}
id = match.getId() + id;
return id;
}
use of org.kie.api.definition.process.Node in project jbpm by kiegroup.
the class CompositeNode method removeIncomingConnection.
public void removeIncomingConnection(String type, Connection connection) {
super.removeIncomingConnection(type, connection);
CompositeNode.NodeAndType nodeAndType = internalGetLinkedIncomingNode(type);
if (nodeAndType != null) {
for (Connection inConnection : nodeAndType.getNode().getIncomingConnections(nodeAndType.getType())) {
if (((CompositeNodeStart) inConnection.getFrom()).getInNodeId() == connection.getFrom().getId()) {
Node compositeNodeStart = inConnection.getFrom();
((ConnectionImpl) inConnection).terminate();
internalRemoveNode(compositeNodeStart);
return;
}
}
throw new IllegalArgumentException("Could not find internal incoming connection for node");
}
}
Aggregations