diff --git a/independent-projects/qute/core/src/main/java/io/quarkus/qute/ReflectionValueResolver.java b/independent-projects/qute/core/src/main/java/io/quarkus/qute/ReflectionValueResolver.java index d89bc9d7baa1b..b73328237337e 100644 --- a/independent-projects/qute/core/src/main/java/io/quarkus/qute/ReflectionValueResolver.java +++ b/independent-projects/qute/core/src/main/java/io/quarkus/qute/ReflectionValueResolver.java @@ -4,6 +4,9 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.concurrent.CompletableFuture; @@ -100,26 +103,41 @@ private static Method findMethod(Class clazz, String name) { Method foundGetterMatch = null; Method foundBooleanMatch = null; - for (Method method : clazz.getMethods()) { - if (!isMethodValid(method)) { - continue; + // Explore interface methods first... + List> classes = new ArrayList<>(); + Collections.addAll(classes, clazz.getInterfaces()); + Class superClass = clazz.getSuperclass(); + while (superClass != null) { + Collections.addAll(classes, superClass.getInterfaces()); + superClass = superClass.getSuperclass(); + } + classes.add(clazz); + + for (Class clazzToTest : classes) { + for (Method method : clazzToTest.getMethods()) { + if (!isMethodValid(method)) { + continue; + } + if (method.isBridge()) { + continue; + } + if (name.equals(method.getName())) { + foundMatch = method; + } else if (matchesPrefix(name, method.getName(), + GET_PREFIX)) { + foundGetterMatch = method; + } else if (isBoolean(method.getReturnType()) && (matchesPrefix(name, method.getName(), + IS_PREFIX) || matchesPrefix(name, method.getName(), HAS_PREFIX))) { + foundBooleanMatch = method; + } } - if (method.isBridge()) { - continue; + if (foundMatch == null) { + foundMatch = (foundGetterMatch != null ? foundGetterMatch : foundBooleanMatch); } - if (name.equals(method.getName())) { - foundMatch = method; - } else if (matchesPrefix(name, method.getName(), - GET_PREFIX)) { - foundGetterMatch = method; - } else if (isBoolean(method.getReturnType()) && (matchesPrefix(name, method.getName(), - IS_PREFIX) || matchesPrefix(name, method.getName(), HAS_PREFIX))) { - foundBooleanMatch = method; + if (foundMatch != null) { + break; } } - if (foundMatch == null) { - foundMatch = (foundGetterMatch != null ? foundGetterMatch : foundBooleanMatch); - } return foundMatch; } diff --git a/independent-projects/qute/core/src/test/java/io/quarkus/qute/ReflectionResolverTest.java b/independent-projects/qute/core/src/test/java/io/quarkus/qute/ReflectionResolverTest.java new file mode 100644 index 0000000000000..e9223aa693683 --- /dev/null +++ b/independent-projects/qute/core/src/test/java/io/quarkus/qute/ReflectionResolverTest.java @@ -0,0 +1,20 @@ +package io.quarkus.qute; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Map; +import java.util.TreeMap; +import org.junit.jupiter.api.Test; + +public class ReflectionResolverTest { + + @Test + public void testReflectionResolver() { + Map treeMap = new TreeMap<>(Integer::compare); + treeMap.put(2, "bar"); + treeMap.put(1, "foo"); + assertEquals("foo", Engine.builder().addDefaults().addValueResolver(new ReflectionValueResolver()).build() + .parse("{map.entrySet.iterator.next.value}").data("map", treeMap).render()); + } + +}