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

commit eb89b1c1ea8366d29c22ce07bf39c1824a72894f
Author: James Bognar <[email protected]>
AuthorDate: Thu Nov 6 10:18:47 2025 -0500

    Utility class modernization
---
 .../juneau/common/reflect/AnnotationInfo.java      | 35 +++++++++++++++
 .../apache/juneau/common/reflect/ClassInfo.java    | 31 ++++++++++++-
 .../apache/juneau/common/reflect/MethodInfo.java   |  2 +-
 .../java/org/apache/juneau/rest/RestContext.java   |  1 +
 .../java/org/apache/juneau/rest/RestOpContext.java | 34 ++++++++++++---
 .../juneau/common/reflect/ClassInfo_Test.java      | 51 ++++++++++++++++++++++
 6 files changed, 145 insertions(+), 9 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 01190f5137..39f4601155 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
@@ -258,6 +258,41 @@ public class AnnotationInfo<T extends Annotation> {
                return a.equals(o);
        }
 
+       /**
+        * Returns a simple string representation of this annotation showing 
the annotation type and location.
+        *
+        * <p>
+        * Format: {@code @AnnotationName(on=location)}
+        *
+        * <h5 class='section'>Examples:</h5>
+        * <ul>
+        *      <li>{@code @Rest(on=MyClass)} - Annotation on a class
+        *      <li>{@code @RestGet(on=MyClass.myMethod)} - Annotation on a 
method
+        *      <li>{@code @Inject(on=MyClass.myField)} - Annotation on a field
+        *      <li>{@code @PackageAnnotation(on=my.package)} - Annotation on a 
package
+        * </ul>
+        *
+        * @return A simple string representation of this annotation.
+        */
+       public String toSimpleString() {
+               var location = new StringBuilder();
+               var ci = annotatable.getClassInfo();
+
+               if (nn(ci)) {
+                       location.append(ci.getNameSimple());
+                       var type = annotatable.getAnnotatableType();
+                       if (type == AnnotatableType.METHOD_TYPE || type == 
AnnotatableType.FIELD_TYPE ||
+                               type == AnnotatableType.CONSTRUCTOR_TYPE || 
type == AnnotatableType.PARAMETER_TYPE) {
+                               
location.append('.').append(annotatable.getAnnotatableName());
+                       }
+               } else {
+                       // Package
+                       location.append(annotatable.getAnnotatableName());
+               }
+
+               return "@" + scn(a.annotationType()) + "(on=" + location + ")";
+       }
+
        /**
         * Returns a string representation of this annotation.
         *
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 651fe4a148..caf7530df4 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
@@ -262,7 +262,7 @@ public class ClassInfo extends ElementInfo implements 
Annotatable {
                        return;
 
                // Process parent interfaces recursively
-               var parentInterfaces = iface.getParents();
+               var parentInterfaces = iface.getDeclaredInterfaces();
                for (int i = 0; i < parentInterfaces.size(); i++)
                        addInterfaceHierarchy(set, parentInterfaces.get(i));
        }
@@ -878,6 +878,35 @@ public class ClassInfo extends ElementInfo implements 
Annotatable {
         * This is useful for annotation processing where you need to traverse 
the complete type hierarchy
         * without duplicates.
         *
+        * <h5 class='section'>Example:</h5>
+        * <p class='bjava'>
+        *      <jc>// Interface hierarchy:</jc>
+        *      <jk>interface</jk> ISuperGrandParent {}
+        *      <jk>interface</jk> IGrandParent <jk>extends</jk> 
ISuperGrandParent {}
+        *      <jk>interface</jk> ISuperParent {}
+        *      <jk>interface</jk> IParent <jk>extends</jk> ISuperParent {}
+        *      <jk>interface</jk> IChild {}
+        *
+        *      <jc>// Class hierarchy:</jc>
+        *      <jk>class</jk> GrandParent <jk>implements</jk> IGrandParent {}
+        *      <jk>class</jk> Parent <jk>extends</jk> GrandParent 
<jk>implements</jk> IParent {}
+        *      <jk>class</jk> Child <jk>extends</jk> Parent 
<jk>implements</jk> IChild {}
+        *
+        *      <jc>// For Child, returns (in this order):</jc>
+        *      ClassInfo <jv>ci</jv> = 
ClassInfo.<jsm>of</jsm>(Child.<jk>class</jk>);
+        *      List&lt;ClassInfo&gt; <jv>result</jv> = 
<jv>ci</jv>.getParentsAndInterfaces();
+        *      <jc>// Result: [</jc>
+        *      <jc>//   Child,                  // 1. This class</jc>
+        *      <jc>//   IChild,                 // 2. Interface on Child</jc>
+        *      <jc>//   Parent,                 // 3. Parent class</jc>
+        *      <jc>//   IParent,                // 4. Interface on Parent</jc>
+        *      <jc>//   ISuperParent,           // 5. Parent interface of 
IParent</jc>
+        *      <jc>//   GrandParent,            // 6. Grandparent class</jc>
+        *      <jc>//   IGrandParent,           // 7. Interface on 
GrandParent</jc>
+        *      <jc>//   ISuperGrandParent       // 8. Parent interface of 
IGrandParent</jc>
+        *      <jc>// ]</jc>
+        * </p>
+        *
         * @return An unmodifiable list of all parent classes and interfaces, 
properly ordered without duplicates.
         */
        public List<ClassInfo> getParentsAndInterfaces() { return 
parentsAndInterfaces.get(); }
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 793d8b280b..f5e522b3b4 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
@@ -99,7 +99,7 @@ public class MethodInfo extends ExecutableInfo implements 
Comparable<MethodInfo>
        // All annotations on this method and parent overridden methods in 
