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 695b7c770d Utility class modernization
695b7c770d is described below
commit 695b7c770dcbe490fd02a78767763c7c53bd8b12
Author: James Bognar <[email protected]>
AuthorDate: Wed Nov 5 15:54:37 2025 -0500
Utility class modernization
---
.../juneau/common/reflect/AnnotationProvider2.java | 42 ++++++++++++++++++
.../apache/juneau/common/utils/PredicateUtils.java | 50 ++++++++++++++++++++++
.../src/main/java/org/apache/juneau/Context.java | 5 +--
3 files changed, 93 insertions(+), 4 deletions(-)
diff --git
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationProvider2.java
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationProvider2.java
index e425717e59..7e97c077c5 100644
---
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationProvider2.java
+++
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationProvider2.java
@@ -272,6 +272,7 @@ public class AnnotationProvider2 {
return classDeclaredAnnotations.get(onClass);
}
+ @SuppressWarnings("unchecked")
public <A extends Annotation> Stream<AnnotationInfo<A>>
findDeclared(Class<A> type, Class<?> onClass) {
assertArgNotNull("type", type);
assertArgNotNull("onClass", onClass);
@@ -280,6 +281,47 @@ public class AnnotationProvider2 {
.map(a -> (AnnotationInfo<A>)a);
}
+ /**
+ * Finds all declared annotations on the specified class in
parent-to-child order (reversed).
+ *
+ * <p>
+ * This method returns annotations in the opposite order from {@link
#findDeclared(Class)}.
+ * It processes parent/declared annotations first (lower priority),
then runtime annotations (higher priority).
+ * This is useful when you want to process multiple annotation values
where child annotations
+ * can override values from parent annotations.
+ *
+ * @param onClass The class to search on.
+ * @return A stream of {@link AnnotationInfo} objects in
parent-to-child order.
+ */
+ public Stream<AnnotationInfo<Annotation>>
findDeclaredParentFirst(Class<?> onClass) {
+ assertArgNotNull("onClass", onClass);
+ var list = classDeclaredAnnotations.get(onClass);
+ // Iterate backwards to get parent-to-child order
+ return java.util.stream.IntStream.range(0, list.size())
+ .map(i -> list.size() - 1 - i)
+ .mapToObj(list::get);
+ }
+
+ /**
+ * Finds all declared annotations of the specified type on the
specified class in parent-to-child order (reversed).
+ *
+ * <p>
+ * This method returns annotations in the opposite order from {@link
#findDeclared(Class, Class)}.
+ *
+ * @param <A> The annotation type to find.
+ * @param type The annotation type to find.
+ * @param onClass The class to search on.
+ * @return A stream of {@link AnnotationInfo} objects in
parent-to-child order.
+ */
+ @SuppressWarnings("unchecked")
+ public <A extends Annotation> Stream<AnnotationInfo<A>>
findDeclaredParentFirst(Class<A> type, Class<?> onClass) {
+ assertArgNotNull("type", type);
+ assertArgNotNull("onClass", onClass);
+ return findDeclaredParentFirst(onClass)
+ .filter(a -> a.isType(type))
+ .map(a -> (AnnotationInfo<A>)a);
+ }
+
public List<AnnotationInfo<Annotation>> find(Method onMethod) {
assertArgNotNull("onMethod", onMethod);
return methodAnnotations.get(onMethod);
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 6c81f67a85..ac8186b639 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
@@ -124,4 +124,54 @@ public final class PredicateUtils {
if (test(predicate, value))
consumer.accept(value);
}
+
+ /**
+ * Returns a function that prints the input value to stderr and returns
it unchanged.
+ *
+ * <p>
+ * Useful for debugging streams by inserting into a stream pipeline
with {@code .map(peek())}.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * list.stream()
+ * .map(peek())
+ * .filter(x -> x != <jk>null</jk>)
+ * .collect(Collectors.toList());
+ * </p>
+ *
+ * @param <T> The type of value.
+ * @return A function that prints and returns the value.
+ */
+ public static <T> Function<T,T> peek() {
+ return v -> {
+ System.err.println(v);
+ return v;
+ };
+ }
+
+ /**
+ * Returns a function that prints the input value to stderr using a
custom formatter and returns it unchanged.
+ *
+ * <p>
+ * Useful for debugging streams by inserting into a stream pipeline
with {@code .map(peek(...))}.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * list.stream()
+ * .map(peek(<js>"Processing: {0}"</js>, x ->
x.getName()))
+ * .filter(x -> x != <jk>null</jk>)
+ * .collect(Collectors.toList());
+ * </p>
+ *
+ * @param <T> The type of value.
+ * @param message A format string using {@code {0}} as placeholder for
the formatted value.
+ * @param formatter A function to extract/format the value for display.
+ * @return A function that prints and returns the value.
+ */
+ public static <T> Function<T,T> peek(String message, Function<T,?>
formatter) {
+ return v -> {
+ System.err.println(message.replace("{0}",
String.valueOf(formatter.apply(v))));
+ return v;
+ };
+ }
}
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
index ce025328e4..2f4fc7f394 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
@@ -895,10 +895,7 @@ public abstract class Context implements
AnnotationProvider {
@Override /* Overridden from MetaProvider */
public <A extends Annotation> void forEachDeclaredAnnotation(Class<A>
type, Class<?> onClass, Predicate<A> filter, Consumer<A> action) {
-// getAnnotationProvider().find(type, onClass).map(x ->
x.inner()).filter(x -> filter.test(x)).forEach(x -> action.accept(x));
- if (nn(type) && nn(onClass))
- for (var a : declaredAnnotations(type, onClass))
- consumeIf(filter, action, a);
+ getAnnotationProvider().findDeclaredParentFirst(type,
onClass).map(x -> x.inner()).filter(x -> filter == null ||
filter.test(x)).forEach(x -> action.accept(x));
}
/**