You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bval.apache.org by mb...@apache.org on 2018/04/05 17:19:13 UTC

[3/3] bval git commit: handle reflection bug with non-static inner class constructor parameter annotations

handle reflection bug with non-static inner class constructor parameter annotations


Project: http://git-wip-us.apache.org/repos/asf/bval/repo
Commit: http://git-wip-us.apache.org/repos/asf/bval/commit/0dd0106b
Tree: http://git-wip-us.apache.org/repos/asf/bval/tree/0dd0106b
Diff: http://git-wip-us.apache.org/repos/asf/bval/diff/0dd0106b

Branch: refs/heads/bv2
Commit: 0dd0106b0f2f234fde618d93aea6ea9d80bda2e4
Parents: 69a817d
Author: Matt Benson <mb...@apache.org>
Authored: Thu Apr 5 12:19:01 2018 -0500
Committer: Matt Benson <mb...@apache.org>
Committed: Thu Apr 5 12:19:01 2018 -0500

----------------------------------------------------------------------
 .../bval/jsr/metadata/ReflectionBuilder.java    |  6 +-
 .../bval/jsr/util/AnnotationsManager.java       | 68 +++++++++++++-------
 2 files changed, 47 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/bval/blob/0dd0106b/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ReflectionBuilder.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ReflectionBuilder.java b/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ReflectionBuilder.java
index 0a70b7c..daa531e 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ReflectionBuilder.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ReflectionBuilder.java
@@ -204,7 +204,7 @@ public class ReflectionBuilder {
 
         @Override
         public List<Class<?>> getGroupSequence(Meta<Class<T>> ignored) {
-            final GroupSequence groupSequence = meta.getHost().getAnnotation(GroupSequence.class);
+            final GroupSequence groupSequence = AnnotationsManager.getAnnotation(meta.getHost(), GroupSequence.class);
             return groupSequence == null ? null : Collections.unmodifiableList(Arrays.asList(groupSequence.value()));
         }
     }
@@ -238,12 +238,12 @@ public class ReflectionBuilder {
 
         @Override
         public boolean isCascade(Meta<E> ignored) {
-            return meta.getHost().isAnnotationPresent(Valid.class);
+            return AnnotationsManager.isAnnotationDirectlyPresent(meta.getHost(), Valid.class);
         }
 
         @Override
         public Set<GroupConversion> getGroupConversions(Meta<E> ignored) {
-            return Stream.of(meta.getHost().getDeclaredAnnotationsByType(ConvertGroup.class))
+            return Stream.of(AnnotationsManager.getDeclaredAnnotationsByType(meta.getHost(), ConvertGroup.class))
                 .map(cg -> GroupConversion.from(cg.from()).to(cg.to())).collect(ToUnmodifiable.set());
         }
     }

http://git-wip-us.apache.org/repos/asf/bval/blob/0dd0106b/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationsManager.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationsManager.java b/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationsManager.java
index dac1294..ead0a3b 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationsManager.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationsManager.java
@@ -21,8 +21,11 @@ package org.apache.bval.jsr.util;
 import java.lang.annotation.Annotation;
 import java.lang.annotation.Repeatable;
 import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Parameter;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumSet;
@@ -56,6 +59,7 @@ import org.apache.bval.jsr.metadata.Meta;
 import org.apache.bval.jsr.xml.AnnotationProxyBuilder;
 import org.apache.bval.util.Exceptions;
 import org.apache.bval.util.Lazy;
+import org.apache.bval.util.ObjectUtils;
 import org.apache.bval.util.StringUtils;
 import org.apache.bval.util.Validate;
 import org.apache.bval.util.reflection.Reflection;
@@ -219,31 +223,19 @@ public class AnnotationsManager {
         return result.optional().map(Collections::unmodifiableMap).orElseGet(Collections::emptyMap);
     }
 
-    /**
-     * Meta-annotation aware.
-     * 
-     * @param e
-     * @param t
-     * @return {@code boolean}
-     * @see AnnotatedElement#isAnnotationPresent(Class)
-     */
-    public static boolean isAnnotationPresent(AnnotatedElement e, Class<? extends Annotation> t) {
-        if (e.isAnnotationPresent(t)) {
-            return true;
-        }
-        return Stream.of(e.getAnnotations()).map(Annotation::annotationType).anyMatch(a -> isAnnotationPresent(a, t));
+    public static boolean isAnnotationDirectlyPresent(AnnotatedElement e, Class<? extends Annotation> t) {
+        return substitute(e).filter(s -> s.isAnnotationPresent(t)).isPresent();
     }
 
-    /**
-     * Get declared annotations with a particular meta-annotation.
-     * 
-     * @param e
-     * @param meta
-     * @return {@link Annotation}[]
-     */
-    public static Annotation[] getDeclared(AnnotatedElement e, Class<? extends Annotation> meta) {
-        return Stream.of(e.getDeclaredAnnotations()).filter(ann -> isAnnotationPresent(ann.annotationType(), meta))
-            .toArray(Annotation[]::new);
+    public static <T extends Annotation> T getAnnotation(AnnotatedElement e, Class<T> annotationClass) {
+        return substitute(e).map(s -> s.getAnnotation(annotationClass)).orElse(null);
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T extends Annotation> T[] getDeclaredAnnotationsByType(AnnotatedElement e,
+        Class<T> annotationClass) {
+        return substitute(e).map(s -> s.getDeclaredAnnotationsByType(annotationClass))
+            .orElse((T[]) ObjectUtils.EMPTY_ANNOTATION_ARRAY);
     }
 
     /**
@@ -258,7 +250,9 @@ public class AnnotationsManager {
     }
 
     private static Annotation[] getDeclaredConstraints(AnnotatedElement e) {
-        final Annotation[] declaredAnnotations = e.getDeclaredAnnotations();
+        final Annotation[] declaredAnnotations =
+            substitute(e).map(AnnotatedElement::getDeclaredAnnotations).orElse(ObjectUtils.EMPTY_ANNOTATION_ARRAY);
+        
         if (declaredAnnotations.length == 0) {
             return declaredAnnotations;
         }
@@ -287,6 +281,32 @@ public class AnnotationsManager {
         }
         return constraints.toArray(Annotation[]::new);
     }
+    
+
+    private static Optional<AnnotatedElement> substitute(AnnotatedElement e) {
+        if (e instanceof Parameter) {
+            final Parameter p = (Parameter) e;
+            if (p.getDeclaringExecutable() instanceof Constructor<?>) {
+                final Constructor<?> ctor = (Constructor<?>) p.getDeclaringExecutable();
+                final Class<?> dc = ctor.getDeclaringClass();
+                if (!(dc.getDeclaringClass() == null || Modifier.isStatic(dc.getModifiers()))) {
+                    // found ctor for non-static inner class
+                    final Annotation[][] parameterAnnotations = ctor.getParameterAnnotations();
+                    if (parameterAnnotations.length == ctor.getParameterCount() - 1) {
+                        final Parameter[] parameters = ctor.getParameters();
+                        final int idx = ObjectUtils.indexOf(parameters, p);
+                        if (idx == 0) {
+                            return Optional.empty();
+                        }
+                        return Optional.of(parameters[idx - 1]);
+                    }
+                    Validate.validState(parameterAnnotations.length == ctor.getParameterCount(),
+                            "Cannot make sense of parameter annotations of %s", ctor);
+                }
+            }
+        }
+        return Optional.of(e);
+    }
 
     private final ApacheValidatorFactory validatorFactory;
     private final LRUCache<Class<? extends Annotation>, Composition> compositions;