Skip to content
Browse files

[DROOLS-82] fix null safe dereferencing when used in a method argument

  • Loading branch information...
1 parent 0b61178 commit cced277b2e91e9e431e5670337237eae51cc3e8c @mariofusco mariofusco committed Mar 19, 2013
View
38 drools-compiler/src/main/java/org/drools/compiler/lang/MVELDumper.java
@@ -172,7 +172,7 @@ private StringBuilder processRightAtomicExpr(StringBuilder left, AtomicExprDescr
} else {
String[] nullCheckAndExpr = processNullSafeDereferencing(expr, atomicExpr, nullSafePos);
expr = nullCheckAndExpr[1];
- constrAndExpr = new String[] { constrAndExpr[0] + nullCheckAndExpr[0], expr };
+ constrAndExpr = new String[] { constrAndExpr[0].contains(nullCheckAndExpr[0]) ? constrAndExpr[0] : constrAndExpr[0] + nullCheckAndExpr[0], expr };
}
sharpPos = hasQuotes ? indexOfOutOfQuotes(expr, '#') : expr.indexOf('#');
nullSafePos = hasQuotes ? indexOfOutOfQuotes(expr, "!.") : expr.indexOf("!.");
@@ -216,11 +216,45 @@ private String processInferredCast(String expr, AtomicExprDescr atomicExpr, MVEL
// convert "field1!.field2" in ["field1 != null && ", "field1.field2"]
String field1 = expr.substring(0, nullSafePos).trim();
expr = field1 + "." + expr.substring(nullSafePos+2).trim();
- String[] nullCheckAndExpr = new String[] { field1 + " != null && ", expr };
+ String[] nullCheckAndExpr = new String[] { getPreconditionsToAppend(field1) + " != null && ", expr };
atomicExpr.setRewrittenExpression(nullCheckAndExpr[1]);
return nullCheckAndExpr;
}
+ private String getPreconditionsToAppend(String field1) {
+ int parenthesisDepth = 0;
+ int squareDepth = 0;
+ String precondition = field1;
+ for (int i = field1.length()-1; i >= 0; i--) {
+ switch (field1.charAt(i)) {
+ case '(':
+ parenthesisDepth--;
+ if (parenthesisDepth < 0) {
+ return field1.substring(i+1, field1.length()).trim();
+ }
+ break;
+ case ')':
+ parenthesisDepth++;
+ break;
+ case '[':
+ squareDepth--;
+ if (squareDepth < 0) {
+ return field1.substring(i+1, field1.length()).trim();
+ }
+ break;
+ case ']':
+ squareDepth++;
+ break;
+ case ',':
+ if (squareDepth == 0 && parenthesisDepth == 0) {
+ return field1.substring(i+1, field1.length()).trim();
+ }
+ break;
+ }
+ }
+ return field1;
+ }
+
private String processEval(String expr) {
// stripping "eval" as it is no longer necessary
return evalRegexp.matcher( expr ).find() ? expr.substring( expr.indexOf( '(' ) + 1, expr.lastIndexOf( ')' ) ) : expr;
View
52 ...ompiler/src/test/java/org/drools/compiler/integrationtests/NullSafeDereferencingTest.java
@@ -60,6 +60,58 @@ public void testNullSafeNullComparison() {
}
@Test
+ public void testNullSafeNullComparisonReverse() {
+ // DROOLS-82
+ String str =
+ "import org.drools.compiler.*;\n" +
+ "rule R1 when\n" +
+ " Person( \"Main Street\".equalsIgnoreCase(address!.street) )\n" +
+ "then\n" +
+ "end";
+
+ KnowledgeBase kbase = loadKnowledgeBaseFromString(str);
+ StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
+ ksession.insert(new Person("Mario", 38));
+
+ Person mark = new Person("Mark", 37);
+ mark.setAddress(new Address("Main Street"));
+ ksession.insert(mark);
+
+ Person edson = new Person("Edson", 34);
+ edson.setAddress(new Address(null));
+ ksession.insert(edson);
+
+ assertEquals(1, ksession.fireAllRules());
+ ksession.dispose();
+ }
+
+ @Test
+ public void testNullSafeNullComparisonReverseComplex() {
+ // DROOLS-82
+ String str =
+ "import org.drools.compiler.*;\n" +
+ "rule R1 when\n" +
+ " Person( \"Main\".equalsIgnoreCase(address!.street!.substring(0, address!.street!.indexOf(' '))) )\n" +
+ "then\n" +
+ "end";
+
+ KnowledgeBase kbase = loadKnowledgeBaseFromString(str);
+ StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
+ ksession.insert(new Person("Mario", 38));
+
+ Person mark = new Person("Mark", 37);
+ mark.setAddress(new Address("Main Street"));
+ ksession.insert(mark);
+
+ Person edson = new Person("Edson", 34);
+ edson.setAddress(new Address(null));
+ ksession.insert(edson);
+
+ assertEquals(1, ksession.fireAllRules());
+ ksession.dispose();
+ }
+
+ @Test
public void testDoubleNullSafe() {
String str = "import org.drools.compiler.*;\n" +
"rule R1 when\n" +

0 comments on commit cced277

Please sign in to comment.
Something went wrong with that request. Please try again.