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

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new 91aa3269ee org.apache.juneau.common.reflect API improvements
91aa3269ee is described below

commit 91aa3269eeae698043f0d7a7277d5cef4802d53b
Author: James Bognar <[email protected]>
AuthorDate: Mon Nov 17 11:18:01 2025 -0500

    org.apache.juneau.common.reflect API improvements
---
 .../juneau/common/reflect/AnnotationInfo.java      | 114 ---------------------
 .../apache/juneau/common/reflect/ClassInfo.java    |  41 ++++++++
 .../apache/juneau/common/reflect/MethodInfo.java   |  83 +++++++++++++++
 3 files changed, 124 insertions(+), 114 deletions(-)

diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationInfo.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationInfo.java
index f3b473ac7d..64dc47512f 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationInfo.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationInfo.java
@@ -283,96 +283,6 @@ public class AnnotationInfo<T extends Annotation> {
        }
 
 
-       
//-----------------------------------------------------------------------------------------------------------------
-       // Static methods for ClassInfo
-       
//-----------------------------------------------------------------------------------------------------------------
-
-       /**
-        * Performs an action on all matching annotations on the specified 
class/parents/package.
-        *
-        * <p>
-        * Annotations are consumed in the following order:
-        * <ol>
-        *      <li>On the package of this class.
-        *      <li>On interfaces ordered parent-to-child.
-        *      <li>On parent classes ordered parent-to-child.
-        *      <li>On this class.
-        * </ol>
-        *
-        * @param classInfo The class to process.
-        * @param filter A predicate to apply to the entries to determine if 
action should be performed.  Can be <jk>null</jk>.
-        * @param action An action to perform on the entry.
-        */
-       // TODO: Once ClassInfo arrays are converted to Lists, convert reverse 
iterations to rstream() and nested loops to flatMap()
-       public static void forEachAnnotationInfo(ClassInfo classInfo, 
Predicate<AnnotationInfo<?>> filter, Consumer<AnnotationInfo<?>> action) {
-               var pi = classInfo.getPackage();
-               if (nn(pi))
-                       for (var ai : pi.getAnnotations())
-                               if (filter == null || filter.test(ai))
-                                       action.accept(ai);
-               var interfaces = classInfo.getInterfaces();
-               for (int i = interfaces.size() - 1; i >= 0; i--)
-                       for (var a : 
interfaces.get(i).inner().getDeclaredAnnotations())
-                               for (var a2 : splitRepeated(a)) {
-                                       var ai = 
AnnotationInfo.of(interfaces.get(i), a2);
-                                       if (filter == null || filter.test(ai))
-                                               action.accept(ai);
-                               }
-               var parents = classInfo.getParents();
-               for (int i = parents.size() - 1; i >= 0; i--)
-                       for (var a : 
parents.get(i).inner().getDeclaredAnnotations())
-                               for (var a2 : splitRepeated(a)) {
-                                       var ai = 
AnnotationInfo.of(parents.get(i), a2);
-                                       if (filter == null || filter.test(ai))
-                                               action.accept(ai);
-                               }
-       }
-
-       
//-----------------------------------------------------------------------------------------------------------------
-       // Static methods for MethodInfo
-       
//-----------------------------------------------------------------------------------------------------------------
-
-       /**
-        * Performs an action on all matching annotations on the specified 
method.
-        *
-        * @param methodInfo The method to process.
-        * @param filter A predicate to apply to the entries to determine if 
action should be performed.  Can be <jk>null</jk>.
-        * @param action An action to perform on the entry.
-        */
-       // TODO: Once ClassInfo arrays are converted to Lists, convert reverse 
iterations to rstream()
-       public static void forEachAnnotationInfo(MethodInfo methodInfo, 
Predicate<AnnotationInfo<?>> filter, Consumer<AnnotationInfo<?>> action) {
-               var c = methodInfo.getDeclaringClass();
-               forEachDeclaredAnnotationInfo(c.getPackage(), filter, action);
-               var interfaces = c.getInterfaces();
-               for (int i = interfaces.size() - 1; i >= 0; i--) {
-                       forEachDeclaredAnnotationInfo(interfaces.get(i), 
filter, action);
-                       forEachDeclaredMethodAnnotationInfo(methodInfo, 
interfaces.get(i), filter, action);
-               }
-               var parents = c.getParents();
-               for (int i = parents.size() - 1; i >= 0; i--) {
-                       forEachDeclaredAnnotationInfo(parents.get(i), filter, 
action);
-                       forEachDeclaredMethodAnnotationInfo(methodInfo, 
parents.get(i), filter, action);
-               }
-       }
-
-       /**
-        * Performs an action on all matching annotations on methods only.
-        *
-        * @param methodInfo The method to process.
-        * @param filter A predicate to apply to the entries to determine if 
action should be performed.  Can be <jk>null</jk>.
-        * @param action An action to perform on the entry.
-        */
-       // TODO: Once ClassInfo arrays are converted to Lists, convert reverse 
iterations to rstream()
-       public static void forEachAnnotationInfoMethodOnly(MethodInfo 
methodInfo, Predicate<AnnotationInfo<?>> filter, Consumer<AnnotationInfo<?>> 
action) {
-               var c = methodInfo.getDeclaringClass();
-               var interfaces = c.getInterfaces();
-               for (int i = interfaces.size() - 1; i >= 0; i--)
-                       forEachDeclaredMethodAnnotationInfo(methodInfo, 
interfaces.get(i), filter, action);
-               var parents = c.getParents();
-               for (int i = parents.size() - 1; i >= 0; i--)
-                       forEachDeclaredMethodAnnotationInfo(methodInfo, 
parents.get(i), filter, action);
-       }
-
        
