Skip to content

Commit

Permalink
[incubator-kie-issues-1287] Intermediate Catch / Throw missing functi…
Browse files Browse the repository at this point in the history
…onality (#3544)
  • Loading branch information
elguardian authored Jun 17, 2024
1 parent 2b44f00 commit 9e55645
Show file tree
Hide file tree
Showing 65 changed files with 615 additions and 1,337 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,16 @@
import org.jbpm.process.core.context.variable.Variable;
import org.jbpm.process.core.context.variable.VariableScope;
import org.jbpm.process.core.datatype.DataTypeResolver;
import org.jbpm.process.core.impl.DataTransformerRegistry;
import org.jbpm.process.instance.impl.MVELInterpretedReturnValueEvaluator;
import org.jbpm.process.instance.impl.ReturnValueEvaluator;
import org.jbpm.ruleflow.core.RuleFlowProcess;
import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
import org.jbpm.util.PatternConstants;
import org.jbpm.workflow.core.DroolsAction;
import org.jbpm.workflow.core.Node;
import org.jbpm.workflow.core.NodeContainer;
import org.jbpm.workflow.core.impl.DataAssociation;
import org.jbpm.workflow.core.impl.DataAssociation.DataAssociationType;
import org.jbpm.workflow.core.impl.DataDefinition;
import org.jbpm.workflow.core.impl.DroolsConsequenceAction;
import org.jbpm.workflow.core.impl.ExtendedNodeImpl;
Expand All @@ -74,7 +76,6 @@
import org.jbpm.workflow.core.node.StateNode;
import org.jbpm.workflow.core.node.TimerNode;
import org.jbpm.workflow.core.node.Transformation;
import org.kie.api.runtime.process.DataTransformer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
Expand Down Expand Up @@ -425,7 +426,10 @@ protected IOSpecification readCatchSpecification(Parser parser, Element element)
while (xmlNode != null) {
String nodeName = xmlNode.getNodeName();
if ("dataOutputAssociation".equals(nodeName)) {
readDataAssociation((Element) xmlNode, id -> ioSpec.getDataOutput().get(id), id -> getVariableDataSpec(parser, id)).ifPresent(e -> ioSpec.getDataOutputAssociation().add(e));
readDataAssociation((Element) xmlNode, id -> ioSpec.getDataOutput().get(id), id -> getVariableDataSpec(parser, id)).ifPresent(e -> {
e.setType(DataAssociationType.OUTPUT);
ioSpec.getDataOutputAssociation().add(e);
});
}
xmlNode = xmlNode.getNextSibling();
}
Expand All @@ -440,7 +444,10 @@ protected IOSpecification readThrowSpecification(Parser parser, Element element)
while (xmlNode != null) {
String nodeName = xmlNode.getNodeName();
if ("dataInputAssociation".equals(nodeName)) {
readDataAssociation((Element) xmlNode, id -> getVariableDataSpec(parser, id), id -> ioSpec.getDataInput().get(id)).ifPresent(e -> ioSpec.getDataInputAssociation().add(e));
readDataAssociation((Element) xmlNode, id -> getVariableDataSpec(parser, id), id -> ioSpec.getDataInput().get(id)).ifPresent(e -> {
e.setType(DataAssociationType.INPUT);
ioSpec.getDataInputAssociation().add(e);
});
}
xmlNode = xmlNode.getNextSibling();
}
Expand All @@ -457,9 +464,15 @@ protected IOSpecification readIOEspecification(Parser parser, Element element) {
ioSpec.getDataInputs().addAll(readDataInput(parser, xmlNode));
ioSpec.getDataOutputs().addAll(readDataOutput(parser, xmlNode));
} else if ("dataInputAssociation".equals(nodeName)) {
readDataAssociation((Element) xmlNode, id -> getVariableDataSpec(parser, id), id -> ioSpec.getDataInput().get(id)).ifPresent(e -> ioSpec.getDataInputAssociation().add(e));
readDataAssociation((Element) xmlNode, id -> getVariableDataSpec(parser, id), id -> ioSpec.getDataInput().get(id)).ifPresent(e -> {
e.setType(DataAssociationType.INPUT);
ioSpec.getDataInputAssociation().add(e);
});
} else if ("dataOutputAssociation".equals(nodeName)) {
readDataAssociation((Element) xmlNode, id -> ioSpec.getDataOutput().get(id), id -> getVariableDataSpec(parser, id)).ifPresent(e -> ioSpec.getDataOutputAssociation().add(e));
readDataAssociation((Element) xmlNode, id -> ioSpec.getDataOutput().get(id), id -> getVariableDataSpec(parser, id)).ifPresent(e -> {
e.setType(DataAssociationType.OUTPUT);
ioSpec.getDataOutputAssociation().add(e);
});
}
xmlNode = xmlNode.getNextSibling();
}
Expand Down Expand Up @@ -561,11 +574,11 @@ private Transformation readTransformation(Element parent) {
String lang = element.get().getAttribute("language");
String expression = element.get().getTextContent();

DataTransformer transformer = DataTransformerRegistry.get().find(lang);
if (transformer == null) {
throw new ProcessParsingValidationException("No transformer registered for language " + lang);
ReturnValueEvaluator evaluator = null;
if (lang.toLowerCase().contains("mvel")) {
evaluator = new MVELInterpretedReturnValueEvaluator(expression);
}
return new Transformation(lang, expression);
return new Transformation(lang, expression, evaluator);
}

protected List<DataDefinition> readSources(org.w3c.dom.Node parent, Function<String, DataDefinition> variableResolver) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@

import static org.jbpm.bpmn2.xml.ProcessHandler.createJavaAction;
import static org.jbpm.ruleflow.core.Metadata.EVENT_TYPE;
import static org.jbpm.ruleflow.core.Metadata.EVENT_TYPE_COMPENSATION;
import static org.jbpm.ruleflow.core.Metadata.EVENT_TYPE_ESCALATION;
import static org.jbpm.ruleflow.core.Metadata.EVENT_TYPE_LINK;
import static org.jbpm.ruleflow.core.Metadata.EVENT_TYPE_MESSAGE;
import static org.jbpm.ruleflow.core.Metadata.EVENT_TYPE_SIGNAL;
import static org.jbpm.ruleflow.core.Metadata.MAPPING_VARIABLE;
import static org.jbpm.ruleflow.core.Metadata.MAPPING_VARIABLE_INPUT;
import static org.jbpm.ruleflow.core.Metadata.MESSAGE_TYPE;
Expand Down Expand Up @@ -87,28 +91,33 @@ protected Node handleNode(Node newNode, Element element, String uri, String loca
// reuse already created ActionNode
setThrowVariable(ioSpecification, node);
handleSignalNode(node, element, uri, localName, parser);
node.setMetaData(EVENT_TYPE, EVENT_TYPE_SIGNAL);
break;
} else if ("messageEventDefinition".equals(nodeName)) {
// reuse already created ActionNode
setThrowVariable(ioSpecification, node);
handleMessageNode(node, element, uri, localName, parser);
node.setMetaData(EVENT_TYPE, EVENT_TYPE_MESSAGE);
break;
} else if ("escalationEventDefinition".equals(nodeName)) {
// reuse already created ActionNode
setThrowVariable(ioSpecification, node);
handleEscalationNode(node, element, uri, localName, parser);
node.setMetaData(EVENT_TYPE, EVENT_TYPE_ESCALATION);
break;
} else if ("compensateEventDefinition".equals(nodeName)) {
// reuse already created ActionNode
setThrowVariable(ioSpecification, node);
handleThrowCompensationEventNode(node, element, uri, localName, parser);
node.setMetaData(EVENT_TYPE, EVENT_TYPE_COMPENSATION);
break;
} else if ("linkEventDefinition".equals(nodeName)) {
ThrowLinkNode linkNode = new ThrowLinkNode();
linkNode.setId(node.getId());
node = linkNode;
setThrowVariable(ioSpecification, node);
handleLinkNode(element, node, xmlNode, parser);
node.setMetaData(EVENT_TYPE, EVENT_TYPE_LINK);
}
xmlNode = xmlNode.getNextSibling();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import org.kie.kogito.Model;
import org.kie.kogito.process.Process;
Expand All @@ -44,4 +45,22 @@ public Process<? extends Model> processById(String processId) {
public Collection<String> processIds() {
return mappedProcesses.keySet();
}

@Override
public int hashCode() {
return Objects.hash(mappedProcesses.keySet());
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BpmnProcesses other = (BpmnProcesses) obj;
return Objects.equals(mappedProcesses, other.mappedProcesses);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,35 @@
import java.util.function.Predicate;
import java.util.stream.Collectors;

import org.jbpm.compiler.canonical.builtin.ReturnValueEvaluatorBuilderService;
import org.jbpm.process.builder.action.ActionCompilerRegistry;
import org.jbpm.process.builder.transformation.DataTransformerCompilerRegistry;
import org.jbpm.process.core.Context;
import org.jbpm.process.core.ContextContainer;
import org.jbpm.process.core.ContextResolver;
import org.jbpm.process.core.context.variable.Mappable;
import org.jbpm.process.core.context.variable.Variable;
import org.jbpm.process.core.context.variable.VariableScope;
import org.jbpm.process.core.datatype.DataTypeResolver;
import org.jbpm.process.instance.impl.actions.ProduceEventAction;
import org.jbpm.process.instance.impl.actions.SignalProcessInstanceAction;
import org.jbpm.ruleflow.core.Metadata;
import org.jbpm.ruleflow.core.factory.MappableNodeFactory;
import org.jbpm.util.JbpmClassLoaderUtil;
import org.jbpm.workflow.core.impl.ConnectionImpl;
import org.jbpm.workflow.core.impl.DataAssociation;
import org.jbpm.workflow.core.impl.DataAssociation.DataAssociationType;
import org.jbpm.workflow.core.impl.DataDefinition;
import org.jbpm.workflow.core.impl.DroolsConsequenceAction;
import org.jbpm.workflow.core.impl.ExtendedNodeImpl;
import org.jbpm.workflow.core.impl.NodeImpl;
import org.jbpm.workflow.core.node.Assignment;
import org.jbpm.workflow.core.node.HumanTaskNode;
import org.jbpm.workflow.core.node.StartNode;
import org.jbpm.workflow.core.node.Transformation;
import org.kie.api.definition.process.Connection;
import org.kie.api.definition.process.Node;

import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.expr.AssignExpr;
Expand Down Expand Up @@ -215,24 +222,25 @@ protected Statement makeAssignmentFromModel(Variable v, String name) {

protected void addNodeMappings(Mappable node, BlockStmt body, String variableName) {
for (DataAssociation entry : node.getInAssociations()) {
body.addStatement(getFactoryMethod(variableName, MappableNodeFactory.METHOD_IN_ASSOCIATION, buildDataAssociationExpression(entry)));
body.addStatement(getFactoryMethod(variableName, MappableNodeFactory.METHOD_IN_ASSOCIATION, buildDataAssociationExpression((NodeImpl) node, entry)));
}
for (DataAssociation entry : node.getOutAssociations()) {
body.addStatement(getFactoryMethod(variableName, MappableNodeFactory.METHOD_OUT_ASSOCIATION, buildDataAssociationExpression(entry)));
body.addStatement(getFactoryMethod(variableName, MappableNodeFactory.METHOD_OUT_ASSOCIATION, buildDataAssociationExpression((NodeImpl) node, entry)));
}
}

protected Expression buildDataAssociationsExpression(List<DataAssociation> dataAssociations) {
NodeList<Expression> expressions = NodeList.nodeList(dataAssociations.stream().map(this::buildDataAssociationExpression).collect(Collectors.toList()));
protected Expression buildDataAssociationsExpression(NodeImpl node, List<DataAssociation> dataAssociations) {
NodeList<Expression> expressions = NodeList.nodeList(dataAssociations.stream().map(da -> buildDataAssociationExpression(node, da)).collect(Collectors.toList()));
return new MethodCallExpr(null, "java.util.Arrays.asList", NodeList.nodeList(expressions));
}

protected Expression buildDataAssociationExpression(DataAssociation dataAssociation) {
protected Expression buildDataAssociationExpression(NodeImpl node, DataAssociation dataAssociation) {
List<DataDefinition> sourceExpr = dataAssociation.getSources();
DataDefinition targetExpr = dataAssociation.getTarget();
Transformation transformation = dataAssociation.getTransformation();
List<Assignment> assignments = dataAssociation.getAssignments();
return toDataAssociation(toDataDef(sourceExpr), toDataDef(targetExpr), toAssignmentExpr(assignments), toTransformation(sourceExpr, singletonList(targetExpr), transformation));
return toDataAssociation(toDataDef(sourceExpr), toDataDef(targetExpr), toAssignmentExpr(assignments),
toTransformation(node, dataAssociation.getType(), sourceExpr, singletonList(targetExpr), transformation));
}

private Expression toAssignmentExpr(List<Assignment> assignments) {
Expand All @@ -252,16 +260,44 @@ private Expression toAssignmentExpr(List<Assignment> assignments) {
return new MethodCallExpr(null, "java.util.Arrays.asList", NodeList.nodeList(expressions));
}

protected Expression toTransformation(List<DataDefinition> inputs, List<DataDefinition> outputs, Transformation transformation) {
protected Expression toTransformation(NodeImpl node, DataAssociationType type, List<DataDefinition> inputs, List<DataDefinition> outputs, Transformation transformation) {
if (transformation == null) {
return new NullLiteralExpr();
}

Expression lang = new StringLiteralExpr(transformation.getLanguage());
Expression expression = new StringLiteralExpr(transformation.getExpression());
Expression compiledExpression = DataTransformerCompilerRegistry.instance().find(transformation.getLanguage()).compile(inputs, outputs, transformation);
ClassOrInterfaceType clazz = new ClassOrInterfaceType(null, "org.jbpm.workflow.core.node.Transformation");
return new ObjectCreationExpr(null, clazz, NodeList.nodeList(lang, expression, compiledExpression));
Expression expression = new StringLiteralExpr(sanitizeString(transformation.getExpression()));

ContextResolver contextResolver = type.equals(DataAssociationType.INPUT) ? node : wrapContextResolver(node, inputs);

ReturnValueEvaluatorBuilderService service = ReturnValueEvaluatorBuilderService.instance();
Expression returnValueEvaluatorExpression = service.build(contextResolver, transformation.getLanguage(), transformation.getExpression(), Object.class, null);
ClassOrInterfaceType clazz = StaticJavaParser.parseClassOrInterfaceType(Transformation.class.getName());
return new ObjectCreationExpr(null, clazz, NodeList.nodeList(lang, expression, returnValueEvaluatorExpression));

}

private ContextResolver wrapContextResolver(NodeImpl node, List<DataDefinition> variables) {
VariableScope variableScope = new VariableScope();

for (DataDefinition variable : variables) {
Variable var = new Variable();
var.setId(variable.getId());
var.setName(variable.getLabel());
var.setType(DataTypeResolver.fromType(variable.getType(), JbpmClassLoaderUtil.findClassLoader()));
variableScope.addVariable(var);
}
return new ContextResolver() {

@Override
public Context resolveContext(String contextId, Object param) {
if (VariableScope.VARIABLE_SCOPE.equals(contextId)) {
return variableScope.resolveContext(param);
}
return null;
}

};
}

protected Expression toDataAssociation(Expression sourceExprs, Expression target, Expression transformation, Expression assignments) {
Expand Down Expand Up @@ -360,7 +396,7 @@ public static LambdaExpr buildCompensationLambdaExpr(String compensationRef) {
}

protected ObjectCreationExpr buildProducerAction(Node node, ProcessMetaData metadata) {
TriggerMetaData trigger = TriggerMetaData.of(node);
TriggerMetaData trigger = TriggerMetaData.of(node, (String) node.getMetaData().get(Metadata.MAPPING_VARIABLE_INPUT));
return buildProducerAction(parseClassOrInterfaceType(ProduceEventAction.class.getCanonicalName()).setTypeArguments(NodeList.nodeList(parseClassOrInterfaceType(trigger.getDataType()))),
trigger, metadata);

Expand All @@ -369,8 +405,10 @@ protected ObjectCreationExpr buildProducerAction(Node node, ProcessMetaData meta
public static ObjectCreationExpr buildProducerAction(ClassOrInterfaceType actionClass, TriggerMetaData trigger, ProcessMetaData metadata) {
metadata.addTrigger(trigger);
return new ObjectCreationExpr(null, actionClass, NodeList.nodeList(
new StringLiteralExpr(trigger.getName()), new StringLiteralExpr(trigger.getModelRef()),
new LambdaExpr(NodeList.nodeList(), new NameExpr("producer_" + trigger.getOwnerId()))));
new StringLiteralExpr(trigger.getName()),
new StringLiteralExpr(trigger.getModelRef()),
new LambdaExpr(NodeList.nodeList(),
new NameExpr("producer_" + trigger.getOwnerId()))));
}

protected void visitCompensationScope(ContextContainer process, BlockStmt body) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ protected void handleSignal(StartNode startNode, Map<String, Object> nodeMetaDat

body.addStatement(getFactoryMethod(getNodeId(startNode), METHOD_TRIGGER,
new StringLiteralExpr((String) nodeMetaData.get(TRIGGER_REF)),
buildDataAssociationsExpression(startNode.getIoSpecification().getDataOutputAssociation())));
buildDataAssociationsExpression(startNode, startNode.getIoSpecification().getDataOutputAssociation())));

String triggerMapping = (String) nodeMetaData.get(TRIGGER_MAPPING);
variable = variableScope.findVariable(triggerMapping);
Expand All @@ -99,13 +99,13 @@ protected void handleSignal(StartNode startNode, Map<String, Object> nodeMetaDat
} else {
body.addStatement(getFactoryMethod(getNodeId(startNode), METHOD_TRIGGER,
new StringLiteralExpr((String) nodeMetaData.get(MESSAGE_TYPE)),
buildDataAssociationsExpression(startNode.getIoSpecification().getDataOutputAssociation())));
buildDataAssociationsExpression(startNode, startNode.getIoSpecification().getDataOutputAssociation())));
}
metadata.addSignal((String) nodeMetaData.get(MESSAGE_TYPE), variable != null ? variable.getType().getStringType() : null);
} else {
body.addStatement(getFactoryMethod(getNodeId(startNode), METHOD_TRIGGER,
new StringLiteralExpr((String) nodeMetaData.get(TRIGGER_REF)),
buildDataAssociationsExpression(startNode.getIoSpecification().getDataOutputAssociation())));
buildDataAssociationsExpression(startNode, startNode.getIoSpecification().getDataOutputAssociation())));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ public Expression build(ContextResolver resolver, String expression, Class<?> ty
if (blockStmt == null) {
blockStmt = StaticJavaParser.parseBlock("{" + expression + "}");
}

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

for (NameExpr v : identifiers) {
Expand Down
Loading

0 comments on commit 9e55645

Please sign in to comment.