This is an automated email from the ASF dual-hosted git repository.
fjtiradosarti pushed a commit to branch main
in repository
https://gitbox.apache.org/repos/asf/incubator-kie-kogito-runtimes.git
The following commit(s) were added to refs/heads/main by this push:
new 73b0e84fa5 [Fix #3456]Support multiple constraint over same connection
(#3459)
73b0e84fa5 is described below
commit 73b0e84fa5cbe42e71dc51059a757ffe6362f017
Author: Francisco Javier Tirado Sarti
<[email protected]>
AuthorDate: Wed Apr 3 16:49:32 2024 +0200
[Fix #3456]Support multiple constraint over same connection (#3459)
* [Fix #3456]Support multiple constraint over same connection
* [Fix #3456] Unit test
* [Fix #3456] Gonzalo's comments
---
.../org/jbpm/bpmn2/feel/FeelProcessValidator.java | 21 ++++---
.../main/java/org/jbpm/bpmn2/xml/SplitHandler.java | 33 ++++++-----
.../java/org/jbpm/compiler/ProcessBuilderImpl.java | 22 ++++---
.../jbpm/compiler/canonical/SplitNodeVisitor.java | 59 +++++++++---------
.../jbpm/compiler/canonical/StateNodeVisitor.java | 30 ++++++----
.../MultiConditionalSequenceFlowNodeBuilder.java | 57 +++++++++---------
.../org/jbpm/process/builder/SplitNodeBuilder.java | 68 +++++++++++----------
.../core/validation/RuleFlowProcessValidator.java | 8 +--
.../java/org/jbpm/workflow/core/impl/NodeImpl.java | 20 +++++--
.../java/org/jbpm/workflow/core/node/Split.java | 41 ++++---------
.../org/jbpm/workflow/core/node/StateNode.java | 53 -----------------
.../workflow/instance/impl/NodeInstanceImpl.java | 36 +++++++----
.../jbpm/workflow/instance/node/SplitInstance.java | 69 ++++++++++++++--------
.../workflow/instance/node/StateNodeInstance.java | 50 ++++++++++------
.../codegen/process/ProcessGenerationIT.java | 16 ++---
.../workflow/ServerlessWorkflowParsingTest.java | 17 ++----
.../serverless/workflow/WorkflowTestUtils.java | 2 +
.../executor/StaticWorkflowApplicationTest.java | 15 +++++
.../src/test/resources/switch.yaml | 32 ++++++++++
19 files changed, 355 insertions(+), 294 deletions(-)
diff --git
a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/feel/FeelProcessValidator.java
b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/feel/FeelProcessValidator.java
index 5ff61b89ae..ccf60a5a4c 100755
---
a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/feel/FeelProcessValidator.java
+++
b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/feel/FeelProcessValidator.java
@@ -19,6 +19,7 @@
package org.jbpm.bpmn2.feel;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -63,15 +64,17 @@ public class FeelProcessValidator extends
RuleFlowProcessValidator {
Arrays.stream(nodes).filter(n -> n instanceof Split).forEach(node -> {
final Split split = (Split) node;
if (split.getType() == Split.TYPE_XOR || split.getType() ==
Split.TYPE_OR) {
- for (Map.Entry<ConnectionRef, Constraint> entry :
split.getConstraints().entrySet()) {
- if (entry.getValue() != null &&
"FEEL".equals(entry.getValue().getDialect())) {
- try {
-
verifyFEELbyCompilingExpression(process.getVariableScope(),
entry.getValue().getConstraint());
- } catch (FeelCompilationException ex) {
- addErrorMessage(process,
- node,
- errors,
- format("Invalid FEEL expression: '%s'.",
entry.getValue().getConstraint()));
+ for (Map.Entry<ConnectionRef, Collection<Constraint>> entry :
split.getConstraints().entrySet()) {
+ for (Constraint constraint : entry.getValue()) {
+ if (constraint != null &&
"FEEL".equals(constraint.getDialect())) {
+ try {
+
verifyFEELbyCompilingExpression(process.getVariableScope(),
constraint.getConstraint());
+ } catch (FeelCompilationException ex) {
+ addErrorMessage(process,
+ node,
+ errors,
+ format("Invalid FEEL expression:
'%s'.", constraint.getConstraint()));
+ }
}
}
}
diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/SplitHandler.java
b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/SplitHandler.java
index 760172f8a5..8c908b508e 100755
--- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/SplitHandler.java
+++ b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/SplitHandler.java
@@ -18,6 +18,7 @@
*/
package org.jbpm.bpmn2.xml;
+import java.util.Collection;
import java.util.Map;
import org.jbpm.workflow.core.Constraint;
@@ -48,26 +49,30 @@ public class SplitHandler extends AbstractNodeHandler {
case Split.TYPE_XOR:
type = "exclusiveGateway";
writeNode(type, node, xmlDump, metaDataType);
- for (Map.Entry<ConnectionRef, Constraint> entry :
split.getConstraints().entrySet()) {
- if (entry.getValue() != null &&
entry.getValue().isDefault()) {
- xmlDump.append("default=\"" +
- XmlBPMNProcessDumper.getUniqueNodeId(split) +
"-" +
-
XmlBPMNProcessDumper.getUniqueNodeId(node.getParentContainer().getNode(entry.getKey().getNodeId()))
+
- "\" ");
- break;
+ for (Map.Entry<ConnectionRef, Collection<Constraint>> entry :
split.getConstraints().entrySet()) {
+ for (Constraint constraint : entry.getValue()) {
+ if (constraint != null && constraint.isDefault()) {
+ xmlDump.append("default=\"" +
+
XmlBPMNProcessDumper.getUniqueNodeId(split) + "-" +
+
XmlBPMNProcessDumper.getUniqueNodeId(node.getParentContainer().getNode(entry.getKey().getNodeId()))
+
+ "\" ");
+ break;
+ }
}
}
break;
case Split.TYPE_OR:
type = "inclusiveGateway";
writeNode(type, node, xmlDump, metaDataType);
- for (Map.Entry<ConnectionRef, Constraint> entry :
split.getConstraints().entrySet()) {
- if (entry.getValue() != null &&
entry.getValue().isDefault()) {
- xmlDump.append("default=\"" +
- XmlBPMNProcessDumper.getUniqueNodeId(split) +
"-" +
-
XmlBPMNProcessDumper.getUniqueNodeId(node.getParentContainer().getNode(entry.getKey().getNodeId()))
+
- "\" ");
- break;
+ for (Map.Entry<ConnectionRef, Collection<Constraint>> entry :
split.getConstraints().entrySet()) {
+ for (Constraint constraint : entry.getValue()) {
+ if (constraint != null && constraint.isDefault()) {
+ xmlDump.append("default=\"" +
+
XmlBPMNProcessDumper.getUniqueNodeId(split) + "-" +
+
XmlBPMNProcessDumper.getUniqueNodeId(node.getParentContainer().getNode(entry.getKey().getNodeId()))
+
+ "\" ");
+ break;
+ }
}
}
break;
diff --git
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/ProcessBuilderImpl.java
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/ProcessBuilderImpl.java
index 9e9dd2bf92..3257a0db6f 100755
---
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/ProcessBuilderImpl.java
+++
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/ProcessBuilderImpl.java
@@ -22,6 +22,7 @@ import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -330,11 +331,14 @@ public class ProcessBuilderImpl implements
org.drools.compiler.compiler.ProcessB
Split split = (Split) nodes[i];
if (split.getType() == Split.TYPE_XOR || split.getType() ==
Split.TYPE_OR) {
for (Connection connection :
split.getDefaultOutgoingConnections()) {
- Constraint constraint =
split.getConstraint(connection);
- if (constraint != null &&
"rule".equals(constraint.getType())) {
- builder.append(createSplitRule(process,
- connection,
-
split.getConstraint(connection).getConstraint()));
+ Collection<Constraint> constraints =
split.getConstraints(connection);
+ if (constraints != null) {
+ for (Constraint constraint : constraints)
+ if (constraint != null &&
"rule".equals(constraint.getType())) {
+ builder.append(createSplitRule(process,
+ connection,
+ constraint.getConstraint()));
+ }
}
}
}
@@ -385,7 +389,7 @@ public class ProcessBuilderImpl implements
org.drools.compiler.compiler.ProcessB
key.getNodeId() + "-" + key.getToType() + "\"
@Propagation(EAGER) \n" +
" ruleflow-group \"DROOLS_SYSTEM\" \n" +
" when \n" +
- " " + state.getConstraints().get(key).getConstraint()
+ "\n" +
+ " " +
state.internalGetConstraint(key).getConstraint() + "\n" +
" then \n" +
"end \n\n";
}
@@ -426,8 +430,10 @@ public class ProcessBuilderImpl implements
org.drools.compiler.compiler.ProcessB
private String createStateRules(Process process, StateNode state) {
StringBuilder result = new StringBuilder();
- for (Map.Entry<ConnectionRef, Constraint> entry :
state.getConstraints().entrySet()) {
- result.append(createStateRule(process, state, entry.getKey(),
entry.getValue()));
+ for (Map.Entry<ConnectionRef, Collection<Constraint>> entry :
state.getConstraints().entrySet()) {
+ for (Constraint constraint : entry.getValue()) {
+ result.append(createStateRule(process, state, entry.getKey(),
constraint));
+ }
}
return result.toString();
}
diff --git
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/SplitNodeVisitor.java
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/SplitNodeVisitor.java
index b60a5f3bfb..4eebbc0a16 100644
---
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/SplitNodeVisitor.java
+++
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/SplitNodeVisitor.java
@@ -18,6 +18,7 @@
*/
package org.jbpm.compiler.canonical;
+import java.util.Collection;
import java.util.Map.Entry;
import java.util.function.Supplier;
@@ -61,45 +62,49 @@ public class SplitNodeVisitor extends
AbstractNodeVisitor<Split> {
visitMetaData(node.getMetaData(), body, getNodeId(node));
if (node.getType() == Split.TYPE_OR || node.getType() ==
Split.TYPE_XOR) {
- for (Entry<ConnectionRef, Constraint> entry :
node.getConstraints().entrySet()) {
+ for (Entry<ConnectionRef, Collection<Constraint>> entry :
node.getConstraints().entrySet()) {
if (entry.getValue() != null) {
- Expression returnValueEvaluator;
- if (entry.getValue() instanceof
ReturnValueConstraintEvaluator && ((ReturnValueConstraintEvaluator)
entry.getValue()).getReturnValueEvaluator() instanceof Supplier) {
- returnValueEvaluator = ((Supplier<Expression>)
((ReturnValueConstraintEvaluator)
entry.getValue()).getReturnValueEvaluator()).get();
- } else if ("FEEL".equals(entry.getValue().getDialect())) {
- returnValueEvaluator =
buildFEELReturnValueEvaluator(entry);
- } else {
- BlockStmt actionBody = new BlockStmt();
- LambdaExpr lambda = new LambdaExpr(
- new Parameter(new UnknownType(),
KCONTEXT_VAR), // (kcontext) ->
- actionBody);
+ for (Constraint constraint : entry.getValue()) {
+ if (constraint != null) {
+ Expression returnValueEvaluator;
+ if (constraint instanceof
ReturnValueConstraintEvaluator && ((ReturnValueConstraintEvaluator)
constraint).getReturnValueEvaluator() instanceof Supplier) {
+ returnValueEvaluator = ((Supplier<Expression>)
((ReturnValueConstraintEvaluator) constraint).getReturnValueEvaluator()).get();
+ } else if ("FEEL".equals(constraint.getDialect()))
{
+ returnValueEvaluator =
buildFEELReturnValueEvaluator(constraint);
+ } else {
+ BlockStmt actionBody = new BlockStmt();
+ LambdaExpr lambda = new LambdaExpr(
+ new Parameter(new UnknownType(),
KCONTEXT_VAR), // (kcontext) ->
+ actionBody);
- for (Variable v : variableScope.getVariables()) {
- actionBody.addStatement(makeAssignment(v));
- }
+ for (Variable v :
variableScope.getVariables()) {
+ actionBody.addStatement(makeAssignment(v));
+ }
- BlockStmt blockStmt = StaticJavaParser.parseBlock("{"
+ entry.getValue().getConstraint() + "}");
-
blockStmt.getStatements().forEach(actionBody::addStatement);
+ BlockStmt blockStmt =
StaticJavaParser.parseBlock("{" + constraint.getConstraint() + "}");
+
blockStmt.getStatements().forEach(actionBody::addStatement);
- returnValueEvaluator = lambda;
+ returnValueEvaluator = lambda;
+ }
+
body.addStatement(getFactoryMethod(getNodeId(node), METHOD_CONSTRAINT,
+ new
LongLiteralExpr(entry.getKey().getNodeId()),
+ new
StringLiteralExpr(getOrDefault(entry.getKey().getConnectionId(), "")),
+ new
StringLiteralExpr(entry.getKey().getToType()),
+ new
StringLiteralExpr(constraint.getDialect()),
+ returnValueEvaluator,
+ new
IntegerLiteralExpr(constraint.getPriority()),
+ new
BooleanLiteralExpr(constraint.isDefault())));
+ }
}
- body.addStatement(getFactoryMethod(getNodeId(node),
METHOD_CONSTRAINT,
- new LongLiteralExpr(entry.getKey().getNodeId()),
- new
StringLiteralExpr(getOrDefault(entry.getKey().getConnectionId(), "")),
- new StringLiteralExpr(entry.getKey().getToType()),
- new
StringLiteralExpr(entry.getValue().getDialect()),
- returnValueEvaluator,
- new
IntegerLiteralExpr(entry.getValue().getPriority()),
- new
BooleanLiteralExpr(entry.getValue().isDefault())));
}
}
}
body.addStatement(getDoneMethod(getNodeId(node)));
}
- public static ObjectCreationExpr
buildFEELReturnValueEvaluator(Entry<ConnectionRef, Constraint> entry) {
+ private static ObjectCreationExpr buildFEELReturnValueEvaluator(Constraint
constraint) {
return new ObjectCreationExpr(null,
StaticJavaParser.parseClassOrInterfaceType("org.jbpm.bpmn2.feel.FeelReturnValueEvaluator"),
- new NodeList<>(new
StringLiteralExpr(entry.getValue().getConstraint())));
+ new NodeList<>(new
StringLiteralExpr(constraint.getConstraint())));
}
}
diff --git
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/StateNodeVisitor.java
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/StateNodeVisitor.java
index 31faf6b45c..cec7b37a91 100644
---
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/StateNodeVisitor.java
+++
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/StateNodeVisitor.java
@@ -18,11 +18,15 @@
*/
package org.jbpm.compiler.canonical;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.Map;
import java.util.stream.Stream;
import org.jbpm.process.core.context.variable.VariableScope;
import org.jbpm.ruleflow.core.factory.StateNodeFactory;
+import org.jbpm.workflow.core.Constraint;
+import org.jbpm.workflow.core.impl.ConnectionRef;
import org.jbpm.workflow.core.node.StateNode;
import org.kie.api.definition.process.Node;
@@ -60,15 +64,21 @@ public class StateNodeVisitor extends
CompositeContextNodeVisitor<StateNode> {
if (node.getConstraints() == null) {
return Stream.empty();
}
- return node.getConstraints()
- .entrySet()
- .stream()
- .map((e -> getFactoryMethod(getNodeId(node), METHOD_CONSTRAINT,
- getOrNullExpr(e.getKey().getConnectionId()),
- new LongLiteralExpr(e.getKey().getNodeId()),
- new StringLiteralExpr(e.getKey().getToType()),
- new StringLiteralExpr(e.getValue().getDialect()),
- new
StringLiteralExpr(StringEscapeUtils.escapeJava(e.getValue().getConstraint())),
- new IntegerLiteralExpr(e.getValue().getPriority()))));
+ Collection<MethodCallExpr> result = new ArrayList<>();
+ for (Map.Entry<ConnectionRef, Collection<Constraint>> entry :
node.getConstraints().entrySet()) {
+ ConnectionRef ref = entry.getKey();
+ for (Constraint constraint : entry.getValue()) {
+ if (constraint != null) {
+ result.add(getFactoryMethod(getNodeId(node),
METHOD_CONSTRAINT,
+ getOrNullExpr(ref.getConnectionId()),
+ new LongLiteralExpr(ref.getNodeId()),
+ new StringLiteralExpr(ref.getToType()),
+ new StringLiteralExpr(constraint.getDialect()),
+ new
StringLiteralExpr(StringEscapeUtils.escapeJava(constraint.getConstraint())),
+ new IntegerLiteralExpr(constraint.getPriority())));
+ }
+ }
+ }
+ return result.stream();
}
}
diff --git
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/MultiConditionalSequenceFlowNodeBuilder.java
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/MultiConditionalSequenceFlowNodeBuilder.java
index 917e1f3ccb..5f6f92f395 100755
---
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/MultiConditionalSequenceFlowNodeBuilder.java
+++
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/MultiConditionalSequenceFlowNodeBuilder.java
@@ -18,8 +18,9 @@
*/
package org.jbpm.process.builder;
-import java.util.HashMap;
+import java.util.Collection;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.Map;
import org.drools.drl.ast.descr.ProcessDescr;
@@ -30,7 +31,6 @@ import
org.jbpm.process.instance.impl.ReturnValueConstraintEvaluator;
import org.jbpm.process.instance.impl.RuleConstraintEvaluator;
import org.jbpm.workflow.core.Constraint;
import org.jbpm.workflow.core.impl.ConnectionRef;
-import org.jbpm.workflow.core.impl.ConstraintImpl;
import org.jbpm.workflow.core.impl.NodeImpl;
import org.jbpm.workflow.core.node.Split;
import org.kie.api.definition.process.Connection;
@@ -42,19 +42,16 @@ public class MultiConditionalSequenceFlowNodeBuilder
implements ProcessNodeBuild
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) {
+ if (node instanceof Split) {
return;
}
// we need to clone the map, so we can update the original while
iterating.
- Map<ConnectionRef, Constraint> map = new HashMap<>(constraints);
- for (Iterator<Map.Entry<ConnectionRef, Constraint>> it =
map.entrySet().iterator(); it.hasNext();) {
- Map.Entry<ConnectionRef, Constraint> entry = it.next();
+ for (Iterator<Map.Entry<ConnectionRef, Collection<Constraint>>> it =
((NodeImpl) node).getConstraints().entrySet().iterator(); it.hasNext();) {
+ Map.Entry<ConnectionRef, Collection<Constraint>> entry = it.next();
ConnectionRef connection = entry.getKey();
- ConstraintImpl constraint = (ConstraintImpl) entry.getValue();
+ Collection<Constraint> constraints = new
LinkedList<>(entry.getValue());
Connection outgoingConnection = null;
for (Connection out : ((NodeImpl)
node).getDefaultOutgoingConnections()) {
if (out.getToType().equals(connection.getToType())
@@ -65,27 +62,31 @@ public class MultiConditionalSequenceFlowNodeBuilder
implements ProcessNodeBuild
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);
+ for (Constraint constraint : constraints) {
+ if (constraint != null) {
+ 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());
+ 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);
+ ProcessDialect dialect =
ProcessDialectRegistry.getDialect(constraint.getDialect());
+
dialect.getReturnValueEvaluatorBuilder().build(context, returnValueConstraint,
returnValueDescr, (NodeImpl) node);
+ }
+ }
}
}
diff --git
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/SplitNodeBuilder.java
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/SplitNodeBuilder.java
index 3d2194cd25..3fc60663da 100755
---
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/SplitNodeBuilder.java
+++
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/SplitNodeBuilder.java
@@ -18,8 +18,9 @@
*/
package org.jbpm.process.builder;
-import java.util.HashMap;
+import java.util.Collection;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.Map;
import org.drools.drl.ast.descr.ProcessDescr;
@@ -30,7 +31,6 @@ import
org.jbpm.process.instance.impl.ReturnValueConstraintEvaluator;
import org.jbpm.process.instance.impl.RuleConstraintEvaluator;
import org.jbpm.workflow.core.Constraint;
import org.jbpm.workflow.core.impl.ConnectionRef;
-import org.jbpm.workflow.core.impl.ConstraintImpl;
import org.jbpm.workflow.core.impl.NodeImpl;
import org.jbpm.workflow.core.node.Split;
import org.kie.api.definition.process.Connection;
@@ -50,11 +50,11 @@ public class SplitNodeBuilder implements ProcessNodeBuilder
{
return;
}
// we need to clone the map, so we can update the original while
iterating.
- Map<ConnectionRef, Constraint> map = new
HashMap<>(splitNode.getConstraints());
- for (Iterator<Map.Entry<ConnectionRef, Constraint>> it =
map.entrySet().iterator(); it.hasNext();) {
- Map.Entry<ConnectionRef, Constraint> entry = it.next();
+ Map<ConnectionRef, Collection<Constraint>> map =
splitNode.getConstraints();
+ for (Iterator<Map.Entry<ConnectionRef, Collection<Constraint>>> it =
map.entrySet().iterator(); it.hasNext();) {
+ Map.Entry<ConnectionRef, Collection<Constraint>> entry = it.next();
ConnectionRef connection = entry.getKey();
- ConstraintImpl constraint = (ConstraintImpl) entry.getValue();
+ Collection<Constraint> constraints = entry.getValue();
Connection outgoingConnection = null;
for (Connection out : splitNode.getDefaultOutgoingConnections()) {
if (out.getToType().equals(connection.getToType())
@@ -65,35 +65,39 @@ public class SplitNodeBuilder implements ProcessNodeBuilder
{
if (outgoingConnection == null) {
throw new IllegalArgumentException("Could not find outgoing
connection");
}
- if (constraint == null && splitNode.isDefault(outgoingConnection))
{
- // do nothing since conditions are ignored for default
sequence flow
- } else if (constraint != null &&
"rule".equals(constraint.getType())) {
- RuleConstraintEvaluator ruleConstraint = new
RuleConstraintEvaluator();
- ruleConstraint.setDialect(constraint.getDialect());
- ruleConstraint.setName(constraint.getName());
- ruleConstraint.setPriority(constraint.getPriority());
- ruleConstraint.setDefault(constraint.isDefault());
- ruleConstraint.setType(constraint.getType());
- ruleConstraint.setConstraint(constraint.getConstraint());
- splitNode.setConstraint(outgoingConnection, ruleConstraint);
- } else if (constraint != null &&
"code".equals(constraint.getType())) {
- ReturnValueConstraintEvaluator returnValueConstraint = new
ReturnValueConstraintEvaluator();
- returnValueConstraint.setDialect(constraint.getDialect());
- returnValueConstraint.setName(constraint.getName());
- returnValueConstraint.setPriority(constraint.getPriority());
- returnValueConstraint.setDefault(constraint.isDefault());
- returnValueConstraint.setType(constraint.getType());
-
returnValueConstraint.setConstraint(constraint.getConstraint());
- splitNode.setConstraint(outgoingConnection,
returnValueConstraint);
+ if (!splitNode.isDefault(outgoingConnection) && constraints !=
null)
+ for (Constraint constraint : new LinkedList<>(constraints)) {
+ if (constraint != null) {
+ 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());
+ ruleConstraint.setType(constraint.getType());
+
ruleConstraint.setConstraint(constraint.getConstraint());
+ splitNode.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());
+
returnValueConstraint.setType(constraint.getType());
+
returnValueConstraint.setConstraint(constraint.getConstraint());
+ splitNode.setConstraint(outgoingConnection,
returnValueConstraint);
- ReturnValueDescr returnValueDescr = new ReturnValueDescr();
- returnValueDescr.setText(constraint.getConstraint());
- returnValueDescr.setResource(processDescr.getResource());
+ 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);
- }
+ ProcessDialect dialect =
ProcessDialectRegistry.getDialect(constraint.getDialect());
+
dialect.getReturnValueEvaluatorBuilder().build(context, returnValueConstraint,
returnValueDescr, (NodeImpl) node);
+ }
+ }
+ }
}
+
}
}
diff --git
a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/validation/RuleFlowProcessValidator.java
b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/validation/RuleFlowProcessValidator.java
index 831354914d..72106aa8cf 100755
---
a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/validation/RuleFlowProcessValidator.java
+++
b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/validation/RuleFlowProcessValidator.java
@@ -20,6 +20,7 @@ package org.jbpm.ruleflow.core.validation;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
@@ -43,6 +44,7 @@ import org.jbpm.process.core.validation.ProcessValidator;
import org.jbpm.process.core.validation.impl.ProcessValidationErrorImpl;
import org.jbpm.ruleflow.core.Metadata;
import org.jbpm.ruleflow.core.RuleFlowProcess;
+import org.jbpm.workflow.core.Constraint;
import org.jbpm.workflow.core.DroolsAction;
import org.jbpm.workflow.core.Node;
import org.jbpm.workflow.core.WorkflowProcess;
@@ -268,10 +270,8 @@ public class RuleFlowProcessValidator implements
ProcessValidator {
if (split.getType() == Split.TYPE_XOR || split.getType() ==
Split.TYPE_OR) {
for (final Iterator<Connection> it =
split.getDefaultOutgoingConnections().iterator(); it.hasNext();) {
final Connection connection = it.next();
- if (split.getConstraint(connection) == null &&
!split.isDefault(connection)
- || (!split.isDefault(connection)
- &&
(split.getConstraint(connection).getConstraint() == null
- ||
split.getConstraint(connection).getConstraint().trim().length() == 0))) {
+ Collection<Constraint> constraints =
split.getConstraints(connection);
+ if ((constraints == null ||
constraints.stream().allMatch(c -> c == null || c.getConstraint() == null ||
c.getConstraint().isBlank())) && !split.isDefault(connection)) {
addErrorMessage(process,
node,
errors,
diff --git
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/NodeImpl.java
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/NodeImpl.java
index e58e08bb24..694e3049c2 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/NodeImpl.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/NodeImpl.java
@@ -19,15 +19,18 @@
package org.jbpm.workflow.core.impl;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;
import org.jbpm.process.core.Context;
import org.jbpm.process.core.ContextResolver;
import org.jbpm.process.core.context.variable.Mappable;
+import org.jbpm.process.instance.impl.ReturnValueConstraintEvaluator;
import org.jbpm.ruleflow.core.RuleFlowProcess;
import org.jbpm.workflow.core.Constraint;
import org.jbpm.workflow.core.Node;
@@ -53,7 +56,7 @@ public abstract class NodeImpl implements Node,
ContextResolver, Mappable {
private Map<String, Context> contexts = new HashMap<>();
private Map<String, Object> metaData = new HashMap<>();
- protected Map<ConnectionRef, Constraint> constraints = new HashMap<>();
+ protected Map<ConnectionRef, Collection<Constraint>> constraints = new
HashMap<>();
private IOSpecification ioSpecification;
private MultiInstanceSpecification multiInstanceSpecification;
@@ -398,18 +401,23 @@ public abstract class NodeImpl implements Node,
ContextResolver, Mappable {
this.metaData = metaData;
}
- public Constraint getConstraint(final Connection connection) {
+ public Collection<Constraint> getConstraints(final Connection connection) {
if (connection == null) {
throw new IllegalArgumentException("connection is null");
}
ConnectionRef ref = new ConnectionRef((String)
connection.getMetaData().get("UniqueId"), connection.getTo().getId(),
connection.getToType());
return this.constraints.get(ref);
+ }
+ public Constraint getConstraint(final Connection connection) {
+ Collection<Constraint> constraints = getConstraints(connection);
+ return constraints != null ? constraints.iterator().next() : null;
}
public Constraint internalGetConstraint(final ConnectionRef ref) {
- return this.constraints.get(ref);
+ Collection<Constraint> constraints = this.constraints.get(ref);
+ return constraints != null ? constraints.iterator().next() : null;
}
public void setConstraint(final Connection connection,
@@ -431,10 +439,12 @@ public abstract class NodeImpl implements Node,
ContextResolver, Mappable {
throw new IllegalArgumentException(
"A " + this.getName() + " node only accepts constraints
linked to a connection");
}
- this.constraints.put(connectionRef, constraint);
+ Collection<Constraint> values =
this.constraints.computeIfAbsent(connectionRef, r -> new ArrayList<>());
+ values.removeIf(v ->
!ReturnValueConstraintEvaluator.class.isInstance(v) &&
Objects.equals(v.getConstraint(), constraint.getConstraint()));
+ values.add(constraint);
}
- public Map<ConnectionRef, Constraint> getConstraints() {
+ public Map<ConnectionRef, Collection<Constraint>> getConstraints() {
return Collections.unmodifiableMap(this.constraints);
}
diff --git
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/Split.java
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/Split.java
index 9186851e9c..659b877dc6 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/Split.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/Split.java
@@ -18,8 +18,7 @@
*/
package org.jbpm.workflow.core.node;
-import java.util.Collections;
-import java.util.Map;
+import java.util.Collection;
import org.jbpm.workflow.core.Constraint;
import org.jbpm.workflow.core.Node;
@@ -86,23 +85,24 @@ public class Split extends NodeImpl implements
Constrainable {
if (this.type == TYPE_OR || this.type == TYPE_XOR) {
ConnectionRef ref = new ConnectionRef((String)
connection.getMetaData().get("UniqueId"), connection.getTo().getId(),
connection.getToType());
- Constraint constraint = this.constraints.get(ref);
+ Collection<Constraint> constraints = this.constraints.get(ref);
+ if (constraints != null) {
+ for (Constraint constraint : constraints) {
+ if (constraint != null) {
+ return constraint.isDefault();
+ }
+ }
+ }
String defaultConnection = (String) getMetaData().get("Default");
String connectionId = (String)
connection.getMetaData().get("UniqueId");
- if (constraint != null) {
- return constraint.isDefault();
- } else if (constraint == null &&
connectionId.equals(defaultConnection)) {
- return true;
- } else {
- return false;
- }
+ return connectionId.equals(defaultConnection);
}
throw new UnsupportedOperationException("Constraints are " +
"only supported with XOR or OR split types, not with: " +
getType());
}
@Override
- public Constraint getConstraint(final Connection connection) {
+ public Collection<Constraint> getConstraints(final Connection connection) {
if (connection == null) {
throw new IllegalArgumentException("connection is null");
}
@@ -115,11 +115,6 @@ public class Split extends NodeImpl implements
Constrainable {
"only supported with XOR or OR split types, not with: " +
getType());
}
- @Override
- public Constraint internalGetConstraint(final ConnectionRef ref) {
- return this.constraints.get(ref);
- }
-
@Override
public void setConstraint(final Connection connection,
final Constraint constraint) {
@@ -139,20 +134,6 @@ public class Split extends NodeImpl implements
Constrainable {
}
}
- @Override
- public void addConstraint(ConnectionRef connectionRef, Constraint
constraint) {
- if (connectionRef == null) {
- throw new IllegalArgumentException(
- "A split node only accepts constraints linked to a
connection");
- }
- this.constraints.put(connectionRef, constraint);
- }
-
- @Override
- public Map<ConnectionRef, Constraint> getConstraints() {
- return Collections.unmodifiableMap(this.constraints);
- }
-
@Override
public void validateAddIncomingConnection(final String type, final
Connection connection) {
super.validateAddIncomingConnection(type, connection);
diff --git
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/StateNode.java
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/StateNode.java
index b760ec9882..013876f710 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/StateNode.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/StateNode.java
@@ -18,60 +18,7 @@
*/
package org.jbpm.workflow.core.node;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.jbpm.workflow.core.Constraint;
-import org.jbpm.workflow.core.impl.ConnectionRef;
-import org.kie.api.definition.process.Connection;
-
public class StateNode extends CompositeContextNode implements Constrainable {
private static final long serialVersionUID = 510l;
-
- private Map<ConnectionRef, Constraint> constraints = new HashMap<>();
-
- public void setConstraints(Map<ConnectionRef, Constraint> constraints) {
- this.constraints = constraints;
- }
-
- @Override
- public void setConstraint(final Connection connection, final Constraint
constraint) {
- if (connection == null) {
- throw new IllegalArgumentException("connection is null");
- }
- if (!getDefaultOutgoingConnections().contains(connection)) {
- throw new IllegalArgumentException("connection is unknown:" +
connection);
- }
- addConstraint(new ConnectionRef((String)
connection.getMetaData().get("UniqueId"),
- connection.getTo().getId(), connection.getToType()),
constraint);
- }
-
- @Override
- public void addConstraint(ConnectionRef connectionRef, Constraint
constraint) {
- if (connectionRef == null) {
- throw new IllegalArgumentException(
- "A state node only accepts constraints linked to a
connection");
- }
- constraints.put(connectionRef, constraint);
- }
-
- public Constraint getConstraint(ConnectionRef connectionRef) {
- return constraints.get(connectionRef);
- }
-
- @Override
- public Map<ConnectionRef, Constraint> getConstraints() {
- return constraints;
- }
-
- @Override
- public Constraint getConstraint(final Connection connection) {
- if (connection == null) {
- throw new IllegalArgumentException("connection is null");
- }
- ConnectionRef ref = new ConnectionRef((String)
connection.getMetaData().get("UniqueId"), connection.getTo().getId(),
connection.getToType());
- return this.constraints.get(ref);
- }
-
}
diff --git
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceImpl.java
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceImpl.java
index eecc9e3378..0cfd7ea001 100755
---
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceImpl.java
+++
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceImpl.java
@@ -46,6 +46,7 @@ import org.jbpm.process.instance.impl.Action;
import org.jbpm.process.instance.impl.ConstraintEvaluator;
import org.jbpm.util.ContextFactory;
import org.jbpm.util.PatternConstants;
+import org.jbpm.workflow.core.Constraint;
import org.jbpm.workflow.core.Node;
import org.jbpm.workflow.core.impl.NodeImpl;
import org.jbpm.workflow.instance.WorkflowProcessInstance;
@@ -311,7 +312,7 @@ public abstract class NodeInstanceImpl implements
org.jbpm.workflow.instance.Nod
List<Connection> connections = null;
if (node != null) {
- if ("true".equals(System.getProperty("jbpm.enable.multi.con")) &&
((NodeImpl) node).getConstraints().size() > 0) {
+ if ("true".equals(System.getProperty("jbpm.enable.multi.con")) &&
!((NodeImpl) node).getConstraints().isEmpty()) {
int priority;
connections = ((NodeImpl)
node).getDefaultOutgoingConnections();
boolean found = false;
@@ -323,13 +324,17 @@ public abstract class NodeInstanceImpl implements
org.jbpm.workflow.instance.Nod
Connection selectedConnection = null;
ConstraintEvaluator selectedConstraint = null;
for (final Connection connection : outgoingCopy) {
- ConstraintEvaluator constraint = (ConstraintEvaluator)
((NodeImpl) node).getConstraint(connection);
- if (constraint != null
- && constraint.getPriority() < priority
- && !constraint.isDefault()) {
- priority = constraint.getPriority();
- selectedConnection = connection;
- selectedConstraint = constraint;
+ Collection<Constraint> constraints = ((NodeImpl)
node).getConstraints(connection);
+ if (constraints != null) {
+ for (Constraint constraint : constraints) {
+ if (constraint instanceof ConstraintEvaluator
&& constraint.getPriority() < priority
+ && !constraint.isDefault()) {
+ priority = constraint.getPriority();
+ selectedConnection = connection;
+ selectedConstraint = (ConstraintEvaluator)
constraint;
+ }
+
+ }
}
}
if (selectedConstraint == null) {
@@ -352,10 +357,17 @@ public abstract class NodeInstanceImpl implements
org.jbpm.workflow.instance.Nod
}
if (!found) {
for (final Connection connection : connections) {
- ConstraintEvaluator constraint = (ConstraintEvaluator)
((NodeImpl) node).getConstraint(connection);
- if (constraint.isDefault()) {
- triggerConnection(connection);
- found = true;
+ Collection<Constraint> constraints = ((NodeImpl)
node).getConstraints(connection);
+ if (constraints != null) {
+ for (Constraint constraint : constraints) {
+ if (constraint.isDefault()) {
+ triggerConnection(connection);
+ found = true;
+ break;
+ }
+ }
+ }
+ if (found) {
break;
}
}
diff --git
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/SplitInstance.java
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/SplitInstance.java
index a211da11fb..47fb7610c8 100755
---
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/SplitInstance.java
+++
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/SplitInstance.java
@@ -19,6 +19,7 @@
package org.jbpm.workflow.instance.node;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -33,6 +34,7 @@ import org.jbpm.process.instance.ContextInstanceContainer;
import org.jbpm.process.instance.InternalProcessRuntime;
import org.jbpm.process.instance.context.exclusive.ExclusiveGroupInstance;
import org.jbpm.process.instance.impl.ConstraintEvaluator;
+import org.jbpm.workflow.core.Constraint;
import org.jbpm.workflow.core.Node;
import org.jbpm.workflow.core.node.Split;
import org.jbpm.workflow.instance.NodeInstanceContainer;
@@ -83,21 +85,25 @@ public class SplitInstance extends NodeInstanceImpl {
Connection selected = null;
for (final Iterator<Connection> iterator =
outgoing.iterator(); iterator.hasNext();) {
final Connection connection = iterator.next();
- ConstraintEvaluator constraint = (ConstraintEvaluator)
split.getConstraint(connection);
- if (constraint != null && constraint.getPriority() <
priority && !constraint.isDefault()) {
- try {
- if (constraint.evaluate(this,
- connection,
- constraint)) {
- selected = connection;
- priority = constraint.getPriority();
+ Collection<Constraint> constraints =
split.getConstraints(connection);
+ if (constraints != null) {
+ for (Constraint constraint : constraints) {
+ if (constraint instanceof ConstraintEvaluator &&
constraint.getPriority() < priority && !constraint.isDefault()) {
+ try {
+ if (((ConstraintEvaluator)
constraint).evaluate(this,
+ connection,
+ constraint)) {
+ selected = connection;
+ priority = constraint.getPriority();
+ }
+ } catch (RuntimeException e) {
+ throw new RuntimeException(
+ "Exception when trying to evaluate
constraint "
+ + constraint.getName() + "
in split "
+ + split.getName(),
+ e);
+ }
}
- } catch (RuntimeException e) {
- throw new RuntimeException(
- "Exception when trying to evaluate
constraint "
- + constraint.getName() + " in
split "
- + split.getName(),
- e);
}
}
}
@@ -133,14 +139,16 @@ public class SplitInstance extends NodeInstanceImpl {
ConstraintEvaluator selectedConstraint = null;
for (final Iterator<Connection> iterator =
outgoingCopy.iterator(); iterator.hasNext();) {
final Connection connection = iterator.next();
- ConstraintEvaluator constraint = (ConstraintEvaluator)
split.getConstraint(connection);
-
- if (constraint != null
- && constraint.getPriority() < priority
- && !constraint.isDefault()) {
- priority = constraint.getPriority();
- selectedConnection = connection;
- selectedConstraint = constraint;
+ Collection<Constraint> constraints =
split.getConstraints(connection);
+ if (constraints != null) {
+ for (Constraint constraint : constraints) {
+ if (constraint instanceof ConstraintEvaluator
&& constraint.getPriority() < priority
+ && !constraint.isDefault()) {
+ priority = constraint.getPriority();
+ selectedConnection = connection;
+ selectedConstraint = (ConstraintEvaluator)
constraint;
+ }
+ }
}
}
if (selectedConstraint == null) {
@@ -163,13 +171,22 @@ public class SplitInstance extends NodeInstanceImpl {
triggerNodeInstance(nodeInstance.getNodeInstance(),
nodeInstance.getToType());
}
if (!found) {
- for (final Iterator<Connection> iterator =
outgoing.iterator(); iterator.hasNext();) {
+ final Iterator<Connection> iterator = outgoing.iterator();
+ while (!found && iterator.hasNext()) {
final Connection connection = iterator.next();
- ConstraintEvaluator constraint = (ConstraintEvaluator)
split.getConstraint(connection);
- if (constraint != null && constraint.isDefault() ||
split.isDefault(connection)) {
+ Collection<Constraint> constraints =
split.getConstraints(connection);
+ if (constraints != null) {
+ for (Constraint constraint : constraints) {
+ if (constraint != null &&
constraint.isDefault()) {
+ triggerConnection(connection);
+ found = true;
+ break;
+ }
+ }
+ }
+ if (!found && split.isDefault(connection)) {
triggerConnection(connection);
found = true;
- break;
}
}
}
diff --git
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/StateNodeInstance.java
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/StateNodeInstance.java
index 34e983bd1c..37a928a293 100755
---
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/StateNodeInstance.java
+++
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/StateNodeInstance.java
@@ -18,6 +18,8 @@
*/
package org.jbpm.workflow.instance.node;
+import java.util.Collection;
+
import org.drools.core.common.InternalAgenda;
import org.drools.core.rule.consequence.InternalMatch;
import org.jbpm.workflow.core.Constraint;
@@ -50,17 +52,22 @@ public class StateNodeInstance extends
CompositeContextNodeInstance implements E
Connection selected = null;
int priority = Integer.MAX_VALUE;
for (Connection connection :
stateNode.getOutgoingConnections(Node.CONNECTION_DEFAULT_TYPE)) {
- Constraint constraint = stateNode.getConstraint(connection);
- if (constraint != null && constraint.getPriority() < priority) {
- String rule = "RuleFlowStateNode-" +
getProcessInstance().getProcessId() + "-" +
- getStateNode().getUniqueId() + "-" +
- connection.getTo().getId() + "-" +
- connection.getToType();
- boolean isActive = ((InternalAgenda)
getProcessInstance().getKnowledgeRuntime().getAgenda())
- .isRuleActiveInRuleFlowGroup("DROOLS_SYSTEM", rule,
getProcessInstance().getStringId());
- if (isActive) {
- selected = connection;
- priority = constraint.getPriority();
+ Collection<Constraint> constraints =
stateNode.getConstraints(connection);
+
+ if (constraints != null) {
+ for (Constraint constraint : constraints) {
+ if (constraint.getPriority() < priority) {
+ String rule = "RuleFlowStateNode-" +
getProcessInstance().getProcessId() + "-" +
+ getStateNode().getUniqueId() + "-" +
+ connection.getTo().getId() + "-" +
+ connection.getToType();
+ boolean isActive = ((InternalAgenda)
getProcessInstance().getKnowledgeRuntime().getAgenda())
+ .isRuleActiveInRuleFlowGroup("DROOLS_SYSTEM",
rule, getProcessInstance().getStringId());
+ if (isActive) {
+ selected = connection;
+ priority = constraint.getPriority();
+ }
+ }
}
}
}
@@ -71,6 +78,7 @@ public class StateNodeInstance extends
CompositeContextNodeInstance implements E
addTriggerListener();
addActivationListener();
}
+
}
@Override
@@ -84,14 +92,19 @@ public class StateNodeInstance extends
CompositeContextNodeInstance implements E
if (event instanceof String) {
for (Connection connection :
getStateNode().getOutgoingConnections(Node.CONNECTION_DEFAULT_TYPE)) {
boolean selected = false;
- Constraint constraint =
getStateNode().getConstraint(connection);
- if (constraint == null) {
+ Collection<Constraint> constraints =
getStateNode().getConstraints(connection);
+ if (constraints == null) {
if (event.equals(connection.getTo().getName())) {
selected = true;
}
- } else if (event.equals(constraint.getName())) {
- selected = true;
- }
+ } else
+ for (Constraint constraint : constraints) {
+
+ if (event.equals(constraint.getName())) {
+ selected = true;
+ break;
+ }
+ }
if (selected) {
triggerEvent(ExtendedNodeImpl.EVENT_NODE_EXIT);
removeEventListeners();
@@ -146,14 +159,15 @@ public class StateNodeInstance extends
CompositeContextNodeInstance implements E
public void activationCreated(MatchCreatedEvent event) {
Connection selected = null;
for (Connection connection :
getNode().getOutgoingConnections(Node.CONNECTION_DEFAULT_TYPE)) {
- Constraint constraint = getStateNode().getConstraint(connection);
- if (constraint != null) {
+ Collection<Constraint> constraints =
getStateNode().getConstraints(connection);
+ if (constraints != null) {
String constraintName = getActivationEventType() + "-"
+ connection.getTo().getId() + "-" +
connection.getToType();
if (constraintName.equals(event.getMatch().getRule().getName())
&& checkProcessInstance((InternalMatch)
event.getMatch())) {
selected = connection;
}
+
}
}
if (selected != null) {
diff --git
a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/process/ProcessGenerationIT.java
b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/process/ProcessGenerationIT.java
index dd896a2147..c728af6aba 100644
---
a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/process/ProcessGenerationIT.java
+++
b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/process/ProcessGenerationIT.java
@@ -532,11 +532,11 @@ public class ProcessGenerationIT extends
AbstractCodegenIT {
assertThat(cNode.getConstraints()).isNull();
return;
}
- Map<ConnectionRef, Constraint> expected = eNode.getConstraints();
- Map<ConnectionRef, Constraint> current = cNode.getConstraints();
+ Map<ConnectionRef, Collection<Constraint>> expected =
eNode.getConstraints();
+ Map<ConnectionRef, Collection<Constraint>> current =
cNode.getConstraints();
assertThat(current).hasSameSizeAs(expected);
expected.forEach((conn, constraint) -> {
- Optional<Map.Entry<ConnectionRef, Constraint>> currentEntry =
current.entrySet()
+ Optional<Map.Entry<ConnectionRef, Collection<Constraint>>>
currentEntry = current.entrySet()
.stream()
.filter(e -> e.getKey().getConnectionId() == null &&
conn.getConnectionId() == null ||
e.getKey().getConnectionId().equals(conn.getConnectionId()))
@@ -545,13 +545,15 @@ public class ProcessGenerationIT extends
AbstractCodegenIT {
ConnectionRef currentConn = currentEntry.get().getKey();
assertThat(currentConn.getNodeId()).isEqualTo(conn.getNodeId());
assertThat(currentConn.getToType()).isEqualTo(conn.getToType());
- Constraint currentConstraint = currentEntry.get().getValue();
+ Collection<Constraint> constraints = currentEntry.get().getValue();
if (constraint == null) {
- assertThat(currentConstraint).isNull();
+ assertThat(constraints).isNull();
} else {
+ Constraint currentConstraint = constraints.iterator().next();
+ Constraint expectedConstraint = constraint.iterator().next();
assertThat(currentConstraint).isNotNull();
-
assertThat(currentConstraint.getPriority()).isEqualTo(constraint.getPriority());
-
assertThat(currentConstraint.getDialect()).isEqualTo(constraint.getDialect());
+
assertThat(currentConstraint.getPriority()).isEqualTo(expectedConstraint.getPriority());
+
assertThat(currentConstraint.getDialect()).isEqualTo(expectedConstraint.getDialect());
assertThat(currentConstraint.getName()).isEqualTo(conn.getConnectionId());
assertThat(currentConstraint.getType()).isEqualTo(CONNECTION_DEFAULT_TYPE);
}
diff --git
a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/test/java/org/kie/kogito/serverless/workflow/ServerlessWorkflowParsingTest.java
b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/test/java/org/kie/kogito/serverless/workflow/ServerlessWorkflowParsingTest.java
index 4341ea27ef..f0f5a11337 100644
---
a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/test/java/org/kie/kogito/serverless/workflow/ServerlessWorkflowParsingTest.java
+++
b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/test/java/org/kie/kogito/serverless/workflow/ServerlessWorkflowParsingTest.java
@@ -18,6 +18,7 @@
*/
package org.kie.kogito.serverless.workflow;
+import java.util.Collection;
import java.util.List;
import org.jbpm.ruleflow.core.Metadata;
@@ -577,12 +578,7 @@ public class ServerlessWorkflowParsingTest extends
AbstractServerlessWorkflowPar
assertThat(split.getType()).isEqualTo(2);
assertThat(split.getConstraints()).hasSize(2);
- boolean haveDefaultConstraint = false;
- for (Constraint constraint : split.getConstraints().values()) {
- haveDefaultConstraint = haveDefaultConstraint ||
constraint.isDefault();
- }
-
- assertThat(haveDefaultConstraint).isTrue();
+ assertHaveDefaultConstraint(split);
}
@ParameterizedTest
@@ -603,12 +599,11 @@ public class ServerlessWorkflowParsingTest extends
AbstractServerlessWorkflowPar
assertThat(split.getType()).isEqualTo(2);
assertThat(split.getConstraints()).hasSize(2);
- boolean haveDefaultConstraint = false;
- for (Constraint constraint : split.getConstraints().values()) {
- haveDefaultConstraint = haveDefaultConstraint ||
constraint.isDefault();
- }
+ assertHaveDefaultConstraint(split);
+ }
- assertThat(haveDefaultConstraint).isTrue();
+ private void assertHaveDefaultConstraint(Split split) {
+
assertThat(split.getConstraints().values().stream().flatMap(Collection::stream).anyMatch(Constraint::isDefault)).isTrue();
}
@ParameterizedTest
diff --git
a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/test/java/org/kie/kogito/serverless/workflow/WorkflowTestUtils.java
b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/test/java/org/kie/kogito/serverless/workflow/WorkflowTestUtils.java
index 5969a3e46b..ba280e7dc6 100644
---
a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/test/java/org/kie/kogito/serverless/workflow/WorkflowTestUtils.java
+++
b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/test/java/org/kie/kogito/serverless/workflow/WorkflowTestUtils.java
@@ -26,6 +26,7 @@ import java.io.Reader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.Collection;
import java.util.List;
import java.util.Objects;
@@ -150,6 +151,7 @@ public class WorkflowTestUtils {
public static void assertConstraintIsDefault(Split splitNode, String
constraintName) {
Constraint constraint = splitNode.getConstraints().values().stream()
+ .flatMap(Collection::stream)
.filter(c -> constraintName.equals(c.getName()))
.findFirst().orElse(null);
assertThat(constraint)
diff --git
a/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/test/java/org/kie/kogito/serverless/workflow/executor/StaticWorkflowApplicationTest.java
b/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/test/java/org/kie/kogito/serverless/workflow/executor/StaticWorkflowApplicationTest.java
index 728fe91a56..5da4db34d0 100644
---
a/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/test/java/org/kie/kogito/serverless/workflow/executor/StaticWorkflowApplicationTest.java
+++
b/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/test/java/org/kie/kogito/serverless/workflow/executor/StaticWorkflowApplicationTest.java
@@ -25,6 +25,7 @@ import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Map;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
@@ -32,6 +33,7 @@ import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.kie.kogito.serverless.workflow.actions.SysoutAction;
+import org.kie.kogito.serverless.workflow.utils.ServerlessWorkflowUtils;
import org.kie.kogito.serverless.workflow.utils.WorkflowFormat;
import org.slf4j.LoggerFactory;
@@ -76,6 +78,19 @@ class StaticWorkflowApplicationTest {
}
}
+ @Test
+ void switchFile() throws IOException {
+ try (
+ StaticWorkflowApplication application =
StaticWorkflowApplication.create();
+ Reader reader = new
InputStreamReader(Thread.currentThread().getContextClassLoader().getResourceAsStream("switch.yaml")))
{
+ Workflow workflow = ServerlessWorkflowUtils.getWorkflow(reader,
WorkflowFormat.YAML);
+ assertThat(application.execute(workflow, Map.of("condition1",
false, "condition2", false)).getWorkflowdata().get("output")).isEqualTo(new
TextNode("default"));
+ assertThat(application.execute(workflow, Map.of("condition1",
true, "condition2", false)).getWorkflowdata().get("output")).isEqualTo(new
TextNode("branch1"));
+ assertThat(application.execute(workflow, Map.of("condition1",
false, "condition2", true)).getWorkflowdata().get("output")).isEqualTo(new
TextNode("branch1"));
+ assertThat(application.execute(workflow, Map.of("condition1",
true, "condition2", true)).getWorkflowdata().get("output")).isEqualTo(new
TextNode("branch1"));
+ }
+ }
+
@ParameterizedTest
@MethodSource("interpolationParameters")
void interpolationFile(String fileName, WorkflowFormat format) throws
IOException {
diff --git
a/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/test/resources/switch.yaml
b/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/test/resources/switch.yaml
new file mode 100644
index 0000000000..1af16001cb
--- /dev/null
+++
b/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/test/resources/switch.yaml
@@ -0,0 +1,32 @@
+version: 1.0.0
+specVersion: "0.8"
+id: Switch test
+name: Switch test
+start: switch test
+states:
+ - name: switch test
+ type: switch
+ dataConditions:
+ - name: Branch1-Name
+ condition: .condition1
+ transition: branch1
+ - name: Branch2-Name
+ condition: .condition2
+ transition: branch1
+
+ defaultCondition:
+ transition: default
+
+ - name: branch1
+ type: inject
+ data:
+ output: branch1
+ end: true
+
+
+ - name: default
+ type: inject
+ data:
+ output: default
+ end: true
+
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]