From 52b2aaca265d991baa49d2b1ee6d70fb323628b3 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Fri, 3 Jun 2016 15:50:38 +0200 Subject: [PATCH] fix issue #41 : Unable to add annotated rule to a composite rule --- .../org/easyrules/core/CompositeRule.java | 20 ++++++++--- .../easyrules/core/DefaultRulesEngine.java | 11 +----- .../java/org/easyrules/core/RuleProxy.java | 18 ++++++---- .../org/easyrules/core/CompositeRuleTest.java | 35 +++++++++++++++++++ 4 files changed, 63 insertions(+), 21 deletions(-) diff --git a/easyrules-core/src/main/java/org/easyrules/core/CompositeRule.java b/easyrules-core/src/main/java/org/easyrules/core/CompositeRule.java index 8be4e09..dfc3b56 100644 --- a/easyrules-core/src/main/java/org/easyrules/core/CompositeRule.java +++ b/easyrules-core/src/main/java/org/easyrules/core/CompositeRule.java @@ -27,9 +27,13 @@ package org.easyrules.core; import org.easyrules.api.Rule; import org.easyrules.util.Utils; +import java.util.HashMap; +import java.util.Map; import java.util.Set; import java.util.TreeSet; +import static org.easyrules.core.RuleProxy.asRule; + /** * Class representing a composite rule composed of a set of rules. * @@ -45,6 +49,8 @@ public class CompositeRule extends BasicRule { */ protected Set rules; + protected Map proxyRules; + public CompositeRule() { this(Utils.DEFAULT_RULE_NAME, Utils.DEFAULT_RULE_DESCRIPTION, Utils.DEFAULT_RULE_PRIORITY); } @@ -60,6 +66,7 @@ public class CompositeRule extends BasicRule { public CompositeRule(final String name, final String description, final int priority) { super(name, description, priority); rules = new TreeSet<>(); + proxyRules = new HashMap<>(); } /** @@ -96,16 +103,21 @@ public class CompositeRule extends BasicRule { * Add a rule to the composite rule. * @param rule the rule to add */ - public void addRule(final Rule rule) { - rules.add(rule); + public void addRule(final Object rule) { + Rule proxy = asRule(rule); + rules.add(proxy); + proxyRules.put(rule, proxy); } /** * Remove a rule from the composite rule. * @param rule the rule to remove */ - public void removeRule(final Rule rule) { - rules.remove(rule); + public void removeRule(final Object rule) { + Rule proxy = proxyRules.get(rule); + if (proxy != null) { + rules.remove(proxy); + } } } diff --git a/easyrules-core/src/main/java/org/easyrules/core/DefaultRulesEngine.java b/easyrules-core/src/main/java/org/easyrules/core/DefaultRulesEngine.java index 39544ea..cf260f3 100644 --- a/easyrules-core/src/main/java/org/easyrules/core/DefaultRulesEngine.java +++ b/easyrules-core/src/main/java/org/easyrules/core/DefaultRulesEngine.java @@ -34,6 +34,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import static java.lang.String.format; +import static org.easyrules.core.RuleProxy.asRule; /** * Default {@link org.easyrules.api.RulesEngine} implementation. @@ -208,16 +209,6 @@ class DefaultRulesEngine implements RulesEngine { } } - private Rule asRule(final Object rule) { - Rule result; - if (Utils.getInterfaces(rule).contains(Rule.class)) { - result = (Rule) rule; - } else { - result = RuleProxy.asRule(rule); - } - return result; - } - @Override public String toString() { return parameters.getName(); diff --git a/easyrules-core/src/main/java/org/easyrules/core/RuleProxy.java b/easyrules-core/src/main/java/org/easyrules/core/RuleProxy.java index dc07910..eb747f9 100644 --- a/easyrules-core/src/main/java/org/easyrules/core/RuleProxy.java +++ b/easyrules-core/src/main/java/org/easyrules/core/RuleProxy.java @@ -30,13 +30,17 @@ class RuleProxy implements InvocationHandler { * @return a proxy that implements the {@link org.easyrules.api.Rule} interface. */ public static org.easyrules.api.Rule asRule(final Object rule) { - - ruleDefinitionValidator.validateRuleDefinition(rule); - - return (org.easyrules.api.Rule) Proxy.newProxyInstance( - org.easyrules.api.Rule.class.getClassLoader(), - new Class[]{org.easyrules.api.Rule.class, Comparable.class}, - new RuleProxy(rule)); + org.easyrules.api.Rule result; + if (Utils.getInterfaces(rule).contains(org.easyrules.api.Rule.class)) { + result = (org.easyrules.api.Rule) rule; + } else { + ruleDefinitionValidator.validateRuleDefinition(rule); + result = (org.easyrules.api.Rule) Proxy.newProxyInstance( + org.easyrules.api.Rule.class.getClassLoader(), + new Class[]{org.easyrules.api.Rule.class, Comparable.class}, + new RuleProxy(rule)); + } + return result; } @Override diff --git a/easyrules-core/src/test/java/org/easyrules/core/CompositeRuleTest.java b/easyrules-core/src/test/java/org/easyrules/core/CompositeRuleTest.java index b8bf596..6bdd601 100644 --- a/easyrules-core/src/test/java/org/easyrules/core/CompositeRuleTest.java +++ b/easyrules-core/src/test/java/org/easyrules/core/CompositeRuleTest.java @@ -1,5 +1,7 @@ package org.easyrules.core; +import org.easyrules.annotation.Action; +import org.easyrules.annotation.Condition; import org.easyrules.api.RulesEngine; import org.junit.Before; import org.junit.Test; @@ -111,4 +113,37 @@ public class CompositeRuleTest { public void whenNoComposingRulesAreRegistered_thenCompositeRuleShouldEvaluateToFalse() { assertThat(compositeRule.evaluate()).isFalse(); } + + @Test + public void testCompositeRuleWithAnnotatedComposingRules() throws Exception { + CompositeRule compositeRule = new CompositeRule(); + MyRule rule = new MyRule(); + compositeRule.addRule(rule); + + RulesEngine engine = aNewRulesEngine().build(); + engine.registerRule(compositeRule); + engine.fireRules(); + + assertThat(rule.isExecuted()).isTrue(); + } + + @org.easyrules.annotation.Rule + class MyRule { + + boolean executed; + + @Condition + public boolean when() { + return true; + } + + @Action + public void then() { + executed = true; + } + + public boolean isExecuted() { + return executed; + } + } }