This is an automated email from the ASF dual-hosted git repository.

jungm pushed a commit to branch BVAL-222
in repository https://gitbox.apache.org/repos/asf/bval.git

commit 08f8bd001e6191c137b10f7f42ec7c2138d8b4f9
Author: Markus Jung <[email protected]>
AuthorDate: Tue Jan 28 13:32:09 2025 +0100

    BVAL222 - enable BValInterceptor when constraints are only placed on parent 
classes
---
 .../java/org/apache/bval/cdi/BValExtension.java    | 105 ++++++++++++++-------
 1 file changed, 72 insertions(+), 33 deletions(-)

diff --git a/bval-jsr/src/main/java/org/apache/bval/cdi/BValExtension.java 
b/bval-jsr/src/main/java/org/apache/bval/cdi/BValExtension.java
index ae02f47..9fd9640 100644
--- a/bval-jsr/src/main/java/org/apache/bval/cdi/BValExtension.java
+++ b/bval-jsr/src/main/java/org/apache/bval/cdi/BValExtension.java
@@ -19,11 +19,17 @@
 package org.apache.bval.cdi;
 
 import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Executable;
 import java.lang.reflect.Modifier;
+import java.lang.reflect.Parameter;
 import java.lang.reflect.Type;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Queue;
 import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -33,10 +39,8 @@ import jakarta.enterprise.context.spi.CreationalContext;
 import jakarta.enterprise.event.Observes;
 import jakarta.enterprise.inject.spi.AfterBeanDiscovery;
 import jakarta.enterprise.inject.spi.AfterDeploymentValidation;
-import jakarta.enterprise.inject.spi.Annotated;
 import jakarta.enterprise.inject.spi.AnnotatedType;
 import jakarta.enterprise.inject.spi.Bean;
-import jakarta.enterprise.inject.spi.BeanAttributes;
 import jakarta.enterprise.inject.spi.BeanManager;
 import jakarta.enterprise.inject.spi.BeforeBeanDiscovery;
 import jakarta.enterprise.inject.spi.CDI;
@@ -128,13 +132,25 @@ public class BValExtension implements Extension {
         final int modifiers = javaClass.getModifiers();
         if (!javaClass.isInterface() && !javaClass.isAnonymousClass() && 
!Modifier.isFinal(modifiers) && !Modifier.isAbstract(modifiers)) {
             try {
-                if (hasValidation(annotatedType)
-                    || hasValidationAnnotation(annotatedType.getMethods())
-                    || hasValidationAnnotation(annotatedType.getConstructors())
-                    || Stream.concat(annotatedType.getMethods().stream(), 
annotatedType.getConstructors().stream())
-                        .flatMap(it -> it.getParameters().stream())
-                        .anyMatch(this::hasValidation)) {
-                    pat.setAnnotatedType(new 
BValAnnotatedType<>(annotatedType));
+                Queue<Class<?>> toProcess = new LinkedList<>();
+                toProcess.add(annotatedType.getJavaClass());
+
+                while (!toProcess.isEmpty()) {
+                    Class<?> now = toProcess.poll();
+                    if (hasValidation(now)
+                            || hasValidation(now.getMethods()) || 
hasValidation(now.getConstructors())
+                            || hasParamsWithValidation(now.getMethods()) || 
hasParamsWithValidation(now.getConstructors())) {
+                        pat.setAnnotatedType(new 
BValAnnotatedType<>(annotatedType));
+
+                        break;
+                    }
+
+                    // Nothing found, collect superclass/interface and repeat 
(See BVAL-222)
+                    if (now.getSuperclass() != Object.class) {
+                        toProcess.add(now.getSuperclass());
+                    }
+
+                    toProcess.addAll(Arrays.asList(now.getInterfaces()));
                 }
             } catch (final Exception e) {
                 if (e instanceof ValidationException) {
@@ -201,32 +217,55 @@ public class BValExtension implements Extension {
         notBValAnnotation.clear();
     }
 
-    private boolean hasValidationAnnotation(final Collection<? extends 
Annotated> annotateds) {
-        return annotateds.stream().anyMatch(this::hasValidation);
+    private boolean hasValidation(final AnnotatedElement[] elements) {
+        for (int i = 0; i < elements.length; i++) {
+            if (hasValidation(elements[i])) {
+                return true;
+            }
+        }
+
+        return false;
     }
 
-    private boolean hasValidation(final Annotated m) {
-        return m.getAnnotations().stream()
-                .anyMatch(it -> {
-                    final Class<? extends Annotation> type = 
it.annotationType();
-                    if (type == ValidateOnExecution.class || type == 
Valid.class) {
-                        return true;
-                    }
-                    if (isSkippedAnnotation(type)) {
-                        return false;
-                    }
-                    if 
(type.getName().startsWith("jakarta.validation.constraints")) {
-                        return true;
-                    }
-                    if (notBValAnnotation.contains(type)) { // more likely so 
faster first
-                        return false;
-                    }
-                    if (potentiallyBValAnnotation.contains(type)) {
-                        return true;
-                    }
-                    cacheIsBvalAnnotation(type);
-                    return potentiallyBValAnnotation.contains(type);
-                });
+    private boolean hasParamsWithValidation(Executable[] executables) {
+        for (int i = 0; i < executables.length; i++) {
+            Parameter[] params = executables[i].getParameters();
+            for (int j = 0; j < params.length; j++) {
+                if (hasValidation(params[j])) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    private boolean hasValidation(final AnnotatedElement element) {
+        Annotation[] annotations = element.getAnnotations();
+        for (int i = 0; i < annotations.length; i++) {
+            final Class<? extends Annotation> type = 
annotations[i].annotationType();
+            if (type == ValidateOnExecution.class || type == Valid.class) {
+                return true;
+            }
+            if (isSkippedAnnotation(type)) {
+                continue;
+            }
+            if (type.getName().startsWith("jakarta.validation.constraints")) {
+                return true;
+            }
+            if (notBValAnnotation.contains(type)) { // more likely so faster 
first
+                continue;
+            }
+            if (potentiallyBValAnnotation.contains(type)) {
+                return true;
+            }
+            cacheIsBvalAnnotation(type);
+            if (potentiallyBValAnnotation.contains(type)) {
+                return true;
+            }
+        }
+
+        return false;
     }
 
     private boolean isSkippedAnnotation(final Class<? extends Annotation> 
type) {

Reply via email to