From 2edccf83f4f10990a7501df072d03c13a2989578 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Sun, 14 Jun 2020 23:11:37 +0200 Subject: [PATCH] Update RuleProxy to accept POJO implementing Comparable Resolves #291 --- .../java/org/jeasy/rules/core/RuleProxy.java | 16 +++-- .../org/jeasy/rules/core/RuleProxyTest.java | 72 +++++++++++++++++++ 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/easy-rules-core/src/main/java/org/jeasy/rules/core/RuleProxy.java b/easy-rules-core/src/main/java/org/jeasy/rules/core/RuleProxy.java index 0dc27f0..0e68454 100644 --- a/easy-rules-core/src/main/java/org/jeasy/rules/core/RuleProxy.java +++ b/easy-rules-core/src/main/java/org/jeasy/rules/core/RuleProxy.java @@ -147,11 +147,15 @@ public class RuleProxy implements InvocationHandler { private Object compareToMethod(final Object[] args) throws Exception { Method compareToMethod = getCompareToMethod(); - if (compareToMethod != null) { - return compareToMethod.invoke(target, args); + Object otherRule = args[0]; // validated upfront + if (compareToMethod != null && Proxy.isProxyClass(otherRule.getClass())) { + if (compareToMethod.getParameters().length != 1) { + throw new IllegalArgumentException("compareTo method must have a single argument"); + } + RuleProxy ruleProxy = (RuleProxy) Proxy.getInvocationHandler(otherRule); + return compareToMethod.invoke(target, ruleProxy.getTarget()); } else { - Rule otherRule = (Rule) args[0]; - return compareTo(otherRule); + return compareTo((Rule) otherRule); } } @@ -352,6 +356,10 @@ public class RuleProxy implements InvocationHandler { } } } + + public Object getTarget() { + return target; + } private Class getTargetClass() { return target.getClass(); diff --git a/easy-rules-core/src/test/java/org/jeasy/rules/core/RuleProxyTest.java b/easy-rules-core/src/test/java/org/jeasy/rules/core/RuleProxyTest.java index 9d3cf8d..f825bea 100644 --- a/easy-rules-core/src/test/java/org/jeasy/rules/core/RuleProxyTest.java +++ b/easy-rules-core/src/test/java/org/jeasy/rules/core/RuleProxyTest.java @@ -28,11 +28,13 @@ import org.jeasy.rules.annotation.AnnotatedRuleWithMetaRuleAnnotation; import org.jeasy.rules.annotation.Condition; import org.jeasy.rules.annotation.Priority; import org.jeasy.rules.api.Rule; +import org.jeasy.rules.api.Rules; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; public class RuleProxyTest { @@ -133,6 +135,76 @@ public class RuleProxyTest { assertEquals(rule.toString(), proxy1.toString()); } + @Test + public void testCompareTo() { + + @org.jeasy.rules.annotation.Rule + class MyComparableRule implements Comparable { + + int comparisonCriteria; + + MyComparableRule(int comparisonCriteria) { + this.comparisonCriteria = comparisonCriteria; + } + + @Condition + public boolean when() { return true; } + + @Action + public void then() { } + + @Override + public int compareTo(MyComparableRule otherRule) { + return Integer.compare(comparisonCriteria, otherRule.comparisonCriteria); + } + } + + Object rule1 = new MyComparableRule(1); + Object rule2 = new MyComparableRule(2); + Object rule3 = new MyComparableRule(2); + Rule proxy1 = RuleProxy.asRule(rule1); + Rule proxy2 = RuleProxy.asRule(rule2); + Rule proxy3 = RuleProxy.asRule(rule3); + assertEquals(proxy1.compareTo(proxy2),-1); + assertEquals(proxy2.compareTo(proxy1),1); + assertEquals(proxy2.compareTo(proxy3),0); + + try { + Rules rules = new Rules(); + rules.register(rule1, rule2); + + Rules mixedRules = new Rules(rule3); + mixedRules.register(proxy1,proxy2); + + Rules yetAnotherRulesSet = new Rules(proxy1, proxy2); + yetAnotherRulesSet.register(rule3); + } catch (Exception exception) { + fail("Should not fail with " + exception.getMessage()); + } + } + + @Test(expected = IllegalArgumentException.class) + public void testCompareToWithIncorrectSignature() { + + @org.jeasy.rules.annotation.Rule + class InvalidComparableRule { + + @Condition + public boolean when() { return true; } + + @Action + public void then() { } + + public int compareTo() { + return 0; + } + } + + Object rule = new InvalidComparableRule(); + Rules rules = new Rules(); + rules.register(rule); + } + @Test public void testPriorityFromAnnotation() {