From ddc7b8bb6fbcc7bbe817bc67d7c4dea78cd133ae Mon Sep 17 00:00:00 2001 From: mariofusco Date: Tue, 27 Feb 2024 17:01:44 +0100 Subject: [PATCH] [KIE-978] fix generation of expression binding in executable model --- .../generator/OOPathExprGenerator.java | 2 +- .../generator/drlxparse/ConstraintParser.java | 14 +-- .../codegen/execmodel/ConstraintTest.java | 90 +++++++++++++++++++ 3 files changed, 99 insertions(+), 7 deletions(-) create mode 100644 drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/ConstraintTest.java diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/OOPathExprGenerator.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/OOPathExprGenerator.java index e16ba61bcf6..ca6882f98c8 100644 --- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/OOPathExprGenerator.java +++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/OOPathExprGenerator.java @@ -199,7 +199,7 @@ private void toPatternExpr(String bindingId, List list, DrlxPar expr.setScope( patternExpr ); patternExpr = expr; } - if (singleDrlx.getExpr() != null && !(singleDrlx.getExpr() instanceof NameExpr)) { + if (singleDrlx.getExpr() != null && singleDrlx.isPredicate()) { MethodCallExpr expr = expressionBuilder.buildExpressionWithIndexing( singleDrlx ); expr.setScope( patternExpr ); patternExpr = expr; diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/ConstraintParser.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/ConstraintParser.java index a6b5cab721a..f8a7365708c 100644 --- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/ConstraintParser.java +++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/ConstraintParser.java @@ -506,21 +506,23 @@ private DrlxParseResult parseNameExpr(DrlNameExpr nameExpr, Class patternType Expression withThis = DrlxParseUtil.prepend(new NameExpr(THIS_PLACEHOLDER), converted.getExpression()); if (hasBind) { - return new SingleDrlxParseSuccess(patternType, bindingId, null, converted.getType() ) + return new SingleDrlxParseSuccess(patternType, bindingId, withThis, converted.getType() ) .setLeft( new TypedExpression( withThis, converted.getType() ) ) .addReactOnProperty( lcFirstForBean(nameExpr.getNameAsString()) ); - } else if (context.hasDeclaration( expression )) { + } + + if (context.hasDeclaration( expression )) { Optional declarationSpec = context.getTypedDeclarationById(expression); if (declarationSpec.isPresent()) { return new SingleDrlxParseSuccess(patternType, bindingId, context.getVarExpr(printNode(drlxExpr)), declarationSpec.get().getDeclarationClass() ).setIsPredicate(true); } else { throw new IllegalArgumentException("Cannot find declaration specification by specified expression " + expression + "!"); } - } else { - return new SingleDrlxParseSuccess(patternType, bindingId, withThis, converted.getType() ) - .addReactOnProperty( nameExpr.getNameAsString() ) - .setIsPredicate(true); } + + return new SingleDrlxParseSuccess(patternType, bindingId, withThis, converted.getType() ) + .addReactOnProperty( nameExpr.getNameAsString() ) + .setIsPredicate(true); } private DrlxParseResult parseFieldAccessExpr( FieldAccessExpr fieldCallExpr, Class patternType, String bindingId ) { diff --git a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/ConstraintTest.java b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/ConstraintTest.java new file mode 100644 index 00000000000..b3475e58c2d --- /dev/null +++ b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/ConstraintTest.java @@ -0,0 +1,90 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.drools.model.codegen.execmodel; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import org.drools.model.codegen.execmodel.domain.Person; +import org.junit.Before; +import org.junit.Test; +import org.kie.api.runtime.KieSession; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ConstraintTest extends BaseModelTest { + + private static final String RULE_STRING = "package constraintexpression\n" + + "\n" + + "import " + Person.class.getCanonicalName() + "\n" + + "import java.util.List; \n" + + "import java.math.BigDecimal; \n" + + "global List bigDecimalListGlobal; \n" + + "rule \"r1\"\n" + + "when \n" + + " $p : Person($amount: (money == null ? BigDecimal.valueOf(100.0) : money))\n" + + "then \n" + + " System.out.println($amount); \n" + + " System.out.println($p); \n" + + " bigDecimalListGlobal.add($amount); \n " + + "end \n"; + + private KieSession ksession; + + private List bigDecimalListGlobal; + + public ConstraintTest(RUN_TYPE testRunType) { + super(testRunType); + } + + @Before + public void setup() { + ksession = getKieSession(RULE_STRING); + bigDecimalListGlobal = new ArrayList<>(); + ksession.setGlobal("bigDecimalListGlobal", bigDecimalListGlobal); + } + + @Test + public void testConstraintWithMoney() { + try { + BigDecimal money = BigDecimal.valueOf(34.45); + Person person = new Person("", money); + ksession.insert(person); + int rulesFired = ksession.fireAllRules(); + assertThat(rulesFired).isEqualTo(1); + assertThat(bigDecimalListGlobal).isNotEmpty().containsExactly(money); + } finally { + ksession.dispose(); + } + } + + @Test + public void testConstraintWithoutMoney() { + try { + Person person = new Person(); + ksession.insert(person); + int rulesFired = ksession.fireAllRules(); + assertThat(rulesFired).isEqualTo(1); + assertThat(bigDecimalListGlobal).isNotEmpty().containsExactly(BigDecimal.valueOf(100.0)); + } finally { + ksession.dispose(); + } + } +}