child-to-parent order.
        private final Supplier<List<AnnotationInfo<Annotation>>> 
annotationInfos = memoize(this::findAnnotationInfos);
 
-       // All annotations on declaring class, this method and parent 
overridden methods, and return type in child-to-parent order.
+       // All annotations on declaring class, this method and parent 
overridden methods, return type, and package in child-to-parent order.
        private final Supplier<List<AnnotationInfo<Annotation>>> 
allAnnotationInfos = memoize(this::findAllAnnotationInfos);
 
        /**
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 66fd11f4b2..e07988704a 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
@@ -604,6 +604,7 @@ public class RestContext extends Context {
                        try {
                                return 
beanStore().createBean(RestContext.class).type(getType().orElse(RestContext.class)).builder(RestContext.Builder.class,
 this).run();
                        } catch (Exception e) {
+                               e.printStackTrace();  // NOSONAR
                                throw new InternalServerError(e, "Could not 
instantiate RestContext.");
                        }
                }
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 887e1684fd..6af71590b6 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
@@ -34,6 +34,7 @@ import java.nio.charset.*;
 import java.util.*;
 import java.util.concurrent.*;
 import java.util.function.*;
+import java.util.stream.*;
 
 import org.apache.http.*;
 import org.apache.juneau.*;
@@ -126,15 +127,34 @@ public class RestOpContext extends Context implements 
Comparable<RestOpContext>
                        this.parent = context.builder;
                        this.restMethod = method;
 
-               this.beanStore = BeanStore.of(context.getBeanStore(), 
context.builder.resource().get()).addBean(java.lang.reflect.Method.class, 
method);
+                       this.beanStore = BeanStore.of(context.getBeanStore(), 
context.builder.resource().get()).addBean(java.lang.reflect.Method.class, 
method);
 
-               var mi = MethodInfo.of(context.getResourceClass(), method);
+                       var mi = MethodInfo.of(context.getResourceClass(), 
method);
 
-               try {
-
-                       var vr = context.getVarResolver();
-                       var vrs = vr.createSession();
-                       var work = AnnotationWorkList.of(vrs, 
mi.getAnnotationList(CONTEXT_APPLY_FILTER));
+                       try {
+                               var vr = context.getVarResolver();
+                               var vrs = vr.createSession();
+
+//                             var oldList = 
mi.getAnnotationList(CONTEXT_APPLY_FILTER);
+                               var newList = 
rstream(mi.getAllAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).collect(Collectors.toCollection(AnnotationList::new));
+                       
+//                     if (!oldList.equals(newList)) {
+//                             var sb = new StringBuilder();
+//                             sb.append("\n=== ANNOTATION MISMATCH for 
method: ").append(mi.getFullName()).append(" ===\n");
+//                             sb.append("OLD way size: 
").append(oldList.size()).append("\n");
+//                             sb.append("NEW way size: 
").append(newList.size()).append("\n");
+//                             sb.append("OLD way:\n");
+//                             oldList.forEach(x -> sb.append("  
").append(x.toSimpleString()).append("\n"));
+//                             sb.append("NEW way:\n");
+//                             newList.forEach(x -> sb.append("  
").append(x.toSimpleString()).append("\n"));
+//                             sb.append("In OLD but not NEW:\n");
+//                             oldList.stream().filter(x -> 
!newList.contains(x)).forEach(x -> sb.append("  - 
").append(x.toSimpleString()).append("\n"));
+//                             sb.append("In NEW but not OLD:\n");
+//                             newList.stream().filter(x -> 
!oldList.contains(x)).forEach(x -> sb.append("  + 
").append(x.toSimpleString()).append("\n"));
+//                             System.err.println(sb);
+//                     }
+
+                               var work = AnnotationWorkList.of(vrs, newList);
 
                                apply(work);
 
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/common/reflect/ClassInfo_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/ClassInfo_Test.java
index 9f655faafd..bc7dcede01 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/common/reflect/ClassInfo_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/ClassInfo_Test.java
@@ -1848,6 +1848,57 @@ public class ClassInfo_Test extends TestBase {
                }
        }
 
+       
//-----------------------------------------------------------------------------------------------------------------
+       // getParentsAndInterfaces tests
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       // Test hierarchy that mimics RootResources structure:
+       // - Child extends Parent implements IChild
+       // - Parent extends GrandParent implements IParent
+       // - GrandParent implements IGrandParent
+       // - IParent extends ISuperParent
+       // - IGrandParent extends ISuperGrandParent
+
+       interface ISuperGrandParent {}
+       interface IGrandParent extends ISuperGrandParent {}
+       interface ISuperParent {}
+       interface IParent extends ISuperParent {}
+       interface IChild {}
+       static class GrandParent implements IGrandParent {}
+       static class Parent extends GrandParent implements IParent {}
+       static class Child extends Parent implements IChild {}
+
+       @Test
+       void getParentsAndInterfaces_includesAllInterfaces() {
+               var ci = ClassInfo.of(Child.class);
+               var parentsAndInterfaces = ci.getParentsAndInterfaces();
+               
+               // Should include:
+               // 1. Child itself
+               // 2. IChild (direct interface on Child)
+               // 3. Parent (direct parent)
+               // 4. IParent (direct interface on Parent)
+               // 5. ISuperParent (parent interface of IParent)
+               // 6. GrandParent (parent's parent)
+               // 7. IGrandParent (direct interface on GrandParent)
+               // 8. ISuperGrandParent (parent interface of IGrandParent)
+               
+               var names = parentsAndInterfaces.stream()
+                       .map(ClassInfo::getNameSimple)
+                       .collect(Collectors.toList());
+               
+               // Verify all expected classes/interfaces are present
+               assertTrue(names.contains("Child"), "Should include Child 
itself");
+               assertTrue(names.contains("Parent"), "Should include Parent");
+               assertTrue(names.contains("GrandParent"), "Should include 
GrandParent");
+               
+               assertTrue(names.contains("IChild"), "Should include IChild");
+               assertTrue(names.contains("IParent"), "Should include IParent 
from Parent");
+               assertTrue(names.contains("ISuperParent"), "Should include 
ISuperParent from IParent hierarchy");
+               assertTrue(names.contains("IGrandParent"), "Should include 
IGrandParent from GrandParent");
+               assertTrue(names.contains("ISuperGrandParent"), "Should include 
ISuperGrandParent from IGrandParent hierarchy");
+       }
+
        
//-----------------------------------------------------------------------------------------------------------------
        // Other
        
//-----------------------------------------------------------------------------------------------------------------

Reply via email to