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 c96cc884c4 Utility class modernization
c96cc884c4 is described below
commit c96cc884c4da75babbe49cf2e25ee14e338b4116
Author: James Bognar <[email protected]>
AuthorDate: Thu Nov 6 08:20:40 2025 -0500
Utility class modernization
---
.../apache/juneau/common/reflect/MethodInfo.java | 42 +++-------------------
.../apache/juneau/common/utils/PredicateUtils.java | 27 ++++++++++++++
.../httppart/bean/RequestBeanPropertyMeta.java | 4 +--
.../juneau/httppart/bean/ResponseBeanMeta.java | 6 ++--
.../java/org/apache/juneau/rest/RestContext.java | 10 +++---
.../java/org/apache/juneau/rest/RestOpContext.java | 16 +++++----
.../rest/swagger/BasicSwaggerProviderSession.java | 4 +--
.../juneau/common/reflect/MethodInfo_Test.java | 11 ++----
8 files changed, 55 insertions(+), 65 deletions(-)
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 180eddb967..960f8d52cb 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
@@ -429,27 +429,9 @@ public class MethodInfo extends ExecutableInfo implements
Comparable<MethodInfo>
getReturnType().unwrap(Value.class,
Optional.class).forEachAnnotation(annotationProvider, type, filter, action);
}
- /**
- * Performs an action on all matching annotations defined on this
method.
- *
- * <p>
- * Searches all methods with the same signature on the parent classes
or interfaces
- * and the return type on the method.
- * <br>Results are parent-to-child ordered.
- *
- * @param <A> The annotation type to look for.
- * @param type The annotation to look for.
- * @param filter A predicate to apply to the entries to determine if
action should be performed. Can be <jk>null</jk>.
- * @param action An action to perform on the entry.
- * @return This object.
- */
- public <A extends Annotation> void forEachAnnotation(Class<A> type,
Predicate<A> filter, Consumer<A> action) {
- rstream(getAllAnnotationInfos())
- .filter(x -> x.isType(type))
- .map(AnnotationInfo::inner)
- .map(x -> (A)x)
- .filter(x -> filter == null || filter.test(x))
- .forEach(action);
+ public <A extends Annotation> Stream<AnnotationInfo<A>>
getAllAnnotationInfosParentFirst(Class<A> type) {
+ return rstream(getAllAnnotationInfos())
+ .flatMap(type(type));
}
public Stream<MethodInfo> getMatching() {
@@ -480,22 +462,6 @@ public class MethodInfo extends ExecutableInfo implements
Comparable<MethodInfo>
.orElse(null);
}
- /**
- * Finds the annotation of the specified type defined on this method.
- *
- * <p>
- * If this is a method and the annotation cannot be found on the
immediate method, searches methods with the same
- * signature on the parent classes or interfaces.
- * <br>The search is performed in child-to-parent order.
- *
- * @param <A> The annotation type to look for.
- * @param type The annotation to look for.
- * @return The annotation if found, or <jk>null</jk> if not.
- */
- public <A extends Annotation> A getAnnotation(Class<A> type) {
- return getAnnotation(AnnotationProvider.DEFAULT, type);
- }
-
/**
* Constructs an {@link AnnotationList} of all annotations found on
this method.
*
@@ -544,7 +510,7 @@ public class MethodInfo extends ExecutableInfo implements
Comparable<MethodInfo>
@SafeVarargs
public final Annotation getAnyAnnotation(Class<? extends
Annotation>...types) {
return Arrays.stream(types)
- .map(this::getAnnotation)
+ .map(t ->
getAnnotationInfos(t).findFirst().map(AnnotationInfo::inner).orElse(null))
.filter(Objects::nonNull)
.findFirst()
.orElse(null);
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 8c69cd5fd4..abcddef974 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,7 +18,9 @@ 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.*;
@@ -241,4 +243,29 @@ public final class PredicateUtils {
public static Predicate<ElementInfo> isAny(ElementFlag...flags) {
return ei -> ei.isAny(flags);
}
+
+ /**
+ * Returns a function that filters and casts {@link AnnotationInfo}
objects to a specific annotation type.
+ *
+ * <p>
+ * This function is designed to be used with {@link
Stream#flatMap(Function)} to both filter and type-cast
+ * in a single operation.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * List<AnnotationInfo<Annotation>> annotations = ...;
+ * List<MyAnnotation> myAnnotations = annotations.stream()
+ * .flatMap(type(MyAnnotation.<jk>class</jk>))
+ * .map(AnnotationInfo::inner)
+ * .collect(Collectors.toList());
+ * </p>
+ *
+ * @param <A> The annotation type.
+ * @param annotationType The annotation class to filter and cast to.
+ * @return A function that returns a stream containing the annotation
if it matches the type, or an empty stream otherwise.
+ */
+ @SuppressWarnings("unchecked")
+ public static <A extends Annotation> Function<AnnotationInfo<?>,
Stream<AnnotationInfo<A>>> type(Class<A> annotationType) {
+ return ai -> ai.isType(annotationType) ?
Stream.of((AnnotationInfo<A>)ai) : Stream.empty();
+ }
}
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/RequestBeanPropertyMeta.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/RequestBeanPropertyMeta.java
index 11db51e47b..7e0a86f76e 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/RequestBeanPropertyMeta.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/RequestBeanPropertyMeta.java
@@ -64,8 +64,8 @@ public class RequestBeanPropertyMeta {
static RequestBeanPropertyMeta.Builder create(HttpPartType partType,
Class<? extends Annotation> c, MethodInfo m) {
HttpPartSchema.Builder sb =
HttpPartSchema.create().name(m.getPropertyName());
- m.forEachAnnotation(Schema.class, x -> true, x -> sb.apply(x));
- m.forEachAnnotation(c, x -> true, x -> sb.apply(x));
+
m.getAllAnnotationInfosParentFirst(Schema.class).map(AnnotationInfo::inner).forEach(x
-> sb.apply(x));
+
m.getAllAnnotationInfosParentFirst(c).map(AnnotationInfo::inner).forEach(x ->
sb.apply(x));
return new
Builder().partType(partType).schema(sb.build()).getter(m.inner());
}
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanMeta.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanMeta.java
index 63e10ea0d8..13f5f9d20d 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanMeta.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanMeta.java
@@ -86,7 +86,7 @@ public class ResponseBeanMeta {
if (x.hasAnnotation(Header.class)) {
assertNoArgs(x, Header.class);
assertReturnNotVoid(x, Header.class);
- var s =
HttpPartSchema.create(x.getAnnotation(Header.class), x.getPropertyName());
+ var s =
HttpPartSchema.create(x.getAnnotationInfos(Header.class).findFirst().map(AnnotationInfo::inner).orElse(null),
x.getPropertyName());
headerMethods.put(s.getName(),
ResponseBeanPropertyMeta.create(RESPONSE_HEADER, s, x));
} else if (x.hasAnnotation(StatusCode.class)) {
assertNoArgs(x, Header.class);
@@ -125,8 +125,8 @@ public class ResponseBeanMeta {
return null;
var b = new Builder(annotations);
b.apply(m.getReturnType().unwrap(Value.class,
Optional.class).innerType());
- m.forEachAnnotation(Response.class, x -> true, x -> b.apply(x));
- m.forEachAnnotation(StatusCode.class, x -> true, x ->
b.apply(x));
+
m.getAllAnnotationInfosParentFirst(Response.class).map(AnnotationInfo::inner).forEach(x
-> b.apply(x));
+
m.getAllAnnotationInfosParentFirst(StatusCode.class).map(AnnotationInfo::inner).forEach(x
-> b.apply(x));
return b.build();
}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index 7cbe61e5b9..66fd11f4b2 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -204,7 +204,9 @@ public class RestContext extends Context {
// @formatter:off
ClassInfo.ofProxy(r).getAllMethodsParentFirst().stream()
.filter(y -> y.hasAnnotation(annotation))
- .forEach(y -> y.forEachAnnotation(annotation,
predicate, z -> x.put(y.getSignature(), y.accessible().inner())));
+ .forEach(y ->
y.getAllAnnotationInfosParentFirst(annotation).map(AnnotationInfo::inner)
+ .filter(z -> predicate == null ||
predicate.test(z))
+ .forEach(z -> x.put(y.getSignature(),
y.accessible().inner())));
// @formatter:on
var x2 = MethodList.of(x.values());
@@ -212,12 +214,12 @@ public class RestContext extends Context {
}
private static boolean isRestBeanMethod(MethodInfo mi) {
- var x = mi.getAnnotation(RestInject.class);
+ var x =
mi.getAnnotationInfos(RestInject.class).findFirst().map(AnnotationInfo::inner).orElse(null);
return nn(x) && x.methodScope().length == 0;
}
private static boolean isRestBeanMethod(MethodInfo mi, String
name) {
- var x = mi.getAnnotation(RestInject.class);
+ var x =
mi.getAnnotationInfos(RestInject.class).findFirst().map(AnnotationInfo::inner).orElse(null);
return nn(x) && x.methodScope().length == 0 &&
x.name().equals(name);
}
@@ -1770,7 +1772,7 @@ public class RestContext extends Context {
rci.getMethods().stream().filter(x ->
x.hasAnnotation(RestInject.class)).forEach(x -> {
var rt = x.getReturnType().<Object>inner();
- var name =
RestInjectAnnotation.name(x.getAnnotation(RestInject.class));
+ var name =
RestInjectAnnotation.name(x.getAnnotationInfos(RestInject.class).findFirst().map(AnnotationInfo::inner).orElse(null));
if (! (DELAYED_INJECTION.contains(rt) ||
DELAYED_INJECTION_NAMES.contains(name))) {
// @formatter:off
beanStore
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 34f0bb7779..887e1684fd 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
@@ -1307,18 +1307,18 @@ public class RestOpContext extends Context implements
Comparable<RestOpContext>
}
private boolean matches(MethodInfo annotated) {
- var a = annotated.getAnnotation(RestInject.class);
+ var a =
annotated.getAnnotationInfos(RestInject.class).findFirst().map(AnnotationInfo::inner).orElse(null);
if (nn(a)) {
for (var n : a.methodScope()) {
- if ("*".equals(n) ||
restMethod.getName().equals(n))
- return true;
- }
+ if ("*".equals(n) ||
restMethod.getName().equals(n))
+ return true;
}
- return false;
}
+ return false;
+ }
private boolean matches(MethodInfo annotated, String beanName) {
- var a = annotated.getAnnotation(RestInject.class);
+ var a =
annotated.getAnnotationInfos(RestInject.class).findFirst().map(AnnotationInfo::inner).orElse(null);
if (nn(a)) {
if (! a.name().equals(beanName))
return false;
@@ -1948,7 +1948,9 @@ public class RestOpContext extends Context implements
Comparable<RestOpContext>
httpMethod = "delete";
else if (mi.hasAnnotation(RestOp.class)) {
var _httpMethod = Value.<String>empty();
- mi.forEachAnnotation(RestOp.class, x ->
isNotEmpty(x.method()), x -> _httpMethod.set(x.method()));
+
mi.getAllAnnotationInfosParentFirst(RestOp.class).map(AnnotationInfo::inner)
+ .filter(x -> isNotEmpty(x.method()))
+ .forEach(x ->
_httpMethod.set(x.method()));
httpMethod = _httpMethod.orElse(null);
}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/swagger/BasicSwaggerProviderSession.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/swagger/BasicSwaggerProviderSession.java
index c32fe9b182..2d3e97877c 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/swagger/BasicSwaggerProviderSession.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/swagger/BasicSwaggerProviderSession.java
@@ -447,7 +447,7 @@ public class BasicSwaggerProviderSession {
List<MethodInfo> methods =
eci.getMethods();
for (int i = methods.size() - 1; i >=
0; i--) {
MethodInfo ecmi =
methods.get(i);
- Header a =
ecmi.getAnnotation(Header.class);
+ Header a =
ecmi.getAnnotationInfos(Header.class).findFirst().map(AnnotationInfo::inner).orElse(null);
if (a == null)
a =
ecmi.getReturnType().unwrap(Value.class,
Optional.class).getAnnotation(Header.class);
if (nn(a) && ! isMulti(a)) {
@@ -485,7 +485,7 @@ public class BasicSwaggerProviderSession {
for (int i = methods.size() - 1; i >=
0; i--) {
MethodInfo ecmi =
methods.get(i);
if
(ecmi.hasAnnotation(Header.class)) {
- Header a =
ecmi.getAnnotation(Header.class);
+ Header a =
ecmi.getAnnotationInfos(Header.class).findFirst().map(AnnotationInfo::inner).orElse(null);
String ha = a.name();
if (! isMulti(a)) {
for (var code :
codes) {
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/common/reflect/MethodInfo_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/MethodInfo_Test.java
index bc0b62a81a..11e2da9d19 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/common/reflect/MethodInfo_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/MethodInfo_Test.java
@@ -354,18 +354,11 @@ class MethodInfo_Test extends TestBase {
private static List<A> annotations(MethodInfo mi, Class<? extends
Annotation> a) {
var l = new ArrayList<A>();
- mi.forEachAnnotation(a, x -> true, x -> l.add((A)x));
+
mi.getAllAnnotationInfosParentFirst(a).map(AnnotationInfo::inner)
+ .forEach(x -> l.add((A)x));
return l;
}
- @Test void getAnnotation() {
- check("@A(a1)", c_a1.getAnnotation(A.class));
- check("@A(a2b)", c_a2.getAnnotation(A.class));
- check("@A(a3)", c_a3.getAnnotation(A.class));
- check("@A(a4)", c_a4.getAnnotation(A.class));
- check(null, c_a5.getAnnotation(A.class));
- }
-
@Test void getAnnotationAny() {
check("@A(a1)", c_a1.getAnyAnnotation(AX.class, A.class));
check("@A(a2b)", c_a2.getAnyAnnotation(AX.class, A.class));