From e2eb3dc7b47b45268853abf34b3f02377d40bb07 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Sat, 13 May 2017 00:54:01 +0200 Subject: [PATCH] issue #37 : add Facts abstraction and update APIs accordingly --- .../main/java/org/easyrules/api/Facts.java | 61 +++++++++++++++ .../src/main/java/org/easyrules/api/Rule.java | 8 +- .../java/org/easyrules/api/RuleListener.java | 12 ++- .../main/java/org/easyrules/api/Rules.java | 75 +++++++++++++++++++ .../java/org/easyrules/api/RulesEngine.java | 39 +--------- 5 files changed, 151 insertions(+), 44 deletions(-) create mode 100644 easyrules-core/src/main/java/org/easyrules/api/Facts.java create mode 100644 easyrules-core/src/main/java/org/easyrules/api/Rules.java diff --git a/easyrules-core/src/main/java/org/easyrules/api/Facts.java b/easyrules-core/src/main/java/org/easyrules/api/Facts.java new file mode 100644 index 00000000..a00356cc --- /dev/null +++ b/easyrules-core/src/main/java/org/easyrules/api/Facts.java @@ -0,0 +1,61 @@ +/** + * The MIT License + * + * Copyright (c) 2017, Mahmoud Ben Hassine (mahmoud.benhassine@icloud.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.easyrules.api; + +import java.util.*; + +import static java.lang.String.format; + +public class Facts implements Iterable> { + + private Map facts = new HashMap<>(); + + public void add(String name, Object fact) { + facts.put(name, fact); + } + + public void remove(String name) { + facts.remove(name); + } + + public Object get(String name) { + return facts.get(name); + } + + @Override + public Iterator> iterator() { + return facts.entrySet().iterator(); + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("Facts {").append("\n"); + for (Map.Entry fact : facts.entrySet()) { + stringBuilder.append(format(" Fact { %s : %s }", fact.getKey(), fact.getValue().toString())); + stringBuilder.append("\n"); + } + stringBuilder.append("}"); + return stringBuilder.toString(); + } +} diff --git a/easyrules-core/src/main/java/org/easyrules/api/Rule.java b/easyrules-core/src/main/java/org/easyrules/api/Rule.java index aadcbd05..1fefca0c 100644 --- a/easyrules-core/src/main/java/org/easyrules/api/Rule.java +++ b/easyrules-core/src/main/java/org/easyrules/api/Rule.java @@ -30,7 +30,7 @@ * * @author Mahmoud Ben Hassine (mahmoud.benhassine@icloud.com) */ -public interface Rule { +public interface Rule extends Comparable { /** * Default rule name. @@ -67,14 +67,14 @@ public interface Rule { /** * Rule conditions abstraction : this method encapsulates the rule's conditions. - * @return true if the rule should be applied, false else + * @return true if the rule should be applied given the provided facts, false else */ - boolean evaluate(); + boolean evaluate(Facts facts); /** * Rule actions abstraction : this method encapsulates the rule's actions. * @throws Exception thrown if an exception occurs during actions performing */ - void execute() throws Exception; + void execute(Facts facts) throws Exception; } diff --git a/easyrules-core/src/main/java/org/easyrules/api/RuleListener.java b/easyrules-core/src/main/java/org/easyrules/api/RuleListener.java index 3c6c8b4f..ad8fab5c 100644 --- a/easyrules-core/src/main/java/org/easyrules/api/RuleListener.java +++ b/easyrules-core/src/main/java/org/easyrules/api/RuleListener.java @@ -34,9 +34,10 @@ public interface RuleListener { * Triggered before the evaluation of a rule. * * @param rule being evaluated + * @param facts known before evaluating the rule * @return true if the rule should be evaluated, false otherwise */ - boolean beforeEvaluate(Rule rule); + boolean beforeEvaluate(Rule rule, Facts facts); /** * Triggered after the evaluation of a rule. @@ -50,22 +51,25 @@ public interface RuleListener { * Triggered before the execution of a rule. * * @param rule the current rule + * @param rule known before executing the rule */ - void beforeExecute(Rule rule); + void beforeExecute(Rule rule, Facts facts); /** * Triggered after a rule has been executed successfully. * * @param rule the current rule + * @param facts known after executing the rule */ - void onSuccess(Rule rule); + void onSuccess(Rule rule, Facts facts); /** * Triggered after a rule has failed. * * @param rule the current rule * @param exception the exception thrown when attempting to execute the rule + * @param facts known after executing the rule */ - void onFailure(Rule rule, Exception exception); + void onFailure(Rule rule, Exception exception, Facts facts); } diff --git a/easyrules-core/src/main/java/org/easyrules/api/Rules.java b/easyrules-core/src/main/java/org/easyrules/api/Rules.java new file mode 100644 index 00000000..67d7ddc0 --- /dev/null +++ b/easyrules-core/src/main/java/org/easyrules/api/Rules.java @@ -0,0 +1,75 @@ +/** + * The MIT License + * + * Copyright (c) 2017, Mahmoud Ben Hassine (mahmoud.benhassine@icloud.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.easyrules.api; + +import org.easyrules.core.RuleProxy; + +import java.util.Collections; +import java.util.Iterator; +import java.util.Set; +import java.util.TreeSet; + +public class Rules implements Iterable { + + private Set rules = new TreeSet<>(); + + public Rules(Set rules) { + this.rules = rules; + } + + public Rules(Rule... rules ) { + Collections.addAll(this.rules, rules); + } + + public Rules(Object... rules ) { + for (Object rule : rules) { + this.register(RuleProxy.asRule(rule)); + } + } + + public void register(Object rule) { + rules.add(RuleProxy.asRule(rule)); + } + + public void unregister(Object rule) { + rules.remove(RuleProxy.asRule(rule)); + } + + public boolean isEmpty() { + return rules.isEmpty(); + } + + public void clear() { + rules.clear(); + } + + @Override + public Iterator iterator() { + return rules.iterator(); + } + + public void sort() { + rules = new TreeSet<>(rules); + } +} diff --git a/easyrules-core/src/main/java/org/easyrules/api/RulesEngine.java b/easyrules-core/src/main/java/org/easyrules/api/RulesEngine.java index 5068dd12..2bf6971d 100644 --- a/easyrules-core/src/main/java/org/easyrules/api/RulesEngine.java +++ b/easyrules-core/src/main/java/org/easyrules/api/RulesEngine.java @@ -52,34 +52,6 @@ public interface RulesEngine { */ RulesEngineParameters getParameters(); - /** - * Register a rule in the rules engine registry. - * - * @param rule the rule to register - */ - void registerRule(Object rule); - - /** - * Unregister a rule from the rules engine registry. - * - * @param rule the rule to unregister - */ - void unregisterRule(Object rule); - - /** - * Unregister a rule by name from the rules engine registry. - * - * @param ruleName the name of the rule to unregister - */ - void unregisterRule(String ruleName); - - /** - * Return the set of registered rules. - * - * @return the set of registered rules - */ - Set getRules(); - /** * Return the list of registered rule listeners. * @@ -88,18 +60,13 @@ public interface RulesEngine { List getRuleListeners(); /** - * Fire all registered rules. + * Fire all registered rules on given facts. */ - void fireRules(); + void fire(Rules rules, Facts facts); /** * Check rules without firing them. * @return a map with the result of evaluation of each rule */ - Map checkRules(); - - /** - * Clear rules engine registry. - */ - void clearRules(); + Map check(Rules rules, Facts facts); }