From commits-return-2380-archive-asf-public=cust-asf.ponee.io@bval.apache.org Tue Oct 16 19:31:13 2018 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id 11A7C180778 for ; Tue, 16 Oct 2018 19:31:11 +0200 (CEST) Received: (qmail 67636 invoked by uid 500); 16 Oct 2018 17:31:06 -0000 Mailing-List: contact commits-help@bval.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@bval.apache.org Delivered-To: mailing list commits@bval.apache.org Received: (qmail 67309 invoked by uid 99); 16 Oct 2018 17:31:06 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 16 Oct 2018 17:31:06 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id AF5B9E11C0; Tue, 16 Oct 2018 17:31:05 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: mbenson@apache.org To: commits@bval.apache.org Date: Tue, 16 Oct 2018 17:31:24 -0000 Message-Id: <88d3dbc67b9f41f68810624eb1a7848c@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [20/50] 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/f5ad0442 Tree: http://git-wip-us.apache.org/repos/asf/bval/tree/f5ad0442 Diff: http://git-wip-us.apache.org/repos/asf/bval/diff/f5ad0442 Branch: refs/heads/bv2 Commit: f5ad04424300265f3f8685b5fa17233e12329950 Parents: d34b59b Author: Matt Benson Authored: Thu Apr 5 12:19:01 2018 -0500 Committer: Matt Benson Committed: Tue Oct 16 12:28:20 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/f5ad0442/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> getGroupSequence(Meta> 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 ignored) { - return meta.getHost().isAnnotationPresent(Valid.class); + return AnnotationsManager.isAnnotationDirectlyPresent(meta.getHost(), Valid.class); } @Override public Set getGroupConversions(Meta 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/f5ad0442/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 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 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 meta) { - return Stream.of(e.getDeclaredAnnotations()).filter(ann -> isAnnotationPresent(ann.annotationType(), meta)) - .toArray(Annotation[]::new); + public static T getAnnotation(AnnotatedElement e, Class annotationClass) { + return substitute(e).map(s -> s.getAnnotation(annotationClass)).orElse(null); + } + + @SuppressWarnings("unchecked") + public static T[] getDeclaredAnnotationsByType(AnnotatedElement e, + Class 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 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, Composition> compositions;