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<ClassInfo> <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
//-----------------------------------------------------------------------------------------------------------------