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 c96cc884c4 Utility class modernization
c96cc884c4 is described below

commit c96cc884c4da75babbe49cf2e25ee14e338b4116
Author: James Bognar <[email protected]>
AuthorDate: Thu Nov 6 08:20:40 2025 -0500

    Utility class modernization
---
 .../apache/juneau/common/reflect/MethodInfo.java   | 42 +++-------------------
 .../apache/juneau/common/utils/PredicateUtils.java | 27 ++++++++++++++
 .../httppart/bean/RequestBeanPropertyMeta.java     |  4 +--
 .../juneau/httppart/bean/ResponseBeanMeta.java     |  6 ++--
 .../java/org/apache/juneau/rest/RestContext.java   | 10 +++---
 .../java/org/apache/juneau/rest/RestOpContext.java | 16 +++++----
 .../rest/swagger/BasicSwaggerProviderSession.java  |  4 +--
 .../juneau/common/reflect/MethodInfo_Test.java     | 11 ++----
 8 files changed, 55 insertions(+), 65 deletions(-)

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 180eddb967..960f8d52cb 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
@@ -429,27 +429,9 @@ public class MethodInfo extends ExecutableInfo implements 
Comparable<MethodInfo>
                getReturnType().unwrap(Value.class, 
Optional.class).forEachAnnotation(annotationProvider, type, filter, action);
        }
 
