From 9137dc7c70ebcc957926cf0dc94b251c24a6b21d Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Fri, 23 Dec 2016 12:53:36 +0100 Subject: [PATCH] DATACMNS-967 - Getters that are default methods are not considered projection input properties anymore. We now exclude getter methods that are default methods from the consideration which properties of a projection interface are considered input properties in the first place. Unfortunately no tests for this one as we can't declare default methods in our codebase requiring JDK 6 compatibility. --- .../DefaultProjectionInformation.java | 37 ++++++++++++++++++- .../SpelAwareProxyProjectionFactory.java | 4 ++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/springframework/data/projection/DefaultProjectionInformation.java b/src/main/java/org/springframework/data/projection/DefaultProjectionInformation.java index 4cb6adb28..80c345301 100644 --- a/src/main/java/org/springframework/data/projection/DefaultProjectionInformation.java +++ b/src/main/java/org/springframework/data/projection/DefaultProjectionInformation.java @@ -16,11 +16,12 @@ package org.springframework.data.projection; import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import org.springframework.beans.BeanUtils; +import org.springframework.data.util.ReflectionUtils; import org.springframework.util.Assert; /** @@ -104,7 +105,7 @@ class DefaultProjectionInformation implements ProjectionInformation { private static List collectDescriptors(Class type) { List result = new ArrayList(); - result.addAll(Arrays.asList(BeanUtils.getPropertyDescriptors(type))); + result.addAll(filterDefaultMethods(BeanUtils.getPropertyDescriptors(type))); for (Class interfaze : type.getInterfaces()) { result.addAll(collectDescriptors(interfaze)); @@ -112,4 +113,36 @@ class DefaultProjectionInformation implements ProjectionInformation { return result; } + + /** + * Returns all {@link PropertyDescriptor}s that don't have a Java 8 default method as getter. + * + * @param descriptors must not be {@literal null}. + * @return + */ + private static List filterDefaultMethods(PropertyDescriptor[] descriptors) { + + List result = new ArrayList(descriptors.length); + + for (PropertyDescriptor descriptor : descriptors) { + if (!hasDefaultGetter(descriptor)) { + result.add(descriptor); + } + } + + return result; + } + + /** + * Returns whether the given {@link PropertyDescriptor} has a getter that is a Java 8 default method. + * + * @param descriptor must not be {@literal null}. + * @return + */ + private static boolean hasDefaultGetter(PropertyDescriptor descriptor) { + + Method method = descriptor.getReadMethod(); + + return method == null ? false : ReflectionUtils.isDefaultMethod(method); + } } diff --git a/src/main/java/org/springframework/data/projection/SpelAwareProxyProjectionFactory.java b/src/main/java/org/springframework/data/projection/SpelAwareProxyProjectionFactory.java index 91fa404c5..5493d5e4d 100644 --- a/src/main/java/org/springframework/data/projection/SpelAwareProxyProjectionFactory.java +++ b/src/main/java/org/springframework/data/projection/SpelAwareProxyProjectionFactory.java @@ -96,6 +96,10 @@ public class SpelAwareProxyProjectionFactory extends ProxyProjectionFactory impl @Override protected boolean isInputProperty(PropertyDescriptor descriptor) { + if (!super.isInputProperty(descriptor)) { + return false; + } + Method readMethod = descriptor.getReadMethod(); if (readMethod == null) {