Override equals()/hashCode()/toString() same as BasicRule (#115)

* override equals()/hashCode()/toString() same as BasicRule

* replace if with switch
pull/112/merge
wg1j 7 years ago committed by Mahmoud Ben Hassine
parent 503f5f063a
commit db6438350c

@ -32,6 +32,7 @@ import org.jeasy.rules.api.Rule;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.util.*; import java.util.*;
@ -76,55 +77,60 @@ public class RuleProxy implements InvocationHandler {
@Override @Override
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
String methodName = method.getName(); String methodName = method.getName();
if (methodName.equals("getName")) { switch (methodName) {
return getRuleName(); case "getName":
} return getRuleName();
if (methodName.equals("getDescription")) { case "getDescription":
return getRuleDescription(); return getRuleDescription();
} case "getPriority":
if (methodName.equals("getPriority")) { return getRulePriority();
return getRulePriority(); case "compareTo":
} return compareToMethod(args);
if (methodName.equals("evaluate")) { case "evaluate":
Facts facts = (Facts) args[0]; return evaluateMethod(args);
Method conditionMethod = getConditionMethod(); case "execute":
List<Object> actualParameters = getActualParameters(conditionMethod, facts); return executeMethod(args);
try { case "equals":
return conditionMethod.invoke(target, actualParameters.toArray()); // validated upfront return equalsMethod(args);
} catch (IllegalArgumentException e) { case "hashCode":
String error = "Types of injected facts in method '%s' in rule '%s' do not match parameters types"; return hashCodeMethod();
throw new RuntimeException(format(error, conditionMethod.getName(), target.getClass().getName()), e); case "toString":
} return toStringMethod();
} default:
if (methodName.equals("execute")) { return null;
for (ActionMethodOrderBean actionMethodBean : getActionMethodBeans()) {
Facts facts = (Facts) args[0];
Method actionMethod = actionMethodBean.getMethod();
List<Object> actualParameters = getActualParameters(actionMethod, facts);
actionMethod.invoke(target, actualParameters.toArray());
}
}
if (methodName.equals("equals")) {
return target.equals(args[0]);
} }
if (methodName.equals("hashCode")) { }
return target.hashCode();
} private Object evaluateMethod(final Object[] args) throws IllegalAccessException, InvocationTargetException {
if (methodName.equals("toString")) { Facts facts = (Facts) args[0];
return target.toString(); Method conditionMethod = getConditionMethod();
List<Object> actualParameters = getActualParameters(conditionMethod, facts);
try {
return conditionMethod.invoke(target, actualParameters.toArray()); // validated upfront
} catch (IllegalArgumentException e) {
String error = "Types of injected facts in method '%s' in rule '%s' do not match parameters types";
throw new RuntimeException(format(error, conditionMethod.getName(), target.getClass().getName()), e);
} }
if (methodName.equals("compareTo")) { }
Method compareToMethod = getCompareToMethod();
if (compareToMethod != null) { private Object executeMethod(final Object[] args) throws IllegalAccessException, InvocationTargetException {
return compareToMethod.invoke(target, args); Facts facts = (Facts) args[0];
} else { for (ActionMethodOrderBean actionMethodBean : getActionMethodBeans()) {
Rule otherRule = (Rule) args[0]; Method actionMethod = actionMethodBean.getMethod();
return compareTo(otherRule); List<Object> actualParameters = getActualParameters(actionMethod, facts);
} actionMethod.invoke(target, actualParameters.toArray());
} }
return null; return null;
} }
private Object compareToMethod(final Object[] args) throws Exception {
Method compareToMethod = getCompareToMethod();
if (compareToMethod != null) {
return compareToMethod.invoke(target, args);
} else {
Rule otherRule = (Rule) args[0];
return compareTo(otherRule);
}
}
private List<Object> getActualParameters(Method method, Facts facts) { private List<Object> getActualParameters(Method method, Facts facts) {
List<Object> actualParameters = new ArrayList<>(); List<Object> actualParameters = new ArrayList<>();
Annotation[][] parameterAnnotations = method.getParameterAnnotations(); Annotation[][] parameterAnnotations = method.getParameterAnnotations();
@ -143,6 +149,39 @@ public class RuleProxy implements InvocationHandler {
return actualParameters; return actualParameters;
} }
private boolean equalsMethod(final Object[] args) throws Exception {
if (!(args[0] instanceof Rule)) {
return false;
}
Rule otherRule = (Rule) args[0];
int otherPriority = otherRule.getPriority();
int priority = getRulePriority();
if (priority != otherPriority) {
return false;
}
String otherName = otherRule.getName();
String name = getRuleName();
if (!name.equals(otherName)) {
return false;
}
String otherDescription = otherRule.getDescription();
String description = getRuleDescription();
return !(description != null ? !description.equals(otherDescription) : otherDescription != null);
}
private int hashCodeMethod() throws Exception {
int result = getRuleName().hashCode();
int priority = getRulePriority();
String description = getRuleDescription();
result = 31 * result + (description != null ? description.hashCode() : 0);
result = 31 * result + priority;
return result;
}
private String toStringMethod(){
return getRuleName();
}
private int compareTo(final Rule otherRule) throws Exception { private int compareTo(final Rule otherRule) throws Exception {
int otherPriority = otherRule.getPriority(); int otherPriority = otherRule.getPriority();
int priority = getRulePriority(); int priority = getRulePriority();

@ -30,6 +30,7 @@ import org.jeasy.rules.api.Rule;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
public class RuleProxyTest { public class RuleProxyTest {
@ -81,6 +82,64 @@ public class RuleProxyTest {
Rule proxy = RuleProxy.asRule(rule); Rule proxy = RuleProxy.asRule(rule);
} }
@Test
public void invokeEquals() {
Object rule = new DummyRule();
Rule proxy1 = RuleProxy.asRule(rule);
Rule proxy2 = RuleProxy.asRule(proxy1);
Rule proxy3 = RuleProxy.asRule(proxy2);
/**
* @see Object#equals(Object) reflexive
*/
assertEquals(rule,rule);
assertEquals(proxy1, proxy1);
assertEquals(proxy2, proxy2);
assertEquals(proxy3, proxy3);
/**
* @see Object#equals(Object) symmetric
*/
assertNotEquals(rule, proxy1);
assertNotEquals(proxy1, rule);
assertEquals(proxy1, proxy2);
assertEquals(proxy2, proxy1);
/**
* @see Object#equals(Object) transitive consistent
*/
assertEquals(proxy1, proxy2);
assertEquals(proxy2, proxy3);
assertEquals(proxy3, proxy1);
/**
* @see Object#equals(Object) non-null
*/
assertNotEquals(rule, null);
assertNotEquals(proxy1, null);
assertNotEquals(proxy2, null);
assertNotEquals(proxy3, null);
}
@Test
public void invokeHashCode() {
Object rule = new DummyRule();
Rule proxy1 = RuleProxy.asRule(rule);
Rule proxy2 = RuleProxy.asRule(proxy1);
/**
* @see Object#hashCode rule1
*/
assertEquals(proxy1.hashCode(), proxy1.hashCode());
/**
* @see Object#hashCode rule2
*/
assertEquals(proxy1, proxy2);
assertEquals(proxy1.hashCode(), proxy2.hashCode());
/**
* @see Object#hashCode rule3
*/
assertNotEquals(rule, proxy1);
assertNotEquals(rule.hashCode(), proxy1.hashCode());
}
@org.jeasy.rules.annotation.Rule @org.jeasy.rules.annotation.Rule
class DummyRule { class DummyRule {
@Condition @Condition

Loading…
Cancel
Save