Skip to content

Commit

Permalink
unify return value builder
Browse files Browse the repository at this point in the history
  • Loading branch information
elguardian committed Jun 3, 2024
1 parent b9a38c2 commit 30793c6
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,17 +63,26 @@ protected Node handleNode(final Node node, final Element element, final String u
if ("false".equals(cancelRemainingInstances)) {
dynamicNode.setCancelRemainingInstances(false);
}

dynamicNode.setLanguage("http://www.java.com/java");

// by default it should not autocomplete as it's adhoc
org.w3c.dom.Node xmlNode = element.getFirstChild();
dynamicNode.setActivationCondition((String) node.getMetaData().get(CUSTOM_ACTIVATION_CONDITION));
while (xmlNode != null) {
String nodeName = xmlNode.getNodeName();
if (COMPLETION_CONDITION.equals(nodeName)) {
Element completeConditionElement = (Element) xmlNode;
String dialect = completeConditionElement.getAttribute("language");

String expression = xmlNode.getTextContent();
if (AUTOCOMPLETE_EXPRESSIONS.contains(expression)) {
dynamicNode.setAutoComplete(true);
} else {
dynamicNode.setCompletionCondition(expression);
if (!dialect.isBlank()) {
dynamicNode.setLanguage(dialect);
}
}
}
xmlNode = xmlNode.getNextSibling();
Expand Down Expand Up @@ -104,7 +113,7 @@ public void writeNode(Node node, StringBuilder xmlDump, int metaDataType) {
visitConnectionsAndAssociations(dynamicNode, xmlDump, metaDataType);

if (dynamicNode.isAutoComplete()) {
xmlDump.append(" <completionCondition xsi:type=\"tFormalExpression\">" + AUTOCOMPLETE_COMPLETION_CONDITION + "</completionCondition>" + EOL);
xmlDump.append("<completionCondition xsi:type=\"tFormalExpression\" language=\"" + dynamicNode.getLanguage() + "\">" + AUTOCOMPLETE_COMPLETION_CONDITION + "</completionCondition>" + EOL);
}
endNode("adHocSubProcess", xmlDump);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.stream.Stream;

import org.jbpm.compiler.canonical.builtin.ReturnValueEvaluatorBuilderService;
import org.jbpm.compiler.canonical.node.NodeVisitorBuilderService;
import org.jbpm.process.core.context.variable.VariableScope;
import org.jbpm.ruleflow.core.factory.DynamicNodeFactory;
Expand All @@ -35,8 +37,11 @@

public class DynamicNodeVisitor extends CompositeContextNodeVisitor<DynamicNode> {

public DynamicNodeVisitor(NodeVisitorBuilderService nodeVisitorService) {
private ReturnValueEvaluatorBuilderService builder;

public DynamicNodeVisitor(NodeVisitorBuilderService nodeVisitorService, ClassLoader classLoader) {
super(nodeVisitorService);
this.builder = ReturnValueEvaluatorBuilderService.instance(classLoader);
}

@Override
Expand All @@ -56,22 +61,26 @@ protected String getDefaultName() {

@Override
public Stream<MethodCallExpr> visitCustomFields(DynamicNode node, VariableScope variableScope) {
if (node.isAutoComplete()) {
return Collections.<MethodCallExpr> emptyList().stream();
}

Collection<MethodCallExpr> methods = new ArrayList<>();
methods.add(getFactoryMethod(getNodeId(node), METHOD_LANGUAGE, getOrNullExpr(node.getLanguage())));
if (node.getActivationCondition() != null && !node.getActivationCondition().trim().isEmpty()) {
methods.add(getActivationConditionStatement(node, variableScope));
if (node.getActivationCondition() != null && !node.getActivationCondition().isBlank()) {
methods.add(getActivationConditionStatement(node));
}
if (node.getCompletionCondition() != null && !node.getCompletionCondition().trim().isEmpty()) {
methods.add(getCompletionConditionStatement(node, variableScope));
if (node.getCompletionCondition() != null && !node.getCompletionCondition().isBlank()) {
methods.add(getCompletionConditionStatement(node));
}
return methods.stream();
}

private MethodCallExpr getActivationConditionStatement(DynamicNode node, VariableScope scope) {
return getFactoryMethod(getNodeId(node), METHOD_ACTIVATION_EXPRESSION, createLambdaExpr(node.getActivationCondition(), scope));
private MethodCallExpr getActivationConditionStatement(DynamicNode node) {
return getFactoryMethod(getNodeId(node), METHOD_ACTIVATION_EXPRESSION, builder.build(node, node.getLanguage(), node.getActivationCondition(), Boolean.class, (String) null));
}

private MethodCallExpr getCompletionConditionStatement(DynamicNode node, VariableScope scope) {
return getFactoryMethod(getNodeId(node), METHOD_COMPLETION_EXPRESSION, createLambdaExpr(node.getCompletionCondition(), scope));
private MethodCallExpr getCompletionConditionStatement(DynamicNode node) {
return getFactoryMethod(getNodeId(node), METHOD_COMPLETION_EXPRESSION, builder.build(node, node.getLanguage(), node.getCompletionCondition(), Boolean.class, (String) null));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@
import org.jbpm.process.core.context.variable.Variable;
import org.jbpm.process.core.context.variable.VariableScope;

import com.github.javaparser.ParseProblemException;
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.LambdaExpr;
import com.github.javaparser.ast.expr.NameExpr;
import com.github.javaparser.ast.stmt.BlockStmt;
import com.github.javaparser.ast.stmt.ReturnStmt;
import com.github.javaparser.ast.type.UnknownType;

public class JavaConstraintEvaluatorBuilder implements ReturnValueEvaluatorBuilder {
Expand All @@ -48,7 +50,16 @@ public Expression build(ContextResolver resolver, String expression, Class<?> ty
new Parameter(new UnknownType(), KCONTEXT_VAR), // (kcontext) ->
actionBody);

BlockStmt blockStmt = StaticJavaParser.parseBlock("{" + expression + "}");
BlockStmt blockStmt = parseExpression(expression);

if (blockStmt == null) {
blockStmt = parseStatement(expression);
}

if (blockStmt == null) {
blockStmt = StaticJavaParser.parseBlock(expression);
}

Set<NameExpr> identifiers = new HashSet<>(blockStmt.findAll(NameExpr.class));

for (NameExpr v : identifiers) {
Expand All @@ -57,12 +68,31 @@ public Expression build(ContextResolver resolver, String expression, Class<?> ty
continue;
}
Variable variable = variableScope.findVariable(v.getNameAsString());
actionBody.addStatement(AbstractNodeVisitor.makeAssignment(variable));
actionBody.addStatement(0, AbstractNodeVisitor.makeAssignment(variable));
}

blockStmt.getStatements().forEach(actionBody::addStatement);

return lambda;
}

private BlockStmt parseStatement(String expression) {
try {
BlockStmt block = new BlockStmt();
block.addStatement(StaticJavaParser.parseStatement("{" + expression + "}"));
return block;
} catch (ParseProblemException e) {
return null;
}
}

private BlockStmt parseExpression(String expression) {
try {
BlockStmt block = new BlockStmt();
block.addStatement(new ReturnStmt(StaticJavaParser.parseExpression(expression)));
return block;
} catch (ParseProblemException e) {
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public Class<?> type() {

@Override
public AbstractNodeVisitor<? extends Node> visitor(NodeVisitorBuilderService nodeVisitorService, ClassLoader classLoader) {
return new DynamicNodeVisitor(nodeVisitorService);
return new DynamicNodeVisitor(nodeVisitorService, classLoader);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@
*/
package org.jbpm.ruleflow.core.factory;

import java.util.function.Predicate;

import org.jbpm.process.instance.impl.ReturnValueEvaluator;
import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
import org.jbpm.workflow.core.NodeContainer;
import org.jbpm.workflow.core.node.DynamicNode;
import org.kie.api.definition.process.WorkflowElementIdentifier;
import org.kie.api.runtime.process.ProcessContext;

public class DynamicNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> extends AbstractCompositeNodeFactory<DynamicNodeFactory<T>, T> {

Expand All @@ -45,12 +43,12 @@ public DynamicNodeFactory<T> language(String language) {
return this;
}

public DynamicNodeFactory<T> activationExpression(Predicate<ProcessContext> activationExpression) {
public DynamicNodeFactory<T> activationExpression(ReturnValueEvaluator activationExpression) {
getDynamicNode().setActivationExpression(activationExpression);
return this;
}

public DynamicNodeFactory<T> completionExpression(Predicate<ProcessContext> completionExpression) {
public DynamicNodeFactory<T> completionExpression(ReturnValueEvaluator completionExpression) {
getDynamicNode().setCompletionExpression(completionExpression);
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import org.jbpm.process.instance.impl.ReturnValueEvaluator;
import org.kie.api.definition.process.Node;
import org.kie.api.definition.process.WorkflowElementIdentifier;
import org.kie.api.runtime.process.ProcessContext;
Expand All @@ -42,8 +42,8 @@ public class DynamicNode extends CompositeContextNode {
*/
private String completionCondition;

private Predicate<ProcessContext> activationPredicate;
private Predicate<ProcessContext> completionPredicate;
private ReturnValueEvaluator activationPredicate;
private ReturnValueEvaluator completionPredicate;
private String language;

public DynamicNode() {
Expand Down Expand Up @@ -89,22 +89,22 @@ public void setCompletionCondition(String completionCondition) {
this.completionCondition = completionCondition;
}

public DynamicNode setActivationExpression(Predicate<ProcessContext> activationPredicate) {
public DynamicNode setActivationExpression(ReturnValueEvaluator activationPredicate) {
this.activationPredicate = activationPredicate;
return this;
}

public DynamicNode setCompletionExpression(Predicate<ProcessContext> copmletionPredicate) {
public DynamicNode setCompletionExpression(ReturnValueEvaluator copmletionPredicate) {
this.completionPredicate = copmletionPredicate;
return this;
}

public boolean canActivate(ProcessContext context) {
return activationPredicate == null || activationPredicate.test(context);
return activationPredicate == null || (Boolean) activationPredicate.eval(context);
}

public boolean canComplete(ProcessContext context) {
return isAutoComplete() || (completionPredicate != null && completionPredicate.test(context));
return isAutoComplete() || (completionPredicate != null && (Boolean) completionPredicate.eval(context));
}

public boolean hasCompletionCondition() {
Expand Down

0 comments on commit 30793c6

Please sign in to comment.