handle IllegalArgumentException when fact type does not match parameter type

pull/94/head
Mahmoud Ben Hassine 8 years ago
parent 90ec13b00a
commit 9124cdddc3

@ -23,11 +23,11 @@
*/
package org.jeasy.rules.core;
import org.jeasy.rules.annotation.Fact;
import org.jeasy.rules.api.Facts;
import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Fact;
import org.jeasy.rules.annotation.Priority;
import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rule;
import java.lang.annotation.Annotation;
@ -36,6 +36,8 @@ import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.*;
import static java.lang.String.format;
/**
* Main class to create rule proxies from annotated objects.
*
@ -87,7 +89,12 @@ public class RuleProxy implements InvocationHandler {
Facts facts = (Facts) args[0];
Method conditionMethod = getConditionMethod();
List<Object> actualParameters = getActualParameters(conditionMethod, facts);
return conditionMethod.invoke(target, actualParameters.toArray()); // validated upfront
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("execute")) {
for (ActionMethodOrderBean actionMethodBean : getActionMethodBeans()) {
@ -121,19 +128,18 @@ public class RuleProxy implements InvocationHandler {
private List<Object> getActualParameters(Method method, Facts facts) {
List<Object> actualParameters = new ArrayList<>();
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
for(Annotation[] ann : parameterAnnotations){
if(ann.length == 1){
String factName = ((Fact) (ann[0])).value(); //validated upfront.
for (Annotation[] annotations : parameterAnnotations) {
if (annotations.length == 1) {
String factName = ((Fact) (annotations[0])).value(); //validated upfront.
Object fact = facts.get(factName);
if(fact == null){
throw new RuntimeException(String.format("No fact named %s found in known facts", factName));
if (fact == null) {
throw new RuntimeException(format("No fact named %s found in known facts", factName));
}
actualParameters.add(fact);
} else {
actualParameters.add(facts); //validated upfront, there may be only one parameter not annotated and which is of type Facts.class
}
}
return actualParameters;
}

@ -32,6 +32,8 @@ import org.jeasy.rules.api.Rules;
import org.jeasy.rules.api.RulesEngine;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class AnnotatedRulesTest {
@Test
@ -40,10 +42,23 @@ public class AnnotatedRulesTest {
facts.add("rain", true);
facts.add("age", 18);
Rules rules = new Rules(
new WeatherRule(),
new AgeRule()
);
WeatherRule weatherRule = new WeatherRule();
AgeRule ageRule = new AgeRule();
Rules rules = new Rules(weatherRule, ageRule);
RulesEngine rulesEngine = new DefaultRulesEngine();
rulesEngine.fire(rules, facts);
assertThat(ageRule.isExecuted()).isTrue();
assertThat(weatherRule.isExecuted()).isTrue();
}
@Test(expected = RuntimeException.class)
public void whenFactTypeDoesNotMatchParameterType_thenShouldThrowRuntimeException() throws Exception {
Facts facts = new Facts();
facts.add("age", "foo");
Rules rules = new Rules(new AgeRule());
RulesEngine rulesEngine = new DefaultRulesEngine();
@ -53,22 +68,30 @@ public class AnnotatedRulesTest {
@Rule
class AgeRule {
private boolean isExecuted;
@Condition
public boolean isAdult(@Fact("age") int age) {
return age >= 18;
}
@Action
public void then() {
public void printYourAreAdult() {
System.out.println("You are an adult");
isExecuted = true;
}
public boolean isExecuted() {
return isExecuted;
}
}
@Rule
class WeatherRule {
private boolean isExecuted;
@Condition
public boolean itRains(@Fact("rain") boolean rain) {
return rain;
@ -77,7 +100,11 @@ public class AnnotatedRulesTest {
@Action
public void takeAnUmbrella(Facts facts) {
System.out.println("It rains, take an umbrella!");
isExecuted = true;
}
public boolean isExecuted() {
return isExecuted;
}
}
}

Loading…
Cancel
Save