From 36c99a13244f9a5d5e407254f475a62302251aa9 Mon Sep 17 00:00:00 2001 From: Toshiya Kobayashi Date: Thu, 21 Jul 2022 16:09:16 +0900 Subject: [PATCH] [DROOLS-6908] Arithmetic operation with String coercion in constraint fails in executable-model (#4317) (#4554) --- .../java/org/drools/core/util/ClassUtils.java | 9 + .../builder/generator/TypedExpression.java | 2 +- .../ArithmeticCoercedExpression.java | 155 +++++++++++++++ .../expressiontyper/ExpressionTyper.java | 25 ++- .../modelcompiler/ArithmeticCoecionTest.java | 178 ++++++++++++++++++ .../drlxparse/ConstraintParserTest.java | 10 + .../modelcompiler/domain/ValueHolder.java | 62 ++++++ .../ast/ObjectCreationExpressionT.java | 3 +- .../mvelcompiler/ConstraintCompilerTest.java | 2 +- .../drools/mvelcompiler/MvelCompilerTest.java | 22 +-- 10 files changed, 449 insertions(+), 19 deletions(-) create mode 100644 drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/builder/generator/drlxparse/ArithmeticCoercedExpression.java create mode 100644 drools-model/drools-model-compiler/src/test/java/org/drools/modelcompiler/ArithmeticCoecionTest.java create mode 100644 drools-model/drools-model-compiler/src/test/java/org/drools/modelcompiler/domain/ValueHolder.java diff --git a/drools-core/src/main/java/org/drools/core/util/ClassUtils.java b/drools-core/src/main/java/org/drools/core/util/ClassUtils.java index 2dc794dc9aa..3827a7dd936 100644 --- a/drools-core/src/main/java/org/drools/core/util/ClassUtils.java +++ b/drools-core/src/main/java/org/drools/core/util/ClassUtils.java @@ -56,6 +56,7 @@ import static java.lang.System.arraycopy; import static java.lang.reflect.Modifier.PUBLIC; import static java.lang.reflect.Modifier.STATIC; +import static java.util.Arrays.asList; import static org.drools.core.util.MethodUtils.getMethod; import static org.drools.core.util.StringUtils.ucFirst; @@ -74,6 +75,10 @@ public final class ClassUtils { private static final Map> primitiveNameToType; + private static final Set> numericClasses = new HashSet>(asList(int.class, long.class, double.class, float.class, short.class, char.class, byte.class, + Integer.class, Long.class, Double.class, Float.class, Short.class, Character.class, Byte.class, + BigInteger.class, BigDecimal.class)); + static { final Map m = new HashMap<>(); m.put("int", "I"); @@ -1003,4 +1008,8 @@ public static String getCanonicalSimpleName(Class c, char separator) { getCanonicalSimpleName(enclosingClass) + separator + c.getSimpleName() : c.getSimpleName(); } + + public static boolean isNumericClass(Class clazz) { + return numericClasses.contains(clazz); + } } diff --git a/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/builder/generator/TypedExpression.java b/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/builder/generator/TypedExpression.java index 79d5e45ac03..fc3ee104629 100644 --- a/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/builder/generator/TypedExpression.java +++ b/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/builder/generator/TypedExpression.java @@ -186,7 +186,7 @@ public boolean containThis() { @Override public String toString() { return "TypedExpression{" + - "expression=" + expression + + "expression=" + PrintUtil.printNode(expression) + ", jpType=" + (expression == null ? "" : expression.getClass().getSimpleName()) + ", type=" + type + ", fieldName='" + fieldName + '\'' + diff --git a/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/builder/generator/drlxparse/ArithmeticCoercedExpression.java b/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/builder/generator/drlxparse/ArithmeticCoercedExpression.java new file mode 100644 index 00000000000..d9074df9ca1 --- /dev/null +++ b/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/builder/generator/drlxparse/ArithmeticCoercedExpression.java @@ -0,0 +1,155 @@ +/* + * Copyright 2022 Red Hat, Inc. and/or its affiliates. + * + * Licensed 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.modelcompiler.builder.generator.drlxparse; + +import java.math.BigDecimal; +import java.util.HashSet; +import java.util.Set; + +import com.github.javaparser.ast.expr.BinaryExpr.Operator; +import com.github.javaparser.ast.expr.Expression; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.ast.expr.NameExpr; +import org.drools.modelcompiler.builder.errors.InvalidExpressionErrorResult; +import org.drools.modelcompiler.builder.generator.TypedExpression; + +import static com.github.javaparser.ast.NodeList.nodeList; +import static com.github.javaparser.ast.expr.BinaryExpr.Operator.DIVIDE; +import static com.github.javaparser.ast.expr.BinaryExpr.Operator.MINUS; +import static com.github.javaparser.ast.expr.BinaryExpr.Operator.MULTIPLY; +import static com.github.javaparser.ast.expr.BinaryExpr.Operator.PLUS; +import static com.github.javaparser.ast.expr.BinaryExpr.Operator.REMAINDER; +import static java.util.Arrays.asList; +import static org.drools.core.util.ClassUtils.isNumericClass; + +public class ArithmeticCoercedExpression { + + private final TypedExpression left; + private final TypedExpression right; + private final Operator operator; + + private final static Set arithmeticOperators = new HashSet(asList(PLUS, MINUS, MULTIPLY, DIVIDE, REMAINDER)); + + public ArithmeticCoercedExpression(TypedExpression left, TypedExpression right, Operator operator) { + this.left = left; + this.right = right; + this.operator = operator; + } + + public ArithmeticCoercedExpressionResult coerce() { + + if (!requiresCoercion()) { + return new ArithmeticCoercedExpressionResult(left, right); // do not coerce + } + + final Class leftClass = left.getRawClass(); + final Class rightClass = right.getRawClass(); + + if (!canCoerce(leftClass, rightClass)) { + throw new ArithmeticCoercedExpressionException(new InvalidExpressionErrorResult("Arithmetic operation requires compatible types. Found " + leftClass + " and " + rightClass)); + } + + TypedExpression coercedLeft = left; + TypedExpression coercedRight = right; + if (leftClass == String.class) { + if (operator == Operator.PLUS) { + // String concatenation : Compatibility with mvel + coercedRight = coerceToString(right); + } else { + // We may coerce to BigDecimal but Mvel MathProcessor uses double so followed the same. + coercedLeft = coerceToDouble(left); + } + } + if (rightClass == String.class) { + if (operator == Operator.PLUS) { + // String concatenation : Compatibility with mvel + coercedLeft = coerceToString(left); + } else { + // We may coerce to BigDecimal but Mvel MathProcessor uses double so followed the same. + coercedRight = coerceToDouble(right); + } + } + + return new ArithmeticCoercedExpressionResult(coercedLeft, coercedRight); + } + + private boolean requiresCoercion() { + if (!arithmeticOperators.contains(operator)) { + return false; + } + final Class leftClass = left.getRawClass(); + final Class rightClass = right.getRawClass(); + if (leftClass == rightClass) { + return false; + } + if (isNumericClass(leftClass) && isNumericClass(rightClass)) { + return false; + } + return true; + } + + private boolean canCoerce(Class leftClass, Class rightClass) { + return leftClass == String.class && isNumericClass(rightClass) || + rightClass == String.class && isNumericClass(leftClass); + } + + private TypedExpression coerceToDouble(TypedExpression typedExpression) { + final Expression expression = typedExpression.getExpression(); + TypedExpression coercedExpression = typedExpression.cloneWithNewExpression(new MethodCallExpr(new NameExpr("Double"), "valueOf", nodeList(expression))); + return coercedExpression.setType(BigDecimal.class); + } + + private TypedExpression coerceToString(TypedExpression typedExpression) { + final Expression expression = typedExpression.getExpression(); + TypedExpression coercedExpression = typedExpression.cloneWithNewExpression(new MethodCallExpr(new NameExpr("String"), "valueOf", nodeList(expression))); + return coercedExpression.setType(String.class); + } + + public static class ArithmeticCoercedExpressionResult { + + private final TypedExpression coercedLeft; + private final TypedExpression coercedRight; + + public ArithmeticCoercedExpressionResult(TypedExpression left, TypedExpression coercedRight) { + this.coercedLeft = left; + this.coercedRight = coercedRight; + } + + public TypedExpression getCoercedLeft() { + return coercedLeft; + } + + public TypedExpression getCoercedRight() { + return coercedRight; + } + } + + public static class ArithmeticCoercedExpressionException extends RuntimeException { + + private final transient InvalidExpressionErrorResult invalidExpressionErrorResult; + + ArithmeticCoercedExpressionException(InvalidExpressionErrorResult invalidExpressionErrorResult) { + this.invalidExpressionErrorResult = invalidExpressionErrorResult; + } + + public InvalidExpressionErrorResult getInvalidExpressionErrorResult() { + return invalidExpressionErrorResult; + } + } + +} diff --git a/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/builder/generator/expressiontyper/ExpressionTyper.java b/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/builder/generator/expressiontyper/ExpressionTyper.java index fd5d8d0aefb..bc374e76c2a 100644 --- a/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/builder/generator/expressiontyper/ExpressionTyper.java +++ b/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/builder/generator/expressiontyper/ExpressionTyper.java @@ -72,6 +72,7 @@ import org.drools.modelcompiler.builder.generator.RuleContext; import org.drools.modelcompiler.builder.generator.TypedExpression; import org.drools.modelcompiler.builder.generator.UnificationTypedExpression; +import org.drools.modelcompiler.builder.generator.drlxparse.ArithmeticCoercedExpression; import org.drools.modelcompiler.builder.generator.operatorspec.CustomOperatorSpec; import org.drools.modelcompiler.builder.generator.operatorspec.NativeOperatorSpec; import org.drools.modelcompiler.builder.generator.operatorspec.OperatorSpec; @@ -212,10 +213,26 @@ private Optional toTypedExpressionRec(Expression drlxExpr) { Optional optLeft = toTypedExpressionRec(binaryExpr.getLeft()); Optional optRight = toTypedExpressionRec(binaryExpr.getRight()); - return optLeft.flatMap(left -> optRight.flatMap(right -> { - final BinaryExpr combo = new BinaryExpr(left.getExpression(), right.getExpression(), operator); - return of(new TypedExpression(combo, left.getType())); - })); + if (!optLeft.isPresent() || !optRight.isPresent()) { + return empty(); + } + + TypedExpression left = optLeft.get(); + TypedExpression right = optRight.get(); + + ArithmeticCoercedExpression.ArithmeticCoercedExpressionResult coerced; + try { + coerced = new ArithmeticCoercedExpression(left, right, operator).coerce(); + } catch (ArithmeticCoercedExpression.ArithmeticCoercedExpressionException e) { + logger.error("Failed to coerce : " + e.getInvalidExpressionErrorResult()); + return empty(); + } + + left = coerced.getCoercedLeft(); + right = coerced.getCoercedRight(); + + final BinaryExpr combo = new BinaryExpr(left.getExpression(), right.getExpression(), operator); + return of(new TypedExpression(combo, left.getType())); } if (drlxExpr instanceof HalfBinaryExpr) { diff --git a/drools-model/drools-model-compiler/src/test/java/org/drools/modelcompiler/ArithmeticCoecionTest.java b/drools-model/drools-model-compiler/src/test/java/org/drools/modelcompiler/ArithmeticCoecionTest.java new file mode 100644 index 00000000000..0123d306512 --- /dev/null +++ b/drools-model/drools-model-compiler/src/test/java/org/drools/modelcompiler/ArithmeticCoecionTest.java @@ -0,0 +1,178 @@ +/* + * Copyright 2022 Red Hat, Inc. and/or its affiliates. + * + * Licensed 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.modelcompiler; + +import java.math.BigDecimal; + +import org.drools.modelcompiler.domain.ValueHolder; +import org.junit.Test; +import org.kie.api.runtime.KieSession; + +import static org.junit.Assert.assertEquals; + +public class ArithmeticCoecionTest extends BaseModelTest { + + public ArithmeticCoecionTest(RUN_TYPE testRunType) { + super(testRunType); + } + + // NOTE: For BigDecimal specific issues, use BigDecimalTest + + @Test + public void testMultiplyStringInt() { + ValueHolder holder = new ValueHolder(); + holder.setIntValue(100); + holder.setStrValue("10"); + testValueHolder("ValueHolder( intValue == strValue * 10 )", holder); + } + + @Test + public void testMultiplyStringIntWithBindVariable() { + ValueHolder holder = new ValueHolder(); + holder.setIntValue(100); + holder.setStrValue("10"); + testValueHolder("ValueHolder( $strValue : strValue, intValue == $strValue * 10 )", holder); + } + + @Test + public void testMultiplyIntStringWithBindVariable() { + ValueHolder holder = new ValueHolder(); + holder.setIntValue(100); + holder.setStrValue("10"); + testValueHolder("ValueHolder( $strValue : strValue, intValue == 10 * $strValue)", holder); + } + + @Test + public void testMultiplyStringIntWithBindVariableCompareToBigDecimal() { + ValueHolder holder = new ValueHolder(); + holder.setStrValue("10"); + holder.setBdValue(new BigDecimal("-10")); + testValueHolder("ValueHolder( $strValue : strValue, bdValue == $strValue * -1 )", holder); + } + + @Test + public void testMultiplyStringIntWithBindVariableCompareToObject() { + ValueHolder holder = new ValueHolder(); + holder.setStrValue("20"); + holder.setObjValue("200"); + testValueHolder("ValueHolder( $strValue : strValue, objValue == $strValue * 10 )", holder); + } + + @Test + public void testMultiplyStringBigDecimal() { + ValueHolder holder = new ValueHolder(); + holder.setIntValue(10); + holder.setStrValue("20"); + testValueHolder("ValueHolder( intValue == strValue * 0.5B )", holder); + } + + @Test + public void testMultiplyDecimalStringInt() { + ValueHolder holder = new ValueHolder(); + holder.setIntValue(5); + holder.setStrValue("0.5"); + testValueHolder("ValueHolder( intValue == strValue * 10 )", holder); + } + + @Test + public void testMultiplyDecimalStringBigDecimal() { + ValueHolder holder = new ValueHolder(); + holder.setIntValue(5); + holder.setStrValue("0.5"); + testValueHolder("ValueHolder( intValue == strValue * 10B )", holder); + } + + @Test + public void testMultiplyIntDecimalString() { + ValueHolder holder = new ValueHolder(); + holder.setIntValue(5); + holder.setStrValue("0.5"); + testValueHolder("ValueHolder( intValue == 10 * strValue )", holder); + } + + @Test + public void testMultiplyStringDouble() { + ValueHolder holder = new ValueHolder(); + holder.setIntValue(101); + holder.setStrValue("10"); + testValueHolder("ValueHolder( intValue == strValue * 10.1 )", holder); + } + + @Test + public void testAddStringIntWithBindVariableCompareToObject() { + ValueHolder holder = new ValueHolder(); + holder.setStrValue("20"); + holder.setObjValue("2010"); // String concat + testValueHolder("ValueHolder( $strValue : strValue, objValue == $strValue + 10 )", holder); + } + + @Test + public void testAddIntStringWithBindVariableCompareToObject() { + ValueHolder holder = new ValueHolder(); + holder.setStrValue("20"); + holder.setObjValue("1020"); // String concat + testValueHolder("ValueHolder( $strValue : strValue, objValue == 10 + $strValue )", holder); + } + + @Test + public void testAddStringIntWithBindVariableCompareToObjectNonNumeric() { + ValueHolder holder = new ValueHolder(); + holder.setStrValue("ABC"); + holder.setObjValue("ABC10"); // String concat + testValueHolder("ValueHolder( $strValue : strValue, objValue == $strValue + 10 )", holder); + } + + @Test + public void testSubtractStringInt() { + ValueHolder holder = new ValueHolder(); + holder.setIntValue(40); + holder.setStrValue("50"); + testValueHolder("ValueHolder( intValue == strValue - 10 )", holder); + } + + @Test + public void testModStringInt() { + ValueHolder holder = new ValueHolder(); + holder.setIntValue(2); + holder.setStrValue("12"); + testValueHolder("ValueHolder( intValue == strValue % 10 )", holder); + } + + @Test + public void testDivideStringInt() { + ValueHolder holder = new ValueHolder(); + holder.setIntValue(5); + holder.setStrValue("50"); + testValueHolder("ValueHolder( intValue == strValue / 10 )", holder); + } + + private void testValueHolder(String pattern, ValueHolder holder) { + String str = + "import " + ValueHolder.class.getCanonicalName() + "\n" + + "rule R dialect \"mvel\" when\n" + + pattern + "\n" + + "then\n" + + "end"; + + KieSession ksession = getKieSession(str); + + ksession.insert(holder); + int fired = ksession.fireAllRules(); + + assertEquals(1, fired); + } +} diff --git a/drools-model/drools-model-compiler/src/test/java/org/drools/modelcompiler/builder/generator/drlxparse/ConstraintParserTest.java b/drools-model/drools-model-compiler/src/test/java/org/drools/modelcompiler/builder/generator/drlxparse/ConstraintParserTest.java index f581410974b..9dd0c4506af 100644 --- a/drools-model/drools-model-compiler/src/test/java/org/drools/modelcompiler/builder/generator/drlxparse/ConstraintParserTest.java +++ b/drools-model/drools-model-compiler/src/test/java/org/drools/modelcompiler/builder/generator/drlxparse/ConstraintParserTest.java @@ -93,4 +93,14 @@ public void testImplicitCastExpressionWithOr() { assertEquals("\"Mark\" == _this.toString() || _this instanceof org.drools.modelcompiler.domain.Person && \"Mark\" == ((org.drools.modelcompiler.domain.Person) _this).getAddress().getCity()", result.getExpr().toString()); } + + @Test + public void testMultiplyStringIntWithBindVariableCompareToBigDecimal() { + SingleDrlxParseSuccess result = (SingleDrlxParseSuccess) parser.drlxParse(Person.class, "$p", "money == likes * 10"); // assuming likes contains number String + + System.out.println(result.getExpr().toString()); + + assertEquals("org.drools.modelcompiler.util.EvaluationUtil.equals(org.drools.modelcompiler.util.EvaluationUtil.toBigDecimal(_this.getMoney()), org.drools.modelcompiler.util.EvaluationUtil.toBigDecimal(Double.valueOf(_this.getLikes()) * 10))", + result.getExpr().toString()); + } } diff --git a/drools-model/drools-model-compiler/src/test/java/org/drools/modelcompiler/domain/ValueHolder.java b/drools-model/drools-model-compiler/src/test/java/org/drools/modelcompiler/domain/ValueHolder.java new file mode 100644 index 00000000000..fb05b647867 --- /dev/null +++ b/drools-model/drools-model-compiler/src/test/java/org/drools/modelcompiler/domain/ValueHolder.java @@ -0,0 +1,62 @@ +/* + * Copyright 2022 Red Hat, Inc. and/or its affiliates. + * + * Licensed 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.modelcompiler.domain; + +import java.math.BigDecimal; + +public class ValueHolder { + + private int intValue; + private String strValue; + private BigDecimal bdValue; + private Object objValue; + + public ValueHolder() {} + + public int getIntValue() { + return intValue; + } + + public void setIntValue(int intValue) { + this.intValue = intValue; + } + + public String getStrValue() { + return strValue; + } + + public void setStrValue(String strValue) { + this.strValue = strValue; + } + + public BigDecimal getBdValue() { + return bdValue; + } + + public void setBdValue(BigDecimal bdValue) { + this.bdValue = bdValue; + } + + public Object getObjValue() { + return objValue; + } + + public void setObjValue(Object objValue) { + this.objValue = objValue; + } + +} diff --git a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/ObjectCreationExpressionT.java b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/ObjectCreationExpressionT.java index d63b919d21f..62bfb54460e 100644 --- a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/ObjectCreationExpressionT.java +++ b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/ObjectCreationExpressionT.java @@ -20,7 +20,6 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; -import java.util.stream.Stream; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.NodeList; @@ -45,7 +44,7 @@ public Optional getType() { @Override public Node toJavaExpression() { ObjectCreationExpr objectCreationExpr = new ObjectCreationExpr(); - objectCreationExpr.setType(type); + objectCreationExpr.setType(type.getCanonicalName()); List arguments = this.constructorArguments.stream() .map(typedExpression -> (Expression)typedExpression.toJavaExpression()) .collect(Collectors.toList()); diff --git a/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/ConstraintCompilerTest.java b/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/ConstraintCompilerTest.java index 0b8c951f870..51755da1abb 100644 --- a/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/ConstraintCompilerTest.java +++ b/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/ConstraintCompilerTest.java @@ -57,7 +57,7 @@ public void testBigDecimalPromotionToIntMethod() { @Test public void testConversionConstructorArgument() { testExpression(c -> c.addDeclaration("$p", Person.class), "new Person($p.name, $p)", - "new Person($p.getName(), $p)"); + "new org.drools.Person($p.getName(), $p)"); } @Test diff --git a/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/MvelCompilerTest.java b/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/MvelCompilerTest.java index 60b37cead2a..9ad62da1ab0 100644 --- a/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/MvelCompilerTest.java +++ b/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/MvelCompilerTest.java @@ -444,7 +444,7 @@ public void testInitializerArrayAccess() { "System.out.println(l[0]); " + "}", "{ " + - "java.util.ArrayList l = new ArrayList(); " + + "java.util.ArrayList l = new java.util.ArrayList(); " + "l.add(\"first\"); " + "System.out.println(l.get(0)); " + "}"); @@ -564,7 +564,7 @@ public void testMapSetToNewMap() { "$p.items = newhashmap;\n" + "}", "{ " + - "java.util.Map newhashmap = new HashMap(); \n" + + "java.util.Map newhashmap = new java.util.HashMap(); \n" + "$p.setItems(newhashmap); " + "}"); } @@ -578,7 +578,7 @@ public void testInitializerMap() { "System.out.println(m[\"key\"]);\n" + "}", "{ " + - "java.util.HashMap m = new HashMap();\n" + + "java.util.HashMap m = new java.util.HashMap();\n" + "m.put(\"key\", 2);\n" + "System.out.println(m.get(\"key\"));\n" + "}"); @@ -596,8 +596,8 @@ public void testMixArrayMap() { " list.add(((ArrayList)m[\"content\"])[0]);\n" + "}", "{ " + - " java.util.HashMap m = new HashMap();\n" + - " java.util.ArrayList l = new ArrayList();\n" + + " java.util.HashMap m = new java.util.HashMap();\n" + + " java.util.ArrayList l = new java.util.ArrayList();\n" + " l.add(\"first\");\n" + " m.put(\"content\", l);\n" + " System.out.println(((java.util.ArrayList) m.get(\"content\")).get(0));\n" + @@ -763,7 +763,7 @@ public void testModifyWithAssignment() { @Test public void testWithSemiColon() { test("{ with( $l = new ArrayList()) { $l.add(2); }; }", - "{ java.util.ArrayList $l = new ArrayList(); $l.add(2); }", + "{ java.util.ArrayList $l = new java.util.ArrayList(); $l.add(2); }", result -> assertThat(allUsedBindings(result), is(empty()))); } @@ -771,7 +771,7 @@ public void testWithSemiColon() { public void testWithWithAssignment() { test(ctx -> ctx.addDeclaration("$p", Person.class), "{ with($p = new Person()) { age = $p.age+1 }; }", - "{ org.drools.Person $p = new Person(); $p.setAge($p.getAge() + 1); }", + "{ org.drools.Person $p = new org.drools.Person(); $p.setAge($p.getAge() + 1); }", result -> assertThat(allUsedBindings(result), is(empty()))); } @@ -779,7 +779,7 @@ public void testWithWithAssignment() { public void testWithInIf() { test(ctx -> ctx.addDeclaration("$p", Person.class), "{ if (true) { with($p = new Person()) { age = $p.age+1 }; } }", - "{ if (true) { org.drools.Person $p = new Person(); $p.setAge($p.getAge() + 1); } }", + "{ if (true) { org.drools.Person $p = new org.drools.Person(); $p.setAge($p.getAge() + 1); } }", result -> assertThat(allUsedBindings(result), is(empty()))); } @@ -845,10 +845,10 @@ public void testWithOrdering() { " }", "{ " + - "org.drools.Person s0 = new Person(); " + + "org.drools.Person s0 = new org.drools.Person(); " + "s0.setAge(0); " + "insertLogical(s0);\n" + - "org.drools.Person s1 = new Person(); " + + "org.drools.Person s1 = new org.drools.Person(); " + "s1.setAge(1);\n" + "insertLogical(s1);\n" + "}"); @@ -867,7 +867,7 @@ public void testModifyOrdering() { "}", "{ " + - "org.drools.Address $newAddress = new Address(); " + + "org.drools.Address $newAddress = new org.drools.Address(); " + "$newAddress.setCity(\"Brno\"); " + "insert($newAddress);\n" + "{ " +