use of org.jbpm.workflow.core.impl.NodeImpl in project jbpm by kiegroup.
the class MultiConditionalSequenceFlowNodeBuilder method build.
public void build(Process process, ProcessDescr processDescr, ProcessBuildContext context, Node node) {
Map<ConnectionRef, Constraint> constraints = ((NodeImpl) node).getConstraints();
// exclude split as it is handled with separate builder and nodes with non conditional sequence flows
if (node instanceof Split || constraints.size() == 0) {
return;
}
// we need to clone the map, so we can update the original while iterating.
Map<ConnectionRef, Constraint> map = new HashMap<ConnectionRef, Constraint>(constraints);
for (Iterator<Map.Entry<ConnectionRef, Constraint>> it = map.entrySet().iterator(); it.hasNext(); ) {
Map.Entry<ConnectionRef, Constraint> entry = it.next();
ConnectionRef connection = entry.getKey();
ConstraintImpl constraint = (ConstraintImpl) entry.getValue();
Connection outgoingConnection = null;
for (Connection out : ((NodeImpl) node).getDefaultOutgoingConnections()) {
if (out.getToType().equals(connection.getToType()) && out.getTo().getId() == connection.getNodeId()) {
outgoingConnection = out;
}
}
if (outgoingConnection == null) {
throw new IllegalArgumentException("Could not find outgoing connection");
}
if ("rule".equals(constraint.getType())) {
RuleConstraintEvaluator ruleConstraint = new RuleConstraintEvaluator();
ruleConstraint.setDialect(constraint.getDialect());
ruleConstraint.setName(constraint.getName());
ruleConstraint.setPriority(constraint.getPriority());
ruleConstraint.setDefault(constraint.isDefault());
((NodeImpl) node).setConstraint(outgoingConnection, ruleConstraint);
} else if ("code".equals(constraint.getType())) {
ReturnValueConstraintEvaluator returnValueConstraint = new ReturnValueConstraintEvaluator();
returnValueConstraint.setDialect(constraint.getDialect());
returnValueConstraint.setName(constraint.getName());
returnValueConstraint.setPriority(constraint.getPriority());
returnValueConstraint.setDefault(constraint.isDefault());
((NodeImpl) node).setConstraint(outgoingConnection, returnValueConstraint);
ReturnValueDescr returnValueDescr = new ReturnValueDescr();
returnValueDescr.setText(constraint.getConstraint());
returnValueDescr.setResource(processDescr.getResource());
ProcessDialect dialect = ProcessDialectRegistry.getDialect(constraint.getDialect());
dialect.getReturnValueEvaluatorBuilder().build(context, returnValueConstraint, returnValueDescr, (NodeImpl) node);
}
}
}
use of org.jbpm.workflow.core.impl.NodeImpl 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.jbpm.workflow.core.impl.NodeImpl in project jbpm by kiegroup.
the class WorkflowProcessInstanceUpgrader method updateNodeInstances.
private static void updateNodeInstances(NodeInstanceContainer nodeInstanceContainer, Map<String, Long> nodeMapping) {
for (NodeInstance nodeInstance : nodeInstanceContainer.getNodeInstances()) {
String oldNodeId = ((NodeImpl) ((org.jbpm.workflow.instance.NodeInstance) nodeInstance).getNode()).getUniqueId();
Long newNodeId = nodeMapping.get(oldNodeId);
if (newNodeId == null) {
newNodeId = nodeInstance.getNodeId();
}
// clean up iteration levels for removed (old) nodes
Map<String, Integer> iterLevels = ((WorkflowProcessInstanceImpl) nodeInstance.getProcessInstance()).getIterationLevels();
String uniqueId = (String) ((NodeImpl) nodeInstance.getNode()).getMetaData("UniqueId");
iterLevels.remove(uniqueId);
// and now set to new node id
((NodeInstanceImpl) nodeInstance).setNodeId(newNodeId);
if (nodeInstance instanceof NodeInstanceContainer) {
updateNodeInstances((NodeInstanceContainer) nodeInstance, nodeMapping);
}
}
}
use of org.jbpm.workflow.core.impl.NodeImpl in project jbpm by kiegroup.
the class ChecklistItemFactory method getPendingChecklistItems.
private static void getPendingChecklistItems(NodeContainer container, List<ChecklistItem> result, String processId) {
for (Node node : container.getNodes()) {
if (node instanceof HumanTaskNode) {
Work workItem = ((HumanTaskNode) node).getWork();
int priority = 0;
String priorityString = (String) workItem.getParameter("Priority");
if (priorityString != null) {
try {
priority = new Integer(priorityString);
} catch (NumberFormatException e) {
// Do nothing
}
}
String actorId = (String) workItem.getParameter("ActorId");
if (actorId != null && actorId.trim().length() == 0) {
actorId = null;
}
String groupId = (String) workItem.getParameter("GroupId");
if (groupId != null && groupId.trim().length() == 0) {
groupId = null;
}
String actors = null;
if (actorId == null) {
if (groupId == null) {
actors = "";
} else {
actors = groupId;
}
} else {
if (groupId == null) {
actors = actorId;
} else {
actors = actorId + "," + groupId;
}
}
Status status = Status.Pending;
if (((HumanTaskNode) node).getDefaultIncomingConnections().size() == 0) {
status = Status.Optional;
}
result.add(createChecklistItem((String) workItem.getParameter("TaskName"), "HumanTaskNode", actors, (String) workItem.getParameter("Comment"), priority, processId, status));
} else if (node instanceof NodeContainer) {
getPendingChecklistItems((NodeContainer) node, result, processId);
} else {
String docs = (String) node.getMetaData().get("Documentation");
if (docs != null) {
int position = docs.indexOf("OrderingNb=");
if (position >= 0) {
int end = docs.indexOf(";", position + 1);
String orderingNumber = docs.substring(position + 11, end);
Status status = Status.Pending;
if (((NodeImpl) node).getDefaultIncomingConnections().size() == 0 && !(node instanceof StartNode)) {
status = Status.Optional;
}
result.add(createChecklistItem(node.getName(), node.getClass().getSimpleName(), "", orderingNumber, 0, processId, status));
}
}
}
}
}
use of org.jbpm.workflow.core.impl.NodeImpl in project jbpm by kiegroup.
the class ProcessHandler method checkBoundaryEventCompensationHandler.
/**
* This logic belongs in {@link RuleFlowProcessValidator} -- except that {@link Association}s are a jbpm-bpmn2 class,
* and {@link RuleFlowProcessValidator} is a jbpm-flow class..
* </p>
* Maybe we should have a BPMNProcessValidator class?
*
* @param association The association to check.
* @param source The source of the association.
* @param target The target of the association.
*/
private static void checkBoundaryEventCompensationHandler(Association association, Node source, Node target) {
// - event node is boundary event node
if (!(source instanceof BoundaryEventNode)) {
throw new IllegalArgumentException("(Compensation) activities may only be associated with Boundary Event Nodes (not with" + source.getClass().getSimpleName() + " nodes [node " + ((String) source.getMetaData().get("UniqueId")) + "].");
}
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 IllegalArgumentException("An Event [" + ((String) eventNode.getMetaData("UniqueId")) + "] 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.getNodeContainer().getNodes()) {
if (attachedToId.equals(node.getMetaData().get("UniqueId"))) {
attachedToNode = node;
break;
}
}
if (attachedToNode == null) {
throw new IllegalArgumentException("Boundary Event [" + ((String) eventNode.getMetaData("UniqueId")) + "] 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 IllegalArgumentException("Compensation Boundary Event [" + ((String) eventNode.getMetaData("UniqueId")) + "] 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 IllegalArgumentException("An Activity [" + ((String) ((NodeImpl) target).getMetaData("UniqueId")) + "] 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 IllegalArgumentException("A Compensation Activity [" + ((String) targetNode.getMetaData("UniqueId")) + "] may not have any outgoing connection [" + (String) outgoingConnection.getMetaData("UniqueId") + "]");
}
}
Aggregations