From 9ab946738614c15df64136c8867964f97e2c726d Mon Sep 17 00:00:00 2001 From: Thomas Darimont Date: Mon, 7 Jul 2014 14:49:20 +0200 Subject: [PATCH] DATACMNS-533 - Discover declared functions on EvaluationContextExtension. We new automatically register public static methods declared on classes extending EvaluationContextExtensionSupport as functions to be used within SpEL expressions. Related pull request: spring-projects/spring-data-jpa#101 Related ticket: DATAJPA-564 --- ...tensionAwareEvaluationContextProvider.java | 6 ++-- .../EvaluationContextExtensionSupport.java | 32 ++++++++++++++++++- ...bleEvaluationContextProviderUnitTests.java | 12 +++++-- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/springframework/data/repository/query/ExtensionAwareEvaluationContextProvider.java b/src/main/java/org/springframework/data/repository/query/ExtensionAwareEvaluationContextProvider.java index b2f421d66..fe7078399 100644 --- a/src/main/java/org/springframework/data/repository/query/ExtensionAwareEvaluationContextProvider.java +++ b/src/main/java/org/springframework/data/repository/query/ExtensionAwareEvaluationContextProvider.java @@ -168,11 +168,13 @@ public class ExtensionAwareEvaluationContextProvider implements EvaluationContex for (EvaluationContextExtension ext : extensions) { + Map extFunctions = ext.getFunctions(); + if (ext.getExtensionId() != null) { - functions.put(ext.getExtensionId(), ext.getFunctions()); + functions.put(ext.getExtensionId(), extFunctions); } - functions.putAll(ext.getFunctions()); + functions.putAll(extFunctions); } this.functions = functions; diff --git a/src/main/java/org/springframework/data/repository/query/spi/EvaluationContextExtensionSupport.java b/src/main/java/org/springframework/data/repository/query/spi/EvaluationContextExtensionSupport.java index c4032d8f1..c80620a64 100644 --- a/src/main/java/org/springframework/data/repository/query/spi/EvaluationContextExtensionSupport.java +++ b/src/main/java/org/springframework/data/repository/query/spi/EvaluationContextExtensionSupport.java @@ -16,9 +16,14 @@ package org.springframework.data.repository.query.spi; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.Collections; +import java.util.HashMap; import java.util.Map; +import org.springframework.util.ReflectionUtils; +import org.springframework.util.ReflectionUtils.MethodCallback; + /** * A base class for {@link EvaluationContextExtension}s. * @@ -28,6 +33,31 @@ import java.util.Map; */ public abstract class EvaluationContextExtensionSupport implements EvaluationContextExtension { + private final Map declaredFunctions; + + public EvaluationContextExtensionSupport() { + + this.declaredFunctions = discoverDeclaredFunctions(); + } + + private Map discoverDeclaredFunctions() { + + final Map map = new HashMap(); + + ReflectionUtils.doWithMethods(getClass(), new MethodCallback() { + + @Override + public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { + + if (Modifier.isPublic(method.getModifiers()) && Modifier.isStatic(method.getModifiers())) { + map.put(method.getName(), method); + } + } + }); + + return map.isEmpty() ? Collections. emptyMap() : Collections.unmodifiableMap(map); + } + /* * (non-Javadoc) * @see org.springframework.data.repository.query.EvaluationContextExtension#getProperties() @@ -43,6 +73,6 @@ public abstract class EvaluationContextExtensionSupport implements EvaluationCon */ @Override public Map getFunctions() { - return Collections.emptyMap(); + return this.declaredFunctions; } } diff --git a/src/test/java/org/springframework/data/repository/query/ExtensibleEvaluationContextProviderUnitTests.java b/src/test/java/org/springframework/data/repository/query/ExtensibleEvaluationContextProviderUnitTests.java index 667ad9c34..47dc537fb 100644 --- a/src/test/java/org/springframework/data/repository/query/ExtensibleEvaluationContextProviderUnitTests.java +++ b/src/test/java/org/springframework/data/repository/query/ExtensibleEvaluationContextProviderUnitTests.java @@ -21,6 +21,7 @@ import static org.junit.Assert.*; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -36,7 +37,7 @@ import org.springframework.expression.spel.standard.SpelExpressionParser; * * @author Oliver Gierke */ -public class ExtensibleEvaluationContextProviderUnitTests> { +public class ExtensibleEvaluationContextProviderUnitTests { DefaultParameters parameters; @@ -110,7 +111,9 @@ public class ExtensibleEvaluationContextProviderUnitTests getFunctions() { + Map functions = new HashMap(super.getFunctions()); + try { - return Collections.singletonMap("method", getClass().getMethod("extensionMethod")); + functions.put("aliasedMethod", getClass().getMethod("extensionMethod")); + return functions; } catch (Exception o_O) { throw new RuntimeException(o_O); }