use of io.automatiko.engine.workflow.process.core.node.RuleSetNode in project automatiko-engine by automatiko-io.
the class SvgBpmnProcessImageGenerator method buildNodeContainer.
/*
* Build methods
*/
protected void buildNodeContainer(int x, int y, NodeContainer nodeContainer, SVGGraphics2D g2) {
try {
for (Node node : nodeContainer.getNodes()) {
if (node instanceof StartNode) {
buildStartEvent(x, y, (StartNode) node, g2);
} else if (node instanceof EndNode) {
buildEndEvent(x, y, (EndNode) node, g2);
} else if (node instanceof FaultNode) {
buildErrorEndEvent(x, y, (FaultNode) node, g2);
} else if (node instanceof BoundaryEventNode) {
buildBoundaryEvent(x, y, node, g2);
} else if (node instanceof EventNode || node instanceof StateNode) {
buildIntermediateEvent(x, y, node, g2);
} else if (node instanceof HumanTaskNode) {
buildHumanTaskNode(x, y, (HumanTaskNode) node, g2);
} else if (node instanceof ActionNode) {
buildScriptTaskNode(x, y, (ActionNode) node, g2);
} else if (node instanceof WorkItemNode) {
buildServiceTaskNode(x, y, (WorkItemNode) node, g2);
} else if (node instanceof Split || node instanceof Join) {
buildGateway(x, y, node, g2);
} else if (node instanceof ForEachNode) {
buildNodeContainer(x(node), y(node), ((ForEachNode) node).getCompositeNode(), g2);
} else if (node instanceof CompositeNode) {
buildSubprocessNode(x, y, (CompositeNode) node, g2);
int sx = x(node);
int sy = y(node);
buildNodeContainer(sx, sy, (CompositeNode) node, g2);
} else if (node instanceof RuleSetNode) {
buildBusinessRuleTaskNode(x, y, (RuleSetNode) node, g2);
} else if (node instanceof TimerNode) {
buildTimerEvent(x, y, (TimerNode) node, g2);
} else if (node instanceof SubProcessNode) {
buildCallActivity(x, y, (SubProcessNode) node, g2);
}
buildSequenceFlow(x, y, node, g2);
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
use of io.automatiko.engine.workflow.process.core.node.RuleSetNode in project automatiko-engine by automatiko-io.
the class ProcessHandler method checkBoundaryEventCompensationHandler.
/**
* This logic belongs in {@link ExecutableProcessValidator} -- except that
* {@link Association}s are a jbpm-bpmn2 class, and
* {@link ExecutableProcessValidator} 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.getParentContainer().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<io.automatiko.engine.api.definition.process.Connection>> connectionsMap = targetNode.getOutgoingConnections();
ConnectionImpl outgoingConnection = null;
for (String connectionType : connectionsMap.keySet()) {
List<io.automatiko.engine.api.definition.process.Connection> connections = connectionsMap.get(connectionType);
if (connections != null && !connections.isEmpty()) {
for (io.automatiko.engine.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") + "]");
}
}
use of io.automatiko.engine.workflow.process.core.node.RuleSetNode in project automatiko-engine by automatiko-io.
the class RuleSetNodeInstance method internalTrigger.
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void internalTrigger(final NodeInstance from, String type) {
try {
super.internalTrigger(from, type);
// if node instance was cancelled, abort
if (getNodeInstanceContainer().getNodeInstance(getId()) == null) {
return;
}
if (!io.automatiko.engine.workflow.process.core.Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
throw new IllegalArgumentException("A RuleSetNode only accepts default incoming connections!");
}
RuleSetNode ruleSetNode = getRuleSetNode();
Map<String, Object> inputs = evaluateParameters(ruleSetNode);
RuleSetNode.RuleType ruleType = ruleSetNode.getRuleType();
if (ruleType.isDecision()) {
RuleSetNode.RuleType.Decision decisionModel = (RuleSetNode.RuleType.Decision) ruleType;
String dName = resolveVariable(decisionModel.getDecision());
DecisionModel modelInstance = getRuleSetNode().getDecisionModel().get();
Object context = modelInstance.newContext(inputs);
Object dmnResult = null;
if (dName == null) {
dmnResult = modelInstance.evaluateAll(context);
} else if (decisionModel.isDecisionService()) {
dmnResult = modelInstance.evaluateDecisionService(context, dName);
} else {
dmnResult = modelInstance.evaluateDecisionByName(context, dName);
}
if (modelInstance.hasErrors(dmnResult)) {
throw new WorkItemExecutionError("DecisionEvaluationFailure", modelInstance.buildErrorMessage(dmnResult), modelInstance.getErrorData(dmnResult));
}
processOutputs(inputs, modelInstance.getResultData(dmnResult));
triggerCompleted();
} else {
throw new UnsupportedOperationException("Unsupported Rule Type: " + ruleType);
}
} catch (Exception e) {
handleException(e);
}
}
use of io.automatiko.engine.workflow.process.core.node.RuleSetNode in project automatiko-engine by automatiko-io.
the class RuleSetNodeInstance method processOutputs.
@SuppressWarnings({ "unchecked", "rawtypes" })
private void processOutputs(Map<String, Object> inputs, Map<String, Object> objects) {
logger.debug("Rules evaluation results {}", objects);
RuleSetNode ruleSetNode = getRuleSetNode();
if (ruleSetNode != null) {
for (Iterator<DataAssociation> iterator = ruleSetNode.getOutAssociations().iterator(); iterator.hasNext(); ) {
DataAssociation association = iterator.next();
if (association.getTransformation() != null) {
Transformation transformation = association.getTransformation();
DataTransformer transformer = DataTransformerRegistry.get().find(transformation.getLanguage());
if (transformer != null) {
Map<String, Object> dataSet = new HashMap<String, Object>();
if (getNodeInstanceContainer() instanceof CompositeContextNodeInstance) {
VariableScopeInstance variableScopeInstance = (VariableScopeInstance) ((CompositeContextNodeInstance) getNodeInstanceContainer()).getContextInstance(VariableScope.VARIABLE_SCOPE);
if (variableScopeInstance != null) {
dataSet.putAll(variableScopeInstance.getVariables());
}
}
dataSet.putAll(inputs);
dataSet.putAll(objects);
Object parameterValue = transformer.transform(transformation.getCompiledExpression(), dataSet);
VariableScopeInstance variableScopeInstance = (VariableScopeInstance) resolveContextInstance(VariableScope.VARIABLE_SCOPE, association.getTarget());
if (variableScopeInstance != null && parameterValue != null) {
variableScopeInstance.setVariable(this, association.getTarget(), parameterValue);
} else {
logger.warn("Could not find variable scope for variable {}", association.getTarget());
logger.warn("Continuing without setting variable.");
}
}
} else if (association.getAssignments() == null || association.getAssignments().isEmpty()) {
VariableScopeInstance variableScopeInstance = (VariableScopeInstance) resolveContextInstance(VariableScope.VARIABLE_SCOPE, association.getTarget());
if (variableScopeInstance != null) {
Object value = objects.get(association.getSources().get(0));
if (value == null) {
try {
ExpressionEvaluator evaluator = (ExpressionEvaluator) ((WorkflowProcess) getProcessInstance().getProcess()).getDefaultContext(ExpressionEvaluator.EXPRESSION_EVALUATOR);
value = evaluator.evaluate(association.getSources().get(0), new MapVariableResolverFactory(objects));
} catch (Throwable t) {
// do nothing
}
}
Variable varDef = variableScopeInstance.getVariableScope().findVariable(association.getTarget());
DataType dataType = varDef.getType();
// exclude java.lang.Object as it is considered unknown type
if (!dataType.getStringType().endsWith("java.lang.Object") && value instanceof String) {
value = dataType.readValue((String) value);
}
variableScopeInstance.setVariable(this, association.getTarget(), value);
} else {
String output = association.getSources().get(0);
String target = association.getTarget();
Matcher matcher = PatternConstants.PARAMETER_MATCHER.matcher(target);
if (matcher.find()) {
String paramName = matcher.group(1);
String expression = VariableUtil.transformDotNotation(paramName, output);
NodeInstanceResolverFactory resolver = new NodeInstanceResolverFactory(this);
resolver.addExtraParameters(objects);
Serializable compiled = MVEL.compileExpression(expression);
MVEL.executeExpression(compiled, resolver);
String varName = VariableUtil.nameFromDotNotation(paramName);
variableScopeInstance = (VariableScopeInstance) resolveContextInstance(VARIABLE_SCOPE, varName);
variableScopeInstance.setVariable(this, varName, variableScopeInstance.getVariable(varName));
} else {
logger.warn("Could not find variable scope for variable {}", association.getTarget());
}
}
}
}
}
}
use of io.automatiko.engine.workflow.process.core.node.RuleSetNode in project automatiko-engine by automatiko-io.
the class RuleSetNodeHandler method writeNode.
public void writeNode(Node node, StringBuilder xmlDump, boolean includeMeta) {
RuleSetNode ruleSetNode = (RuleSetNode) node;
writeNode("ruleSet", ruleSetNode, xmlDump, includeMeta);
RuleSetNode.RuleType ruleType = ruleSetNode.getRuleType();
if (ruleType != null) {
if (!ruleType.isDecision()) {
xmlDump.append("ruleFlowGroup=\"" + ruleType.getName() + "\" ");
}
}
xmlDump.append(" implementation=\"" + ruleSetNode.getLanguage() + "\" ");
if (ruleSetNode.getTimers() != null || (includeMeta && containsMetaData(ruleSetNode))) {
xmlDump.append(">\n");
if (ruleSetNode.getTimers() != null) {
writeTimers(ruleSetNode.getTimers(), xmlDump);
}
if (includeMeta) {
writeMetaData(ruleSetNode, xmlDump);
}
endNode("ruleSet", xmlDump);
} else {
endNode(xmlDump);
}
}
Aggregations