-       /**
-        * Performs an action on all matching annotations defined on this 
method.
-        *
-        * <p>
-        * Searches all methods with the same signature on the parent classes 
or interfaces
-        * and the return type on the method.
-        * <br>Results are parent-to-child ordered.
-        *
-        * @param <A> The annotation type to look for.
-        * @param type The annotation to look for.
-        * @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 <A extends Annotation> void forEachAnnotation(Class<A> type, 
Predicate<A> filter, Consumer<A> action) {
-               rstream(getAllAnnotationInfos())
-                       .filter(x -> x.isType(type))
-                       .map(AnnotationInfo::inner)
-                       .map(x -> (A)x)
-                       .filter(x -> filter == null || filter.test(x))
-                       .forEach(action);
+       public <A extends Annotation> Stream<AnnotationInfo<A>> 
getAllAnnotationInfosParentFirst(Class<A> type) {
+               return rstream(getAllAnnotationInfos())
+                       .flatMap(type(type));
        }
 
        public Stream<MethodInfo> getMatching() {
@@ -480,22 +462,6 @@ public class MethodInfo extends ExecutableInfo implements 
Comparable<MethodInfo>
                        .orElse(null);
        }
 
-       /**
-        * Finds the annotation of the specified type defined on this method.
-        *
-        * <p>
-        * If this is a method and the annotation cannot be found on the 
immediate method, searches methods with the same
-        * signature on the parent classes or interfaces.
-        * <br>The search is performed in child-to-parent order.
-        *
-        * @param <A> The annotation type to look for.
-        * @param type The annotation to look for.
-        * @return The annotation if found, or <jk>null</jk> if not.
-        */
-       public <A extends Annotation> A getAnnotation(Class<A> type) {
-               return getAnnotation(AnnotationProvider.DEFAULT, type);
-       }
-
        /**
         * Constructs an {@link AnnotationList} of all annotations found on 
this method.
         *
@@ -544,7 +510,7 @@ public class MethodInfo extends ExecutableInfo implements 
Comparable<MethodInfo>
        @SafeVarargs
        public final Annotation getAnyAnnotation(Class<? extends 
Annotation>...types) {
                return Arrays.stream(types)
-                       .map(this::getAnnotation)
+                       .map(t -> 
getAnnotationInfos(t).findFirst().map(AnnotationInfo::inner).orElse(null))
                        .filter(Objects::nonNull)
                        .findFirst()
                        .orElse(null);
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/PredicateUtils.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/PredicateUtils.java
index 8c69cd5fd4..abcddef974 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/PredicateUtils.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/PredicateUtils.java
@@ -18,7 +18,9 @@ package org.apache.juneau.common.utils;
 
 import static org.apache.juneau.common.utils.Utils.*;
 
+import java.lang.annotation.*;
 import java.util.function.*;
+import java.util.stream.*;
 
 import org.apache.juneau.common.reflect.*;
 
@@ -241,4 +243,29 @@ public final class PredicateUtils {
        public static Predicate<ElementInfo> isAny(ElementFlag...flags) {
                return ei -> ei.isAny(flags);
        }
+
+       /**
+        * Returns a function that filters and casts {@link AnnotationInfo} 
objects to a specific annotation type.
+        *
+        * <p>
+        * This function is designed to be used with {@link 
Stream#flatMap(Function)} to both filter and type-cast
+        * in a single operation.
+        *
+        * <h5 class='section'>Example:</h5>
+        * <p class='bjava'>
+        *      List&lt;AnnotationInfo&lt;Annotation&gt;&gt; annotations = ...;
+        *      List&lt;MyAnnotation&gt; myAnnotations = annotations.stream()
+        *              .flatMap(type(MyAnnotation.<jk>class</jk>))
+        *              .map(AnnotationInfo::inner)
+        *              .collect(Collectors.toList());
+        * </p>
+        *
+        * @param <A> The annotation type.
+        * @param annotationType The annotation class to filter and cast to.
+        * @return A function that returns a stream containing the annotation 
if it matches the type, or an empty stream otherwise.
+        */
+       @SuppressWarnings("unchecked")
+       public static <A extends Annotation> Function<AnnotationInfo<?>, 
Stream<AnnotationInfo<A>>> type(Class<A> annotationType) {
+               return ai -> ai.isType(annotationType) ? 
Stream.of((AnnotationInfo<A>)ai) : Stream.empty();
+       }
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/RequestBeanPropertyMeta.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/RequestBeanPropertyMeta.java
index 11db51e47b..7e0a86f76e 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/RequestBeanPropertyMeta.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/RequestBeanPropertyMeta.java
@@ -64,8 +64,8 @@ public class RequestBeanPropertyMeta {
 
        static RequestBeanPropertyMeta.Builder create(HttpPartType partType, 
Class<? extends Annotation> c, MethodInfo m) {
                HttpPartSchema.Builder sb = 
HttpPartSchema.create().name(m.getPropertyName());
-               m.forEachAnnotation(Schema.class, x -> true, x -> sb.apply(x));
-               m.forEachAnnotation(c, x -> true, x -> sb.apply(x));
+               
m.getAllAnnotationInfosParentFirst(Schema.class).map(AnnotationInfo::inner).forEach(x
 -> sb.apply(x));
+               
m.getAllAnnotationInfosParentFirst(c).map(AnnotationInfo::inner).forEach(x -> 
sb.apply(x));
                return new 
Builder().partType(partType).schema(sb.build()).getter(m.inner());
        }
 
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanMeta.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanMeta.java
index 63e10ea0d8..13f5f9d20d 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanMeta.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanMeta.java
@@ -86,7 +86,7 @@ public class ResponseBeanMeta {
                                if (x.hasAnnotation(Header.class)) {
                                        assertNoArgs(x, Header.class);
                                        assertReturnNotVoid(x, Header.class);
-                                       var s = 
HttpPartSchema.create(x.getAnnotation(Header.class), x.getPropertyName());
+                                       var s = 
HttpPartSchema.create(x.getAnnotationInfos(Header.class).findFirst().map(AnnotationInfo::inner).orElse(null),
 x.getPropertyName());
                                        headerMethods.put(s.getName(), 
ResponseBeanPropertyMeta.create(RESPONSE_HEADER, s, x));
                                } else if (x.hasAnnotation(StatusCode.class)) {
                                        assertNoArgs(x, Header.class);
@@ -125,8 +125,8 @@ public class ResponseBeanMeta {
                        return null;
                var b = new Builder(annotations);
                b.apply(m.getReturnType().unwrap(Value.class, 
Optional.class).innerType());
-               m.forEachAnnotation(Response.class, x -> true, x -> b.apply(x));
-               m.forEachAnnotation(StatusCode.class, x -> true, x -> 
b.apply(x));
+               
m.getAllAnnotationInfosParentFirst(Response.class).map(AnnotationInfo::inner).forEach(x
 -> b.apply(x));
+               
m.getAllAnnotationInfosParentFirst(StatusCode.class).map(AnnotationInfo::inner).forEach(x
 -> b.apply(x));
                return b.build();
        }
 
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index 7cbe61e5b9..66fd11f4b2 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -204,7 +204,9 @@ public class RestContext extends Context {
                        // @formatter:off
                        ClassInfo.ofProxy(r).getAllMethodsParentFirst().stream()
                                .filter(y -> y.hasAnnotation(annotation))
-                               .forEach(y -> y.forEachAnnotation(annotation, 
predicate, z -> x.put(y.getSignature(), y.accessible().inner())));
+                               .forEach(y -> 
y.getAllAnnotationInfosParentFirst(annotation).map(AnnotationInfo::inner)
+                                       .filter(z -> predicate == null || 
predicate.test(z))
+                                       .forEach(z -> x.put(y.getSignature(), 
y.accessible().inner())));
                        // @formatter:on
 
                        var x2 = MethodList.of(x.values());
@@ -212,12 +214,12 @@ public class RestContext extends Context {
                }
 
                private static boolean isRestBeanMethod(MethodInfo mi) {
-                       var x = mi.getAnnotation(RestInject.class);
+                       var x = 
mi.getAnnotationInfos(RestInject.class).findFirst().map(AnnotationInfo::inner).orElse(null);
                        return nn(x) && x.methodScope().length == 0;
                }
 
                private static boolean isRestBeanMethod(MethodInfo mi, String 
name) {
-                       var x = mi.getAnnotation(RestInject.class);
+                       var x = 
mi.getAnnotationInfos(RestInject.class).findFirst().map(AnnotationInfo::inner).orElse(null);
                        return nn(x) && x.methodScope().length == 0 && 
x.name().equals(name);
                }
 
@@ -1770,7 +1772,7 @@ public class RestContext extends Context {
 
                        rci.getMethods().stream().filter(x -> 
x.hasAnnotation(RestInject.class)).forEach(x -> {
                                var rt = x.getReturnType().<Object>inner();
-                               var name = 
RestInjectAnnotation.name(x.getAnnotation(RestInject.class));
+                               var name = 
RestInjectAnnotation.name(x.getAnnotationInfos(RestInject.class).findFirst().map(AnnotationInfo::inner).orElse(null));
                                if (! (DELAYED_INJECTION.contains(rt) || 
DELAYED_INJECTION_NAMES.contains(name))) {
                                        // @formatter:off
                                        beanStore
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
index 34f0bb7779..887e1684fd 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
@@ -1307,18 +1307,18 @@ public class RestOpContext extends Context implements 
Comparable<RestOpContext>
                }
 
        private boolean matches(MethodInfo annotated) {
-               var a = annotated.getAnnotation(RestInject.class);
+               var a = 
annotated.getAnnotationInfos(RestInject.class).findFirst().map(AnnotationInfo::inner).orElse(null);
                if (nn(a)) {
                        for (var n : a.methodScope()) {
-                                       if ("*".equals(n) || 
restMethod.getName().equals(n))
-                                               return true;
-                               }
+                               if ("*".equals(n) || 
restMethod.getName().equals(n))
+                                       return true;
                        }
-                       return false;
                }
+               return false;
+       }
 
        private boolean matches(MethodInfo annotated, String beanName) {
-               var a = annotated.getAnnotation(RestInject.class);
+               var a = 
annotated.getAnnotationInfos(RestInject.class).findFirst().map(AnnotationInfo::inner).orElse(null);
                if (nn(a)) {
                        if (! a.name().equals(beanName))
                                return false;
@@ -1948,7 +1948,9 @@ public class RestOpContext extends Context implements 
Comparable<RestOpContext>
                                httpMethod = "delete";
                        else if (mi.hasAnnotation(RestOp.class)) {
                                var _httpMethod = Value.<String>empty();
-                               mi.forEachAnnotation(RestOp.class, x -> 
isNotEmpty(x.method()), x -> _httpMethod.set(x.method()));
+                               
mi.getAllAnnotationInfosParentFirst(RestOp.class).map(AnnotationInfo::inner)
+                                       .filter(x -> isNotEmpty(x.method()))
+                                       .forEach(x -> 
_httpMethod.set(x.method()));
                                httpMethod = _httpMethod.orElse(null);
                        }
 
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/swagger/BasicSwaggerProviderSession.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/swagger/BasicSwaggerProviderSession.java
index c32fe9b182..2d3e97877c 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/swagger/BasicSwaggerProviderSession.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/swagger/BasicSwaggerProviderSession.java
@@ -447,7 +447,7 @@ public class BasicSwaggerProviderSession {
                                        List<MethodInfo> methods = 
eci.getMethods();
                                        for (int i = methods.size() - 1; i >= 
0; i--) {
                                                MethodInfo ecmi = 
methods.get(i);
-                                               Header a = 
ecmi.getAnnotation(Header.class);
+                                               Header a = 
ecmi.getAnnotationInfos(Header.class).findFirst().map(AnnotationInfo::inner).orElse(null);
                                                if (a == null)
                                                        a = 
ecmi.getReturnType().unwrap(Value.class, 
Optional.class).getAnnotation(Header.class);
                                                if (nn(a) && ! isMulti(a)) {
@@ -485,7 +485,7 @@ public class BasicSwaggerProviderSession {
                                        for (int i = methods.size() - 1; i >= 
0; i--) {
                                                MethodInfo ecmi = 
methods.get(i);
                                                if 
(ecmi.hasAnnotation(Header.class)) {
-                                                       Header a = 
ecmi.getAnnotation(Header.class);
+                                                       Header a = 
ecmi.getAnnotationInfos(Header.class).findFirst().map(AnnotationInfo::inner).orElse(null);
                                                        String ha = a.name();
                                                        if (! isMulti(a)) {
                                                                for (var code : 
codes) {
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/common/reflect/MethodInfo_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/MethodInfo_Test.java
index bc0b62a81a..11e2da9d19 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/common/reflect/MethodInfo_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/MethodInfo_Test.java
@@ -354,18 +354,11 @@ class MethodInfo_Test extends TestBase {
 
        private static List<A> annotations(MethodInfo mi, Class<? extends 
Annotation> a) {
                var l = new ArrayList<A>();
-               mi.forEachAnnotation(a, x -> true, x -> l.add((A)x));
+               
mi.getAllAnnotationInfosParentFirst(a).map(AnnotationInfo::inner)
+                       .forEach(x -> l.add((A)x));
                return l;
        }
 
-       @Test void getAnnotation() {
-               check("@A(a1)", c_a1.getAnnotation(A.class));
-               check("@A(a2b)", c_a2.getAnnotation(A.class));
-               check("@A(a3)", c_a3.getAnnotation(A.class));
-               check("@A(a4)", c_a4.getAnnotation(A.class));
-               check(null, c_a5.getAnnotation(A.class));
-       }
-
        @Test void getAnnotationAny() {
                check("@A(a1)", c_a1.getAnyAnnotation(AX.class, A.class));
                check("@A(a2b)", c_a2.getAnyAnnotation(AX.class, A.class));

Reply via email to