|
|
@ -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();
|
|
|
|