Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[KOGITO-9811] Evaluating timeout duration as expression #3250

Merged
merged 3 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,6 @@ public void visitNode(String factoryField, ForEachNode node, BlockStmt body, Var
buildDataResolver(node.getOutputVariableType().getStringType())));
}

if (node.getExpressionLanguage() != null) {
body.addStatement(getFactoryMethod(getNodeId(node), "expressionLanguage", new StringLiteralExpr(node.getExpressionLanguage())));
}

if (node.getCompletionAction() instanceof ExpressionSupplier) {
body.addStatement(getFactoryMethod(getNodeId(node), "completionAction", ((ExpressionSupplier) node.getCompletionAction()).get(node, metadata)));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,13 @@ public void visitProcess(WorkflowProcess process, MethodDeclaration processMetho
visitVariableScope(FACTORY_FIELD_NAME, variableScope, body, visitedVariables, metadata.getProcessClassName());
visitSubVariableScopes(process.getNodes(), body, visitedVariables);

if (process instanceof org.jbpm.workflow.core.WorkflowProcess) {
org.jbpm.workflow.core.WorkflowProcess processImpl = (org.jbpm.workflow.core.WorkflowProcess) process;
if (processImpl.getExpressionLanguage() != null) {
body.addStatement(getFactoryMethod(FACTORY_FIELD_NAME, "expressionLanguage", new StringLiteralExpr(processImpl.getExpressionLanguage())));
}
}

visitInterfaces(process.getNodes());

metadata.setDynamic(((org.jbpm.workflow.core.WorkflowProcess) process).isDynamic());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ protected void setId(Object node, Object id) {
getRuleFlowProcess().setId((String) id);
}

public RuleFlowProcessFactory expressionLanguage(String exprLanguage) {
getRuleFlowProcess().setExpressionLanguage(exprLanguage);
return this;
}

protected RuleFlowProcess getRuleFlowProcess() {
return (RuleFlowProcess) node;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,6 @@ public ForEachNodeFactory<T> outputCollectionExpression(String collectionExpress
return this;
}

public ForEachNodeFactory<T> expressionLanguage(String exprLanguage) {
getForEachNode().setExpressionLanguage(exprLanguage);
return this;
}

public ForEachNodeFactory<T> completionAction(Action completionAction) {
getForEachNode().setCompletionAction(completionAction);
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
import org.kie.api.definition.process.Process;
import org.kie.api.io.Resource;
import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcess;
import org.kie.kogito.process.expr.ExpressionHandlerFactory;

import static java.lang.String.format;
import static org.jbpm.ruleflow.core.Metadata.EVENT_TYPE;
Expand Down Expand Up @@ -855,6 +856,11 @@ private boolean acceptsNoOutgoingConnections(org.kie.api.definition.process.Node
(nodeContainer instanceof WorkflowProcess && ((WorkflowProcess) nodeContainer).isDynamic());
}

private boolean isExpression(RuleFlowProcess process, String expression) {
String lang = process.getExpressionLanguage();
return lang != null && ExpressionHandlerFactory.get(lang, expression).isValid();
}

private void validateTimer(final Timer timer,
final org.kie.api.definition.process.Node node,
final RuleFlowProcess process,
Expand Down Expand Up @@ -884,10 +890,12 @@ private void validateTimer(final Timer timer,
break;
}
} catch (RuntimeException e) {
addErrorMessage(process,
node,
errors,
"Could not parse delay '" + timer.getDelay() + "': " + e.getMessage());
if (!isExpression(process, timer.getDelay())) {
addErrorMessage(process,
node,
errors,
"Could not parse delay '" + timer.getDelay() + "': " + e.getMessage());
}
}
}
}
Expand All @@ -898,21 +906,25 @@ private void validateTimer(final Timer timer,
DateTimeUtils.parseRepeatableDateTime(timer.getPeriod());
}
} catch (RuntimeException e) {
addErrorMessage(process,
node,
errors,
"Could not parse period '" + timer.getPeriod() + "': " + e.getMessage());
if (!isExpression(process, timer.getPeriod())) {
addErrorMessage(process,
node,
errors,
"Could not parse period '" + timer.getPeriod() + "': " + e.getMessage());
}
}
}

