DATACMNS-1026 - ExtensionAwareEvaluationContextProvider now returns all overloaded methods as functions.
All overloaded methods are now available in SPeL expressions. Among methods with identical argument list from different sources in the same extension (extension, root object, aliases) the last one in the order in parens wins. If there is more than one method for an application the following rules are applied: if there is one method with exact matching types in the argument list it is used, otherwise an exception is thrown. Original pull request: #217.
This commit is contained in:
committed by
Oliver Gierke
parent
5dba2f4c59
commit
42621086fe
@@ -59,7 +59,8 @@ public class ConvertingPropertyAccessorUnitTests {
|
||||
Entity entity = new Entity();
|
||||
entity.id = 1L;
|
||||
|
||||
assertThat(getIdProperty()).hasValueSatisfying(it -> assertThat(getAccessor(entity, CONVERSION_SERVICE).getProperty(it, String.class)).hasValue("1"));
|
||||
assertThat(getIdProperty()).hasValueSatisfying(
|
||||
it -> assertThat(getAccessor(entity, CONVERSION_SERVICE).getProperty(it, String.class)).hasValue("1"));
|
||||
}
|
||||
|
||||
@Test // DATACMNS-596
|
||||
|
||||
@@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -28,6 +29,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
@@ -44,7 +46,8 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
* Unit tests {@link ExtensionAwareEvaluationContextProvider}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont.
|
||||
* @author Thomas Darimont
|
||||
* @author Jens Schauder
|
||||
*/
|
||||
public class ExtensionAwareEvaluationContextProviderUnitTests {
|
||||
|
||||
@@ -219,6 +222,68 @@ public class ExtensionAwareEvaluationContextProviderUnitTests {
|
||||
assertThat(counter.get()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1026
|
||||
public void overloadedMethodsGetResolved() throws Exception {
|
||||
|
||||
provider = createContextProviderWithOverloads();
|
||||
|
||||
// from the root object
|
||||
assertThat(evaluateExpression("method()")).isEqualTo("zero");
|
||||
assertThat(evaluateExpression("method(23)")).isEqualTo("single-int");
|
||||
assertThat(evaluateExpression("method('hello')")).isEqualTo("single-string");
|
||||
assertThat(evaluateExpression("method('one', 'two')")).isEqualTo("two");
|
||||
|
||||
// from the extension
|
||||
assertThat(evaluateExpression("method(1, 2)")).isEqualTo("two-ints");
|
||||
assertThat(evaluateExpression("method(1, 'two')")).isEqualTo("int-and-string");
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1026
|
||||
public void methodFromRootObjectOverwritesMethodFromExtension() throws Exception {
|
||||
|
||||
provider = createContextProviderWithOverloads();
|
||||
|
||||
assertThat(evaluateExpression("ambiguous()")).isEqualTo("from-root");
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1026
|
||||
public void aliasedMethodOverwritesMethodFromRootObject() throws Exception {
|
||||
|
||||
provider = createContextProviderWithOverloads();
|
||||
|
||||
assertThat(evaluateExpression("aliasedMethod()")).isEqualTo("methodResult");
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1026
|
||||
public void exactMatchIsPreferred() throws Exception {
|
||||
|
||||
provider = createContextProviderWithOverloads();
|
||||
|
||||
assertThat(evaluateExpression("ambiguousOverloaded('aString')")).isEqualTo("string");
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1026
|
||||
public void throwsExceptionWhenStillAmbiguous() throws Exception {
|
||||
|
||||
provider = createContextProviderWithOverloads();
|
||||
|
||||
assertThatExceptionOfType(IllegalStateException.class) //
|
||||
.isThrownBy(() -> evaluateExpression("ambiguousOverloaded(23)")) //
|
||||
.withMessageContaining("ambiguousOverloaded") //
|
||||
.withMessageContaining("(java.lang.Integer)");
|
||||
}
|
||||
|
||||
private ExtensionAwareEvaluationContextProvider createContextProviderWithOverloads() {
|
||||
|
||||
return new ExtensionAwareEvaluationContextProvider(Collections.singletonList( //
|
||||
new DummyExtension("_first", "first") {
|
||||
@Override
|
||||
public Object getRootObject() {
|
||||
return new RootWithOverloads();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public static class DummyExtension extends EvaluationContextExtensionSupport {
|
||||
|
||||
@@ -269,6 +334,22 @@ public class ExtensionAwareEvaluationContextProviderUnitTests {
|
||||
public static String extensionMethod() {
|
||||
return "methodResult";
|
||||
}
|
||||
|
||||
public static String method(int i1, int i2) {
|
||||
return "two-ints";
|
||||
}
|
||||
|
||||
public static String method(int i, String s) {
|
||||
return "int-and-string";
|
||||
}
|
||||
|
||||
public static String ambiguous() {
|
||||
return "from-extension-type";
|
||||
}
|
||||
|
||||
public static String ambiguousToo() {
|
||||
return "from-extension-type";
|
||||
}
|
||||
}
|
||||
|
||||
private Object evaluateExpression(String expression) {
|
||||
@@ -312,4 +393,43 @@ public class ExtensionAwareEvaluationContextProviderUnitTests {
|
||||
return "rootObjectInstanceMethod2";
|
||||
}
|
||||
}
|
||||
|
||||
public static class RootWithOverloads {
|
||||
|
||||
public String method() {
|
||||
return "zero";
|
||||
}
|
||||
|
||||
public String method(String s) {
|
||||
return "single-string";
|
||||
}
|
||||
|
||||
public String method(int i) {
|
||||
return "single-int";
|
||||
}
|
||||
|
||||
public String method(String s1, String s2) {
|
||||
return "two";
|
||||
}
|
||||
|
||||
public String ambiguous() {
|
||||
return "from-root";
|
||||
}
|
||||
|
||||
public String aliasedMethod() {
|
||||
return "from-root";
|
||||
}
|
||||
|
||||
public String ambiguousOverloaded(String s) {
|
||||
return "string";
|
||||
}
|
||||
|
||||
public String ambiguousOverloaded(Object o) {
|
||||
return "object";
|
||||
}
|
||||
|
||||
public String ambiguousOverloaded(Serializable o) {
|
||||
return "serializable";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user