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 318233855e org.apache.juneau.common.reflect API improvements
318233855e is described below
commit 318233855e0ed3f8c4845a52e06ccfa0294b76d5
Author: James Bognar <[email protected]>
AuthorDate: Tue Nov 18 08:32:57 2025 -0500
org.apache.juneau.common.reflect API improvements
---
.../juneau/common/reflect/AnnotationInfo.java | 39 +-
.../juneau/common/reflect/AnnotationProvider.java | 8 +-
.../apache/juneau/common/reflect/ClassInfo.java | 73 ---
.../juneau/common/reflect/ConstructorInfo.java | 64 ---
.../apache/juneau/common/reflect/FieldInfo.java | 57 ---
.../apache/juneau/common/reflect/MethodInfo.java | 75 ----
.../juneau/common/reflect/ParameterInfo.java | 66 ---
.../juneau/common/reflect/ReflectionMap.java | 500 ++++++++++-----------
.../apache/juneau/common/utils/PredicateUtils.java | 3 -
.../java/org/apache/juneau/rest/RestOpContext.java | 2 -
.../juneau/rest/debug/BasicDebugEnablement.java | 9 +-
.../apache/juneau/rest/debug/DebugEnablement.java | 5 +-
.../juneau/rest/matcher/ClientVersionMatcher.java | 2 -
.../juneau/common/reflect/ReflectionMapTest.java | 362 ---------------
14 files changed, 260 insertions(+), 1005 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 bfd81c9dfb..86a97eee06 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
@@ -17,7 +17,6 @@
package org.apache.juneau.common.reflect;
import static org.apache.juneau.common.utils.AssertionUtils.*;
-import static org.apache.juneau.common.utils.ClassUtils.*;
import static org.apache.juneau.common.utils.CollectionUtils.*;
import static org.apache.juneau.common.utils.ThrowableUtils.*;
import static org.apache.juneau.common.utils.Utils.*;
@@ -44,9 +43,9 @@ import org.apache.juneau.common.annotation.*;
* <p class='bjava'>
* <jc>// Get annotation info from a class</jc>
* ClassInfo <jv>ci</jv> = ClassInfo.<jsm>of</jsm>(MyClass.<jk>class</jk>);
- * Optional<AnnotationInfo<MyAnnotation>> <jv>ai</jv> =
+ * Optional<AnnotationInfo<MyAnnotation>> <jv>ai</jv> =
*
<jv>ci</jv>.getAnnotations(MyAnnotation.<jk>class</jk>).findFirst();
- *
+ *
* <jc>// Access annotation values</jc>
* <jv>ai</jv>.ifPresent(<jv>x</jv> -> {
* String <jv>value</jv> =
<jv>x</jv>.getValue(String.<jk>class</jk>,
<js>"value"</js>).orElse(<js>"default"</js>);
@@ -108,11 +107,11 @@ public class AnnotationInfo<T extends Annotation> {
/**
* Returns the rank of this annotation for sorting by precedence.
- *
+ *
* <p>
* The rank is determined by checking if the annotation has a {@code
rank()} method that returns an {@code int}.
* If found, that value is used; otherwise the rank defaults to {@code
0}.
- *
+ *
* <p>
* Higher rank values indicate higher precedence when multiple
annotations of the same type are present.
*
@@ -122,12 +121,12 @@ public class AnnotationInfo<T extends Annotation> {
* <ja>@interface</ja> MyAnnotation {
* <jk>int</jk> rank() <jk>default</jk> 0;
* }
- *
+ *
* <jc>// Get rank from annotation info</jc>
* AnnotationInfo<MyAnnotation> <jv>ai</jv> = ...;
* <jk>int</jk> <jv>rank</jv> = <jv>ai</jv>.getRank(); <jc>//
Returns value from rank() method</jc>
* </p>
- *
+ *
* @return The rank of this annotation, or {@code 0} if no rank method
exists.
*/
public int getRank() {
@@ -158,10 +157,10 @@ public class AnnotationInfo<T extends Annotation> {
* <p class='bjava'>
* <jc>// For annotation: @interface MyAnnotation { String
value(); int priority(); }</jc>
* AnnotationInfo<MyAnnotation> <jv>ai</jv> = ...;
- *
+ *
* <jc>// Get string value</jc>
* Optional<String> <jv>value</jv> =
<jv>ai</jv>.getValue(String.<jk>class</jk>, <js>"value"</js>);
- *
+ *
* <jc>// Get int value</jc>
* Optional<Integer> <jv>priority</jv> =
<jv>ai</jv>.getValue(Integer.<jk>class</jk>, <js>"priority"</js>);
* </p>
@@ -188,7 +187,7 @@ public class AnnotationInfo<T extends Annotation> {
* <h5 class='section'>Example:</h5>
* <p class='bjava'>
* AnnotationInfo<?> <jv>ai</jv> = ...;
- *
+ *
* <jc>// Safe cast</jc>
* AnnotationInfo<MyAnnotation> <jv>myAi</jv> =
<jv>ai</jv>.cast(MyAnnotation.<jk>class</jk>);
* <jk>if</jk> (<jv>myAi</jv> != <jk>null</jk>) {
@@ -233,7 +232,7 @@ public class AnnotationInfo<T extends Annotation> {
* <p class='bjava'>
* AnnotationInfo<MyAnnotation> <jv>ai</jv> = ...;
* MyAnnotation <jv>annotation</jv> = <jv>ai</jv>.inner();
- *
+ *
* <jc>// Access annotation methods directly</jc>
* String <jv>value</jv> = <jv>annotation</jv>.value();
* </p>
@@ -256,11 +255,11 @@ public class AnnotationInfo<T extends Annotation> {
* <p class='bjava'>
* <jc>// Define an annotation group</jc>
* <ja>@interface</ja> MyGroup {}
- *
+ *
* <jc>// Annotation in the group</jc>
* <ja>@AnnotationGroup</ja>(MyGroup.<jk>class</jk>)
* <ja>@interface</ja> MyAnnotation {}
- *
+ *
* <jc>// Check if annotation is in group</jc>
* AnnotationInfo<MyAnnotation> <jv>ai</jv> = ...;
* <jk>boolean</jk> <jv>inGroup</jv> =
<jv>ai</jv>.isInGroup(MyGroup.<jk>class</jk>); <jc>// Returns true</jc>
@@ -282,7 +281,7 @@ public class AnnotationInfo<T extends Annotation> {
* <h5 class='section'>Example:</h5>
* <p class='bjava'>
* AnnotationInfo<?> <jv>ai</jv> = ...;
- *
+ *
* <jk>if</jk> (<jv>ai</jv>.isType(MyAnnotation.<jk>class</jk>)) {
* <jc>// Handle MyAnnotation specifically</jc>
* }
@@ -644,17 +643,17 @@ public class AnnotationInfo<T extends Annotation> {
* <h5 class='section'>Example:</h5>
* <p class='bjava'>
* <jc>// Get a serializer class from an annotation</jc>
- * Optional<Class<? <jk>extends</jk> Serializer>>
<jv>serializerClass</jv> =
+ * Optional<Class<? <jk>extends</jk> Serializer>>
<jv>serializerClass</jv> =
*
<jv>annotationInfo</jv>.getClassValue(<js>"serializer"</js>,
Serializer.<jk>class</jk>);
* </p>
*
* @param <T> The expected supertype of the class.
* @param methodName The method name.
* @param type The expected supertype of the class value.
- * @return An optional containing the value of the specified method
cast to the expected type,
+ * @return An optional containing the value of the specified method
cast to the expected type,
* or empty if not found, not a class, or not assignable to the
expected type.
*/
- @SuppressWarnings("unchecked")
+ @SuppressWarnings({ "unchecked", "hiding" })
public <T> Optional<Class<? extends T>> getClassValue(String
methodName, Class<T> type) {
return getMethod(methodName)
.filter(x -> x.hasReturnType(Class.class))
@@ -707,17 +706,17 @@ public class AnnotationInfo<T extends Annotation> {
* <h5 class='section'>Example:</h5>
* <p class='bjava'>
* <jc>// Get an array of serializer classes from an
annotation</jc>
- * Optional<Class<? <jk>extends</jk> Serializer>[]>
<jv>serializerClasses</jv> =
+ * Optional<Class<? <jk>extends</jk> Serializer>[]>
<jv>serializerClasses</jv> =
*
<jv>annotationInfo</jv>.getClassArray(<js>"serializers"</js>,
Serializer.<jk>class</jk>);
* </p>
*
* @param <T> The expected supertype of the classes.
* @param methodName The method name.
* @param type The expected supertype of the class values.
- * @return An optional containing the value of the specified method
cast to the expected type,
+ * @return An optional containing the value of the specified method
cast to the expected type,
* or empty if not found, not a class array, or any element is
not assignable to the expected type.
*/
- @SuppressWarnings("unchecked")
+ @SuppressWarnings({ "unchecked", "hiding" })
public <T> Optional<Class<? extends T>[]> getClassArray(String
methodName, Class<T> type) {
return getMethod(methodName)
.filter(x -> x.hasReturnType(Class[].class))
diff --git
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationProvider.java
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationProvider.java
index 00cb119f17..1372ab0619 100644
---
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationProvider.java
+++
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationProvider.java
@@ -817,7 +817,7 @@ public class AnnotationProvider {
var list = new ArrayList<AnnotationInfo<Annotation>>();
MethodInfo.of(forMethod).getMatchingMethods().forEach(m -> {
- runtimeAnnotations.findMatching(m.inner()).forEach(a ->
list.add(AnnotationInfo.of(m, a)));
+ runtimeAnnotations.find(m.inner()).forEach(a ->
list.add(AnnotationInfo.of(m, a)));
list.addAll(m.getDeclaredAnnotations());
});
@@ -828,7 +828,7 @@ public class AnnotationProvider {
var list = new ArrayList<AnnotationInfo<Annotation>>();
FieldInfo fi = FieldInfo.of(forField);
- runtimeAnnotations.findMatching(forField).forEach(a ->
list.add(AnnotationInfo.of(fi, a)));
+ runtimeAnnotations.find(forField).forEach(a ->
list.add(AnnotationInfo.of(fi, a)));
list.addAll(fi.getDeclaredAnnotations());
return u(list);
@@ -838,7 +838,7 @@ public class AnnotationProvider {
var list = new ArrayList<AnnotationInfo<Annotation>>();
ConstructorInfo ci = ConstructorInfo.of(forConstructor);
- runtimeAnnotations.findMatching(forConstructor).forEach(a ->
list.add(AnnotationInfo.of(ci, a)));
+ runtimeAnnotations.find(forConstructor).forEach(a ->
list.add(AnnotationInfo.of(ci, a)));
list.addAll(ci.getDeclaredAnnotations());
return u(list);
@@ -852,7 +852,7 @@ public class AnnotationProvider {
*/
private void findDeclaredAnnotations(List<AnnotationInfo<Annotation>>
appendTo, Class<?> forClass) {
var ci = ClassInfo.of(forClass);
- runtimeAnnotations.findMatching(forClass).forEach(x ->
appendTo.add(AnnotationInfo.of(ClassInfo.of(forClass), x)));
+ runtimeAnnotations.find(forClass).forEach(x ->
appendTo.add(AnnotationInfo.of(ClassInfo.of(forClass), x)));
for (var a : forClass.getDeclaredAnnotations())
for (var a2 : splitRepeated(a))
appendTo.add(AnnotationInfo.of(ci, a2));
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 4f38bf3f13..b053678bce 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
@@ -838,79 +838,6 @@ public class ClassInfo extends ElementInfo implements
Annotatable {
return this;
}
- /**
- * Finds annotations on this class using the specified traversal
settings.
- *
- * <p>
- * This method allows flexible annotation traversal across different
scopes using {@link AnnotationTraversal} enums.
- *
- * <h5 class='section'>Examples:</h5>
- * <p class='bjava'>
- * <jc>// Search class only</jc>
- * Stream<AnnotationInfo<MyAnnotation>> <jv>s1</jv> =
- *
<jv>ci</jv>.findAnnotations(MyAnnotation.<jk>class</jk>, SELF);
- *
- * <jc>// Search class and parents</jc>
- * Stream<AnnotationInfo<MyAnnotation>> <jv>s2</jv> =
- *
<jv>ci</jv>.findAnnotations(MyAnnotation.<jk>class</jk>, SELF, PARENTS);
- *
- * <jc>// Search class, parents, and package</jc>
- * Stream<AnnotationInfo<MyAnnotation>> <jv>s3</jv> =
- *
<jv>ci</jv>.findAnnotations(MyAnnotation.<jk>class</jk>, SELF, PARENTS,
PACKAGE);
- * </p>
- *
- * <p>
- * This does NOT include runtime annotations. For runtime annotation
support, use
- * {@link org.apache.juneau.common.reflect.AnnotationProvider}.
- *
- * @param <A> The annotation type.
- * @param type The annotation type to search for.
- * @param traversals The traversal settings defining what to search
(e.g., SELF, PARENTS, PACKAGE).
- * @return A stream of annotation infos matching the specified type and
traversal settings.
- */
- public <A extends Annotation> Stream<AnnotationInfo<A>>
findAnnotations(Class<A> type, AnnotationTraversal... traversals) {
- assertArgNotNull("type", type);
-
- return Arrays.stream(traversals)
-
.sorted(Comparator.comparingInt(AnnotationTraversal::getOrder))
- .flatMap(traversal -> {
- if (traversal == AnnotationTraversal.SELF) {
- return
Arrays.stream(inner.getDeclaredAnnotations())
- .flatMap(a ->
Arrays.stream(splitRepeated(a)))
- .map(a ->
AnnotationInfo.of(this, a))
- .filter(a -> a.isType(type))
- .map(a -> (AnnotationInfo<A>)a);
- } else if (traversal ==
AnnotationTraversal.PARENTS) {
- return
getParentsAndInterfaces().stream()
- .flatMap(x ->
Arrays.stream(x.inner().getDeclaredAnnotations())
- .flatMap(a ->
Arrays.stream(splitRepeated(a)))
- .map(a ->
AnnotationInfo.of(x, a))
- .filter(a ->
a.isType(type))
- .map(a ->
(AnnotationInfo<A>)a));
- } else if (traversal ==
AnnotationTraversal.PACKAGE) {
- A packageAnn =
getPackageAnnotation(type);
- return nn(packageAnn) ?
Stream.of(AnnotationInfo.of(this, packageAnn)) : Stream.empty();
- }
- throw illegalArg("Invalid traversal type for
class annotations: {0}", traversal);
- });
- }
-
- /**
- * Finds annotations on this class using the specified traversal
settings in parent-first order.
- *
- * <p>
- * This method is identical to {@link #findAnnotations(Class,
AnnotationTraversal...)} but returns
- * results in parent-to-child order.
- *
- * @param <A> The annotation type.
- * @param type The annotation type to search for.
- * @param traversals The traversal settings defining what to search
(e.g., SELF, PARENTS, PACKAGE).
- * @return A stream of annotation infos matching the specified type and
traversal settings in parent-first order.
- */
- public <A extends Annotation> Stream<AnnotationInfo<A>>
findAnnotationsParentFirst(Class<A> type, AnnotationTraversal... traversals) {
- return rstream(findAnnotations(type, traversals).toList());
- }
-
/**
* Returns the first matching method on this class.
*
diff --git
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ConstructorInfo.java
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ConstructorInfo.java
index 3aa25e7661..5b4caec8e6 100644
---
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ConstructorInfo.java
+++
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ConstructorInfo.java
@@ -17,16 +17,7 @@
package org.apache.juneau.common.reflect;
import static org.apache.juneau.common.utils.AssertionUtils.*;
-import static org.apache.juneau.common.utils.ClassUtils.*;
-import static org.apache.juneau.common.utils.CollectionUtils.*;
-import static org.apache.juneau.common.utils.ThrowableUtils.*;
-import static org.apache.juneau.common.utils.Utils.*;
-
-import java.lang.annotation.*;
import java.lang.reflect.*;
-import java.util.*;
-import java.util.stream.*;
-
import org.apache.juneau.common.utils.*;
/**
@@ -95,61 +86,6 @@ public class ConstructorInfo extends ExecutableInfo
implements Comparable<Constr
return this;
}
- /**
- * Finds annotations on this constructor using the specified traversal
settings.
- *
- * <p>
- * This method allows flexible annotation traversal across different
scopes using {@link AnnotationTraversal} enums.
- *
- * <h5 class='section'>Examples:</h5>
- * <p class='bjava'>
- * <jc>// Search constructor only</jc>
- * Stream<AnnotationInfo<MyAnnotation>> <jv>s1</jv> =
- *
<jv>ci</jv>.findAnnotations(MyAnnotation.<jk>class</jk>, SELF);
- * </p>
- *
- * <p>
- * This does NOT include runtime annotations. For runtime annotation
support, use
- * {@link org.apache.juneau.common.reflect.AnnotationProvider}.
- *
- * @param <A> The annotation type.
- * @param type The annotation type to search for.
- * @param traversals The traversal settings defining what to search
(currently only SELF is supported for constructors).
- * @return A stream of annotation infos matching the specified type and
traversal settings.
- */
- public <A extends Annotation> Stream<AnnotationInfo<A>>
findAnnotations(Class<A> type, AnnotationTraversal... traversals) {
- assertArgNotNull("type", type);
-
- return Arrays.stream(traversals)
-
.sorted(Comparator.comparingInt(AnnotationTraversal::getOrder))
- .flatMap(traversal -> {
- if (traversal == AnnotationTraversal.SELF) {
- return
Arrays.stream(inner.getDeclaredAnnotations())
- .flatMap(a ->
Arrays.stream(splitRepeated(a)))
- .map(a ->
AnnotationInfo.of(this, a))
- .filter(a -> a.isType(type))
- .map(a -> (AnnotationInfo<A>)a);
- }
- throw illegalArg("Invalid traversal type for
constructor annotations: {0}", traversal);
- });
- }
-
- /**
- * Finds annotations on this constructor using the specified traversal
settings in parent-first order.
- *
- * <p>
- * This method is identical to {@link #findAnnotations(Class,
AnnotationTraversal...)} but returns
- * results in parent-to-child order.
- *
- * @param <A> The annotation type.
- * @param type The annotation type to search for.
- * @param traversals The traversal settings defining what to search
(currently only SELF is supported for constructors).
- * @return A stream of annotation infos matching the specified type and
traversal settings in parent-first order.
- */
- public <A extends Annotation> Stream<AnnotationInfo<A>>
findAnnotationsParentFirst(Class<A> type, AnnotationTraversal... traversals) {
- return rstream(findAnnotations(type, traversals).toList());
- }
-
@Override
public int compareTo(ConstructorInfo o) {
int i = getSimpleName().compareTo(o.getSimpleName());
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 42b1d7c7d6..441f30955b 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
@@ -19,9 +19,7 @@ package org.apache.juneau.common.reflect;
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.ClassUtils.*;
import static org.apache.juneau.common.utils.CollectionUtils.*;
-import static org.apache.juneau.common.utils.ThrowableUtils.*;
import static org.apache.juneau.common.utils.Utils.*;
import java.lang.annotation.*;
@@ -119,61 +117,6 @@ public class FieldInfo extends AccessibleInfo implements
Comparable<FieldInfo>,
.map(x -> (AnnotationInfo<A>)x);
}
- /**
- * Finds annotations on this field using the specified traversal
settings.
- *
- * <p>
- * This method allows flexible annotation traversal across different
scopes using {@link AnnotationTraversal} enums.
- *
- * <h5 class='section'>Examples:</h5>
- * <p class='bjava'>
- * <jc>// Search field only</jc>
- * Stream<AnnotationInfo<MyAnnotation>> <jv>s1</jv> =
- *
<jv>fi</jv>.findAnnotations(MyAnnotation.<jk>class</jk>, SELF);
- * </p>
- *
- * <p>
- * This does NOT include runtime annotations. For runtime annotation
support, use
- * {@link org.apache.juneau.common.reflect.AnnotationProvider}.
- *
- * @param <A> The annotation type.
- * @param type The annotation type to search for.
- * @param traversals The traversal settings defining what to search
(currently only SELF is supported for fields).
- * @return A stream of annotation infos matching the specified type and
traversal settings.
- */
- public <A extends Annotation> Stream<AnnotationInfo<A>>
findAnnotations(Class<A> type, AnnotationTraversal... traversals) {
- assertArgNotNull("type", type);
-
- return Arrays.stream(traversals)
-
.sorted(Comparator.comparingInt(AnnotationTraversal::getOrder))
- .flatMap(traversal -> {
- if (traversal == AnnotationTraversal.SELF) {
- return
Arrays.stream(inner.getDeclaredAnnotations())
- .flatMap(a ->
Arrays.stream(splitRepeated(a)))
- .map(a ->
AnnotationInfo.of(this, a))
- .filter(a -> a.isType(type))
- .map(a -> (AnnotationInfo<A>)a);
- }
- throw illegalArg("Invalid traversal type for
field annotations: {0}", traversal);
- });
- }
-
- /**
- * Finds annotations on this field using the specified traversal
settings in parent-first order.
- *
- * <p>
- * This method is identical to {@link #findAnnotations(Class,
AnnotationTraversal...)} but returns
- * results in parent-to-child order.
- *
- * @param <A> The annotation type.
- * @param type The annotation type to search for.
- * @param traversals The traversal settings defining what to search
(currently only SELF is supported for fields).
- * @return A stream of annotation infos matching the specified type and
traversal settings in parent-first order.
- */
- public <A extends Annotation> Stream<AnnotationInfo<A>>
findAnnotationsParentFirst(Class<A> type, AnnotationTraversal... traversals) {
- return rstream(findAnnotations(type, traversals).toList());
- }
-
/**
* Attempts to call <code>x.setAccessible(<jk>true</jk>)</code> and
quietly ignores security exceptions.
*
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 4c79cc9a73..ee7d44bd27 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
@@ -17,10 +17,7 @@
package org.apache.juneau.common.reflect;
import static org.apache.juneau.common.utils.AssertionUtils.*;
-import static org.apache.juneau.common.utils.ClassUtils.*;
import static org.apache.juneau.common.utils.CollectionUtils.*;
-import static org.apache.juneau.common.utils.PredicateUtils.*;
-import static org.apache.juneau.common.utils.ThrowableUtils.*;
import static org.apache.juneau.common.utils.Utils.*;
import java.beans.*;
@@ -227,78 +224,6 @@ public class MethodInfo extends ExecutableInfo implements
Comparable<MethodInfo>
return this;
}
- /**
- * Finds annotations on this method using the specified traversal
settings.
- *
- * <p>
- * This method allows flexible annotation traversal across different
scopes using {@link AnnotationTraversal} enums.
- *
- * <h5 class='section'>Examples:</h5>
- * <p class='bjava'>
- * <jc>// Search method only</jc>
- * Stream<AnnotationInfo<MyAnnotation>> <jv>s1</jv> =
- *
<jv>mi</jv>.findAnnotations(MyAnnotation.<jk>class</jk>, SELF);
- *
- * <jc>// Search method and matching methods in parent classes</jc>
- * Stream<AnnotationInfo<MyAnnotation>> <jv>s2</jv> =
- *
<jv>mi</jv>.findAnnotations(MyAnnotation.<jk>class</jk>, SELF,
MATCHING_METHODS);
- *
- * <jc>// Search method, matching methods, and return type</jc>
- * Stream<AnnotationInfo<MyAnnotation>> <jv>s3</jv> =
- *
<jv>mi</jv>.findAnnotations(MyAnnotation.<jk>class</jk>, SELF,
MATCHING_METHODS, RETURN_TYPE);
- * </p>
- *
- * <p>
- * This does NOT include runtime annotations. For runtime annotation
support, use
- * {@link org.apache.juneau.common.reflect.AnnotationProvider}.
- *
- * @param <A> The annotation type.
- * @param type The annotation type to search for.
- * @param traversals The traversal settings defining what to search
(e.g., SELF, MATCHING_METHODS, RETURN_TYPE).
- * @return A stream of annotation infos matching the specified type and
traversal settings.
- */
- public <A extends Annotation> Stream<AnnotationInfo<A>>
findAnnotations(Class<A> type, AnnotationTraversal... traversals) {
- assertArgNotNull("type", type);
-
- return Arrays.stream(traversals)
-
.sorted(Comparator.comparingInt(AnnotationTraversal::getOrder))
- .flatMap(traversal -> {
- if (traversal == AnnotationTraversal.SELF) {
- return
Arrays.stream(inner.getDeclaredAnnotations())
- .flatMap(a ->
Arrays.stream(splitRepeated(a)))
- .map(a ->
AnnotationInfo.of(this, a))
- .filter(a -> a.isType(type))
- .map(a -> (AnnotationInfo<A>)a);
- } else if (traversal ==
AnnotationTraversal.MATCHING_METHODS) {
- return
getMatchingMethods().stream().skip(1)
- .flatMap(x ->
Arrays.stream(x.inner().getDeclaredAnnotations())
- .flatMap(a ->
Arrays.stream(splitRepeated(a)))
- .map(a ->
AnnotationInfo.of(x, a))
- .filter(a ->
a.isType(type))
- .map(a ->
(AnnotationInfo<A>)a));
- } else if (traversal ==
AnnotationTraversal.RETURN_TYPE) {
- return
getReturnType().unwrap(Value.class, Optional.class).findAnnotations(type,
AnnotationTraversal.PARENTS);
- }
- throw illegalArg("Invalid traversal type for
method annotations: {0}", traversal);
- });
- }
-
- /**
- * Finds annotations on this method using the specified traversal
settings in parent-first order.
- *
- * <p>
- * This method is identical to {@link #findAnnotations(Class,
AnnotationTraversal...)} but returns
- * results in parent-to-child order.
- *
- * @param <A> The annotation type.
- * @param type The annotation type to search for.
- * @param traversals The traversal settings defining what to search
(e.g., SELF, MATCHING_METHODS, RETURN_TYPE).
- * @return A stream of annotation infos matching the specified type and
traversal settings in parent-first order.
- */
- public <A extends Annotation> Stream<AnnotationInfo<A>>
findAnnotationsParentFirst(Class<A> type, AnnotationTraversal... traversals) {
- return rstream(findAnnotations(type, traversals).toList());
- }
-
/**
* Returns all annotations on the declaring class, this method and
parent overridden methods, return type, and package in child-to-parent order.
*
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 97b90ae640..305b1d6a54 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
@@ -17,10 +17,7 @@
package org.apache.juneau.common.reflect;
-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.ThrowableUtils.*;
import static org.apache.juneau.common.utils.Utils.*;
import java.lang.annotation.*;
@@ -130,69 +127,6 @@ public class ParameterInfo extends ElementInfo implements
Annotatable {
return getAnnotations().stream().filter(x ->
x.isType(type)).map(x -> (AnnotationInfo<A>)x);
}
- /**
- * Finds annotations on this parameter using the specified traversal
settings.
- *
- * <p>
- * This method allows flexible annotation traversal across different
scopes using {@link AnnotationTraversal} enums.
- *
- * <h5 class='section'>Examples:</h5>
- * <p class='bjava'>
- * <jc>// Search parameter only</jc>
- * Stream<AnnotationInfo<MyAnnotation>> <jv>s1</jv> =
- *
<jv>pi</jv>.findAnnotations(MyAnnotation.<jk>class</jk>, SELF);
- *
- * <jc>// Search parameter and matching parameters in parent
methods</jc>
- * Stream<AnnotationInfo<MyAnnotation>> <jv>s2</jv> =
- *
<jv>pi</jv>.findAnnotations(MyAnnotation.<jk>class</jk>, SELF,
MATCHING_PARAMETERS);
- *
- * <jc>// Search parameter, matching parameters, and parameter
type</jc>
- * Stream<AnnotationInfo<MyAnnotation>> <jv>s3</jv> =
- *
<jv>pi</jv>.findAnnotations(MyAnnotation.<jk>class</jk>, SELF,
MATCHING_PARAMETERS, PARAMETER_TYPE);
- * </p>
- *
- * <p>
- * This does NOT include runtime annotations. For runtime annotation
support, use
- * {@link org.apache.juneau.common.reflect.AnnotationProvider}.
- *
- * @param <A> The annotation type.
- * @param type The annotation type to search for.
- * @param traversals The traversal settings defining what to search
(e.g., SELF, MATCHING_PARAMETERS, PARAMETER_TYPE).
- * @return A stream of annotation infos matching the specified type and
traversal settings.
- */
- public <A extends Annotation> Stream<AnnotationInfo<A>>
findAnnotations(Class<A> type, AnnotationTraversal... traversals) {
- assertArgNotNull("type", type);
-
- return Arrays.stream(traversals)
-
.sorted(Comparator.comparingInt(AnnotationTraversal::getOrder))
- .flatMap(traversal -> {
- if (traversal == AnnotationTraversal.SELF) {
- return getAnnotations(type);
- } else if (traversal ==
AnnotationTraversal.MATCHING_PARAMETERS) {
- return
getMatchingParameters().stream().skip(1).flatMap(x -> x.getAnnotations(type));
- } else if (traversal ==
AnnotationTraversal.PARAMETER_TYPE) {
- return
getParameterType().unwrap(Value.class, Optional.class).findAnnotations(type,
AnnotationTraversal.PARENTS, AnnotationTraversal.PACKAGE);
- }
- throw illegalArg("Invalid traversal type for
parameter annotations: {0}", traversal);
- });
- }
-
- /**
- * Finds annotations on this parameter using the specified traversal
settings in parent-first order.
- *
- * <p>
- * This method is identical to {@link #findAnnotations(Class,
AnnotationTraversal...)} but returns
- * results in parent-to-child order.
- *
- * @param <A> The annotation type.
- * @param type The annotation type to search for.
- * @param traversals The traversal settings defining what to search
(e.g., SELF, MATCHING_PARAMETERS, PARAMETER_TYPE).
- * @return A stream of annotation infos matching the specified type and
traversal settings in parent-first order.
- */
- public <A extends Annotation> Stream<AnnotationInfo<A>>
findAnnotationsParentFirst(Class<A> type, AnnotationTraversal... traversals) {
- return rstream(findAnnotations(type, traversals).toList());
- }
-
/**
* Returns this parameter and all matching parameters in parent classes.
*
diff --git
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ReflectionMap.java
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ReflectionMap.java
index 12bb5bf9f3..a63bd46f1e 100644
---
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ReflectionMap.java
+++
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ReflectionMap.java
@@ -30,12 +30,35 @@ import java.util.stream.*;
import org.apache.juneau.common.utils.*;
/**
- * Allows arbitrary objects to be mapped to classes and methods base on
class/method name keys.
+ * Maps arbitrary values to classes, methods, fields, and constructors based
on name-based patterns.
*
* <p>
- * The valid pattern matches are:
+ * This utility allows you to create flexible mappings between reflection
elements and custom values.
+ * It supports various pattern formats for identifying classes and their
members, with intelligent
+ * matching that handles inner classes, method signatures, and field names.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * <jc>// Create a map that associates visibility levels with specific
classes/methods</jc>
+ * ReflectionMap<Visibility> <jv>map</jv> = ReflectionMap
+ * .<jsm>create</jsm>(Visibility.<jk>class</jk>)
+ * .append(<js>"com.foo.MyClass"</js>,
Visibility.<jsf>PUBLIC</jsf>)
+ * .append(<js>"com.foo.MyClass.secretMethod"</js>,
Visibility.<jsf>PRIVATE</jsf>)
+ * .append(<js>"com.foo.MyClass.internalField"</js>,
Visibility.<jsf>PACKAGE</jsf>)
+ * .build();
+ *
+ * <jc>// Find values for specific reflection elements</jc>
+ * Stream<Visibility> <jv>classVisibility</jv> =
<jv>map</jv>.find(MyClass.<jk>class</jk>);
+ * Stream<Visibility> <jv>methodVisibility</jv> =
<jv>map</jv>.find(<jv>secretMethod</jv>);
+ * </p>
+ *
+ * <h5 class='section'>Supported Pattern Formats:</h5>
+ *
+ * <p>
+ * The following pattern formats are supported for mapping keys:
+ *
* <ul class='spaced-list'>
- * <li>Classes:
+ * <li><b>Classes:</b>
* <ul>
* <li>Fully qualified:
* <ul>
@@ -45,18 +68,22 @@ import org.apache.juneau.common.utils.*;
* <ul>
*
<li><js>"com.foo.MyClass$Inner1$Inner2"</js>
* </ul>
- * <li>Simple:
+ * <li>Simple class name:
* <ul>
* <li><js>"MyClass"</js>
* </ul>
- * <li>Simple inner:
+ * <li>Simple inner class:
* <ul>
* <li><js>"MyClass$Inner1$Inner2"</js>
* <li><js>"Inner1$Inner2"</js>
* <li><js>"Inner2"</js>
* </ul>
+ * <li>All classes wildcard:
+ * <ul>
+ * <li><js>"*"</js>
+ * </ul>
* </ul>
- * <li>Methods:
+ * <li><b>Methods:</b>
* <ul>
* <li>Fully qualified with args:
* <ul>
@@ -64,7 +91,7 @@ import org.apache.juneau.common.utils.*;
*
<li><js>"com.foo.MyClass.myMethod(java.lang.String,int)"</js>
*
<li><js>"com.foo.MyClass.myMethod()"</js>
* </ul>
- * <li>Fully qualified:
+ * <li>Fully qualified without args (matches any args):
* <ul>
* <li><js>"com.foo.MyClass.myMethod"</js>
* </ul>
@@ -74,7 +101,7 @@ import org.apache.juneau.common.utils.*;
*
<li><js>"MyClass.myMethod(java.lang.String,int)"</js>
* <li><js>"MyClass.myMethod()"</js>
* </ul>
- * <li>Simple:
+ * <li>Simple without args (matches any args):
* <ul>
* <li><js>"MyClass.myMethod"</js>
* </ul>
@@ -85,7 +112,7 @@ import org.apache.juneau.common.utils.*;
* <li><js>"Inner2.myMethod"</js>
* </ul>
* </ul>
- * <li>Fields:
+ * <li><b>Fields:</b>
* <ul>
* <li>Fully qualified:
* <ul>
@@ -102,7 +129,7 @@ import org.apache.juneau.common.utils.*;
* <li><js>"Inner2.myField"</js>
* </ul>
* </ul>
- * <li>Constructors:
+ * <li><b>Constructors:</b>
* <ul>
* <li>Fully qualified with args:
* <ul>
@@ -123,19 +150,50 @@ import org.apache.juneau.common.utils.*;
* <li><js>"Inner2()"</js>
* </ul>
* </ul>
- * <li>A comma-delimited list of anything on this list.
+ * <li><b>Multiple patterns:</b>
+ * <ul>
+ * <li>A comma-delimited list of any patterns above:
+ * <ul>
+ * <li><js>"com.foo.MyClass,
com.bar.OtherClass"</js>
+ * <li><js>"MyClass.method1,
MyClass.method2, MyClass.field1"</js>
+ * </ul>
+ * </ul>
+ * </ul>
+ *
+ * <h5 class='section'>Notes:</h5>
+ * <ul class='spaced-list'>
+ * <li>Method and constructor patterns without parentheses match any
method signature.
+ * <li>Method and constructor argument types can be specified with simple
or fully qualified names.
+ * <li>Array types in signatures use either <js>"Type[]"</js> or JVM
notation like <js>"[LType;"</js>.
+ * <li>Generic type parameters are stripped from method signatures during
matching.
+ * <li>Patterns are case-sensitive.
* </ul>
*
- * <h5 class='section'>See Also:</h5><ul>
+ * <h5 class='section'>See Also:</h5>
+ * <ul class='seealso'>
+ * <li class='jc'>{@link ClassInfo}
+ * <li class='jc'>{@link MethodInfo}
+ * <li class='jc'>{@link FieldInfo}
+ * <li class='jc'>{@link ConstructorInfo}
* </ul>
*
- * @param <V> The type of object in this map.
+ * @param <V> The type of values stored in this map.
*/
public class ReflectionMap<V> {
/**
- * Builder class.
- * @param <V> The type of object in this map.
+ * Builder for creating {@link ReflectionMap} instances.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * ReflectionMap<String> <jv>map</jv> = ReflectionMap
+ * .<jsm>create</jsm>(String.<jk>class</jk>)
+ * .append(<js>"MyClass"</js>, <js>"value1"</js>)
+ * .append(<js>"MyClass.myMethod"</js>, <js>"value2"</js>)
+ * .build();
+ * </p>
+ *
+ * @param <V> The type of values stored in this map.
*/
public static class Builder<V> {
final List<ClassEntry<V>> classEntries;
@@ -156,7 +214,7 @@ public class ReflectionMap<V> {
/**
* Copy constructor.
*
- * @param copyFrom The builder being copied.
+ * @param copyFrom The builder to copy from.
*/
protected Builder(Builder<V> copyFrom) {
classEntries = copyOf(copyFrom.classEntries);
@@ -166,21 +224,45 @@ public class ReflectionMap<V> {
}
/**
- * Adds a mapping to this builder.
+ * Adds one or more mappings to this builder.
+ *
+ * <p>
+ * This method accepts pattern strings that identify classes,
methods, fields, or constructors,
+ * and associates them with the specified value. Multiple
patterns can be specified in a single
+ * key using comma-delimited format.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * Builder<String> <jv>builder</jv> =
ReflectionMap.<jsm>create</jsm>(String.<jk>class</jk>);
+ *
+ * <jc>// Map a class</jc>
+ * <jv>builder</jv>.append(<js>"com.foo.MyClass"</js>,
<js>"classValue"</js>);
+ *
+ * <jc>// Map a specific method</jc>
+ *
<jv>builder</jv>.append(<js>"MyClass.myMethod(String,int)"</js>,
<js>"methodValue"</js>);
+ *
+ * <jc>// Map multiple patterns at once</jc>
+ * <jv>builder</jv>.append(<js>"MyClass.field1,
MyClass.field2, MyClass.field3"</js>, <js>"fieldValue"</js>);
+ * </p>
*
* @param key
- * The mapping key.
+ * The mapping key pattern(s).
* <br>Can be any of the following:
* <ul>
- * <li>Full class name (e.g.
<js>"com.foo.MyClass"</js>).
- * <li>Simple class name (e.g. <js>"MyClass"</js>).
- * <li>All classes (e.g. <js>"*"</js>).
- * <li>Full method name (e.g.
<js>"com.foo.MyClass.myMethod"</js>).
- * <li>Simple method name (e.g.
<js>"MyClass.myMethod"</js>).
- * <li>A comma-delimited list of anything on this
list.
+ * <li>Fully qualified class name (e.g.,
<js>"com.foo.MyClass"</js>)
+ * <li>Simple class name (e.g., <js>"MyClass"</js>)
+ * <li>All classes wildcard (e.g., <js>"*"</js>)
+ * <li>Method with signature (e.g.,
<js>"com.foo.MyClass.myMethod(String,int)"</js>)
+ * <li>Method without signature (e.g.,
<js>"MyClass.myMethod"</js>) - matches any signature
+ * <li>Field (e.g., <js>"MyClass.myField"</js>)
+ * <li>Constructor (e.g.,
<js>"MyClass(String,int)"</js>)
+ * <li>Comma-delimited list of any of the above
(e.g., <js>"MyClass, MyClass.method1, MyClass.field1"</js>)
* </ul>
- * @param value The value for this mapping.
+ * @param value
+ * The value to associate with the matching reflection
element(s).
+ * <br>Can be <jk>null</jk>.
* @return This object.
+ * @throws RuntimeException If the key pattern is invalid or
empty.
*/
public Builder<V> append(String key, V value) {
if (StringUtils.isEmpty(key))
@@ -215,9 +297,12 @@ public class ReflectionMap<V> {
}
/**
- * Create new instance of {@link ReflectionMap} based on the
contents of this builder.
+ * Builds a new {@link ReflectionMap} from the current state of
this builder.
+ *
+ * <p>
+ * Multiple calls to this method will create independent copies
of the map.
*
- * @return A new {@link ReflectionMap} object.
+ * @return A new immutable {@link ReflectionMap} instance.
*/
public ReflectionMap<V> build() {
return new ReflectionMap<>(this);
@@ -226,14 +311,29 @@ public class ReflectionMap<V> {
/**
* Creates a copy of this builder.
*
- * @return A copy of this builder.
+ * <p>
+ * Useful for creating variations of a base configuration
without modifying the original builder.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * Builder<String> <jv>base</jv> = ReflectionMap
+ * .<jsm>create</jsm>(String.<jk>class</jk>)
+ * .append(<js>"com.foo.*"</js>,
<js>"baseValue"</js>);
+ *
+ * <jc>// Create a variation without modifying base</jc>
+ * ReflectionMap<String> <jv>map1</jv> =
<jv>base</jv>.copy()
+ * .append(<js>"com.bar.*"</js>,
<js>"additionalValue"</js>)
+ * .build();
+ * </p>
+ *
+ * @return A copy of this builder with all current mappings.
*/
public Builder<V> copy() {
return new Builder<>(this);
}
}
- static class ClassEntry<V> {
+ private static class ClassEntry<V> {
final String simpleName, fullName;
final V value;
@@ -256,12 +356,13 @@ public class ReflectionMap<V> {
.add("simpleName", simpleName)
.add("fullName", fullName)
.add("value", value)
+ .build()
.toString();
// @formatter:on
}
}
- static class ConstructorEntry<V> {
+ private static class ConstructorEntry<V> {
String simpleClassName, fullClassName, args[];
V value;
@@ -289,12 +390,13 @@ public class ReflectionMap<V> {
.add("fullClassName", fullClassName)
.add("args", args)
.add("value", value)
+ .build()
.toString();
// @formatter:on
}
}
- static class FieldEntry<V> {
+ private static class FieldEntry<V> {
String simpleClassName, fullClassName, fieldName;
V value;
@@ -323,12 +425,13 @@ public class ReflectionMap<V> {
.add("fullClassName", fullClassName)
.add("fieldName", fieldName)
.add("value", value)
+ .build()
.toString();
// @formatter:on
}
}
- static class MethodEntry<V> {
+ private static class MethodEntry<V> {
String simpleClassName, fullClassName, methodName, args[];
V value;
@@ -387,25 +490,35 @@ public class ReflectionMap<V> {
.add("simpleClassName", simpleClassName)
.add("fullClassName", fullClassName)
.add("methodName", methodName)
- .add("args", args)
+ .add("args", opt(args).map(x -> '[' + toCdl(x)
+ "]").orElse(null))
.add("value", value)
+ .build()
.toString();
// @formatter:on
}
}
/**
- * Static builder creator.
+ * Creates a new builder for constructing a {@link ReflectionMap}.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * ReflectionMap<String> <jv>map</jv> = ReflectionMap
+ * .<jsm>create</jsm>(String.<jk>class</jk>)
+ * .append(<js>"com.foo.MyClass"</js>, <js>"value1"</js>)
+ * .append(<js>"com.foo.MyClass.myMethod"</js>,
<js>"value2"</js>)
+ * .build();
+ * </p>
*
- * @param <V> The type of object in this map.
- * @param c The type of object in this map.
- * @return A new instance of this object.
+ * @param <V> The type of values stored in the map.
+ * @param c The class type of values (used for type safety, not stored).
+ * @return A new builder instance.
*/
public static <V> Builder<V> create(Class<V> c) {
return new Builder<>();
}
- static boolean argsMatch(String[] names, Class<?>[] args) {
+ private static boolean argsMatch(String[] names, Class<?>[] args) {
if (names == null)
return true;
if (names.length != args.length)
@@ -419,7 +532,7 @@ public class ReflectionMap<V> {
return true;
}
- static boolean classMatches(String simpleName, String fullName,
Class<?> c) {
+ private static boolean classMatches(String simpleName, String fullName,
Class<?> c) {
// For class
org.apache.juneau.a.rttests.RountTripBeansWithBuilders$Ac$Builder
// c.getSimpleName() == "Builder"
// c.getFullName() ==
"org.apache.juneau.a.rttests.RountTripBeansWithBuilders$Ac$Builder"
@@ -445,14 +558,14 @@ public class ReflectionMap<V> {
return false;
}
- static String simpleClassName(String name) {
+ private static String simpleClassName(String name) {
int i = name.indexOf('.');
if (i == -1)
return name;
return null;
}
- static void splitNames(String key, Consumer<String> consumer) {
+ private static void splitNames(String key, Consumer<String> consumer) {
if (key.indexOf(',') == -1) {
consumer.accept(key);
} else {
@@ -474,17 +587,14 @@ public class ReflectionMap<V> {
}
final List<ClassEntry<V>> classEntries;
-
final List<MethodEntry<V>> methodEntries;
-
final List<FieldEntry<V>> fieldEntries;
-
final List<ConstructorEntry<V>> constructorEntries;
/**
* Constructor.
*
- * @param b Initializer object.
+ * @param b The builder containing the mappings to initialize this map
with.
*/
protected ReflectionMap(Builder<V> b) {
this.classEntries = u(copyOf(b.classEntries));
@@ -493,260 +603,111 @@ public class ReflectionMap<V> {
this.constructorEntries = u(copyOf(b.constructorEntries));
}
- public Stream<V> findMatching(Class<?> c) {
- return classEntries.stream().filter(x -> x.matches(c)).map(x ->
x.value);
- }
-
- public Stream<V> findMatching(Method m) {
- return methodEntries.stream().filter(x -> x.matches(m)).map(x
-> x.value);
- }
-
- public Stream<V> findMatching(Field f) {
- return fieldEntries.stream().filter(x -> x.matches(f)).map(x ->
x.value);
- }
-
- public Stream<V> findMatching(Constructor c) {
- return constructorEntries.stream().filter(x ->
x.matches(c)).map(x -> x.value);
- }
-
/**
- * Finds first value in this map that matches the specified class.
+ * Finds all values associated with the specified class.
*
- * @param c The class to test for.
- * @return The matching object. Never <jk>null</jk>.
- */
- public Optional<V> find(Class<?> c) {
- return find(c, null);
- }
-
- /**
- * Finds first value in this map that matches the specified class.
+ * <p>
+ * This method searches for mappings that match the given class,
including patterns for
+ * the fully qualified name, simple name, inner class names, and
wildcard patterns.
*
- * @param c The class to test for.
- * @param ofType Only return objects of the specified type.
- * @return The matching object. Never <jk>null</jk>.
- */
- public Optional<V> find(Class<?> c, Class<? extends V> ofType) {
- return opt(findMatching(c).filter(x -> x != null && (ofType ==
null || ofType.isInstance(x))).findFirst().orElse(null));
- }
-
- /**
- * Finds first value in this map that matches the specified constructor.
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * ReflectionMap<String> <jv>map</jv> = ReflectionMap
+ * .<jsm>create</jsm>(String.<jk>class</jk>)
+ * .append(<js>"com.foo.MyClass"</js>, <js>"value1"</js>)
+ * .append(<js>"MyClass"</js>, <js>"value2"</js>)
+ * .build();
*
- * @param c The constructor to test for.
- * @return The matching object. Never <jk>null</jk>.
- */
- public Optional<V> find(Constructor<?> c) {
- return find(c, null);
- }
-
- /**
- * Finds first value in this map that matches the specified constructor.
+ * <jc>// Find all values for MyClass</jc>
+ * Stream<String> <jv>values</jv> =
<jv>map</jv>.find(MyClass.<jk>class</jk>);
+ * <jc>// Returns stream containing ["value1", "value2"]</jc>
+ * </p>
*
- * @param c The constructor to test for.
- * @param ofType Only return objects of the specified type.
- * @return The matching object. Never <jk>null</jk>.
+ * @param c The class to find mappings for. Can be <jk>null</jk>.
+ * @return A stream of all values associated with the class. Empty
stream if no matches found.
*/
- public Optional<V> find(Constructor<?> c, Class<? extends V> ofType) {
- return opt(findMatching(c).filter(x -> x != null && (ofType ==
null || ofType.isInstance(x))).findFirst().orElse(null));
- }
-
- /**
- * Finds first value in this map that matches the specified field.
- *
- * @param f The field to test for.
- * @return The matching object. Never <jk>null</jk>.
- */
- public Optional<V> find(Field f) {
- return find(f, null);
- }
-
- /**
- * Finds first value in this map that matches the specified field.
- *
- * @param f The field to test for.
- * @param ofType Only return objects of the specified type.
- * @return The matching object. Never <jk>null</jk>.
- */
- public Optional<V> find(Field f, Class<? extends V> ofType) {
- return opt(findMatching(f).filter(x -> x != null && (ofType ==
null || ofType.isInstance(x))).findFirst().orElse(null));
- }
-
- /**
- * Finds first value in this map that matches the specified method.
- *
- * @param m The method to test for.
- * @return The matching object. Never <jk>null</jk>.
- */
- public Optional<V> find(Method m) {
- return find(m, null);
+ public Stream<V> find(Class<?> c) {
+ return classEntries.stream().filter(x -> x.matches(c)).map(x ->
x.value);
}
/**
- * Finds first value in this map that matches the specified method.
+ * Finds all values associated with the specified constructor.
*
- * @param m The method to test for.
- * @param ofType Only return objects of the specified type.
- * @return The matching object. Never <jk>null</jk>.
- */
- public Optional<V> find(Method m, Class<? extends V> ofType) {
- return opt(findMatching(m).filter(x -> x != null && (ofType ==
null || ofType.isInstance(x))).findFirst().orElse(null));
- }
-
- /**
- * Finds all values in this map that match the specified class.
+ * <p>
+ * This method searches for mappings that match the given constructor,
considering both
+ * the declaring class and parameter types.
*
- * @param c The class to test for.
- * @return The matching objects. Never <jk>null</jk>.
- */
- public List<V> findAll(Class<?> c) {
- return findAll(c, null);
- }
-
- /**
- * Finds all values in this map that match the specified class.
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * ReflectionMap<String> <jv>map</jv> = ReflectionMap
+ * .<jsm>create</jsm>(String.<jk>class</jk>)
+ * .append(<js>"MyClass(String,int)"</js>,
<js>"value1"</js>)
+ * .build();
*
- * @param c The class to test for.
- * @param ofType Only return objects of the specified type.
- * @return The matching objects. Never <jk>null</jk>.
- */
- public List<V> findAll(Class<?> c, Class<? extends V> ofType) {
- return findMatching(c).filter(x -> ofType == null ||
ofType.isInstance(x)).toList();
- }
-
- /**
- * Finds all values in this map that match the specified constructor.
+ * <jc>// Find value for specific constructor</jc>
+ * Constructor<?> <jv>ctor</jv> =
MyClass.<jk>class</jk>.getConstructor(String.<jk>class</jk>,
<jk>int</jk>.<jk>class</jk>);
+ * Stream<String> <jv>values</jv> =
<jv>map</jv>.find(<jv>ctor</jv>);
+ * </p>
*
- * @param c The constructor to test for.
- * @return The matching objects. Never <jk>null</jk>.
+ * @param c The constructor to find mappings for. Can be <jk>null</jk>.
+ * @return A stream of all values associated with the constructor.
Empty stream if no matches found.
*/
- public List<V> findAll(Constructor<?> c) {
- return findAll(c, null);
- }
-
- /**
- * Finds all values in this map that match the specified constructor.
- *
- * @param c The constructor to test for.
- * @param ofType Only return objects of the specified type.
- * @return The matching objects. Never <jk>null</jk>.
- */
- public List<V> findAll(Constructor<?> c, Class<? extends V> ofType) {
- return findMatching(c).filter(x -> ofType == null ||
ofType.isInstance(x)).toList();
+ public Stream<V> find(Constructor<?> c) {
+ return constructorEntries.stream().filter(x ->
x.matches(c)).map(x -> x.value);
}
/**
- * Finds all values in this map that match the specified field.
+ * Finds all values associated with the specified field.
*
- * @param f The field to test for.
- * @return The matching objects. Never <jk>null</jk>.
- */
- public List<V> findAll(Field f) {
- return findAll(f, null);
- }
-
- /**
- * Finds all values in this map that match the specified field.
+ * <p>
+ * This method searches for mappings that match the given field,
considering both
+ * the declaring class and field name.
*
- * @param f The field to test for.
- * @param ofType Only return objects of the specified type.
- * @return The matching objects. Never <jk>null</jk>.
- */
- public List<V> findAll(Field f, Class<? extends V> ofType) {
- return findMatching(f).filter(x -> ofType == null ||
ofType.isInstance(x)).toList();
- }
-
- /**
- * Finds all values in this map that match the specified method.
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * ReflectionMap<String> <jv>map</jv> = ReflectionMap
+ * .<jsm>create</jsm>(String.<jk>class</jk>)
+ * .append(<js>"MyClass.myField"</js>, <js>"value1"</js>)
+ * .build();
*
- * @param m The method to test for.
- * @return The matching objects. Never <jk>null</jk>.
- */
- public List<V> findAll(Method m) {
- return findAll(m, null);
- }
-
- /**
- * Finds all values in this map that match the specified method.
+ * <jc>// Find value for specific field</jc>
+ * Field <jv>field</jv> =
MyClass.<jk>class</jk>.getField(<js>"myField"</js>);
+ * Stream<String> <jv>values</jv> =
<jv>map</jv>.find(<jv>field</jv>);
+ * </p>
*
- * @param m The method to test for.
- * @param ofType Only return objects of the specified type.
- * @return The matching objects. Never <jk>null</jk>.
+ * @param f The field to find mappings for. Can be <jk>null</jk>.
+ * @return A stream of all values associated with the field. Empty
stream if no matches found.
*/
- public List<V> findAll(Method m, Class<? extends V> ofType) {
- return findMatching(m).filter(x -> ofType == null ||
ofType.isInstance(x)).toList();
+ public Stream<V> find(Field f) {
+ return fieldEntries.stream().filter(x -> x.matches(f)).map(x ->
x.value);
}
/**
- * Finds all values in this map that match the specified class and
appends them to the specified array.
+ * Finds all values associated with the specified method.
*
- * @param c The class to test for.
- * @param ofType Only return objects of the specified type.
- * @param array The array to append to.
- * @return The array with matching objects appended.
- */
- public V[] appendAll(Class<?> c, Class<? extends V> ofType, V[] array) {
- var list = findAll(c, ofType);
- if (list.isEmpty())
- return array;
- var newArray = Arrays.copyOf(array, array.length + list.size());
- for (int i = 0; i < list.size(); i++)
- newArray[array.length + i] = list.get(i);
- return newArray;
- }
-
- /**
- * Finds all values in this map that match the specified constructor
and appends them to the specified array.
+ * <p>
+ * This method searches for mappings that match the given method,
considering the
+ * declaring class, method name, and parameter types.
*
- * @param c The constructor to test for.
- * @param ofType Only return objects of the specified type.
- * @param array The array to append to.
- * @return The array with matching objects appended.
- */
- public V[] appendAll(Constructor<?> c, Class<? extends V> ofType, V[]
array) {
- var list = findAll(c, ofType);
- if (list.isEmpty())
- return array;
- var newArray = Arrays.copyOf(array, array.length + list.size());
- for (int i = 0; i < list.size(); i++)
- newArray[array.length + i] = list.get(i);
- return newArray;
- }
-
- /**
- * Finds all values in this map that match the specified field and
appends them to the specified array.
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * ReflectionMap<String> <jv>map</jv> = ReflectionMap
+ * .<jsm>create</jsm>(String.<jk>class</jk>)
+ * .append(<js>"MyClass.myMethod"</js>, <js>"value1"</js>)
+ * .append(<js>"MyClass.myMethod(String)"</js>,
<js>"value2"</js>)
+ * .build();
*
- * @param f The field to test for.
- * @param ofType Only return objects of the specified type.
- * @param array The array to append to.
- * @return The array with matching objects appended.
- */
- public V[] appendAll(Field f, Class<? extends V> ofType, V[] array) {
- var list = findAll(f, ofType);
- if (list.isEmpty())
- return array;
- var newArray = Arrays.copyOf(array, array.length + list.size());
- for (int i = 0; i < list.size(); i++)
- newArray[array.length + i] = list.get(i);
- return newArray;
- }
-
- /**
- * Finds all values in this map that match the specified method and
appends them to the specified array.
+ * <jc>// Find values for specific method</jc>
+ * Method <jv>method</jv> =
MyClass.<jk>class</jk>.getMethod(<js>"myMethod"</js>, String.<jk>class</jk>);
+ * Stream<String> <jv>values</jv> =
<jv>map</jv>.find(<jv>method</jv>);
+ * <jc>// Returns stream containing ["value1", "value2"] - first
matches any signature</jc>
+ * </p>
*
- * @param m The method to test for.
- * @param ofType Only return objects of the specified type.
- * @param array The array to append to.
- * @return The array with matching objects appended.
+ * @param m The method to find mappings for. Can be <jk>null</jk>.
+ * @return A stream of all values associated with the method. Empty
stream if no matches found.
*/
- public V[] appendAll(Method m, Class<? extends V> ofType, V[] array) {
- var list = findAll(m, ofType);
- if (list.isEmpty())
- return array;
- var newArray = Arrays.copyOf(array, array.length + list.size());
- for (int i = 0; i < list.size(); i++)
- newArray[array.length + i] = list.get(i);
- return newArray;
+ public Stream<V> find(Method m) {
+ return methodEntries.stream().filter(x -> x.matches(m)).map(x
-> x.value);
}
@Override /* Overridden from Object */
@@ -757,6 +718,7 @@ public class ReflectionMap<V> {
.add("methodEntries", methodEntries)
.add("fieldEntries", fieldEntries)
.add("constructorEntries", constructorEntries)
+ .build()
.toString();
// @formatter:on
}
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 0ddd6d6651..b57d77a60d 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,10 +18,7 @@ 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.*;
/**
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 3c30c54df3..65e8d96592 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,8 +34,6 @@ 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.*;
import org.apache.juneau.annotation.*;
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/BasicDebugEnablement.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/BasicDebugEnablement.java
index bec796d635..eac63cc40e 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/BasicDebugEnablement.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/BasicDebugEnablement.java
@@ -18,13 +18,11 @@ package org.apache.juneau.rest.debug;
import static org.apache.juneau.common.utils.CollectionUtils.*;
import static org.apache.juneau.common.utils.StringUtils.*;
+import static org.apache.juneau.common.utils.Utils.*;
import static org.apache.juneau.rest.annotation.RestOpAnnotation.*;
import java.util.*;
-import java.util.stream.*;
-
import org.apache.juneau.*;
-import org.apache.juneau.common.collections.*;
import org.apache.juneau.cp.*;
import org.apache.juneau.common.reflect.*;
import org.apache.juneau.rest.*;
@@ -90,8 +88,7 @@ public class BasicDebugEnablement extends DebugEnablement {
.filter(REST_OP_GROUP)
.flatMap(ai ->
ai.getValue(String.class, "debug").stream())
.map(varResolver::resolve)
- .filter(y -> ! y.isEmpty())
- .forEach(y ->
b.enable(Enablement.fromString(y), x.getFullName()))
+ .forEach(y ->
opt(Enablement.fromString(y)).ifPresent(e -> b.enable(e, x.getFullName())))
);
// @formatter:on
@@ -105,7 +102,7 @@ public class BasicDebugEnablement extends DebugEnablement {
if (v.isEmpty())
v = "ALWAYS";
if (! k.isEmpty())
- b.enable(Enablement.fromString(v), k);
+
opt(Enablement.fromString(v)).ifPresent(en -> b.enable(en, k));
}
});
// @formatter:on
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/DebugEnablement.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/DebugEnablement.java
index 99c33132c7..e04c995519 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/DebugEnablement.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/DebugEnablement.java
@@ -253,7 +253,7 @@ public abstract class DebugEnablement {
*/
public boolean isDebug(RestContext context, HttpServletRequest req) {
Class<?> c = context.getResourceClass();
- Enablement e = enablementMap.find(c).orElse(defaultEnablement);
+ Enablement e =
enablementMap.find(c).findFirst().orElse(defaultEnablement);
return e == ALWAYS || (e == CONDITIONAL &&
isConditionallyEnabled(req));
}
@@ -270,7 +270,8 @@ public abstract class DebugEnablement {
*/
public boolean isDebug(RestOpContext context, HttpServletRequest req) {
Method m = context.getJavaMethod();
- Enablement e =
enablementMap.find(m).orElse(enablementMap.find(m.getDeclaringClass()).orElse(defaultEnablement));
+ Enablement e = enablementMap.find(m).findFirst()
+ .orElseGet(() ->
enablementMap.find(m.getDeclaringClass()).findFirst().orElse(defaultEnablement));
return e == ALWAYS || (e == CONDITIONAL &&
isConditionallyEnabled(req));
}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/matcher/ClientVersionMatcher.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/matcher/ClientVersionMatcher.java
index 9a5d87ae52..29a0c21e05 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/matcher/ClientVersionMatcher.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/matcher/ClientVersionMatcher.java
@@ -20,8 +20,6 @@ import static
org.apache.juneau.common.utils.CollectionUtils.*;
import static org.apache.juneau.common.utils.StringUtils.*;
import static org.apache.juneau.rest.annotation.RestOpAnnotation.*;
-import java.util.stream.*;
-
import org.apache.juneau.common.collections.*;
import org.apache.juneau.common.utils.*;
import org.apache.juneau.common.reflect.*;
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/common/reflect/ReflectionMapTest.java
b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/ReflectionMapTest.java
deleted file mode 100644
index d35df256f0..0000000000
---
a/juneau-utest/src/test/java/org/apache/juneau/common/reflect/ReflectionMapTest.java
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.juneau.common.reflect;
-
-import static org.apache.juneau.TestUtils.*;
-import static org.apache.juneau.junit.bct.BctAssertions.*;
-import static org.junit.jupiter.api.Assertions.*;
-
-import java.lang.reflect.*;
-
-import org.apache.juneau.*;
-import org.junit.jupiter.api.*;
-
-class ReflectionMapTest extends TestBase {
-
- private static ReflectionMap.Builder<Number> create() {
- return ReflectionMap.create(Number.class);
- }
-
- private static void checkEntries(ReflectionMap<?> m, boolean hasClass,
boolean hasMethods, boolean hasFields, boolean hasConstructors) {
- assertEquals(m.classEntries.size() == 0, ! hasClass);
- assertEquals(m.methodEntries.size() == 0, ! hasMethods);
- assertEquals(m.fieldEntries.size() == 0, ! hasFields);
- assertEquals(m.constructorEntries.size() == 0, !
hasConstructors);
- }
-
-
//------------------------------------------------------------------------------------------------------------------
- // Class names
-
//------------------------------------------------------------------------------------------------------------------
-
- static class A1 {}
- static class A2 {}
-
- static ReflectionMap<Number>
- A1_SIMPLE = create().append("A1", 1).build(),
- A1b_SIMPLE = create().append("ReflectionMapTest$A1", 1).build(),
- A1_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$A1",
1).build(); // Note this could be a static field.
-
- @Test void a01_classNames_checkEntries() {
- checkEntries(A1_SIMPLE, true, false, false, false);
- checkEntries(A1_FULL, true, false, true, false);
- }
-
- private static void checkA(Class<?> c, boolean match_A1_SIMPLE, boolean
match_A1b_SIMPLE, boolean match_A1_FULL) {
- assertEquals(match_A1_SIMPLE, A1_SIMPLE.find(c,
null).isPresent());
- assertEquals(match_A1b_SIMPLE, A1b_SIMPLE.find(c,
null).isPresent());
- assertEquals(match_A1_FULL, A1_FULL.find(c, null).isPresent());
-
- assertEquals(match_A1_SIMPLE, A1_SIMPLE.find(c,
Integer.class).isPresent());
- assertEquals(match_A1b_SIMPLE, A1b_SIMPLE.find(c,
Integer.class).isPresent());
- assertEquals(match_A1_FULL, A1_FULL.find(c,
Integer.class).isPresent());
-
- assertFalse(A1_SIMPLE.find(c, Long.class).isPresent());
- assertFalse(A1b_SIMPLE.find(c, Long.class).isPresent());
- assertFalse(A1_FULL.find(c, Long.class).isPresent());
-
- assertEquals(match_A1_SIMPLE, !A1_SIMPLE.findAll(c,
null).isEmpty());
- assertEquals(match_A1b_SIMPLE, !A1b_SIMPLE.findAll(c,
null).isEmpty());
- assertEquals(match_A1_FULL, !A1_FULL.findAll(c,
null).isEmpty());
-
- assertEquals(match_A1_SIMPLE, !A1_SIMPLE.findAll(c,
Integer.class).isEmpty());
- assertEquals(match_A1b_SIMPLE, !A1b_SIMPLE.findAll(c,
Integer.class).isEmpty());
- assertEquals(match_A1_FULL, !A1_FULL.findAll(c,
Integer.class).isEmpty());
-
- assertFalse(A1_SIMPLE.find(c, Long.class).isPresent());
- assertFalse(A1b_SIMPLE.find(c, Long.class).isPresent());
- assertFalse(A1_FULL.find(c, Long.class).isPresent());
- }
-
- @Test void a02_classNames_find() {
- checkA(A1.class, true, true, true);
- checkA(A2.class, false, false, false);
- checkA(null, false, false, false);
- }
-
-
//------------------------------------------------------------------------------------------------------------------
- // Method names
-
//------------------------------------------------------------------------------------------------------------------
-
- static class B1 {
- public void m1() { /* no-op */ }
- public void m1(int x) { /* no-op */ }
- public void m1(String x) { /* no-op */ }
- public void m1(String x, int y) { /* no-op */ }
- public void m2(int x) { /* no-op */ }
- }
- static class B2 {
- public void m1() { /* no-op */ }
- }
-
- static ReflectionMap<Number>
- B1m1_SIMPLE = create().append("B1.m1", 1).build(),
- B1m1i_SIMPLE = create().append("B1.m1(int)", 1).build(),
- B1m1s_SIMPLE = create().append("B1.m1(String)", 1).build(),
- B1m1ss_SIMPLE = create().append("B1.m1(java.lang.String)",
1).build(),
- B1m1si_SIMPLE = create().append("B1.m1(String,int)", 1).build(),
- B1m1ssi_SIMPLE = create().append("B1.m1(java.lang.String ,
int)", 1).build(),
- B1m1_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$B1.m1",
1).build(),
- B1m1i_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$B1.m1(int)",
1).build(),
- B1m1s_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$B1.m1(String)",
1).build(),
- B1m1ss_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$B1.m1(java.lang.String)",
1).build(),
- B1m1si_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$B1.m1(String,int)",
1).build(),
- B1m1ssi_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$B1.m1(java.lang.String
, int)", 1).build();
-
- @Test void b01_methodNames_checkEntries() {
- checkEntries(B1m1_SIMPLE, false, true, true, false);
- checkEntries(B1m1i_SIMPLE, false, true, false, false);
- checkEntries(B1m1s_SIMPLE, false, true, false, false);
- checkEntries(B1m1ss_SIMPLE, false, true, false, false);
- checkEntries(B1m1si_SIMPLE, false, true, false, false);
- checkEntries(B1m1ssi_SIMPLE, false, true, false, false);
- checkEntries(B1m1_FULL, false, true, true, false);
- checkEntries(B1m1i_FULL, false, true, false, false);
- checkEntries(B1m1s_FULL, false, true, false, false);
- checkEntries(B1m1ss_FULL, false, true, false, false);
- checkEntries(B1m1si_FULL, false, true, false, false);
- checkEntries(B1m1ssi_FULL, false, true, false, false);
- }
-
- private static void checkB(Method m, boolean match_B1m1_SIMPLE, boolean
match_B1m1i_SIMPLE, boolean match_B1m1s_SIMPLE, boolean match_B1m1ss_SIMPLE,
- boolean match_B1m1si_SIMPLE, boolean
match_B1m1ssi_SIMPLE, boolean match_B1m1_FULL, boolean match_B1m1i_FULL,
boolean match_B1m1s_FULL,
- boolean match_B1m1ss_FULL, boolean match_B1m1si_FULL,
boolean match_B1m1ssi_FULL) {
-
- assertEquals(match_B1m1_SIMPLE, B1m1_SIMPLE.find(m,
null).isPresent());
- assertEquals(match_B1m1i_SIMPLE, B1m1i_SIMPLE.find(m,
null).isPresent());
- assertEquals(match_B1m1s_SIMPLE, B1m1s_SIMPLE.find(m,
null).isPresent());
- assertEquals(match_B1m1ss_SIMPLE, B1m1ss_SIMPLE.find(m,
null).isPresent());
- assertEquals(match_B1m1si_SIMPLE, B1m1si_SIMPLE.find(m,
null).isPresent());
- assertEquals(match_B1m1ssi_SIMPLE, B1m1ssi_SIMPLE.find(m,
null).isPresent());
- assertEquals(match_B1m1_FULL, B1m1_FULL.find(m,
null).isPresent());
- assertEquals(match_B1m1i_FULL, B1m1i_FULL.find(m,
null).isPresent());
- assertEquals(match_B1m1s_FULL, B1m1s_FULL.find(m,
null).isPresent());
- assertEquals(match_B1m1ss_FULL, B1m1ss_FULL.find(m,
null).isPresent());
- assertEquals(match_B1m1si_FULL, B1m1si_FULL.find(m,
null).isPresent());
- assertEquals(match_B1m1ssi_FULL, B1m1ssi_FULL.find(m,
null).isPresent());
-
- assertEquals(match_B1m1_SIMPLE, B1m1_SIMPLE.find(m,
Integer.class).isPresent());
- assertEquals(match_B1m1i_SIMPLE, B1m1i_SIMPLE.find(m,
Integer.class).isPresent());
- assertEquals(match_B1m1s_SIMPLE, B1m1s_SIMPLE.find(m,
Integer.class).isPresent());
- assertEquals(match_B1m1ss_SIMPLE, B1m1ss_SIMPLE.find(m,
Integer.class).isPresent());
- assertEquals(match_B1m1si_SIMPLE, B1m1si_SIMPLE.find(m,
Integer.class).isPresent());
- assertEquals(match_B1m1ssi_SIMPLE, B1m1ssi_SIMPLE.find(m,
Integer.class).isPresent());
- assertEquals(match_B1m1_FULL, B1m1_FULL.find(m,
Integer.class).isPresent());
- assertEquals(match_B1m1i_FULL, B1m1i_FULL.find(m,
Integer.class).isPresent());
- assertEquals(match_B1m1s_FULL, B1m1s_FULL.find(m,
Integer.class).isPresent());
- assertEquals(match_B1m1ss_FULL, B1m1ss_FULL.find(m,
Integer.class).isPresent());
- assertEquals(match_B1m1si_FULL, B1m1si_FULL.find(m,
Integer.class).isPresent());
- assertEquals(match_B1m1ssi_FULL, B1m1ssi_FULL.find(m,
Integer.class).isPresent());
-
- assertFalse(B1m1_SIMPLE.find(m, Long.class).isPresent());
- assertFalse(B1m1i_SIMPLE.find(m, Long.class).isPresent());
- assertFalse(B1m1s_SIMPLE.find(m, Long.class).isPresent());
- assertFalse(B1m1ss_SIMPLE.find(m, Long.class).isPresent());
- assertFalse(B1m1si_SIMPLE.find(m, Long.class).isPresent());
- assertFalse(B1m1ssi_SIMPLE.find(m, Long.class).isPresent());
- assertFalse(B1m1_FULL.find(m, Long.class).isPresent());
- assertFalse(B1m1i_FULL.find(m, Long.class).isPresent());
- assertFalse(B1m1s_FULL.find(m, Long.class).isPresent());
- assertFalse(B1m1ss_FULL.find(m, Long.class).isPresent());
- assertFalse(B1m1si_FULL.find(m, Long.class).isPresent());
- assertFalse(B1m1ssi_FULL.find(m, Long.class).isPresent());
- }
-
- @Test void b02_methodName_find() throws Exception {
- checkB(B1.class.getMethod("m1"), true, false, false, false,
false, false, true, false, false, false, false, false);
- checkB(B1.class.getMethod("m1", int.class), true, true, false,
false, false, false, true, true, false, false, false, false);
- checkB(B1.class.getMethod("m1", String.class), true, false,
true, true, false, false, true, false, true, true, false, false);
- checkB(B1.class.getMethod("m1", String.class, int.class), true,
false, false, false, true, true, true, false, false, false, true, true);
- checkB(B1.class.getMethod("m2", int.class), false, false,
false, false, false, false, false, false, false, false, false, false);
- checkB(B2.class.getMethod("m1"), false, false, false, false,
false, false, false, false, false, false, false, false);
- checkB(null, false, false, false, false, false, false, false,
false, false, false, false, false);
- }
-
-
//------------------------------------------------------------------------------------------------------------------
- // Field names
-
//------------------------------------------------------------------------------------------------------------------
-
- static class C1 {
- public int f1;
- public int f2;
- }
- static class C2 {
- public int f1;
- }
-
- static ReflectionMap<Number>
- C1f1_SIMPLE = create().append("C1.f1", 1).build(),
- C1f1_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$C1.f1",
1).build();
-
- @Test void c01_fieldNames_checkEntries() {
- checkEntries(C1f1_SIMPLE, false, true, true, false);
- checkEntries(C1f1_FULL, false, true, true, false);
- }
-
- private static void checkC(Field f, boolean match_C1f1_SIMPLE, boolean
match_C1f1_FULL) {
- assertEquals(match_C1f1_SIMPLE, C1f1_SIMPLE.find(f,
null).isPresent());
- assertEquals(match_C1f1_FULL, C1f1_FULL.find(f,
null).isPresent());
-
- assertEquals(match_C1f1_SIMPLE, C1f1_SIMPLE.find(f,
Integer.class).isPresent());
- assertEquals(match_C1f1_FULL, C1f1_FULL.find(f,
Integer.class).isPresent());
-
- assertFalse(C1f1_SIMPLE.find(f, Long.class).isPresent());
- assertFalse(C1f1_FULL.find(f, Long.class).isPresent());
- }
-
- @Test void c02_fieldName_find() throws Exception {
- checkC(C1.class.getField("f1"), true, true);
- checkC(C1.class.getField("f2"), false, false);
- checkC(C2.class.getField("f1"), false, false);
- checkC(null, false, false);
- }
-
-
//------------------------------------------------------------------------------------------------------------------
- // Constructor names
-
//------------------------------------------------------------------------------------------------------------------
-
- static class D1 {
- public D1() { /* no-op */ }
- public D1(int x) { /* no-op */ }
- public D1(String x) { /* no-op */ }
- public D1(String x, int y) { /* no-op */ }
- }
- static class D2 {
- public D2() { /* no-op */ }
- }
-
- static ReflectionMap<Number>
- D_SIMPLE = create().append("D1()", 1).build(),
- Di_SIMPLE = create().append("D1(int)", 1).build(),
- Ds_SIMPLE = create().append("D1(String)", 1).build(),
- Dss_SIMPLE = create().append("D1(java.lang.String)", 1).build(),
- Dsi_SIMPLE = create().append("D1(String, int)", 1).build(),
- Dssi_SIMPLE = create().append("D1(java.lang.String, int)",
1).build(),
- D_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$D1()",
1).build(),
- Di_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$D1(int)",
1).build(),
- Ds_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$D1(String)",
1).build(),
- Dss_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$D1(java.lang.String)",
1).build(),
- Dsi_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$D1(String,
int)", 1).build(),
- Dssi_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$D1(java.lang.String,
int)", 1).build();
-
- @Test void d01_constructorNames_checkEntries() {
- checkEntries(D_SIMPLE, false, false, false, true);
- checkEntries(Di_SIMPLE, false, false, false, true);
- checkEntries(Ds_SIMPLE, false, false, false, true);
- checkEntries(Dss_SIMPLE, false, false, false, true);
- checkEntries(Dsi_SIMPLE, false, false, false, true);
- checkEntries(Dssi_SIMPLE, false, false, false, true);
- checkEntries(D_FULL, false, false, false, true);
- checkEntries(Di_FULL, false, false, false, true);
- checkEntries(Ds_FULL, false, false, false, true);
- checkEntries(Dss_FULL, false, false, false, true);
- checkEntries(Dsi_FULL, false, false, false, true);
- checkEntries(Dssi_FULL, false, false, false, true);
- }
-
- private static void checkD(Constructor<?> c, boolean match_D_SIMPLE,
boolean match_Di_SIMPLE, boolean match_Ds_SIMPLE, boolean match_Dss_SIMPLE,
- boolean match_Dsi_SIMPLE, boolean match_Dssi_SIMPLE,
boolean match_D_FULL, boolean match_Di_FULL, boolean match_Ds_FULL,
- boolean match_Dss_FULL, boolean match_Dsi_FULL, boolean
match_Dssi_FULL) {
-
- assertEquals(match_D_SIMPLE, D_SIMPLE.find(c,
null).isPresent());
- assertEquals(match_Di_SIMPLE, Di_SIMPLE.find(c,
null).isPresent());
- assertEquals(match_Ds_SIMPLE, Ds_SIMPLE.find(c,
null).isPresent());
- assertEquals(match_Dss_SIMPLE, Dss_SIMPLE.find(c,
null).isPresent());
- assertEquals(match_Dsi_SIMPLE, Dsi_SIMPLE.find(c,
null).isPresent());
- assertEquals(match_Dssi_SIMPLE, Dssi_SIMPLE.find(c,
null).isPresent());
- assertEquals(match_D_FULL, D_FULL.find(c, null).isPresent());
- assertEquals(match_Di_FULL, Di_FULL.find(c, null).isPresent());
- assertEquals(match_Ds_FULL, Ds_FULL.find(c, null).isPresent());
- assertEquals(match_Dss_FULL, Dss_FULL.find(c,
null).isPresent());
- assertEquals(match_Dsi_FULL, Dsi_FULL.find(c,
null).isPresent());
- assertEquals(match_Dssi_FULL, Dssi_FULL.find(c,
null).isPresent());
-
- assertEquals(match_D_SIMPLE, D_SIMPLE.find(c,
Integer.class).isPresent());
- assertEquals(match_Di_SIMPLE, Di_SIMPLE.find(c,
Integer.class).isPresent());
- assertEquals(match_Ds_SIMPLE, Ds_SIMPLE.find(c,
Integer.class).isPresent());
- assertEquals(match_Dss_SIMPLE, Dss_SIMPLE.find(c,
Integer.class).isPresent());
- assertEquals(match_Dsi_SIMPLE, Dsi_SIMPLE.find(c,
Integer.class).isPresent());
- assertEquals(match_Dssi_SIMPLE, Dssi_SIMPLE.find(c,
Integer.class).isPresent());
- assertEquals(match_D_FULL, D_FULL.find(c,
Integer.class).isPresent());
- assertEquals(match_Di_FULL, Di_FULL.find(c,
Integer.class).isPresent());
- assertEquals(match_Ds_FULL, Ds_FULL.find(c,
Integer.class).isPresent());
- assertEquals(match_Dss_FULL, Dss_FULL.find(c,
Integer.class).isPresent());
- assertEquals(match_Dsi_FULL, Dsi_FULL.find(c,
Integer.class).isPresent());
- assertEquals(match_Dssi_FULL, Dssi_FULL.find(c,
Integer.class).isPresent());
-
- assertFalse(D_SIMPLE.find(c, Long.class).isPresent());
- assertFalse(Di_SIMPLE.find(c, Long.class).isPresent());
- assertFalse(Ds_SIMPLE.find(c, Long.class).isPresent());
- assertFalse(Dss_SIMPLE.find(c, Long.class).isPresent());
- assertFalse(Dsi_SIMPLE.find(c, Long.class).isPresent());
- assertFalse(Dssi_SIMPLE.find(c, Long.class).isPresent());
- assertFalse(D_FULL.find(c, Long.class).isPresent());
- assertFalse(Di_FULL.find(c, Long.class).isPresent());
- assertFalse(Ds_FULL.find(c, Long.class).isPresent());
- assertFalse(Dss_FULL.find(c, Long.class).isPresent());
- assertFalse(Dsi_FULL.find(c, Long.class).isPresent());
- assertFalse(Dssi_FULL.find(c, Long.class).isPresent());
- }
-
- @Test void d02_constructorName_find() throws Exception {
- checkD(D1.class.getConstructor(), true, false, false, false,
false, false, true, false, false, false, false, false);
- checkD(D1.class.getConstructor(int.class), false, true, false,
false, false, false, false, true, false, false, false, false);
- checkD(D1.class.getConstructor(String.class), false, false,
true, true, false, false, false, false, true, true, false, false);
- checkD(D1.class.getConstructor(String.class, int.class), false,
false, false, false, true, true, false, false, false, false, true, true);
- checkD(D2.class.getConstructor(), false, false, false, false,
false, false, false, false, false, false, false, false);
- checkD(null, false, false, false, false, false, false, false,
false, false, false, false, false);
- }
-
-
//------------------------------------------------------------------------------------------------------------------
- // Invalid input
-
//------------------------------------------------------------------------------------------------------------------
-
- @Test void e01_blankInput() {
- assertThrowsWithMessage(RuntimeException.class, "Invalid
reflection signature: []", ()->create().append("", 1));
- }
-
- @Test void e02_nullInput() {
- assertThrowsWithMessage(RuntimeException.class, "Invalid
reflection signature: [null]", ()->create().append(null, 1));
- }
-
- @Test void e03_badInput() {
- assertThrowsWithMessage(RuntimeException.class, "Invalid
reflection signature: [foo)]", ()->create().append("foo)", 1));
- }
-
-
//------------------------------------------------------------------------------------------------------------------
- // Comma-delimited list.
-
//------------------------------------------------------------------------------------------------------------------
- static class F1 {}
-
- static ReflectionMap<Number> RM_F = create().append("F2, F1",
1).build();
-
- @Test void f01_cdl() {
- assertString("1", RM_F.find(F1.class, null));
- }
-
-
//------------------------------------------------------------------------------------------------------------------
- // Empty reflection map.
-
//------------------------------------------------------------------------------------------------------------------
-
- static ReflectionMap<Number> RM_G = create().build();
-
- @Test void g01_emptyReflectionMap() throws Exception {
- assertFalse(RM_G.find(A1.class, null).isPresent());
- assertFalse(RM_G.find(B1.class.getMethod("m1"),
null).isPresent());
- assertFalse(RM_G.find(C1.class.getField("f1"),
null).isPresent());
- assertFalse(RM_G.find(D1.class.getConstructor(),
null).isPresent());
- }
-}
\ No newline at end of file