//-----------------------------------------------------------------------------------------------------------------
        // Private helper methods
        
//-----------------------------------------------------------------------------------------------------------------
@@ -385,30 +295,6 @@ public class AnnotationInfo<T extends Annotation> {
                        .orElse(0);
        }
 
-       @SuppressWarnings("unchecked")
-       private static void forEachDeclaredAnnotationInfo(ClassInfo ci, 
Predicate<AnnotationInfo<?>> filter, Consumer<AnnotationInfo<?>> action) {
-               if (nn(ci))
-                       for (var ai : ci.getDeclaredAnnotationInfos())
-                               if (filter == null || filter.test(ai))
-                                       action.accept(ai);
-       }
-
-       private static void forEachDeclaredAnnotationInfo(PackageInfo pi, 
Predicate<AnnotationInfo<?>> filter, Consumer<AnnotationInfo<?>> action) {
-               if (nn(pi))
-                       for (var ai : pi.getAnnotations())
-                               if (filter == null || filter.test(ai))
-                                       action.accept(ai);
-       }
-
-       private static void forEachDeclaredMethodAnnotationInfo(MethodInfo 
methodInfo, ClassInfo ci, Predicate<AnnotationInfo<?>> filter, 
Consumer<AnnotationInfo<?>> action) {
-               MethodInfo mi = methodInfo.findMatchingOnClass(ci);
-               if (nn(mi))
-                       mi.getDeclaredAnnotationInfos().forEach(ai -> {
-                               if (filter == null || filter.test(ai))
-                                       action.accept(ai);
-                       });
-       }
-
        /**
         * Returns <jk>true</jk> if this annotation has the specified simple 
name.
         *
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ClassInfo.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ClassInfo.java
index 11767a3651..1ff4436cee 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ClassInfo.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ClassInfo.java
@@ -752,6 +752,47 @@ public class ClassInfo extends ElementInfo implements 
Annotatable {
                        .map(a -> (AnnotationInfo<A>)a);
        }
 
+       /**
+        * Performs an action on all matching annotations on this class and 
parent classes/interfaces.
+        *
+        * <p>
+        * Annotations are consumed in the following order:
+        * <ol>
+        *      <li>On the package of this class.
+        *      <li>On interfaces ordered parent-to-child.
+        *      <li>On parent classes ordered parent-to-child.
+        *      <li>On this class.
+        * </ol>
+        *
+        * @param filter A predicate to apply to the entries to determine if 
action should be performed.  Can be <jk>null</jk>.
+        * @param action An action to perform on the entry.
+        * @return This object.
+        */
+       public ClassInfo forEachAnnotationInfo(Predicate<AnnotationInfo<?>> 
filter, Consumer<AnnotationInfo<?>> action) {
+               var pi = getPackage();
+               if (nn(pi))
+                       for (var ai : pi.getAnnotations())
+                               if (filter == null || filter.test(ai))
+                                       action.accept(ai);
+               var interfaces = getInterfaces();
+               for (int i = interfaces.size() - 1; i >= 0; i--)
+                       for (var a : 
interfaces.get(i).inner().getDeclaredAnnotations())
+                               for (var a2 : splitRepeated(a)) {
+                                       var ai = 
AnnotationInfo.of(interfaces.get(i), a2);
+                                       if (filter == null || filter.test(ai))
+                                               action.accept(ai);
+                               }
+               var parents = getParents();
+               for (int i = parents.size() - 1; i >= 0; i--)
+                       for (var a : 
parents.get(i).inner().getDeclaredAnnotations())
+                               for (var a2 : splitRepeated(a)) {
+                                       var ai = 
AnnotationInfo.of(parents.get(i), a2);
+                                       if (filter == null || filter.test(ai))
+                                               action.accept(ai);
+                               }
+               return this;
+       }
+
        /**
         * Finds annotations on this class using the specified traversal 
settings.
         *
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/MethodInfo.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/MethodInfo.java
index fa319ca42d..145c80c5a2 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/MethodInfo.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/MethodInfo.java
@@ -171,6 +171,62 @@ public class MethodInfo extends ExecutableInfo implements 
Comparable<MethodInfo>
                        .map(a -> (AnnotationInfo<A>)a);
        }
 
+       /**
+        * Performs an action on all matching annotations on this method.
+        *
+        * <p>
+        * Processes annotations on:
+        * <ul>
+        *      <li>Package of the declaring class
+        *      <li>Interfaces (and their methods) in parent-to-child order
+        *      <li>Parent classes (and their methods) in parent-to-child order
+        * </ul>
+        *
+        * @param filter A predicate to apply to the entries to determine if 
action should be performed.  Can be <jk>null</jk>.
+        * @param action An action to perform on the entry.
+        * @return This object.
+        */
+       public MethodInfo forEachAnnotationInfo(Predicate<AnnotationInfo<?>> 
filter, Consumer<AnnotationInfo<?>> action) {
+               var c = getDeclaringClass();
+               forEachDeclaredAnnotationInfo(c.getPackage(), filter, action);
+               var interfaces = c.getInterfaces();
+               for (int i = interfaces.size() - 1; i >= 0; i--) {
+                       forEachDeclaredAnnotationInfo(interfaces.get(i), 
filter, action);
+                       forEachDeclaredMethodAnnotationInfo(this, 
interfaces.get(i), filter, action);
+               }
+               var parents = c.getParents();
+               for (int i = parents.size() - 1; i >= 0; i--) {
+                       forEachDeclaredAnnotationInfo(parents.get(i), filter, 
action);
+                       forEachDeclaredMethodAnnotationInfo(this, 
parents.get(i), filter, action);
+               }
+               return this;
+       }
+
+       /**
+        * Performs an action on all matching annotations on methods only.
+        *
+        * <p>
+        * Processes annotations on:
+        * <ul>
+        *      <li>Matching methods in interfaces in parent-to-child order
+        *      <li>Matching methods in parent classes in parent-to-child order
+        * </ul>
+        *
+        * @param filter A predicate to apply to the entries to determine if 
action should be performed.  Can be <jk>null</jk>.
+        * @param action An action to perform on the entry.
+        * @return This object.
+        */
+       public MethodInfo 
forEachAnnotationInfoMethodOnly(Predicate<AnnotationInfo<?>> filter, 
Consumer<AnnotationInfo<?>> action) {
+               var c = getDeclaringClass();
+               var interfaces = c.getInterfaces();
+               for (int i = interfaces.size() - 1; i >= 0; i--)
+                       forEachDeclaredMethodAnnotationInfo(this, 
interfaces.get(i), filter, action);
+               var parents = c.getParents();
+               for (int i = parents.size() - 1; i >= 0; i--)
+                       forEachDeclaredMethodAnnotationInfo(this, 
parents.get(i), filter, action);
+               return this;
+       }
+
        /**
         * Finds annotations on this method using the specified traversal 
settings.
         *
@@ -789,6 +845,33 @@ public class MethodInfo extends ExecutableInfo implements 
Comparable<MethodInfo>
                return null;
        }
 
+       
//-----------------------------------------------------------------------------------------------------------------
+       // Helper methods for forEachAnnotationInfo
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       private static void forEachDeclaredAnnotationInfo(ClassInfo ci, 
Predicate<AnnotationInfo<?>> filter, Consumer<AnnotationInfo<?>> action) {
+               if (nn(ci))
+                       for (var ai : ci.getDeclaredAnnotationInfos())
+                               if (filter == null || filter.test(ai))
+                                       action.accept(ai);
+       }
+
+       private static void forEachDeclaredAnnotationInfo(PackageInfo pi, 
Predicate<AnnotationInfo<?>> filter, Consumer<AnnotationInfo<?>> action) {
+               if (nn(pi))
+                       for (var ai : pi.getAnnotations())
+                               if (filter == null || filter.test(ai))
+                                       action.accept(ai);
+       }
+
+       private static void forEachDeclaredMethodAnnotationInfo(MethodInfo 
methodInfo, ClassInfo ci, Predicate<AnnotationInfo<?>> filter, 
Consumer<AnnotationInfo<?>> action) {
+               MethodInfo mi = methodInfo.findMatchingOnClass(ci);
+               if (nn(mi))
+                       mi.getDeclaredAnnotationInfos().forEach(ai -> {
+                               if (filter == null || filter.test(ai))
+                                       action.accept(ai);
+                       });
+       }
+
        
//-----------------------------------------------------------------------------------------------------------------
        // Annotatable interface methods
        
//-----------------------------------------------------------------------------------------------------------------

Reply via email to