if (timer.getDate() != null && !timer.getDate().contains("#{")) {
try {
DateTimeUtils.parseDateAsDuration(timer.getDate());
} catch (RuntimeException e) {
addErrorMessage(process,
node,
errors,
"Could not parse date '" + timer.getDate() + "': " + e.getMessage());
if (!isExpression(process, timer.getDate())) {
addErrorMessage(process,
node,
errors,
"Could not parse date '" + timer.getDate() + "': " + e.getMessage());
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,7 @@ public interface WorkflowProcess extends KogitoWorkflowProcess, Process, NodeCon

void setOutputValidator(WorkflowModelValidator validator);

void setExpressionLanguage(String exprLanguage);

String getExpressionLanguage();
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@
import org.jbpm.process.core.Context;
import org.jbpm.process.core.ContextResolver;
import org.jbpm.process.core.context.variable.Mappable;
import org.jbpm.ruleflow.core.RuleFlowProcess;
import org.jbpm.workflow.core.Constraint;
import org.jbpm.workflow.core.Node;
import org.jbpm.workflow.core.WorkflowProcess;
import org.jbpm.workflow.core.node.CompositeNode;
import org.kie.api.definition.process.Connection;
import org.kie.api.definition.process.NodeContainer;
Expand Down Expand Up @@ -80,52 +82,72 @@ public IOSpecification getIoSpecification() {
return ioSpecification;
}

@Override
public Map<String, String> getInMappings() {
return getIoSpecification().getInputMapping();
}

@Override
public Map<String, String> getOutMappings() {
return getIoSpecification().getOutputMappingBySources();
}

@Override
public String getInMapping(String key) {
return getIoSpecification().getInputMapping().get(key);
}

@Override
public String getOutMapping(String key) {
return getIoSpecification().getOutputMappingBySources().get(key);
}

@Override
public void addInMapping(String from, String to) {
getIoSpecification().addInputMapping(from, to);
}

@Override
public void addOutMapping(String from, String to) {
getIoSpecification().addOutputMapping(from, to);
}

@Override
public void addInAssociation(DataAssociation dataAssociation) {
getIoSpecification().getDataInputs().add(dataAssociation.getTarget());
getIoSpecification().getDataInputAssociation().add(dataAssociation);
}

@Override
public List<DataAssociation> getInAssociations() {
return getIoSpecification().getDataInputAssociation();
}

@Override
public void addOutAssociation(DataAssociation dataAssociation) {
dataAssociation.getSources().forEach(s -> getIoSpecification().getDataOutputs().add(s));
getIoSpecification().getDataOutputAssociation().add(dataAssociation);
}

public WorkflowProcess getProcess() {
NodeContainer container = parentContainer;
while (!(container instanceof RuleFlowProcess)) {
container = ((NodeImpl) container).parentContainer;
}
return (WorkflowProcess) container;
}

@Override
public List<DataAssociation> getOutAssociations() {
return getIoSpecification().getDataOutputAssociation();
}

@Override
public long getId() {
return this.id;
}

@Override
public String getUniqueId() {
StringBuilder result = new StringBuilder(id + "");
NodeContainer nodeContainer = getParentContainer();
Expand All @@ -137,6 +159,7 @@ public String getUniqueId() {
return result.toString();
}

@Override
public void setId(final long id) {
this.id = id;
String uniqueId = (String) getMetaData("UniqueId");
Expand All @@ -145,24 +168,29 @@ public void setId(final long id) {
}
}

@Override
public String getName() {
return this.name;
}

@Override
public void setName(final String name) {
this.name = name;
}

@Override
public Map<String, List<Connection>> getIncomingConnections() {
// TODO: users can still modify the lists inside this Map
return Collections.unmodifiableMap(this.incomingConnections);
}

@Override
public Map<String, List<Connection>> getOutgoingConnections() {
// TODO: users can still modify the lists inside this Map
return Collections.unmodifiableMap(this.outgoingConnections);
}

@Override
public void addIncomingConnection(final String type, final Connection connection) {
validateAddIncomingConnection(type, connection);
List<Connection> connections = this.incomingConnections.get(type);
Expand All @@ -182,6 +210,7 @@ public void validateAddIncomingConnection(final String type, final Connection co
}
}

@Override
public List<Connection> getIncomingConnections(String type) {
List<Connection> result = incomingConnections.get(type);
if (result == null) {
Expand All @@ -190,6 +219,7 @@ public List<Connection> getIncomingConnections(String type) {
return result;
}

@Override
public void addOutgoingConnection(final String type, final Connection connection) {
validateAddOutgoingConnection(type, connection);
List<Connection> connections = this.outgoingConnections.get(type);
Expand All @@ -209,6 +239,7 @@ public void validateAddOutgoingConnection(final String type, final Connection co
}
}

@Override
public List<Connection> getOutgoingConnections(String type) {
List<Connection> result = outgoingConnections.get(type);
if (result == null) {
Expand All @@ -217,6 +248,7 @@ public List<Connection> getOutgoingConnections(String type) {
return result;
}

@Override
public void removeIncomingConnection(final String type, final Connection connection) {
validateRemoveIncomingConnection(type, connection);
this.incomingConnections.get(type).remove(connection);
Expand All @@ -243,6 +275,7 @@ public void validateRemoveIncomingConnection(final String type, final Connection
}
}

@Override
public void removeOutgoingConnection(final String type, final Connection connection) {
validateRemoveOutgoingConnection(type, connection);
this.outgoingConnections.get(type).remove(connection);
Expand Down Expand Up @@ -315,22 +348,27 @@ public List<Connection> getDefaultOutgoingConnections() {
return getOutgoingConnections(Node.CONNECTION_DEFAULT_TYPE);
}

@Override
public NodeContainer getParentContainer() {
return parentContainer;
}

@Override
public void setParentContainer(NodeContainer nodeContainer) {
this.parentContainer = nodeContainer;
}

@Override
public void setContext(String contextId, Context context) {
this.contexts.put(contextId, context);
}

@Override
public Context getContext(String contextId) {
return this.contexts.get(contextId);
}

@Override
public Context resolveContext(String contextId, Object param) {
Context context = getContext(contextId);
if (context != null) {
Expand All @@ -342,6 +380,7 @@ public Context resolveContext(String contextId, Object param) {
return ((org.jbpm.workflow.core.NodeContainer) parentContainer).resolveContext(contextId, param);
}

@Override
public void setMetaData(String name, Object value) {
this.metaData.put(name, value);
}
Expand All @@ -350,6 +389,7 @@ public Object getMetaData(String name) {
return this.metaData.get(name);
}

@Override
public Map<String, Object> getMetaData() {
return this.metaData;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public class WorkflowProcessImpl extends ProcessImpl implements WorkflowProcess,
private WorkflowModelValidator inputValidator;
private WorkflowModelValidator outputValidator;
private org.jbpm.workflow.core.NodeContainer nodeContainer;
private String exprLanguage;

private transient BiFunction<String, ProcessInstance, String> expressionEvaluator = (expression, p) -> {

Expand Down Expand Up @@ -239,4 +240,12 @@ public Optional<WorkflowModelValidator> getOutputValidator() {
public void setOutputValidator(WorkflowModelValidator outputValidator) {
this.outputValidator = outputValidator;
}

public void setExpressionLanguage(String exprLanguage) {
this.exprLanguage = exprLanguage;
}

public String getExpressionLanguage() {
return exprLanguage;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public class ForEachNode extends CompositeContextNode {
private String collectionExpression;
private String outputCollectionExpression;
private String completionConditionExpression;
private String exprLanguage;

private Action finishAction;
private boolean waitForCompletion = true;
private Expression evaluateExpression;
Expand Down Expand Up @@ -108,14 +108,6 @@ public DataType getVariableType() {
return null;
}

public void setExpressionLanguage(String exprLanguage) {
this.exprLanguage = exprLanguage;
}

public String getExpressionLanguage() {
return exprLanguage;
}

public Action getCompletionAction() {
return finishAction;
}
Expand All @@ -125,6 +117,7 @@ public void setCompletionAction(Action finishAction) {
}

public Expression getEvaluateExpression() {
String exprLanguage = getProcess().getExpressionLanguage();
if (evaluateExpression == null && ExpressionHandlerFactory.isSupported(exprLanguage)) {
evaluateExpression = ExpressionHandlerFactory.get(exprLanguage, collectionExpression);
}
Expand Down
Loading