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 a273f2d8d0 Utility class modernization
a273f2d8d0 is described below
commit a273f2d8d0e16ec26eee1fb1f837fd487a79e48a
Author: James Bognar <[email protected]>
AuthorDate: Fri Nov 7 11:31:22 2025 -0500
Utility class modernization
---
.../apache/juneau/common/reflect/ClassInfo.java | 334 ++++++++++-----------
.../juneau/common/reflect/ExecutableInfo.java | 70 ++---
.../apache/juneau/common/reflect/FieldInfo.java | 16 +-
.../apache/juneau/common/reflect/PackageInfo.java | 13 +-
.../juneau/common/reflect/ParameterInfo.java | 29 +-
5 files changed, 203 insertions(+), 259 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 d29d37774c..4c097af3ef 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
@@ -179,189 +179,41 @@ public class ClassInfo extends ElementInfo implements
Annotatable {
return c == null ? ClassInfo.of(o) : ClassInfo.of(c);
}
- // The underlying Type object (may be Class, ParameterizedType,
GenericArrayType, etc.).
- private final Type t;
-
- // The underlying Class object (null for non-class types like
TypeVariable). Effectively final.
- private Class<?> inner;
-
- // True if this represents a ParameterizedType (e.g., List<String>).
- private final boolean isParameterizedType;
-
- // Number of array dimensions (0 if not an array).
- private final Supplier<Integer> dimensions =
memoize(this::findDimensions);
-
- // Base component type for arrays (e.g., String for String[][]), also
handles GenericArrayType. Cached and never null.
- private final Supplier<ClassInfo> componentType =
memoize(this::findComponentType);
-
- // The package this class belongs to (null for primitive types and
arrays).
- private final Supplier<PackageInfo> packageInfo = memoize(() ->
opt(inner).map(x -> PackageInfo.of(x.getPackage())).orElse(null));
-
- // All superclasses of this class in child-to-parent order, starting
with this class.
- private final Supplier<List<ClassInfo>> parents =
memoize(this::findParents);
-
- // All annotations declared directly on this class, wrapped in
AnnotationInfo.
- private final Supplier<List<AnnotationInfo>> declaredAnnotations2 =
memoize(() -> (List)opt(inner).map(x ->
u(l(x.getDeclaredAnnotations()))).orElse(liste()).stream().map(a ->
AnnotationInfo.of(this, a)).toList());
-
- // Fully qualified class name with generics (e.g.,
"java.util.List<java.lang.String>").
- private final Supplier<String> fullName = memoize(() ->
getNameFormatted(FULL, true, '$', BRACKETS));
-
- // Simple class name with generics (e.g., "List<String>").
- private final Supplier<String> shortName = memoize(() ->
getNameFormatted(SHORT, true, '$', BRACKETS));
-
- // Human-readable class name without generics (e.g., "List").
- private final Supplier<String> readableName = memoize(() ->
getNameFormatted(SIMPLE, false, '$', WORD));
-
- // All interfaces declared directly by this class.
- private final Supplier<List<ClassInfo>> declaredInterfaces = memoize(()
-> opt(inner).map(x ->
stream(x.getInterfaces()).map(ClassInfo::of).toList()).orElse(liste()));
-
- // All interfaces implemented by this class and its parents, in
child-to-parent order.
- private final Supplier<List<ClassInfo>> interfaces = memoize(() ->
getParents().stream().flatMap(x ->
x.getDeclaredInterfaces().stream()).flatMap(ci2 -> concat(Stream.of(ci2),
ci2.getInterfaces().stream())).distinct().toList());
-
- // All parent classes and interfaces, classes first, then in
child-to-parent order.
- // TODO - Determine if this field is still needed now that we have
parentsAndInterfaces which handles the hierarchy better.
- private final Supplier<List<ClassInfo>> allParents = memoize(() ->
concat(getParents().stream(), getInterfaces().stream()).toList());
-
- // All parent classes and interfaces with proper traversal of interface
hierarchy to avoid duplicates.
- private final Supplier<List<ClassInfo>> parentsAndInterfaces =
memoize(this::findParentsAndInterfaces);
-
- /**
- * Finds all parent classes and interfaces with proper traversal of
interface hierarchy.
- *
- * @return A list of all parent classes and interfaces without
duplicates.
- */
- private List<ClassInfo> findParentsAndInterfaces() {
- var set = new LinkedHashSet<ClassInfo>();
-
- // Process all parent classes (includes this class)
- var parents = getParents();
- for (int i = 0; i < parents.size(); i++) {
- var parent = parents.get(i);
- set.add(parent);
-
- // Process interfaces declared on this parent (and
their parent interfaces)
- var declaredInterfaces = parent.getDeclaredInterfaces();
- for (int j = 0; j < declaredInterfaces.size(); j++)
- addInterfaceHierarchy(set,
declaredInterfaces.get(j));
- }
-
- return u(new ArrayList<>(set));
- }
-
- /**
- * Helper method to recursively add an interface and its parent
interfaces to the set.
- *
- * @param set The set to add to.
- * @param iface The interface to add.
- */
- private void addInterfaceHierarchy(LinkedHashSet<ClassInfo> set,
ClassInfo iface) {
- if (!set.add(iface))
- return;
-
- // Process parent interfaces recursively
- var parentInterfaces = iface.getDeclaredInterfaces();
- for (int i = 0; i < parentInterfaces.size(); i++)
- addInterfaceHierarchy(set, parentInterfaces.get(i));
- }
-
- /**
- * Finds all annotations on this class and parent classes/interfaces in
child-to-parent order.
- *
- * <p>
- * This is similar to {@link
org.apache.juneau.common.reflect.AnnotationProvider#find(Class)} but without
runtime annotations.
- *
- * <p>
- * Order of traversal:
- * <ol>
- * <li>Annotations declared on this class
- * <li>Annotations declared on parent classes (child-to-parent
order)
- * <li>For each parent class, annotations on interfaces declared
on that class (child-to-parent interface hierarchy)
- * <li>Annotations on the package of this class
- * </ol>
- *
- * @return A list of all annotation infos in child-to-parent order.
- */
- private List<AnnotationInfo<Annotation>> findAnnotationInfos() {
- var list = new ArrayList<AnnotationInfo<Annotation>>();
-
- // On all parent classes and interfaces (properly traversed to
avoid duplicates)
- var parentsAndInterfaces = getParentsAndInterfaces();
- for (int i = 0; i < parentsAndInterfaces.size(); i++) {
- var ci = parentsAndInterfaces.get(i);
- // Add declared annotations from this class/interface
- for (var a : ci.inner().getDeclaredAnnotations())
- for (var a2 : splitRepeated(a))
- list.add(AnnotationInfo.of(ci, a2));
- }
-
- // On the package of this class
- var pkg = getPackage();
- if (nn(pkg)) {
- var pi = PackageInfo.of(pkg.inner());
- for (var a : pkg.inner().getAnnotations())
- for (var a2 : splitRepeated(a))
- list.add(AnnotationInfo.of(pi, a2));
- }
-
- return u(list);
- }
-
- // All annotations on this class and parent classes/interfaces in
child-to-parent order.
- private final Supplier<List<AnnotationInfo<Annotation>>>
annotationInfos = memoize(this::findAnnotationInfos);
-
- // All record components if this is a record class (Java 14+).
- private final Supplier<List<RecordComponent>> recordComponents =
memoize(() -> opt(inner).filter(Class::isRecord).map(x ->
u(l(x.getRecordComponents()))).orElse(liste()));
-
- // All generic interface types (e.g., List<String> implements
Comparable<List<String>>).
- private final Supplier<List<Type>> genericInterfaces = memoize(() ->
opt(inner).map(x -> u(l(x.getGenericInterfaces()))).orElse(liste()));
-
- // All type parameters declared on this class (e.g., <T, U> in class
Foo<T, U>).
- private final Supplier<List<TypeVariable<?>>> typeParameters =
memoize(() -> opt(inner).map(x ->
u(l((TypeVariable<?>[])x.getTypeParameters()))).orElse(liste()));
-
- // All annotated interface types with their annotations.
- private final Supplier<List<AnnotatedType>> annotatedInterfaces =
memoize(() -> opt(inner).map(x ->
u(l(x.getAnnotatedInterfaces()))).orElse(liste()));
-
- // All signers of this class (for signed JARs).
- private final Supplier<List<Object>> signers = memoize(() ->
opt(inner).map(Class::getSigners).map(x -> u(l(x))).orElse(liste()));
-
- // All public methods on this class and inherited, excluding Object
methods.
- private final Supplier<List<MethodInfo>> publicMethods = memoize(() ->
opt(inner).map(x -> stream(x.getMethods()).filter(m ->
ne(m.getDeclaringClass(),
Object.class)).map(this::getMethodInfo).sorted().toList()).orElse(liste()));
-
- // All methods declared directly on this class (public, protected,
package, private).
- private final Supplier<List<MethodInfo>> declaredMethods = memoize(()
-> opt(inner).map(x -> stream(x.getDeclaredMethods()).filter(m ->
ne("$jacocoInit",
m.getName())).map(this::getMethodInfo).sorted().toList()).orElse(liste()));
-
- // All methods from this class and all parents, in child-to-parent
order.
- private final Supplier<List<MethodInfo>> allMethods = memoize(() ->
allParents.get().stream().flatMap(c ->
c.getDeclaredMethods().stream()).toList());
-
- // All methods from this class and all parents, in parent-to-child
order.
- private final Supplier<List<MethodInfo>> allMethodsParentFirst =
memoize(() -> rstream(getAllParents()).flatMap(c ->
c.getDeclaredMethods().stream()).toList());
-
- // All public fields from this class and parents, deduplicated by name
(child wins).
- private final Supplier<List<FieldInfo>> publicFields = memoize(() ->
parents.get().stream().flatMap(c -> c.getDeclaredFields().stream()).filter(f ->
f.isPublic() && ne("$jacocoData",
f.getName())).collect(toMap(FieldInfo::getName, x -> x, (a, b) -> a,
LinkedHashMap::new)).values().stream().sorted().collect(toList()));
-
- // All fields declared directly on this class (public, protected,
package, private).
- private final Supplier<List<FieldInfo>> declaredFields = memoize(() ->
opt(inner).map(x -> stream(x.getDeclaredFields()).filter(f -> ne("$jacocoData",
f.getName())).map(this::getFieldInfo).sorted().toList()).orElse(liste()));
-
- // All fields from this class and all parents, in parent-to-child order.
- private final Supplier<List<FieldInfo>> allFields = memoize(() ->
rstream(allParents.get()).flatMap(c ->
c.getDeclaredFields().stream()).toList());
-
- // All public constructors declared on this class.
- private final Supplier<List<ConstructorInfo>> publicConstructors =
memoize(() -> opt(inner).map(x ->
stream(x.getConstructors()).map(this::getConstructorInfo).sorted().toList()).orElse(liste()));
-
- // All constructors declared on this class (public, protected, package,
private).
- private final Supplier<List<ConstructorInfo>> declaredConstructors =
memoize(() -> opt(inner).map(x ->
stream(x.getDeclaredConstructors()).map(this::getConstructorInfo).sorted().toList()).orElse(liste()));
-
- // The repeated annotation method (value()) if this class is a
@Repeatable container.
- private final Supplier<MethodInfo> repeatedAnnotationMethod =
memoize(this::findRepeatedAnnotationMethod);
-
- // Cache of wrapped Method objects.
- private final Cache<Method,MethodInfo> methodCache =
Cache.of(Method.class, MethodInfo.class).build();
-
- // Cache of wrapped Field objects.
- private final Cache<Field,FieldInfo> fieldCache = Cache.of(Field.class,
FieldInfo.class).build();
-
- // Cache of wrapped Constructor objects.
- private final Cache<Constructor,ConstructorInfo> constructorCache =
Cache.of(Constructor.class, ConstructorInfo.class).build();
+ private final Type t; // The underlying Type object (may be Class,
ParameterizedType, GenericArrayType, etc.).
+ private Class<?> inner; // The underlying Class object (null for
non-class types like TypeVariable). Effectively final.
+ private final boolean isParameterizedType; // True if this represents
a ParameterizedType (e.g., List<String>).
+
+ private final Supplier<Integer> dimensions; // Number of array
dimensions (0 if not an array).
+ 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<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").
+ private final Supplier<List<ClassInfo>> declaredInterfaces; // All
interfaces declared directly by this class.
+ private final Supplier<List<ClassInfo>> interfaces; // All interfaces
implemented by this class and its parents, in child-to-parent order.
+ private final Supplier<List<ClassInfo>> allParents; // All parent
classes and interfaces, classes first, then in child-to-parent order.
+ private final Supplier<List<ClassInfo>> parentsAndInterfaces; // All
parent classes and interfaces with proper traversal of interface hierarchy to
avoid duplicates.
+ private final Supplier<List<AnnotationInfo<Annotation>>>
annotationInfos; // All annotations on this class and parent
classes/interfaces in child-to-parent order.
+ private final Supplier<List<RecordComponent>> recordComponents; // All
record components if this is a record class (Java 14+).
+ private final Supplier<List<Type>> genericInterfaces; // All generic
interface types (e.g., List<String> implements Comparable<List<String>>).
+ private final Supplier<List<TypeVariable<?>>> typeParameters; // All
type parameters declared on this class (e.g., <T, U> in class Foo<T, U>).
+ private final Supplier<List<AnnotatedType>> annotatedInterfaces; //
All annotated interface types with their annotations.
+ private final Supplier<List<Object>> signers; // All signers of this
class (for signed JARs).
+ private final Supplier<List<MethodInfo>> publicMethods; // All public
methods on this class and inherited, excluding Object methods.
+ private final Supplier<List<MethodInfo>> declaredMethods; // All
methods declared directly on this class (public, protected, package, private).
+ private final Supplier<List<MethodInfo>> allMethods; // All methods
from this class and all parents, in child-to-parent order.
+ private final Supplier<List<MethodInfo>> allMethodsParentFirst; // All
methods from this class and all parents, in parent-to-child order.
+ private final Supplier<List<FieldInfo>> publicFields; // All public
fields from this class and parents, deduplicated by name (child wins).
+ private final Supplier<List<FieldInfo>> declaredFields; // All fields
declared directly on this class (public, protected, package, private).
+ private final Supplier<List<FieldInfo>> allFields; // All fields from
this class and all parents, in parent-to-child order.
+ private final Supplier<List<ConstructorInfo>> publicConstructors; //
All public constructors declared on this class.
+ private final Supplier<List<ConstructorInfo>> declaredConstructors; //
All constructors declared on this class (public, protected, package, private).
+ private final Supplier<MethodInfo> repeatedAnnotationMethod; // The
repeated annotation method (value()) if this class is a @Repeatable container.
+ private final Cache<Method,MethodInfo> methodCache; // Cache of
wrapped Method objects.
+ private final Cache<Field,FieldInfo> fieldCache; // Cache of wrapped
Field objects.
+ private final Cache<Constructor,ConstructorInfo> constructorCache; //
Cache of wrapped Constructor objects.
/**
* Constructor.
@@ -374,6 +226,37 @@ public class ClassInfo extends ElementInfo implements
Annotatable {
this.t = t;
this.inner = c;
this.isParameterizedType = t == null ? false : (t instanceof
ParameterizedType);
+ this.dimensions = memoize(this::findDimensions);
+ 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.fullName = memoize(() -> getNameFormatted(FULL, true, '$',
BRACKETS));
+ this.shortName = memoize(() -> getNameFormatted(SHORT, true,
'$', BRACKETS));
+ this.readableName = memoize(() -> getNameFormatted(SIMPLE,
false, '$', WORD));
+ this.declaredInterfaces = memoize(() -> opt(inner).map(x ->
stream(x.getInterfaces()).map(ClassInfo::of).toList()).orElse(liste()));
+ this.interfaces = memoize(() -> getParents().stream().flatMap(x
-> x.getDeclaredInterfaces().stream()).flatMap(ci2 -> concat(Stream.of(ci2),
ci2.getInterfaces().stream())).distinct().toList());
+ this.allParents = memoize(() -> concat(getParents().stream(),
getInterfaces().stream()).toList());
+ this.parentsAndInterfaces =
memoize(this::findParentsAndInterfaces);
+ this.annotationInfos = memoize(this::findAnnotationInfos);
+ this.recordComponents = memoize(() ->
opt(inner).filter(Class::isRecord).map(x ->
u(l(x.getRecordComponents()))).orElse(liste()));
+ this.genericInterfaces = memoize(() -> opt(inner).map(x ->
u(l(x.getGenericInterfaces()))).orElse(liste()));
+ this.typeParameters = memoize(() -> opt(inner).map(x ->
u(l((TypeVariable<?>[])x.getTypeParameters()))).orElse(liste()));
+ this.annotatedInterfaces = memoize(() -> opt(inner).map(x ->
u(l(x.getAnnotatedInterfaces()))).orElse(liste()));
+ this.signers = memoize(() ->
opt(inner).map(Class::getSigners).map(x -> u(l(x))).orElse(liste()));
+ this.publicMethods = memoize(() -> opt(inner).map(x ->
stream(x.getMethods()).filter(m -> ne(m.getDeclaringClass(),
Object.class)).map(this::getMethodInfo).sorted().toList()).orElse(liste()));
+ this.declaredMethods = memoize(() -> opt(inner).map(x ->
stream(x.getDeclaredMethods()).filter(m -> ne("$jacocoInit",
m.getName())).map(this::getMethodInfo).sorted().toList()).orElse(liste()));
+ this.allMethods = memoize(() ->
allParents.get().stream().flatMap(c2 ->
c2.getDeclaredMethods().stream()).toList());
+ this.allMethodsParentFirst = memoize(() ->
rstream(getAllParents()).flatMap(c2 ->
c2.getDeclaredMethods().stream()).toList());
+ this.publicFields = memoize(() ->
parents.get().stream().flatMap(c2 -> c2.getDeclaredFields().stream()).filter(f
-> f.isPublic() && ne("$jacocoData",
f.getName())).collect(toMap(FieldInfo::getName, x -> x, (a, b) -> a,
LinkedHashMap::new)).values().stream().sorted().collect(toList()));
+ this.declaredFields = memoize(() -> opt(inner).map(x ->
stream(x.getDeclaredFields()).filter(f -> ne("$jacocoData",
f.getName())).map(this::getFieldInfo).sorted().toList()).orElse(liste()));
+ this.allFields = memoize(() ->
rstream(allParents.get()).flatMap(c2 ->
c2.getDeclaredFields().stream()).toList());
+ this.publicConstructors = memoize(() -> opt(inner).map(x ->
stream(x.getConstructors()).map(this::getConstructorInfo).sorted().toList()).orElse(liste()));
+ this.declaredConstructors = memoize(() -> opt(inner).map(x ->
stream(x.getDeclaredConstructors()).map(this::getConstructorInfo).sorted().toList()).orElse(liste()));
+ this.repeatedAnnotationMethod =
memoize(this::findRepeatedAnnotationMethod);
+ this.methodCache = Cache.of(Method.class,
MethodInfo.class).build();
+ this.fieldCache = Cache.of(Field.class,
FieldInfo.class).build();
+ this.constructorCache = Cache.of(Constructor.class,
ConstructorInfo.class).build();
}
/**
@@ -2460,6 +2343,91 @@ public class ClassInfo extends ElementInfo implements
Annotatable {
}
}
+
//-----------------------------------------------------------------------------------------------------------------
+ // Find methods
+
//-----------------------------------------------------------------------------------------------------------------
+
+ /**
+ * Finds all parent classes and interfaces with proper traversal of
interface hierarchy.
+ *
+ * @return A list of all parent classes and interfaces without
duplicates.
+ */
+ private List<ClassInfo> findParentsAndInterfaces() {
+ var set = new LinkedHashSet<ClassInfo>();
+
+ // Process all parent classes (includes this class)
+ var parents = getParents();
+ for (int i = 0; i < parents.size(); i++) {
+ var parent = parents.get(i);
+ set.add(parent);
+
+ // Process interfaces declared on this parent (and
their parent interfaces)
+ var declaredInterfaces = parent.getDeclaredInterfaces();
+ for (int j = 0; j < declaredInterfaces.size(); j++)
+ addInterfaceHierarchy(set,
declaredInterfaces.get(j));
+ }
+
+ return u(new ArrayList<>(set));
+ }
+
+ /**
+ * Helper method to recursively add an interface and its parent
interfaces to the set.
+ *
+ * @param set The set to add to.
+ * @param iface The interface to add.
+ */
+ private void addInterfaceHierarchy(LinkedHashSet<ClassInfo> set,
ClassInfo iface) {
+ if (!set.add(iface))
+ return;
+
+ // Process parent interfaces recursively
+ var parentInterfaces = iface.getDeclaredInterfaces();
+ for (int i = 0; i < parentInterfaces.size(); i++)
+ addInterfaceHierarchy(set, parentInterfaces.get(i));
+ }
+
+ /**
+ * Finds all annotations on this class and parent classes/interfaces in
child-to-parent order.
+ *
+ * <p>
+ * This is similar to {@link
org.apache.juneau.common.reflect.AnnotationProvider#find(Class)} but without
runtime annotations.
+ *
+ * <p>
+ * Order of traversal:
+ * <ol>
+ * <li>Annotations declared on this class
+ * <li>Annotations declared on parent classes (child-to-parent
order)
+ * <li>For each parent class, annotations on interfaces declared
on that class (child-to-parent interface hierarchy)
+ * <li>Annotations on the package of this class
+ * </ol>
+ *
+ * @return A list of all annotation infos in child-to-parent order.
+ */
+ private List<AnnotationInfo<Annotation>> findAnnotationInfos() {
+ var list = new ArrayList<AnnotationInfo<Annotation>>();
+
+ // On all parent classes and interfaces (properly traversed to
avoid duplicates)
+ var parentsAndInterfaces = getParentsAndInterfaces();
+ for (int i = 0; i < parentsAndInterfaces.size(); i++) {
+ var ci = parentsAndInterfaces.get(i);
+ // Add declared annotations from this class/interface
+ for (var a : ci.inner().getDeclaredAnnotations())
+ for (var a2 : splitRepeated(a))
+ list.add(AnnotationInfo.of(ci, a2));
+ }
+
+ // On the package of this class
+ var pkg = getPackage();
+ if (nn(pkg)) {
+ var pi = PackageInfo.of(pkg.inner());
+ for (var a : pkg.inner().getAnnotations())
+ for (var a2 : splitRepeated(a))
+ list.add(AnnotationInfo.of(pi, a2));
+ }
+
+ return u(list);
+ }
+
//-----------------------------------------------------------------------------------------------------------------
// Annotatable interface methods
//-----------------------------------------------------------------------------------------------------------------
diff --git
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ExecutableInfo.java
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ExecutableInfo.java
index 5a41ef45d6..86b8901376 100644
---
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ExecutableInfo.java
+++
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ExecutableInfo.java
@@ -20,7 +20,6 @@ import static
org.apache.juneau.common.reflect.ClassArrayFormat.*;
import static org.apache.juneau.common.reflect.ClassNameFormat.*;
import static org.apache.juneau.common.utils.AssertionUtils.*;
import static org.apache.juneau.common.utils.CollectionUtils.*;
-import static org.apache.juneau.common.utils.PredicateUtils.*;
import static org.apache.juneau.common.utils.StringUtils.*;
import static org.apache.juneau.common.utils.Utils.*;
import static java.util.stream.Collectors.*;
@@ -46,23 +45,28 @@ public abstract class ExecutableInfo extends AccessibleInfo
{
private final Executable inner;
private final boolean isConstructor;
- private final Supplier<List<ParameterInfo>> parameters =
memoize(this::findParameters);
- private final Supplier<List<ClassInfo>> exceptions =
memoize(this::findExceptions);
- private final Supplier<List<AnnotationInfo<Annotation>>>
declaredAnnotations = memoize(this::findDeclaredAnnotations);
- private final Supplier<String> shortName = memoize(this::findShortName);
- private final Supplier<String> fullName = memoize(this::findFullName);
+ private final Supplier<List<ParameterInfo>> parameters; // All
parameters of this executable.
+ private final Supplier<List<ClassInfo>> exceptions; // All exceptions
declared by this executable.
+ private final Supplier<List<AnnotationInfo<Annotation>>>
declaredAnnotations; // All annotations declared directly on this executable.
+ private final Supplier<String> shortName; // Short name
(method/constructor name with parameters).
+ private final Supplier<String> fullName; // Fully qualified name
(declaring-class.method-name with parameters).
/**
* Constructor.
*
* @param declaringClass The class that declares this method or
constructor.
- * @param e The constructor orĂ¥ method that this info represents.
+ * @param e The constructor or method that this info represents.
*/
protected ExecutableInfo(ClassInfo declaringClass, Executable e) {
super(e, e.getModifiers());
this.declaringClass = declaringClass;
this.inner = e;
this.isConstructor = e instanceof Constructor;
+ this.parameters = memoize(this::findParameters);
+ this.exceptions = memoize(() ->
stream(inner.getExceptionTypes()).map(ClassInfo::of).toList());
+ this.declaredAnnotations = memoize(() ->
stream(inner.getDeclaredAnnotations()).map(a ->
AnnotationInfo.of((Annotatable)this, a)).toList());
+ this.shortName = memoize(() -> f("{0}({1})", getSimpleName(),
getParameters().stream().map(p ->
p.getParameterType().getNameSimple()).collect(joining(","))));
+ this.fullName = memoize(this::findFullName);
}
/**
@@ -221,24 +225,6 @@ public abstract class ExecutableInfo extends
AccessibleInfo {
return fullName.get();
}
- private String findFullName() {
- var sb = new StringBuilder(128);
- var dc = declaringClass;
- var pi = dc.getPackage();
- if (nn(pi))
- sb.append(pi.getName()).append('.');
- dc.appendNameFormatted(sb, SHORT, true, '$', BRACKETS);
- if (! isConstructor)
- sb.append('.').append(getSimpleName());
- sb.append('(');
- sb.append(getParameters().stream()
- .map(p -> p.getParameterType().getNameFormatted(FULL,
true, '$', BRACKETS))
- .collect(joining(","))
- );
- sb.append(')');
- return sb.toString();
- }
-
/**
* Returns parameter information at the specified index.
*
@@ -285,10 +271,6 @@ public abstract class ExecutableInfo extends
AccessibleInfo {
return shortName.get();
}
- private String findShortName() {
- return f("{0}({1})", getSimpleName(),
getParameters().stream().map(p ->
p.getParameterType().getNameSimple()).collect(joining(",")));
- }
-
/**
* Returns the simple name of the underlying method.
*
@@ -741,18 +723,6 @@ public abstract class ExecutableInfo extends
AccessibleInfo {
throw new IndexOutOfBoundsException(format("Invalid
index ''{0}''. Parameter count: {1}", index, pc));
}
- private List<AnnotationInfo<Annotation>> findDeclaredAnnotations() {
- return stream(inner.getDeclaredAnnotations())
- .map(a -> AnnotationInfo.of((Annotatable)this, a))
- .toList();
- }
-
- private List<ClassInfo> findExceptions() {
- return stream(inner.getExceptionTypes())
- .map(ClassInfo::of)
- .toList();
- }
-
private List<ParameterInfo> findParameters() {
var rp = inner.getParameters();
var ptc = inner.getParameterTypes();
@@ -779,4 +749,22 @@ public abstract class ExecutableInfo extends
AccessibleInfo {
.mapToObj(i -> new ParameterInfo(this, rp[i], i,
ClassInfo.of(ptc[i], genericTypes[i])))
.toList();
}
+
+ private String findFullName() {
+ var sb = new StringBuilder(128);
+ var dc = declaringClass;
+ var pi = dc.getPackage();
+ if (nn(pi))
+ sb.append(pi.getName()).append('.');
+ dc.appendNameFormatted(sb, SHORT, true, '$', BRACKETS);
+ if (! isConstructor)
+ sb.append('.').append(getSimpleName());
+ sb.append('(');
+ sb.append(getParameters().stream()
+ .map(p -> p.getParameterType().getNameFormatted(FULL,
true, '$', BRACKETS))
+ .collect(joining(","))
+ );
+ sb.append(')');
+ return sb.toString();
+ }
}
\ No newline at end of file
diff --git
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/FieldInfo.java
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/FieldInfo.java
index 86717cb262..1bc43a8cf7 100644
---
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/FieldInfo.java
+++
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/FieldInfo.java
@@ -68,8 +68,8 @@ public class FieldInfo extends AccessibleInfo implements
Comparable<FieldInfo>,
private final Field inner;
private final ClassInfo declaringClass;
private final Supplier<ClassInfo> type;
- private final Supplier<List<AnnotationInfo<Annotation>>> annotations =
memoize(this::_findAnnotations);
- private final Supplier<String> fullName = memoize(this::findFullName);
+ private final Supplier<List<AnnotationInfo<Annotation>>> annotations;
// All annotations on this field.
+ private final Supplier<String> fullName; // Fully qualified field name
(declaring-class.field-name).
/**
* Constructor.
@@ -81,15 +81,9 @@ public class FieldInfo extends AccessibleInfo implements
Comparable<FieldInfo>,
super(f, f.getModifiers());
this.declaringClass = declaringClass;
this.inner = f;
- this.type = memoize(() -> findType(f));
- }
-
- private static ClassInfo findType(Field f) {
- return ClassInfo.of(f.getType());
- }
-
- private List<AnnotationInfo<Annotation>> _findAnnotations() {
- return stream(inner.getAnnotations()).map(a ->
AnnotationInfo.of(this, a)).toList();
+ this.type = memoize(() -> ClassInfo.of(f.getType()));
+ this.annotations = memoize(() ->
stream(inner.getAnnotations()).map(a -> AnnotationInfo.of(this, a)).toList());
+ this.fullName = memoize(this::findFullName);
}
private String findFullName() {
diff --git
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/PackageInfo.java
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/PackageInfo.java
index 57a18e9151..555b9c3f2c 100644
---
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/PackageInfo.java
+++
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/PackageInfo.java
@@ -48,13 +48,13 @@ public class PackageInfo implements Annotatable {
/**
* Returns a package info wrapper around the specified package object.
*
- * @param p The package object. Can be <jk>null</jk>.
+ * @param inner The package object. Can be <jk>null</jk>.
* @return A package info wrapper, or <jk>null</jk> if the parameter
was null.
*/
- public static PackageInfo of(Package p) {
- if (p == null)
+ public static PackageInfo of(Package inner) {
+ if (inner == null)
return null;
- return CACHE.get(p, () -> new PackageInfo(p));
+ return CACHE.get(inner, () -> new PackageInfo(inner));
}
/**
@@ -82,9 +82,7 @@ public class PackageInfo implements Annotatable {
//-----------------------------------------------------------------------------------------------------------------
private Package inner; // Effectively final
-
- // All annotations on this package, wrapped in AnnotationInfo. Repeated
annotations have been unwrapped and are present as individual instances.
Lazy-initialized in getter.
- private final Supplier<List<AnnotationInfo<Annotation>>> annotations =
memoize(() -> opt(inner).map(p -> stream(p.getAnnotations()).flatMap(a ->
stream(splitRepeated(a))).map(a -> AnnotationInfo.of(this,
a)).toList()).orElse(liste()));
+ private final Supplier<List<AnnotationInfo<Annotation>>> annotations;
// All annotations on this package, wrapped in AnnotationInfo. Repeated
annotations have been unwrapped and are present as individual instances.
/**
* Constructor.
@@ -93,6 +91,7 @@ public class PackageInfo implements Annotatable {
*/
protected PackageInfo(Package p) {
this.inner = p;
+ this.annotations = memoize(() -> opt(inner).map(pkg ->
stream(pkg.getAnnotations()).flatMap(a -> stream(splitRepeated(a))).map(a ->
AnnotationInfo.of(this, a)).toList()).orElse(liste()));
}
/**
diff --git
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ParameterInfo.java
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ParameterInfo.java
index 95f276ee8e..9a57a7011e 100644
---
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ParameterInfo.java
+++
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ParameterInfo.java
@@ -61,8 +61,8 @@ public class ParameterInfo extends ElementInfo implements
Annotatable {
@SuppressWarnings({"rawtypes","unchecked"})
private final Cache<Class,List<AnnotationInfo<Annotation>>>
foundAnnotations =
Cache.<Class,List<AnnotationInfo<Annotation>>>create().supplier((k) ->
findAnnotationInfosInternal(k)).build();
- private final Supplier<List<AnnotationInfo<Annotation>>> annotations =
memoize(this::_findAnnotations);
- private final Supplier<List<ParameterInfo>> matchingParameters =
memoize(this::_findMatchingParameters);
+ private final Supplier<List<AnnotationInfo<Annotation>>> annotations;
// All annotations on this parameter.
+ private final Supplier<List<ParameterInfo>> matchingParameters; //
Matching parameters in parent methods.
private final ResettableSupplier<String> foundName =
memoizeResettable(this::findNameInternal);
private final ResettableSupplier<String> foundQualifier =
memoizeResettable(this::findQualifierInternal);
@@ -81,6 +81,8 @@ public class ParameterInfo extends ElementInfo implements
Annotatable {
this.inner = p;
this.index = index;
this.type = type;
+ this.annotations = memoize(() ->
stream(inner.getAnnotations()).map(a -> AnnotationInfo.of(this, a)).toList());
+ this.matchingParameters = memoize(this::findMatchingParameters);
}
/**
@@ -92,10 +94,6 @@ public class ParameterInfo extends ElementInfo implements
Annotatable {
return inner;
}
- private List<AnnotationInfo<Annotation>> _findAnnotations() {
- return stream(inner.getAnnotations()).map(a ->
AnnotationInfo.of(this, a)).toList();
- }
-
/**
* Returns all annotations declared on this parameter.
*
@@ -226,7 +224,7 @@ public class ParameterInfo extends ElementInfo implements
Annotatable {
return matchingParameters.get();
}
- private List<ParameterInfo> _findMatchingParameters() {
+ private List<ParameterInfo> findMatchingParameters() {
if (executable.isConstructor()) {
// For constructors: search parent class constructors
for parameters with matching index and type
// Note: We match by index and type only, not by name,
to avoid circular dependency
@@ -398,16 +396,13 @@ public class ParameterInfo extends ElementInfo implements
Annotatable {
private String findQualifierInternal() {
// Search through matching parameters in hierarchy for @Named
or javax.inject.Qualifier annotations
- for (var mp : getMatchingParameters()) {
- for (var ai : mp.getAnnotationInfos()) {
- if (ai.hasSimpleName("Named") ||
ai.hasSimpleName("Qualifier")) {
- String value =
ai.getValue().orElse(null);
- if (value != null)
- return value;
- }
- }
- }
- return null;
+ return getMatchingParameters().stream()
+ .flatMap(mp -> mp.getAnnotationInfos().stream())
+ .filter(ai -> ai.hasSimpleName("Named") ||
ai.hasSimpleName("Qualifier"))
+ .map(ai -> ai.getValue().orElse(null))
+ .filter(Objects::nonNull)
+ .findFirst()
+ .orElse(null);
}
/**