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

commit eba60810266597e6556fa8def32b3ce75c2b2b6b
Author: James Bognar <[email protected]>
AuthorDate: Fri Nov 7 12:01:42 2025 -0500

    Utility class modernization
---
 .../apache/juneau/common/reflect/ClassInfo.java    | 155 ++++++++++++---------
 .../src/main/java/org/apache/juneau/ClassMeta.java |   6 +-
 .../rest/swagger/BasicSwaggerProviderSession.java  |  12 +-
 3 files changed, 101 insertions(+), 72 deletions(-)

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 e146541421..2910136166 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
@@ -187,7 +187,7 @@ public class ClassInfo extends ElementInfo implements 
Annotatable {
        private final Supplier<ClassInfo> componentType;  // Base component 
type for arrays (e.g., String for String[][]), also handles GenericArrayType.  
Cached and never null.
        private final Supplier<PackageInfo> packageInfo;  // The package this 
class belongs to (null for primitive types and arrays).
        private final Supplier<List<ClassInfo>> parents;  // All superclasses 
of this class in child-to-parent order, starting with this class.
-       private final Supplier<List<AnnotationInfo>> declaredAnnotations2;  // 
All annotations declared directly on this class, wrapped in AnnotationInfo.
+       private final Supplier<List<AnnotationInfo>> declaredAnnotations;  // 
All annotations declared directly on this class, wrapped in AnnotationInfo.
        private final Supplier<String> fullName;  // Fully qualified class name 
with generics (e.g., "java.util.List<java.lang.String>").
        private final Supplier<String> shortName;  // Simple class name with 
generics (e.g., "List<String>").
        private final Supplier<String> readableName;  // Human-readable class 
name without generics (e.g., "List").
@@ -230,7 +230,7 @@ public class ClassInfo extends ElementInfo implements 
Annotatable {
                this.componentType = memoize(this::findComponentType);
                this.packageInfo = memoize(() -> opt(inner).map(x -> 
PackageInfo.of(x.getPackage())).orElse(null));
                this.parents = memoize(this::findParents);
-               this.declaredAnnotations2 = memoize(() -> 
(List)opt(inner).map(x -> 
u(l(x.getDeclaredAnnotations()))).orElse(liste()).stream().map(a -> 
AnnotationInfo.of(this, a)).toList());
+               this.declaredAnnotations = memoize(() -> (List)opt(inner).map(x 
-> u(l(x.getDeclaredAnnotations()))).orElse(liste()).stream().map(a -> 
AnnotationInfo.of(this, a)).toList());
                this.fullName = memoize(() -> getNameFormatted(FULL, true, '$', 
BRACKETS));
                this.shortName = memoize(() -> getNameFormatted(SHORT, true, 
'$', BRACKETS));
                this.readableName = memoize(() -> getNameFormatted(SIMPLE, 
false, '$', WORD));
@@ -365,20 +365,6 @@ public class ClassInfo extends ElementInfo implements 
Annotatable {
        /**
         * Returns all annotations of the specified type defined on this or 
parent classes/interfaces.
         *
-        * <p>
-        * Returns the list in reverse (parent-to-child) order.
-        *
-        * @param <A> The annotation type to look for.
-        * @param annotationProvider The annotation provider.
-        * @param type The annotation type to look for.
-        * @return The matching annotations.
-        */
-       public <A extends Annotation> List<A> getAnnotations(AnnotationProvider 
annotationProvider, Class<A> type) {
-               List<A> l = list();
-               forEachAnnotation(annotationProvider, type, x -> true, x -> 
l.add(x));
-               return l;
-       }
-
        /**
         * Returns the {@link ClassLoader} for this class.
         *
@@ -414,7 +400,22 @@ public class ClassInfo extends ElementInfo implements 
Annotatable {
         * represented by this class.
         *
         * <p>
-        * Returns <jk>null</jk> if this class is not a member class.
+        * This method returns the class in which this class is explicitly 
declared as a member.
+        * It only returns non-null for <b>member classes</b> (static and 
non-static nested classes).
+        *
+        * <p>
+        * <h5 class='section'>Examples:</h5>
+        * <ul class='spaced-list'>
+        *      <li><c>class Outer { class Inner {} }</c> - 
<c>Inner.getDeclaringClass()</c> returns <c>Outer</c>
+        *      <li><c>class Outer { static class Nested {} }</c> - 
<c>Nested.getDeclaringClass()</c> returns <c>Outer</c>
+        *      <li><c>class Outer { void method() { class Local {} } }</c> - 
<c>Local.getDeclaringClass()</c> returns <jk>null</jk>
+        *      <li>Top-level class - <c>getDeclaringClass()</c> returns 
<jk>null</jk>
+        *      <li>Anonymous class - <c>getDeclaringClass()</c> returns 
<jk>null</jk>
+        * </ul>
+        *
+        * <h5 class='section'>See Also:</h5><ul>
+        *      <li class='ja'>{@link #getEnclosingClass()} - Returns the 
immediately enclosing class (works for local and anonymous classes too)
+        * </ul>
         *
         * @return The declaring class, or <jk>null</jk> if this class is not a 
member of another class.
         */
@@ -528,7 +529,30 @@ public class ClassInfo extends ElementInfo implements 
Annotatable {
         * Returns the immediately enclosing class of this class.
         *
         * <p>
-        * Returns <jk>null</jk> if this class is a top-level class.
+        * This method returns the lexically enclosing class, regardless of 
whether this class is a member,
+        * local, or anonymous class. Unlike {@link #getDeclaringClass()}, this 
method works for all types of nested classes.
+        *
+        * <p>
+        * <h5 class='section'>Examples:</h5>
+        * <ul class='spaced-list'>
+        *      <li><c>class Outer { class Inner {} }</c> - 
<c>Inner.getEnclosingClass()</c> returns <c>Outer</c>
+        *      <li><c>class Outer { static class Nested {} }</c> - 
<c>Nested.getEnclosingClass()</c> returns <c>Outer</c>
+        *      <li><c>class Outer { void method() { class Local {} } }</c> - 
<c>Local.getEnclosingClass()</c> returns <c>Outer</c>
+        *      <li><c>class Outer { void method() { new Runnable() {...} } 
}</c> - Anonymous class <c>getEnclosingClass()</c> returns <c>Outer</c>
+        *      <li>Top-level class - <c>getEnclosingClass()</c> returns 
<jk>null</jk>
+        * </ul>
+        *
+        * <h5 class='section'>Differences from {@link 
#getDeclaringClass()}:</h5>
+        * <ul class='spaced-list'>
+        *      <li><c>getDeclaringClass()</c> - Returns non-null only for 
member classes (static or non-static nested classes)
+        *      <li><c>getEnclosingClass()</c> - Returns non-null for all 
nested classes (member, local, and anonymous)
+        * </ul>
+        *
+        * <h5 class='section'>See Also:</h5><ul>
+        *      <li class='ja'>{@link #getDeclaringClass()} - Returns the 
declaring class (only for member classes)
+        *      <li class='ja'>{@link #getEnclosingConstructor()} - Returns the 
enclosing constructor (for classes defined in constructors)
+        *      <li class='ja'>{@link #getEnclosingMethod()} - Returns the 
enclosing method (for classes defined in methods)
+        * </ul>
         *
         * @return The enclosing class, or <jk>null</jk> if this is a top-level 
class.
         */
@@ -2035,49 +2059,6 @@ public class ClassInfo extends ElementInfo implements 
Annotatable {
                return nn(inner) && v.isVisible(inner);
        }
 
-       /**
-        * Returns the last matching annotation on this class and 
superclasses/interfaces.
-        *
-        * <p>
-        * Annotations are searched in the following orders:
-        * <ol>
-        *      <li>On this class.
-        *      <li>On parent classes ordered child-to-parent.
-        *      <li>On interfaces ordered child-to-parent.
-        *      <li>On the package of this class.
-        * </ol>
-        *
-        * @param <A> The annotation type to look for.
-        * @param annotationProvider The annotation provider.
-        * @param type The annotation to look for.
-        * @param filter A predicate to apply to the entries to determine if 
annotation should be returned.  Can be <jk>null</jk>.
-        * @return This object.
-        */
-       public <A extends Annotation> A lastAnnotation(AnnotationProvider 
annotationProvider, Class<A> type, Predicate<A> filter) {
-               if (annotationProvider == null)
-                       throw unsupportedOp();
-               A x = null;
-               x = annotationProvider.find(type, inner()).map(y -> 
y.inner()).filter(y -> filter.test(y)).findFirst().orElse(null);
-               if (nn(x) && test(filter, x))
-                       return x;
-               var parents2 = parents.get();
-               for (var parent : parents2) {
-                       x = annotationProvider.find(type, parent.inner()).map(y 
-> y.inner()).filter(y -> filter.test(y)).findFirst().orElse(null);
-                       if (nn(x))
-                               return x;
-               }
-               var interfaces2 = interfaces.get();
-               for (var element : interfaces2) {
-                       x = annotationProvider.find(type, 
element.inner()).map(y -> y.inner()).filter(y -> 
filter.test(y)).findFirst().orElse(null);
-                       if (nn(x))
-                               return x;
-               }
-               x = getPackageAnnotation(type);
-               if (nn(x) && test(filter, x))
-                       return x;
-               return null;
-       }
-
        /**
         * Returns the last matching annotation on this class and 
superclasses/interfaces.
         *
@@ -2099,13 +2080,13 @@ public class ClassInfo extends ElementInfo implements 
Annotatable {
                // Inline implementation using reflection directly instead of 
delegating to AnnotationProvider
                if (!nn(type))
                        return null;
-               
+
                // Search annotations using reflection (reverse order for 
"last")
                var annotations = rstream(l(inner.getAnnotationsByType(type)));
                var result = annotations.filter(a -> test(filter, 
a)).findFirst().orElse(null);
                if (nn(result))
                        return result;
-               
+
                // Search parents
                var parents2 = parents.get();
                for (var parent : parents2) {
@@ -2114,7 +2095,7 @@ public class ClassInfo extends ElementInfo implements 
Annotatable {
                        if (nn(result))
                                return result;
                }
-               
+
                // Search interfaces
                var interfaces2 = interfaces.get();
                for (var iface : interfaces2) {
@@ -2123,7 +2104,7 @@ public class ClassInfo extends ElementInfo implements 
Annotatable {
                        if (nn(result))
                                return result;
                }
-               
+
                // Search package
                return getPackageAnnotation(type);
        }
@@ -2258,17 +2239,59 @@ public class ClassInfo extends ElementInfo implements 
Annotatable {
         *      <br>Results are in declaration order.
         */
        public List<AnnotationInfo> getDeclaredAnnotationInfos() {
-               return declaredAnnotations2.get();
+               return declaredAnnotations.get();
        }
 
+       /**
+        * Returns a {@link ConstructorInfo} wrapper for the specified raw 
{@link Constructor} object.
+        *
+        * <p>
+        * This is an internal method used to wrap raw reflection objects into 
their cached Info wrappers.
+        * The wrappers provide additional functionality and are cached to 
avoid creating duplicate objects.
+        *
+        * <p>
+        * This method is called internally when building the lists of 
constructors (public, declared, etc.)
+        * and ensures that the same {@link Constructor} object always maps to 
the same {@link ConstructorInfo} instance.
+        *
+        * @param x The raw constructor to wrap.
+        * @return The cached {@link ConstructorInfo} wrapper for this 
constructor.
+        */
        ConstructorInfo getConstructorInfo(Constructor<?> x) {
                return constructorCache.get(x, () -> new ConstructorInfo(this, 
x));
        }
 
+       /**
+        * Returns a {@link FieldInfo} wrapper for the specified raw {@link 
Field} object.
+        *
+        * <p>
+        * This is an internal method used to wrap raw reflection objects into 
their cached Info wrappers.
+        * The wrappers provide additional functionality and are cached to 
avoid creating duplicate objects.
+        *
+        * <p>
+        * This method is called internally when building the lists of fields 
(public, declared, all, etc.)
+        * and ensures that the same {@link Field} object always maps to the 
same {@link FieldInfo} instance.
+        *
+        * @param x The raw field to wrap.
+        * @return The cached {@link FieldInfo} wrapper for this field.
+        */
        FieldInfo getFieldInfo(Field x) {
                return fieldCache.get(x, () -> new FieldInfo(this, x));
        }
 
+       /**
+        * Returns a {@link MethodInfo} wrapper for the specified raw {@link 
Method} object.
+        *
+        * <p>
+        * This is an internal method used to wrap raw reflection objects into 
their cached Info wrappers.
+        * The wrappers provide additional functionality and are cached to 
avoid creating duplicate objects.
+        *
+        * <p>
+        * This method is called internally when building the lists of methods 
(public, declared, all, etc.)
+        * and ensures that the same {@link Method} object always maps to the 
same {@link MethodInfo} instance.
+        *
+        * @param x The raw method to wrap.
+        * @return The cached {@link MethodInfo} wrapper for this method.
+        */
        MethodInfo getMethodInfo(Method x) {
                return methodCache.get(x, () -> new MethodInfo(this, x));
        }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
index a85d798456..201c8e3331 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
@@ -466,7 +466,8 @@ public class ClassMeta<T> implements Type {
 
                private BeanFilter findBeanFilter(BeanContext bc) {
                        try {
-                               List<Bean> ba = 
info.getAnnotations(bc.getAnnotationProvider(), Bean.class);
+                               List<Bean> ba = list();
+                               
info.forEachAnnotation(bc.getAnnotationProvider(), Bean.class, x -> true, x -> 
ba.add(x));
                                if (! ba.isEmpty())
                                        return 
BeanFilter.create(innerClass).applyAnnotations(ba).build();
                        } catch (Exception e) {
@@ -481,7 +482,8 @@ public class ClassMeta<T> implements Type {
 
                private MarshalledFilter findMarshalledFilter(BeanContext bc) {
                        try {
-                               List<Marshalled> ba = 
info.getAnnotations(bc.getAnnotationProvider(), Marshalled.class);
+                               List<Marshalled> ba = list();
+                               
info.forEachAnnotation(bc.getAnnotationProvider(), Marshalled.class, x -> true, 
x -> ba.add(x));
                                if (! ba.isEmpty())
                                        return 
MarshalledFilter.create(innerClass).applyAnnotations(ba).build();
                        } catch (Exception e) {
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 5c0f2fd34c..065977e041 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
@@ -156,8 +156,10 @@ public class BasicSwaggerProviderSession {
                        omSwagger = new JsonMap();
 
                // Combine it with @Rest(swagger)
-               for (var rr : 
rci.getAnnotations(context.getAnnotationProvider(), Rest.class)) {
-
+               List<Rest> restAnnotations = list();
+               rci.forEachAnnotation(context.getAnnotationProvider(), 
Rest.class, x -> true, x -> restAnnotations.add(x));
+               for (var rr : restAnnotations) {
+       
                        JsonMap sInfo = omSwagger.getMap("info", true);
 
                        sInfo
@@ -432,8 +434,10 @@ public class BasicSwaggerProviderSession {
 
                        for (var eci : mi.getExceptionTypes()) {
                                if (eci.hasAnnotation(Response.class)) {
-                                       List<Response> la = 
eci.getAnnotations(context.getAnnotationProvider(), Response.class);
-                                       List<StatusCode> la2 = 
eci.getAnnotations(context.getAnnotationProvider(), StatusCode.class);
+                                       List<Response> la = list();
+                                       
eci.forEachAnnotation(context.getAnnotationProvider(), Response.class, x -> 
true, x -> la.add(x));
+                                       List<StatusCode> la2 = list();
+                                       
eci.forEachAnnotation(context.getAnnotationProvider(), StatusCode.class, x -> 
true, x -> la2.add(x));
                                        Set<Integer> codes = getCodes(la2, 500);
                                        for (var a : la) {
                                                for (var code : codes) {

Reply via email to