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 5621703a6a org.apache.juneau.common.reflect API improvements
5621703a6a is described below
commit 5621703a6adc1d561045d41a284282b122080899
Author: James Bognar <[email protected]>
AuthorDate: Wed Nov 19 09:51:10 2025 -0500
org.apache.juneau.common.reflect API improvements
---
.../juneau/common/reflect/AnnotationProvider.java | 180 ++++++----
.../apache/juneau/common/reflect/FieldInfo.java | 14 +-
.../juneau/common/reflect/ParameterInfo.java | 191 +----------
.../apache/juneau/common/utils/StringUtils.java | 120 +++++++
.../main/java/org/apache/juneau/BeanFilter.java | 8 +-
.../juneau/http/annotation/FormDataAnnotation.java | 33 +-
.../juneau/http/annotation/HeaderAnnotation.java | 33 +-
.../juneau/http/annotation/PathAnnotation.java | 31 +-
.../http/annotation/PathRemainderAnnotation.java | 17 +-
.../juneau/http/annotation/QueryAnnotation.java | 33 +-
.../juneau/httppart/bean/RequestBeanMeta.java | 8 +-
.../juneau/httppart/bean/ResponseBeanMeta.java | 12 +-
.../rest/client/remote/RemoteOperationArg.java | 14 +-
.../java/org/apache/juneau/rest/RestContext.java | 4 +-
.../org/apache/juneau/rest/arg/AttributeArg.java | 20 +-
.../org/apache/juneau/rest/arg/ContentArg.java | 4 +-
.../org/apache/juneau/rest/arg/FormDataArg.java | 23 +-
.../org/apache/juneau/rest/arg/HasFormDataArg.java | 24 +-
.../org/apache/juneau/rest/arg/HasQueryArg.java | 23 +-
.../java/org/apache/juneau/rest/arg/HeaderArg.java | 36 +-
.../java/org/apache/juneau/rest/arg/MethodArg.java | 4 +-
.../java/org/apache/juneau/rest/arg/PathArg.java | 55 ++--
.../apache/juneau/rest/arg/PathRemainderArg.java | 11 +-
.../java/org/apache/juneau/rest/arg/QueryArg.java | 39 +--
.../org/apache/juneau/rest/arg/RequestBeanArg.java | 5 +-
.../apache/juneau/rest/arg/ResponseBeanArg.java | 7 +-
.../apache/juneau/rest/arg/ResponseCodeArg.java | 4 +-
.../apache/juneau/rest/arg/ResponseHeaderArg.java | 17 +-
.../rest/swagger/BasicSwaggerProviderSession.java | 56 ++--
.../reflect/FieldInfo_AnnotationInfos_Test.java | 22 +-
.../juneau/common/reflect/ParamInfoTest.java | 309 ++---------------
.../org/apache/juneau/reflect/ParamInfoTest.java | 364 ---------------------
32 files changed, 564 insertions(+), 1157 deletions(-)
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 87792a2024..7a6d3e5f23 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
@@ -514,67 +514,6 @@ public class AnnotationProvider {
.map(a -> (AnnotationInfo<A>)a);
}
- /**
- * Finds all annotations of the specified type on the specified class
in a bottom-up traversal order.
- *
- * <p>
- * This method provides a very specific traversal order that searches
annotations in the following sequence:
- * <ol>
- * <li><b>This class</b>
- * <ul>
- * <li>Runtime annotations
- * <li>Declared annotations
- * </ul>
- * <li><b>Parent classes (child-to-parent order)</b>
- * <ul>
- * <li>For each parent: runtime annotations, then
declared annotations
- * </ul>
- * <li><b>Interfaces (for each class level, then their parent
interfaces)</b>
- * <ul>
- * <li>For each interface: runtime annotations,
then declared annotations
- * </ul>
- * <li><b>Package of this class</b>
- * <ul>
- * <li>Declared annotations (packages do not
support runtime annotations)
- * </ul>
- * </ol>
- *
- * <p>
- * <b>Example traversal order</b> (given class {@code Child extends
Parent implements I1, I2}):
- * <ol>
- * <li>Child runtime annotations
- * <li>Child declared annotations
- * <li>Parent runtime annotations
- * <li>Parent declared annotations
- * <li>I1 runtime annotations (declared on Child)
- * <li>I1 declared annotations
- * <li>I2 runtime annotations (declared on Child)
- * <li>I2 declared annotations
- * <li>Parent interfaces and their parents...
- * <li>Package declared annotations
- * </ol>
- *
- * <p>
- * <b>Comparison with {@link #find(Class, Class)}:</b>
- * <ul>
- * <li>{@link #find(Class, Class)} interleaves parent classes and
interfaces at each level
- * <li>{@code findBottomUp} processes all parent classes first,
then all interfaces, then package
- * <li>{@code findBottomUp} ensures runtime annotations always
come before declared annotations at each level (except packages which don't
support runtime annotations)
- * </ul>
- *
- * @param <A> The annotation type to find.
- * @param type The annotation type to find.
- * @param onClass The class info to search on.
- * @return A stream of {@link AnnotationInfo} objects in the specified
bottom-up order. Never <jk>null</jk>.
- */
- @SuppressWarnings("unchecked")
- public <A extends Annotation> Stream<AnnotationInfo<A>>
findBottomUp(Class<A> type, ClassInfo onClass) {
- assertArgNotNull("type", type);
- assertArgNotNull("onClass", onClass);
-
- return null; // TODO
- }
-
/**
* Finds annotations declared directly on the specified class,
including runtime annotations.
*
@@ -887,7 +826,7 @@ public class AnnotationProvider {
FieldInfo fi = FieldInfo.of(forField);
runtimeAnnotations.find(forField).forEach(a ->
list.add(AnnotationInfo.of(fi, a)));
- list.addAll(fi.getDeclaredAnnotations());
+ list.addAll(fi.getAnnotations());
return u(list);
}
@@ -1099,31 +1038,49 @@ public class AnnotationProvider {
}
/**
- * Streams annotations from a parameter using configurable traversal
options.
+ * Streams annotations from a parameter using configurable traversal
options in child-to-parent order.
*
* <p>
* This method provides a flexible, stream-based API for traversing
parameter annotations without creating intermediate lists.
*
+ * <h5 class='section'>Supported Traversal Types:</h5>
+ * <ul>
+ * <li>{@link AnnotationTraversal#SELF SELF} - Annotations
declared directly on this parameter
+ * <li>{@link AnnotationTraversal#MATCHING_PARAMETERS
MATCHING_PARAMETERS} - Matching parameters in parent methods/constructors
(child-to-parent)
+ * <li>{@link AnnotationTraversal#PARAMETER_TYPE PARAMETER_TYPE} -
The parameter's type hierarchy (includes class parents and package)
+ * </ul>
+ *
+ * <p>
+ * <b>Default:</b> If no traversals are specified, defaults to: {@code
SELF, MATCHING_PARAMETERS, PARAMETER_TYPE}
+ *
* <h5 class='section'>Examples:</h5>
* <p class='bjava'>
- * <jc>// Search parameter, matching parameters, and parameter
type</jc>
+ * <jc>// Search parameter, matching parameters, and parameter
type (child-to-parent)</jc>
* Stream<AnnotationInfo<MyAnnotation>> <jv>s1</jv> =
- * findAnnotations(MyAnnotation.<jk>class</jk>,
<jv>pi</jv>, SELF, MATCHING_PARAMETERS, PARAMETER_TYPE);
+ * find(MyAnnotation.<jk>class</jk>, <jv>pi</jv>, SELF,
MATCHING_PARAMETERS, PARAMETER_TYPE);
*
- * <jc>// Search in parent-first order using
findAnnotationsParentFirst</jc>
+ * <jc>// Just search this parameter</jc>
* Stream<AnnotationInfo<MyAnnotation>> <jv>s2</jv> =
- * findAnnotationsParentFirst(MyAnnotation.<jk>class</jk>,
<jv>pi</jv>, SELF, MATCHING_PARAMETERS, PARAMETER_TYPE);
+ * find(MyAnnotation.<jk>class</jk>, <jv>pi</jv>, SELF);
+ *
+ * <jc>// Search in parent-to-child order using findTopDown</jc>
+ * Stream<AnnotationInfo<MyAnnotation>> <jv>s3</jv> =
+ * findTopDown(MyAnnotation.<jk>class</jk>, <jv>pi</jv>,
SELF, MATCHING_PARAMETERS, PARAMETER_TYPE);
* </p>
*
* @param <A> The annotation type.
* @param type The annotation type to search for.
* @param parameter The parameter to search.
- * @param traversals The traversal options.
- * @return A stream of {@link AnnotationInfo} objects. Never
<jk>null</jk>.
+ * @param traversals
+ * The traversal options. If not specified, defaults to {@code
SELF, MATCHING_PARAMETERS, PARAMETER_TYPE}.
+ * <br>Valid values: {@link AnnotationTraversal#SELF SELF}, {@link
AnnotationTraversal#MATCHING_PARAMETERS MATCHING_PARAMETERS}, {@link
AnnotationTraversal#PARAMETER_TYPE PARAMETER_TYPE}
+ * @return A stream of {@link AnnotationInfo} objects in
child-to-parent order. Never <jk>null</jk>.
*/
- public <A extends Annotation> Stream<AnnotationInfo<A>>
findAnnotations(Class<A> type, ParameterInfo parameter, AnnotationTraversal...
traversals) {
+ public <A extends Annotation> Stream<AnnotationInfo<A>> find(Class<A>
type, ParameterInfo parameter, AnnotationTraversal... traversals) {
assertArgNotNull("type", type);
assertArgNotNull("parameter", parameter);
+ if (traversals.length == 0)
+ traversals = new AnnotationTraversal[]{SELF,
MATCHING_PARAMETERS, PARAMETER_TYPE};
return Arrays.stream(traversals)
.sorted(Comparator.comparingInt(AnnotationTraversal::getOrder))
@@ -1139,11 +1096,90 @@ public class AnnotationProvider {
});
}
+ /**
+ * Streams annotations from a parameter using configurable traversal
options in parent-to-child order.
+ *
+ * <p>
+ * This is equivalent to calling {@link #find(Class, ParameterInfo,
AnnotationTraversal...)} and reversing the result.
+ * Use this when you need parent annotations to take precedence over
child annotations.
+ *
+ * <h5 class='section'>Supported Traversal Types:</h5>
+ * <ul>
+ * <li>{@link AnnotationTraversal#SELF SELF} - Annotations
declared directly on this parameter
+ * <li>{@link AnnotationTraversal#MATCHING_PARAMETERS
MATCHING_PARAMETERS} - Matching parameters in parent methods/constructors
(parent-to-child)
+ * <li>{@link AnnotationTraversal#PARAMETER_TYPE PARAMETER_TYPE} -
The parameter's type hierarchy (includes class parents and package)
+ * </ul>
+ *
+ * <p>
+ * <b>Default:</b> If no traversals are specified, defaults to: {@code
SELF, MATCHING_PARAMETERS, PARAMETER_TYPE}
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * <jc>// Search in parent-to-child order</jc>
+ * Stream<AnnotationInfo<MyAnnotation>> <jv>s</jv> =
+ * findTopDown(MyAnnotation.<jk>class</jk>, <jv>pi</jv>,
SELF, MATCHING_PARAMETERS, PARAMETER_TYPE);
+ *
+ * <jc>// Get first annotation (from parent)</jc>
+ * Optional<AnnotationInfo<MyAnnotation>>
<jv>first</jv> = <jv>s</jv>.findFirst();
+ * </p>
+ *
+ * @param <A> The annotation type.
+ * @param type The annotation type to search for.
+ * @param parameter The parameter to search.
+ * @param traversals
+ * The traversal options. If not specified, defaults to {@code
SELF, MATCHING_PARAMETERS, PARAMETER_TYPE}.
+ * <br>Valid values: {@link AnnotationTraversal#SELF SELF}, {@link
AnnotationTraversal#MATCHING_PARAMETERS MATCHING_PARAMETERS}, {@link
AnnotationTraversal#PARAMETER_TYPE PARAMETER_TYPE}
+ * @return A stream of {@link AnnotationInfo} objects in
parent-to-child order. Never <jk>null</jk>.
+ */
+ public <A extends Annotation> Stream<AnnotationInfo<A>>
findTopDown(Class<A> type, ParameterInfo parameter, AnnotationTraversal...
traversals) {
+ return rstream(find(type, parameter, traversals).toList());
+ }
+
+ /**
+ * Checks if a parameter has the specified annotation.
+ *
+ * <p>
+ * This is a convenience method equivalent to:
+ * <p class='bjava'>
+ * find(<jv>type</jv>, <jv>parameter</jv>,
<jv>traversals</jv>).findFirst().isPresent()
+ * </p>
+ *
+ * <h5 class='section'>Supported Traversal Types:</h5>
+ * <ul>
+ * <li>{@link AnnotationTraversal#SELF SELF} - Annotations
declared directly on this parameter
+ * <li>{@link AnnotationTraversal#MATCHING_PARAMETERS
MATCHING_PARAMETERS} - Matching parameters in parent methods/constructors
(child-to-parent)
+ * <li>{@link AnnotationTraversal#PARAMETER_TYPE PARAMETER_TYPE} -
The parameter's type hierarchy (includes class parents and package)
+ * </ul>
+ *
+ * <p>
+ * <b>Default:</b> If no traversals are specified, defaults to: {@code
SELF, MATCHING_PARAMETERS, PARAMETER_TYPE}
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * <jc>// Check if parameter has @MyAnnotation anywhere in
hierarchy</jc>
+ * <jk>boolean</jk> <jv>hasIt</jv> =
has(MyAnnotation.<jk>class</jk>, <jv>pi</jv>);
+ *
+ * <jc>// Check only on the parameter itself</jc>
+ * <jk>boolean</jk> <jv>hasIt2</jv> =
has(MyAnnotation.<jk>class</jk>, <jv>pi</jv>, SELF);
+ * </p>
+ *
+ * @param <A> The annotation type.
+ * @param type The annotation type to search for.
+ * @param parameter The parameter to search.
+ * @param traversals
+ * The traversal options. If not specified, defaults to {@code
SELF, MATCHING_PARAMETERS, PARAMETER_TYPE}.
+ * <br>Valid values: {@link AnnotationTraversal#SELF SELF}, {@link
AnnotationTraversal#MATCHING_PARAMETERS MATCHING_PARAMETERS}, {@link
AnnotationTraversal#PARAMETER_TYPE PARAMETER_TYPE}
+ * @return <jk>true</jk> if the annotation is found, <jk>false</jk>
otherwise.
+ */
+ public <A extends Annotation> boolean has(Class<A> type, ParameterInfo
parameter, AnnotationTraversal... traversals) {
+ return find(type, parameter,
traversals).findFirst().isPresent();
+ }
+
/**
* Streams annotations from a parameter using configurable traversal
options in parent-first order.
*
* <p>
- * This is equivalent to calling {@link #findAnnotations(Class,
ParameterInfo, AnnotationTraversal...)}
+ * This is equivalent to calling {@link #find(Class, ParameterInfo,
AnnotationTraversal...)}
* and reversing the result.
*
* @param <A> The annotation type.
@@ -1153,7 +1189,7 @@ public class AnnotationProvider {
* @return A stream of {@link AnnotationInfo} objects in parent-first
order. Never <jk>null</jk>.
*/
public <A extends Annotation> Stream<AnnotationInfo<A>>
findAnnotationsParentFirst(Class<A> type, ParameterInfo parameter,
AnnotationTraversal... traversals) {
- return rstream(findAnnotations(type, parameter,
traversals).toList());
+ return rstream(find(type, parameter, traversals).toList());
}
/**
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 44cdb6b39d..e25f0d20e8 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
@@ -65,7 +65,7 @@ public class FieldInfo extends AccessibleInfo implements
Comparable<FieldInfo>,
private final Field inner;
private final ClassInfo declaringClass;
private final Supplier<ClassInfo> type;
- private final Supplier<List<AnnotationInfo<Annotation>>>
declaredAnnotations; // All annotations declared directly on this field.
+ private final Supplier<List<AnnotationInfo<Annotation>>> annotations;
// All annotations declared directly on this field.
private final Supplier<String> fullName; // Fully qualified field name
(declaring-class.field-name).
/**
@@ -80,7 +80,7 @@ public class FieldInfo extends AccessibleInfo implements
Comparable<FieldInfo>,
this.declaringClass = declaringClass;
this.inner = inner;
this.type = memoize(() -> ClassInfo.of(inner.getType()));
- this.declaredAnnotations = memoize(() ->
stream(inner.getAnnotations()).flatMap(a -> streamRepeated(a)).map(a ->
AnnotationInfo.of(this, a)).toList());
+ this.annotations = memoize(() ->
stream(inner.getAnnotations()).flatMap(a -> streamRepeated(a)).map(a ->
AnnotationInfo.of(this, a)).toList());
this.fullName = memoize(this::findFullName);
}
@@ -108,8 +108,8 @@ public class FieldInfo extends AccessibleInfo implements
Comparable<FieldInfo>,
* An unmodifiable list of all annotations declared on this field.
* <br>Repeatable annotations are expanded into individual
instances.
*/
- public List<AnnotationInfo<Annotation>> getDeclaredAnnotations() {
- return declaredAnnotations.get();
+ public List<AnnotationInfo<Annotation>> getAnnotations() {
+ return annotations.get();
}
/**
@@ -120,8 +120,8 @@ public class FieldInfo extends AccessibleInfo implements
Comparable<FieldInfo>,
* @return A stream of all matching annotations.
*/
@SuppressWarnings("unchecked")
- public <A extends Annotation> Stream<AnnotationInfo<A>>
getDeclaredAnnotations(Class<A> type) {
- return declaredAnnotations.get().stream()
+ public <A extends Annotation> Stream<AnnotationInfo<A>>
getAnnotations(Class<A> type) {
+ return annotations.get().stream()
.filter(x -> type.isInstance(x.inner()))
.map(x -> (AnnotationInfo<A>)x);
}
@@ -204,7 +204,7 @@ public class FieldInfo extends AccessibleInfo implements
Comparable<FieldInfo>,
* @return <jk>true</jk> if the specified annotation is present.
*/
public <A extends Annotation> boolean hasAnnotation(Class<A> type) {
- return inner.isAnnotationPresent(type);
+ return getAnnotations(type).findAny().isPresent();
}
/**
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 2ed7df9c94..1546b39119 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
@@ -27,7 +27,6 @@ import java.util.*;
import java.util.function.*;
import java.util.stream.*;
-import org.apache.juneau.common.collections.*;
import org.apache.juneau.common.function.ResettableSupplier;
/**
@@ -58,10 +57,7 @@ public class ParameterInfo extends ElementInfo implements
Annotatable {
private final int index;
private final ClassInfo type;
- @SuppressWarnings({"rawtypes","unchecked"})
- private final Cache<Class,List<AnnotationInfo<Annotation>>>
allAnnotations =
Cache.<Class,List<AnnotationInfo<Annotation>>>create().supplier((k) ->
findAllAnnotationInfos(k)).build();
-
- private final Supplier<List<AnnotationInfo<Annotation>>>
declaredAnnotations; // All annotations declared directly on this parameter.
+ private final Supplier<List<AnnotationInfo<Annotation>>> annotations;
// All annotations declared directly on this parameter.
private final Supplier<List<ParameterInfo>> matchingParameters; //
Matching parameters in parent methods.
private final ResettableSupplier<String> resolvedName =
memoizeResettable(this::findNameInternal); // Resolved name from @Name
annotation or bytecode.
private final ResettableSupplier<String> resolvedQualifier =
memoizeResettable(this::findQualifierInternal); // Resolved qualifier from
@Named annotation.
@@ -81,7 +77,7 @@ public class ParameterInfo extends ElementInfo implements
Annotatable {
this.inner = inner;
this.index = index;
this.type = type;
- this.declaredAnnotations = memoize(() ->
stream(inner.getAnnotations()).flatMap(a -> streamRepeated(a)).map(a ->
AnnotationInfo.of(this, a)).toList());
+ this.annotations = memoize(() ->
stream(inner.getAnnotations()).flatMap(a -> streamRepeated(a)).map(a ->
AnnotationInfo.of(this, a)).toList());
this.matchingParameters = memoize(this::findMatchingParameters);
}
@@ -111,7 +107,7 @@ public class ParameterInfo extends ElementInfo implements
Annotatable {
* <br>Repeatable annotations are expanded into individual
instances.
*/
public List<AnnotationInfo<Annotation>> getAnnotations() {
- return declaredAnnotations.get();
+ return annotations.get();
}
/**
@@ -199,78 +195,6 @@ public class ParameterInfo extends ElementInfo implements
Annotatable {
return
((MethodInfo)executable).getMatchingMethods().stream().map(m ->
m.getParameter(index)).toList();
}
- /**
- * Returns all annotation infos of the specified type defined on this
parameter.
- *
- * <p>
- * Performs a comprehensive search through the parameter hierarchy and
parameter type hierarchy.
- *
- * <h5 class='section'>Search Order (child-to-parent):</h5>
- * <ol>
- * <li><b>Matching parameters in hierarchy</b>
- * <ul>
- * <li>For methods: This parameter → parent method
parameters (via {@link #getMatchingParameters()})
- * <li>For constructors: This parameter → parent
constructor parameters (via {@link #getMatchingParameters()})
- * </ul>
- * <li><b>Parameter type hierarchy</b> (via {@link
ClassInfo#getParentsAndInterfaces()})
- * <ul>
- * <li>Parameter's class and its interfaces
(interleaved)
- * <li>Parameter's parent classes and their
interfaces (interleaved)
- * <li>Continues up to Object class
- * </ul>
- * <li><b>Package annotation</b> - Package of the parameter type
- * </ol>
- *
- * <h5 class='section'>Example:</h5>
- * <p class='bjava'>
- * <jc>// Given:</jc>
- * <jk>class</jk> Parent {
- * <jk>void</jk> method(@MyAnnotation String
<jv>param</jv>) {}
- * }
- * <jk>class</jk> Child <jk>extends</jk> Parent {
- * <ja>@Override</ja>
- * <jk>void</jk> method(@MyAnnotation String
<jv>param</jv>) {}
- * }
- *
- * <jc>// Search order for Child.method parameter:</jc>
- * ParameterInfo <jv>pi</jv> =
ClassInfo.<jsm>of</jsm>(Child.<jk>class</jk>).getMethod(<js>"method"</js>,
String.<jk>class</jk>).getParameter(0);
- * List<AnnotationInfo<MyAnnotation>>
<jv>annotations</jv> =
<jv>pi</jv>.getAllAnnotations(MyAnnotation.<jk>class</jk>);
- * <jc>// Returns (in order):</jc>
- * <jc>// 1. @MyAnnotation on Child.method parameter</jc>
- * <jc>// 2. @MyAnnotation on Parent.method parameter</jc>
- * <jc>// 3. Any @MyAnnotation on String class hierarchy</jc>
- * <jc>// 4. Any @MyAnnotation on java.lang package</jc>
- * </p>
- *
- * @param <A> The annotation type to look for.
- * @param type The annotation type to look for.
- * @return An unmodifiable list of annotation infos in child-to-parent
order, or an empty list if none found.
- */
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public <A extends Annotation> List<AnnotationInfo<A>>
getAllAnnotations(Class<A> type) {
- return (List)allAnnotations.get(type);
- }
-
- /**
- * Returns the first annotation info of the specified type defined on
this parameter.
- *
- * <p>
- * This is a convenience method that returns the first result from
{@link #getAllAnnotations(Class)}.
- *
- * <p>
- * Performs a comprehensive search through the parameter hierarchy and
parameter type hierarchy
- * in child-to-parent order, returning the first annotation found.
- *
- * @param <A> The annotation type to look for.
- * @param type The annotation type to look for.
- * @return The first annotation info if found (closest to this
parameter), or <jk>null</jk> if not found.
- * @see #getAllAnnotations(Class)
- */
- public <A extends Annotation> AnnotationInfo<A>
getAllAnnotation(Class<A> type) {
- var list = getAllAnnotations(type);
- return list.isEmpty() ? null : list.get(0);
- }
-
/**
* Returns the constructor that this parameter belongs to.
*
@@ -278,21 +202,6 @@ public class ParameterInfo extends ElementInfo implements
Annotatable {
*/
public ConstructorInfo getConstructor() { return
executable.isConstructor() ? (ConstructorInfo)executable : null; }
- /**
- * Returns the specified parameter annotation declared on this
parameter.
- *
- * @param <A> The annotation type to look for.
- * @param type The annotation type to look for.
- * @return The specified parameter annotation declared on this
parameter, or <jk>null</jk> if not found.
- */
- public <A extends Annotation> A getDeclaredAnnotation(Class<A> type) {
- if (nn(type))
- for (var ai : getAnnotations())
- if (type.isInstance(ai.inner()))
- return type.cast(ai.inner());
- return null;
- }
-
/**
* Returns the index position of this parameter.
*
@@ -421,18 +330,6 @@ public class ParameterInfo extends ElementInfo implements
Annotatable {
*/
public ClassInfo getParameterType() { return type; }
- /**
- * Returns <jk>true</jk> if this parameter has the specified annotation.
- *
- * @param <A> The annotation type to look for.
- * @param type The annotation type to look for.
- * @return
- * The <jk>true</jk> if annotation if found.
- */
- public <A extends Annotation> boolean hasAnnotation(Class<A> type) {
- return nn(getAllAnnotation(type));
- }
-
/**
* Returns <jk>true</jk> if the parameter has a name.
*
@@ -673,93 +570,11 @@ public class ParameterInfo extends ElementInfo implements
Annotatable {
return inner.getAnnotatedType();
}
- /**
- * Returns annotations that are <em>directly present</em> on this
parameter.
- *
- * <p>
- * Same as calling {@link Parameter#getDeclaredAnnotations()}.
- *
- * <p>
- * <b>Note:</b> This returns the simple array of declared annotations.
- * For Juneau's enhanced annotation searching, use {@link
#findAnnotations(Class, AnnotationTraversal...)} instead.
- *
- * <h5 class='section'>Example:</h5>
- * <p class='bjava'>
- * <jc>// Get declared annotations on parameter</jc>
- * ParameterInfo <jv>pi</jv> = ...;
- * Annotation[] <jv>annotations</jv> =
<jv>pi</jv>.getDeclaredAnnotations();
- * </p>
- *
- * @return Annotations directly present on this parameter, or an empty
array if there are none.
- * @see Parameter#getDeclaredAnnotations()
- */
- public Annotation[] getDeclaredAnnotations() {
- return inner.getDeclaredAnnotations();
- }
-
- /**
- * Returns this element's declared annotations of the specified type
(including repeated annotations).
- *
- * <p>
- * Same as calling {@link
Parameter#getDeclaredAnnotationsByType(Class)}.
- *
- * <p>
- * This method handles repeatable annotations by "looking through"
container annotations,
- * but only examines annotations directly declared on this parameter
(not inherited).
- *
- * <h5 class='section'>Example:</h5>
- * <p class='bjava'>
- * <jc>// Get declared @Author annotations (including
repeated)</jc>
- * ParameterInfo <jv>pi</jv> = ...;
- * Author[] <jv>authors</jv> =
<jv>pi</jv>.getDeclaredAnnotationsByType(Author.<jk>class</jk>);
- * </p>
- *
- * @param <A> The annotation type.
- * @param annotationClass The Class object corresponding to the
annotation type.
- * @return All this element's declared annotations of the specified
type, or an empty array if there are none.
- * @see Parameter#getDeclaredAnnotationsByType(Class)
- */
- public <A extends Annotation> A[] getDeclaredAnnotationsByType(Class<A>
annotationClass) {
- return inner.getDeclaredAnnotationsByType(annotationClass);
- }
-
@Override
public String toString() {
return (executable.getSimpleName()) + "[" + index + "]";
}
- @SuppressWarnings("unchecked")
- private <A extends Annotation> List<AnnotationInfo<A>>
findAllAnnotationInfos(Class<A> type) {
- var list = new ArrayList<AnnotationInfo<A>>();
-
- // Search through matching parameters in hierarchy
(child-to-parent order)
- for (var mp : getMatchingParameters()) {
- mp.getAnnotations().stream()
- .filter(x -> x.isType(type))
- .map(x -> (AnnotationInfo<A>)x)
- .forEach(list::add);
- }
-
- // Search parameter type hierarchy in child-to-parent order
(interleaved classes and interfaces)
- var paramType =
executable.getParameter(index).getParameterType().unwrap(Value.class,
Optional.class);
-
- // Traverse parent classes and interfaces (child-to-parent,
interleaved)
- var parentsAndInterfaces = paramType.getParentsAndInterfaces();
- for (int i = 0; i < parentsAndInterfaces.size(); i++) {
-
parentsAndInterfaces.get(i).getDeclaredAnnotations().stream()
- .filter(x -> x.isType(type))
- .map(x -> (AnnotationInfo<A>)x)
- .forEach(list::add);
- }
-
- // Package annotation (last)
- var packageAnn = paramType.getPackageAnnotation(type);
- if (nn(packageAnn))
- list.add(AnnotationInfo.of(paramType, packageAnn));
-
- return list;
- }
-
//-----------------------------------------------------------------------------------------------------------------
// Annotatable interface methods
//-----------------------------------------------------------------------------------------------------------------
diff --git
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/StringUtils.java
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/StringUtils.java
index 8469c1014d..363d51c04a 100644
---
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/StringUtils.java
+++
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/StringUtils.java
@@ -1351,6 +1351,126 @@ public class StringUtils {
return ! isBlank(str);
}
+ /**
+ * Checks if any of the provided strings are not empty (not null and
not zero-length).
+ *
+ * <p>
+ * Returns <jk>true</jk> if at least one string is not null and has a
length greater than zero.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * isAnyNotEmpty(<jk>null</jk>, <jk>null</jk>); <jc>//
false</jc>
+ * isAnyNotEmpty(<js>""</js>, <js>""</js>); <jc>//
false</jc>
+ * isAnyNotEmpty(<jk>null</jk>, <js>"hello"</js>); <jc>//
true</jc>
+ * isAnyNotEmpty(<js>""</js>, <js>" "</js>); <jc>//
true</jc>
+ * isAnyNotEmpty(<js>"hello"</js>, <js>"world"</js>); <jc>//
true</jc>
+ * </p>
+ *
+ * @param values The strings to check.
+ * @return <jk>true</jk> if at least one string is not null and not
empty.
+ */
+ public static boolean isAnyNotEmpty(CharSequence...values) {
+ if (values == null)
+ return false;
+ for (CharSequence value : values)
+ if (value != null && !value.isEmpty())
+ return true;
+ return false;
+ }
+
+ /**
+ * Checks if any of the provided strings are not blank (not null, not
empty, and not whitespace only).
+ *
+ * <p>
+ * Returns <jk>true</jk> if at least one string is not null, not empty,
and contains non-whitespace characters.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * isAnyNotBlank(<jk>null</jk>, <jk>null</jk>); <jc>//
false</jc>
+ * isAnyNotBlank(<js>""</js>, <js>""</js>); <jc>//
false</jc>
+ * isAnyNotBlank(<js>" "</js>, <js>" "</js>); <jc>//
false</jc>
+ * isAnyNotBlank(<jk>null</jk>, <js>"hello"</js>); <jc>//
true</jc>
+ * isAnyNotBlank(<js>""</js>, <js>" "</js>, <js>"x"</js>);<jc>//
true</jc>
+ * isAnyNotBlank(<js>"hello"</js>, <js>"world"</js>); <jc>//
true</jc>
+ * </p>
+ *
+ * @param values The strings to check.
+ * @return <jk>true</jk> if at least one string is not null, not empty,
and contains non-whitespace characters.
+ */
+ public static boolean isAnyNotBlank(CharSequence...values) {
+ if (values == null)
+ return false;
+ for (CharSequence value : values)
+ if (isNotBlank(value))
+ return true;
+ return false;
+ }
+
+ /**
+ * Checks if all of the provided strings are not empty (not null and
not zero-length).
+ *
+ * <p>
+ * Returns <jk>true</jk> only if all strings are not null and have a
length greater than zero.
+ * Returns <jk>false</jk> if the array is null or empty, or if any
string is null or empty.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * isAllNotEmpty(); <jc>//
false</jc>
+ * isAllNotEmpty(<jk>null</jk>); <jc>//
false</jc>
+ * isAllNotEmpty(<jk>null</jk>, <jk>null</jk>); <jc>//
false</jc>
+ * isAllNotEmpty(<js>""</js>, <js>""</js>); <jc>//
false</jc>
+ * isAllNotEmpty(<jk>null</jk>, <js>"hello"</js>); <jc>//
false</jc>
+ * isAllNotEmpty(<js>""</js>, <js>" "</js>); <jc>//
false</jc>
+ * isAllNotEmpty(<js>"hello"</js>); <jc>//
true</jc>
+ * isAllNotEmpty(<js>"hello"</js>, <js>"world"</js>); <jc>//
true</jc>
+ * isAllNotEmpty(<js>"hello"</js>, <js>" "</js>); <jc>//
true</jc>
+ * </p>
+ *
+ * @param values The strings to check.
+ * @return <jk>true</jk> if all strings are not null and not empty,
<jk>false</jk> otherwise.
+ */
+ public static boolean isAllNotEmpty(CharSequence...values) {
+ if (values == null || values.length == 0)
+ return false;
+ for (CharSequence value : values)
+ if (value == null || value.isEmpty())
+ return false;
+ return true;
+ }
+
+ /**
+ * Checks if all of the provided strings are not blank (not null, not
empty, and not whitespace only).
+ *
+ * <p>
+ * Returns <jk>true</jk> only if all strings are not null, not empty,
and contain non-whitespace characters.
+ * Returns <jk>false</jk> if the array is null or empty, or if any
string is null, empty, or whitespace only.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * isAllNotBlank(); <jc>//
false</jc>
+ * isAllNotBlank(<jk>null</jk>); <jc>//
false</jc>
+ * isAllNotBlank(<jk>null</jk>, <jk>null</jk>); <jc>//
false</jc>
+ * isAllNotBlank(<js>""</js>, <js>""</js>); <jc>//
false</jc>
+ * isAllNotBlank(<js>" "</js>, <js>" "</js>); <jc>//
false</jc>
+ * isAllNotBlank(<jk>null</jk>, <js>"hello"</js>); <jc>//
false</jc>
+ * isAllNotBlank(<js>""</js>, <js>" "</js>); <jc>//
false</jc>
+ * isAllNotBlank(<js>"hello"</js>, <js>" "</js>); <jc>//
false</jc>
+ * isAllNotBlank(<js>"hello"</js>); <jc>//
true</jc>
+ * isAllNotBlank(<js>"hello"</js>, <js>"world"</js>); <jc>//
true</jc>
+ * </p>
+ *
+ * @param values The strings to check.
+ * @return <jk>true</jk> if all strings are not null, not empty, and
not whitespace only, <jk>false</jk> otherwise.
+ */
+ public static boolean isAllNotBlank(CharSequence...values) {
+ if (values == null || values.length == 0)
+ return false;
+ for (CharSequence value : values)
+ if (! isNotBlank(value))
+ return false;
+ return true;
+ }
+
/**
* Returns <jk>true</jk> if the specified character is a valid number
character.
*
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanFilter.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanFilter.java
index a27419ca24..f426acf309 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanFilter.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanFilter.java
@@ -76,17 +76,17 @@ public class BeanFilter {
public Builder applyAnnotations(List<Bean> annotations) {
annotations.forEach(x -> {
- if (isNotEmpty(x.properties()) ||
isNotEmpty(x.p()))
+ if (isAnyNotEmpty(x.properties(), x.p()))
properties(x.properties(), x.p());
if (x.sort())
sortProperties(true);
if (x.findFluentSetters())
findFluentSetters();
- if (isNotEmpty(x.excludeProperties()) ||
isNotEmpty(x.xp()))
+ if (isAnyNotEmpty(x.excludeProperties(),
x.xp()))
excludeProperties(x.excludeProperties(), x.xp());
- if (isNotEmpty(x.readOnlyProperties()) ||
isNotEmpty(x.ro()))
+ if (isAnyNotEmpty(x.readOnlyProperties(),
x.ro()))
readOnlyProperties(x.readOnlyProperties(), x.ro());
- if (isNotEmpty(x.writeOnlyProperties()) ||
isNotEmpty(x.wo()))
+ if (isAnyNotEmpty(x.writeOnlyProperties(),
x.wo()))
writeOnlyProperties(x.writeOnlyProperties(), x.wo());
if (isNotEmpty(x.typeName()))
typeName(x.typeName());
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormDataAnnotation.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormDataAnnotation.java
index 1a646851c9..3b47907f17 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormDataAnnotation.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormDataAnnotation.java
@@ -19,13 +19,14 @@ package org.apache.juneau.http.annotation;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
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 java.lang.annotation.*;
+import java.util.*;
import org.apache.juneau.*;
import org.apache.juneau.annotation.*;
-import org.apache.juneau.common.collections.*;
import org.apache.juneau.httppart.*;
import org.apache.juneau.common.reflect.*;
import org.apache.juneau.svl.*;
@@ -37,6 +38,9 @@ import org.apache.juneau.svl.*;
* </ul>
*/
public class FormDataAnnotation {
+
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
/**
* Applies targeted {@link FormData} annotations to a {@link
org.apache.juneau.BeanContext.Builder}.
*/
@@ -53,7 +57,7 @@ public class FormDataAnnotation {
@Override
public void apply(AnnotationInfo<FormData> ai,
BeanContext.Builder b) {
- FormData a = ai.inner();
+ var a = ai.inner();
if (isEmptyArray(a.on()) && isEmptyArray(a.onClass()))
return;
b.annotations(a);
@@ -270,12 +274,14 @@ public class FormDataAnnotation {
* Finds the default value from the specified list of annotations.
*
* @param pi The parameter.
- * @return The last matching default value, or {@link Value#empty()} if
not found.
+ * @return The last matching default value, or empty if not found.
*/
- public static Value<String> findDef(ParameterInfo pi) {
- Value<String> n = Value.empty();
-
rstream(pi.getAllAnnotations(FormData.class)).map(AnnotationInfo::inner).filter(x
-> isNotEmpty(x.def())).forEach(x -> n.set(x.def()));
- return n;
+ public static Optional<String> findDef(ParameterInfo pi) {
+ return AP.find(FormData.class, pi)
+ .map(AnnotationInfo::inner)
+ .filter(x -> isNotEmpty(x.def()))
+ .findFirst()
+ .map(x -> x.def());
}
/**
@@ -285,12 +291,13 @@ public class FormDataAnnotation {
* The last matching name found is returned.
*
* @param pi The parameter.
- * @return The last matching name, or {@link Value#empty()} if not
found.
+ * @return The last matching name, or empty if not found.
*/
- public static Value<String> findName(ParameterInfo pi) {
- Value<String> n = Value.empty();
-
rstream(pi.getAllAnnotations(FormData.class)).map(AnnotationInfo::inner).filter(x
-> isNotEmpty(x.value())).forEach(x -> n.set(x.value()));
-
rstream(pi.getAllAnnotations(FormData.class)).map(AnnotationInfo::inner).filter(x
-> isNotEmpty(x.name())).forEach(x -> n.set(x.name()));
- return n;
+ public static Optional<String> findName(ParameterInfo pi) {
+ return AP.find(FormData.class, pi)
+ .map(AnnotationInfo::inner)
+ .filter(x -> isAnyNotBlank(x.value(), x.name()))
+ .findFirst()
+ .map(x -> firstNonBlank(x.name(), x.value()));
}
}
\ No newline at end of file
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/HeaderAnnotation.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/HeaderAnnotation.java
index 91d3daf29d..3a7af85219 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/HeaderAnnotation.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/HeaderAnnotation.java
@@ -19,13 +19,14 @@ package org.apache.juneau.http.annotation;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
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 java.lang.annotation.*;
+import java.util.*;
import org.apache.juneau.*;
import org.apache.juneau.annotation.*;
-import org.apache.juneau.common.collections.*;
import org.apache.juneau.httppart.*;
import org.apache.juneau.common.reflect.*;
import org.apache.juneau.svl.*;
@@ -37,6 +38,9 @@ import org.apache.juneau.svl.*;
* </ul>
*/
public class HeaderAnnotation {
+
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
/**
* Applies targeted {@link Header} annotations to a {@link
org.apache.juneau.BeanContext.Builder}.
*/
@@ -53,7 +57,7 @@ public class HeaderAnnotation {
@Override
public void apply(AnnotationInfo<Header> ai,
BeanContext.Builder b) {
- Header a = ai.inner();
+ var a = ai.inner();
if (isEmptyArray(a.on()) && isEmptyArray(a.onClass()))
return;
b.annotations(a);
@@ -270,12 +274,14 @@ public class HeaderAnnotation {
* Finds the default value from the specified list of annotations.
*
* @param pi The parameter.
- * @return The last matching default value, or {@link Value#empty()} if
not found.
+ * @return The last matching default value, or empty if not found.
*/
- public static Value<String> findDef(ParameterInfo pi) {
- Value<String> n = Value.empty();
-
rstream(pi.getAllAnnotations(Header.class)).map(AnnotationInfo::inner).filter(x
-> isNotEmpty(x.def())).forEach(x -> n.set(x.def()));
- return n;
+ public static Optional<String> findDef(ParameterInfo pi) {
+ return AP.find(Header.class, pi)
+ .map(AnnotationInfo::inner)
+ .filter(x -> isNotEmpty(x.def()))
+ .findFirst()
+ .map(x -> x.def());
}
/**
@@ -285,12 +291,13 @@ public class HeaderAnnotation {
* The last matching name found is returned.
*
* @param pi The parameter.
- * @return The last matching name, or {@link Value#empty()} if not
found.
+ * @return The last matching name, or empty if not found.
*/
- public static Value<String> findName(ParameterInfo pi) {
- Value<String> n = Value.empty();
-
rstream(pi.getAllAnnotations(Header.class)).map(AnnotationInfo::inner).filter(x
-> isNotEmpty(x.value())).forEach(x -> n.set(x.value()));
-
rstream(pi.getAllAnnotations(Header.class)).map(AnnotationInfo::inner).filter(x
-> isNotEmpty(x.name())).forEach(x -> n.set(x.name()));
- return n;
+ public static Optional<String> findName(ParameterInfo pi) {
+ return AP.find(Header.class, pi)
+ .map(AnnotationInfo::inner)
+ .filter(x -> isAnyNotBlank(x.value(), x.name()))
+ .findFirst()
+ .map(x -> firstNonBlank(x.name(), x.value()));
}
}
\ No newline at end of file
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/PathAnnotation.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/PathAnnotation.java
index 829ee71d1b..9f1f9e59c6 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/PathAnnotation.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/PathAnnotation.java
@@ -20,13 +20,14 @@ import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import static org.apache.juneau.Constants.*;
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 java.lang.annotation.*;
+import java.util.*;
import org.apache.juneau.*;
import org.apache.juneau.annotation.*;
-import org.apache.juneau.common.collections.*;
import org.apache.juneau.httppart.*;
import org.apache.juneau.common.reflect.*;
import org.apache.juneau.svl.*;
@@ -38,6 +39,9 @@ import org.apache.juneau.svl.*;
* </ul>
*/
public class PathAnnotation {
+
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
/**
* Applies targeted {@link Path} annotations to a {@link
org.apache.juneau.BeanContext.Builder}.
*/
@@ -271,12 +275,14 @@ public class PathAnnotation {
* Finds the default value from the specified list of annotations.
*
* @param pi The parameter.
- * @return The last matching default value, or {@link Value#empty()} if
not found.
+ * @return The last matching default value, or empty if not found.
*/
- public static Value<String> findDef(ParameterInfo pi) {
- Value<String> n = Value.empty();
-
rstream(pi.getAllAnnotations(Path.class)).map(AnnotationInfo::inner).filter(x
-> isNotEmpty(x.def()) && ne(NONE, x.def())).forEach(x -> n.set(x.def()));
- return n;
+ public static Optional<String> findDef(ParameterInfo pi) {
+ return AP.find(Header.class, pi)
+ .map(AnnotationInfo::inner)
+ .filter(x -> isNotEmpty(x.def()) && ne(NONE, x.def()))
+ .findFirst()
+ .map(x -> x.def());
}
/**
@@ -286,12 +292,13 @@ public class PathAnnotation {
* The last matching name found is returned.
*
* @param pi The parameter.
- * @return The last matching name, or {@link Value#empty()} if not
found.
+ * @return The last matching name, or empty if not found.
*/
- public static Value<String> findName(ParameterInfo pi) {
- Value<String> n = Value.empty();
-
rstream(pi.getAllAnnotations(Path.class)).map(AnnotationInfo::inner).filter(x
-> isNotEmpty(x.value())).forEach(x -> n.set(x.value()));
-
rstream(pi.getAllAnnotations(Path.class)).map(AnnotationInfo::inner).filter(x
-> isNotEmpty(x.name())).forEach(x -> n.set(x.name()));
- return n;
+ public static Optional<String> findName(ParameterInfo pi) {
+ return AP.find(Path.class, pi)
+ .map(AnnotationInfo::inner)
+ .filter(x -> isAnyNotBlank(x.value(), x.name()))
+ .findFirst()
+ .map(x -> firstNonBlank(x.name(), x.value()));
}
}
\ No newline at end of file
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/PathRemainderAnnotation.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/PathRemainderAnnotation.java
index a7d49024b0..1f1de34044 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/PathRemainderAnnotation.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/PathRemainderAnnotation.java
@@ -22,10 +22,10 @@ import static
org.apache.juneau.common.utils.CollectionUtils.*;
import static org.apache.juneau.common.utils.Utils.*;
import java.lang.annotation.*;
+import java.util.*;
import org.apache.juneau.*;
import org.apache.juneau.annotation.*;
-import org.apache.juneau.common.collections.*;
import org.apache.juneau.httppart.*;
import org.apache.juneau.common.reflect.*;
import org.apache.juneau.svl.*;
@@ -41,6 +41,9 @@ import org.apache.juneau.svl.*;
* @since 9.2.0
*/
public class PathRemainderAnnotation {
+
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
/**
* Applies targeted {@link PathRemainder} annotations to a {@link
org.apache.juneau.BeanContext.Builder}.
*/
@@ -259,11 +262,13 @@ public class PathRemainderAnnotation {
* Finds the default value from the specified list of annotations.
*
* @param pi The parameter.
- * @return The last matching default value, or {@link Value#empty()} if
not found.
+ * @return The last matching default value, or empty if not found.
*/
- public static Value<String> findDef(ParameterInfo pi) {
- Value<String> n = Value.empty();
-
rstream(pi.getAllAnnotations(PathRemainder.class)).map(AnnotationInfo::inner).filter(x
-> isNotEmpty(x.def())).forEach(x -> n.set(x.def()));
- return n;
+ public static Optional<String> findDef(ParameterInfo pi) {
+ return AP.find(PathRemainder.class, pi)
+ .map(AnnotationInfo::inner)
+ .filter(x -> isNotEmpty(x.def()))
+ .findFirst()
+ .map(x -> x.def());
}
}
\ No newline at end of file
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/QueryAnnotation.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/QueryAnnotation.java
index 792f0d9c7e..58a31eda37 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/QueryAnnotation.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/QueryAnnotation.java
@@ -19,13 +19,14 @@ package org.apache.juneau.http.annotation;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
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 java.lang.annotation.*;
+import java.util.*;
import org.apache.juneau.*;
import org.apache.juneau.annotation.*;
-import org.apache.juneau.common.collections.*;
import org.apache.juneau.httppart.*;
import org.apache.juneau.common.reflect.*;
import org.apache.juneau.svl.*;
@@ -37,6 +38,9 @@ import org.apache.juneau.svl.*;
* </ul>
*/
public class QueryAnnotation {
+
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
/**
* Applies targeted {@link Query} annotations to a {@link
org.apache.juneau.BeanContext.Builder}.
*/
@@ -53,7 +57,7 @@ public class QueryAnnotation {
@Override
public void apply(AnnotationInfo<Query> ai, BeanContext.Builder
b) {
- Query a = ai.inner();
+ var a = ai.inner();
if (isEmptyArray(a.on()) && isEmptyArray(a.onClass()))
return;
b.annotations(a);
@@ -270,24 +274,27 @@ public class QueryAnnotation {
* Finds the default value from the specified list of annotations.
*
* @param pi The parameter.
- * @return The last matching default value, or {@link Value#empty()} if
not found.
+ * @return The last matching default value, or empty if not found.
*/
- public static Value<String> findDef(ParameterInfo pi) {
- Value<String> n = Value.empty();
-
rstream(pi.getAllAnnotations(Query.class)).map(AnnotationInfo::inner).filter(x
-> isNotEmpty(x.def())).forEach(x -> n.set(x.def()));
- return n;
+ public static Optional<String> findDef(ParameterInfo pi) {
+ return AP.find(Query.class, pi)
+ .map(AnnotationInfo::inner)
+ .filter(x -> isNotEmpty(x.def()))
+ .findFirst()
+ .map(x -> x.def());
}
/**
* Finds the name from the specified list of annotations.
*
* @param pi The parameter.
- * @return The last matching name, or {@link Value#empty()} if not
found.
+ * @return The last matching name, or empty if not found.
*/
- public static Value<String> findName(ParameterInfo pi) {
- Value<String> n = Value.empty();
-
rstream(pi.getAllAnnotations(Query.class)).map(AnnotationInfo::inner).filter(x
-> isNotEmpty(x.value())).forEach(x -> n.set(x.value()));
-
rstream(pi.getAllAnnotations(Query.class)).map(AnnotationInfo::inner).filter(x
-> isNotEmpty(x.name())).forEach(x -> n.set(x.name()));
- return n;
+ public static Optional<String> findName(ParameterInfo pi) {
+ return AP.find(Query.class, pi)
+ .map(AnnotationInfo::inner)
+ .filter(x -> isAnyNotBlank(x.value(), x.name()))
+ .findFirst()
+ .map(x -> firstNonBlank(x.name(), x.value()));
}
}
\ No newline at end of file
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/RequestBeanMeta.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/RequestBeanMeta.java
index 5d8e418d97..7d6aee1e72 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/RequestBeanMeta.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/RequestBeanMeta.java
@@ -39,6 +39,8 @@ import org.apache.juneau.common.reflect.*;
*/
public class RequestBeanMeta {
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
static class Builder {
ClassMeta<?> cm;
AnnotationWorkList annotations;
@@ -54,7 +56,7 @@ public class RequestBeanMeta {
this.cm = BeanContext.DEFAULT.getClassMeta(c);
apply(cm.getLastAnnotation(Request.class));
cm.getInfo().getPublicMethods().stream().forEach(x -> {
- String n = x.getSimpleName();
+ var n = x.getSimpleName();
if (x.hasAnnotation(Header.class)) {
assertNoArgs(x, Header.class);
assertReturnNotVoid(x, Header.class);
@@ -81,7 +83,7 @@ public class RequestBeanMeta {
}
Builder apply(ParameterInfo mpi) {
- return
apply(mpi.getParameterType().inner()).apply(opt(mpi.getAllAnnotation(Request.class)).map(x
-> x.inner()).orElse(null));
+ return
apply(mpi.getParameterType().inner()).apply(AP.find(Request.class,
mpi).findFirst().map(x -> x.inner()).orElse(null));
}
Builder apply(Request a) {
@@ -121,7 +123,7 @@ public class RequestBeanMeta {
* @return Metadata about the parameter, or <jk>null</jk> if parameter
or parameter type not annotated with {@link Request}.
*/
public static RequestBeanMeta create(ParameterInfo mpi,
AnnotationWorkList annotations) {
- if (! mpi.hasAnnotation(Request.class))
+ if (! AP.has(Request.class, mpi))
return null;
return new
RequestBeanMeta.Builder(annotations).apply(mpi).build();
}
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 a67b9c18f1..8a4e54f6c8 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
@@ -42,6 +42,8 @@ import org.apache.juneau.common.reflect.*;
*/
public class ResponseBeanMeta {
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
static class Builder {
ClassMeta<?> cm;
int code;
@@ -78,9 +80,9 @@ public class ResponseBeanMeta {
}
Builder apply(Type t) {
- Class<?> c = toClass(t);
+ var c = toClass(t);
this.cm = BeanContext.DEFAULT.getClassMeta(c);
- ClassInfo ci = cm.getInfo();
+ var ci = cm.getInfo();
ci.getPublicMethods().stream().forEach(x -> {
assertNoInvalidAnnotations(x, Query.class,
FormData.class);
if (x.hasAnnotation(Header.class)) {
@@ -138,12 +140,12 @@ public class ResponseBeanMeta {
* @return Metadata about the class, or <jk>null</jk> if class not
annotated with {@link Response}.
*/
public static ResponseBeanMeta create(ParameterInfo mpi,
AnnotationWorkList annotations) {
- if (! mpi.hasAnnotation(Response.class))
+ if (! AP.has(Response.class, mpi))
return null;
var b = new Builder(annotations);
b.apply(mpi.getParameterType().unwrap(Value.class,
Optional.class).innerType());
-
rstream(mpi.getAllAnnotations(Response.class)).map(AnnotationInfo::inner).forEach(x
-> b.apply(x));
-
rstream(mpi.getAllAnnotations(StatusCode.class)).map(AnnotationInfo::inner).forEach(x
-> b.apply(x));
+ AP.findTopDown(Response.class,
mpi).map(AnnotationInfo::inner).forEach(x -> b.apply(x));
+ AP.findTopDown(StatusCode.class,
mpi).map(AnnotationInfo::inner).forEach(x -> b.apply(x));
return b.build();
}
diff --git
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationArg.java
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationArg.java
index b43dda6ce4..1571515acc 100644
---
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationArg.java
+++
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationArg.java
@@ -35,22 +35,24 @@ import org.apache.juneau.common.reflect.*;
*/
public class RemoteOperationArg {
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
static RemoteOperationArg create(ParameterInfo mpi) {
int i = mpi.getIndex();
- if (mpi.hasAnnotation(Header.class)) {
+ if (AP.has(Header.class, mpi)) {
return new RemoteOperationArg(i, HEADER,
HttpPartSchema.create(Header.class, mpi));
- } else if (mpi.hasAnnotation(Query.class)) {
+ } else if (AP.has(Query.class, mpi)) {
return new RemoteOperationArg(i, QUERY,
HttpPartSchema.create(Query.class, mpi));
- } else if (mpi.hasAnnotation(FormData.class)) {
+ } else if (AP.has(FormData.class, mpi)) {
return new RemoteOperationArg(i, FORMDATA,
HttpPartSchema.create(FormData.class, mpi));
- } else if (mpi.hasAnnotation(PathRemainder.class)) {
+ } else if (AP.has(PathRemainder.class, mpi)) {
// PathRemainder is equivalent to @Path("/*")
// Create with schema properties but override name to
"/*"
var schema = HttpPartSchema.create(PathRemainder.class,
mpi);
return new RemoteOperationArg(i, PATH, schema, "/*");
- } else if (mpi.hasAnnotation(Path.class)) {
+ } else if (AP.has(Path.class, mpi)) {
return new RemoteOperationArg(i, PATH,
HttpPartSchema.create(Path.class, mpi));
- } else if (mpi.hasAnnotation(Content.class)) {
+ } else if (AP.has(Content.class, mpi)) {
return new RemoteOperationArg(i, BODY,
HttpPartSchema.create(Content.class, mpi));
}
return null;
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 cb8631a7e9..bdce59ca4d 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
@@ -1767,7 +1767,7 @@ public class RestContext extends Context {
y -> beanStore.add(
x.getFieldType().inner(),
y,
-
RestInjectAnnotation.name(x.getDeclaredAnnotations(RestInject.class).findFirst().map(AnnotationInfo::inner).orElse(null))
+
RestInjectAnnotation.name(x.getAnnotations(RestInject.class).findFirst().map(AnnotationInfo::inner).orElse(null))
)
));
// @formatter:on
@@ -1804,7 +1804,7 @@ public class RestContext extends Context {
resource.get(),
beanStore.getBean(
x.getFieldType().inner(),
-
RestInjectAnnotation.name(x.getDeclaredAnnotations(RestInject.class).findFirst().map(AnnotationInfo::inner).orElse(null))
+
RestInjectAnnotation.name(x.getAnnotations(RestInject.class).findFirst().map(AnnotationInfo::inner).orElse(null))
).orElse(null)
));
// @formatter:on
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/AttributeArg.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/AttributeArg.java
index adc1034ae3..108395d811 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/AttributeArg.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/AttributeArg.java
@@ -16,10 +16,8 @@
*/
package org.apache.juneau.rest.arg;
-import static org.apache.juneau.common.utils.CollectionUtils.*;
-import static org.apache.juneau.common.utils.Utils.*;
+import static org.apache.juneau.common.utils.StringUtils.*;
-import org.apache.juneau.common.collections.*;
import org.apache.juneau.common.reflect.*;
import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
@@ -44,6 +42,8 @@ import org.apache.juneau.rest.httppart.*;
*/
public class AttributeArg implements RestOpArg {
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
/**
* Static creator.
*
@@ -51,7 +51,7 @@ public class AttributeArg implements RestOpArg {
* @return A new {@link AttributeArg}, or <jk>null</jk> if the
parameter is not annotated with {@link Attr}.
*/
public static AttributeArg create(ParameterInfo paramInfo) {
- if (paramInfo.hasAnnotation(Attr.class) ||
paramInfo.getParameterType().hasAnnotation(Attr.class))
+ if (AP.has(Attr.class, paramInfo))
return new AttributeArg(paramInfo);
return null;
}
@@ -76,11 +76,11 @@ public class AttributeArg implements RestOpArg {
}
private static String getName(ParameterInfo paramInfo) {
- Value<String> n = Value.empty();
-
rstream(paramInfo.getAllAnnotations(Attr.class)).map(AnnotationInfo::inner).filter(x
-> isNotEmpty(x.name())).forEach(x -> n.set(x.name()));
-
rstream(paramInfo.getAllAnnotations(Attr.class)).map(AnnotationInfo::inner).filter(x
-> isNotEmpty(x.value())).forEach(x -> n.set(x.value()));
- if (n.isEmpty())
- throw new ArgException(paramInfo, "@Attr used without
name or value");
- return n.get();
+ return AP.find(Attr.class, paramInfo)
+ .map(AnnotationInfo::inner)
+ .filter(x -> isAnyNotBlank(x.value(), x.name()))
+ .findFirst()
+ .map(x -> firstNonBlank(x.name(), x.value()))
+ .orElseThrow(() -> new ArgException(paramInfo, "@Attr
used without name or value"));
}
}
\ No newline at end of file
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/ContentArg.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/ContentArg.java
index f04688caa5..6579ded7c8 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/ContentArg.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/ContentArg.java
@@ -47,6 +47,8 @@ import org.apache.juneau.rest.httppart.*;
*/
public class ContentArg implements RestOpArg {
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
/**
* Static creator.
*
@@ -54,7 +56,7 @@ public class ContentArg implements RestOpArg {
* @return A new {@link ContentArg}, or <jk>null</jk> if the parameter
is not annotated with {@link Content}.
*/
public static ContentArg create(ParameterInfo paramInfo) {
- if (paramInfo.hasAnnotation(Content.class) ||
paramInfo.getParameterType().hasAnnotation(Content.class))
+ if (AP.has(Content.class, paramInfo))
return new ContentArg(paramInfo);
return null;
}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/FormDataArg.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/FormDataArg.java
index 25f44d0164..44762188fa 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/FormDataArg.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/FormDataArg.java
@@ -57,6 +57,9 @@ import org.apache.juneau.rest.httppart.*;
* </ul>
*/
public class FormDataArg implements RestOpArg {
+
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
/**
* Static creator.
*
@@ -65,7 +68,7 @@ public class FormDataArg implements RestOpArg {
* @return A new {@link FormDataArg}, or <jk>null</jk> if the parameter
is not annotated with {@link FormData}.
*/
public static FormDataArg create(ParameterInfo paramInfo,
AnnotationWorkList annotations) {
- if (paramInfo.hasAnnotation(FormData.class) ||
paramInfo.getParameterType().hasAnnotation(FormData.class))
+ if (AP.has(FormData.class, paramInfo))
return new FormDataArg(paramInfo, annotations);
return null;
}
@@ -79,32 +82,30 @@ public class FormDataArg implements RestOpArg {
*/
private static FormData getMergedFormData(ParameterInfo pi, String
paramName) {
// Get the declaring class
- ClassInfo declaringClass = pi.getMethod().getDeclaringClass();
+ var declaringClass = pi.getMethod().getDeclaringClass();
if (declaringClass == null)
return null;
// Find @Rest annotation on the class
- Rest restAnnotation =
declaringClass.getAnnotations(Rest.class).findFirst().map(AnnotationInfo::inner).orElse(null);
+ var restAnnotation =
declaringClass.getAnnotations(Rest.class).findFirst().map(AnnotationInfo::inner).orElse(null);
if (restAnnotation == null)
return null;
// Find matching @FormData from class-level formDataParams array
FormData classLevelFormData = null;
for (var f : restAnnotation.formDataParams()) {
- String fName = firstNonEmpty(f.name(), f.value());
- if (paramName.equals(fName)) {
+ var fName = firstNonEmpty(f.name(), f.value());
+ if (eq(paramName, fName)) {
classLevelFormData = f;
break;
}
}
- if (classLevelFormData == null)
- return null;
+ if (classLevelFormData == null)
+ return null;
- // Get parameter-level @FormData
- FormData paramFormData = opt(pi.getAllAnnotation(FormData.class)).map(x
-> x.inner()).orElse(null);
- if (paramFormData == null)
- paramFormData =
pi.getParameterType().getAnnotations(FormData.class).findFirst().map(AnnotationInfo::inner).orElse(null);
+ // Get parameter-level @FormData
+ var paramFormData = AP.find(FormData.class,
pi).findFirst().map(x -> x.inner()).orElse(null);
if (paramFormData == null) {
// No parameter-level @FormData, use class-level as-is
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HasFormDataArg.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HasFormDataArg.java
index 8fa4daac1e..48584f9a9e 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HasFormDataArg.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HasFormDataArg.java
@@ -16,14 +16,10 @@
*/
package org.apache.juneau.rest.arg;
-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 java.lang.reflect.*;
-import org.apache.juneau.*;
-import org.apache.juneau.common.collections.*;
import org.apache.juneau.http.annotation.*;
import org.apache.juneau.common.reflect.*;
import org.apache.juneau.rest.*;
@@ -51,6 +47,8 @@ import org.apache.juneau.rest.httppart.*;
*/
public class HasFormDataArg implements RestOpArg {
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
/**
* Static creator.
*
@@ -58,7 +56,7 @@ public class HasFormDataArg implements RestOpArg {
* @return A new {@link HasFormDataArg}, or <jk>null</jk> if the
parameter is not annotated with {@link HasFormData}.
*/
public static HasFormDataArg create(ParameterInfo paramInfo) {
- if (paramInfo.hasAnnotation(HasFormData.class))
+ if (AP.has(HasFormData.class, paramInfo))
return new HasFormDataArg(paramInfo);
return null;
}
@@ -68,11 +66,10 @@ public class HasFormDataArg implements RestOpArg {
}
private static boolean hasName(HasFormData x) {
- return isNotEmpty(x.name()) || isNotEmpty(x.value());
+ return isAnyNotBlank(x.name(), x.value());
}
private final String name;
-
private final Type type;
/**
@@ -81,16 +78,19 @@ public class HasFormDataArg implements RestOpArg {
* @param pi The Java method parameter being resolved.
*/
protected HasFormDataArg(ParameterInfo pi) {
- Value<String> _name = Value.empty();
-
rstream(pi.getAllAnnotations(HasFormData.class)).map(AnnotationInfo::inner).filter(HasFormDataArg::hasName).forEach(x
-> _name.set(getName(x)));
- this.name = _name.orElseThrow(() -> new ArgException(pi,
"@HasFormData used without name or value"));
+ this.name = AP.find(HasFormData.class, pi)
+ .map(AnnotationInfo::inner)
+ .filter(HasFormDataArg::hasName)
+ .findFirst()
+ .map(HasFormDataArg::getName)
+ .orElseThrow(() -> new ArgException(pi, "@HasFormData
used without name or value"));
this.type = pi.getParameterType().innerType();
}
@Override /* Overridden from RestOpArg */
public Object resolve(RestOpSession opSession) throws Exception {
- RestRequest req = opSession.getRequest();
- BeanSession bs = req.getBeanSession();
+ var req = opSession.getRequest();
+ var bs = req.getBeanSession();
return bs.convertToType(req.getFormParams().contains(name),
bs.getClassMeta(type));
}
}
\ No newline at end of file
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HasQueryArg.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HasQueryArg.java
index b639cc253c..2b650c4ba0 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HasQueryArg.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HasQueryArg.java
@@ -16,14 +16,10 @@
*/
package org.apache.juneau.rest.arg;
-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 java.lang.reflect.*;
-import org.apache.juneau.*;
-import org.apache.juneau.common.collections.*;
import org.apache.juneau.http.annotation.*;
import org.apache.juneau.common.reflect.*;
import org.apache.juneau.rest.*;
@@ -51,6 +47,8 @@ import org.apache.juneau.rest.httppart.*;
*/
public class HasQueryArg implements RestOpArg {
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
/**
* Static creator.
*
@@ -58,7 +56,7 @@ public class HasQueryArg implements RestOpArg {
* @return A new {@link HasQueryArg}, or <jk>null</jk> if the parameter
is not annotated with {@link HasQuery}.
*/
public static HasQueryArg create(ParameterInfo paramInfo) {
- if (paramInfo.hasAnnotation(HasQuery.class))
+ if (AP.has(HasQuery.class, paramInfo))
return new HasQueryArg(paramInfo);
return null;
}
@@ -68,7 +66,7 @@ public class HasQueryArg implements RestOpArg {
}
private static boolean hasName(HasQuery x) {
- return isNotEmpty(x.name()) || isNotEmpty(x.value());
+ return isAnyNotBlank(x.name(), x.value());
}
private final String name;
@@ -81,16 +79,19 @@ public class HasQueryArg implements RestOpArg {
* @param pi The Java method parameter being resolved.
*/
protected HasQueryArg(ParameterInfo pi) {
- Value<String> _name = Value.empty();
-
rstream(pi.getAllAnnotations(HasQuery.class)).map(AnnotationInfo::inner).filter(HasQueryArg::hasName).forEach(x
-> _name.set(getName(x)));
- this.name = _name.orElseThrow(() -> new ArgException(pi,
"@HasQuery used without name or value"));
+ this.name = AP.find(HasQuery.class, pi)
+ .map(AnnotationInfo::inner)
+ .filter(HasQueryArg::hasName)
+ .findFirst()
+ .map(HasQueryArg::getName)
+ .orElseThrow(() -> new ArgException(pi, "@HasQuery used
without name or value"));
this.type = pi.getParameterType().innerType();
}
@Override /* Overridden from RestOpArg */
public Object resolve(RestOpSession opSession) throws Exception {
- RestRequest req = opSession.getRequest();
- BeanSession bs = req.getBeanSession();
+ var req = opSession.getRequest();
+ var bs = req.getBeanSession();
return bs.convertToType(req.getQueryParams().contains(name),
bs.getClassMeta(type));
}
}
\ No newline at end of file
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HeaderArg.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HeaderArg.java
index 7df32c7b47..53f5e01407 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HeaderArg.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HeaderArg.java
@@ -33,7 +33,6 @@ import org.apache.juneau.httppart.*;
import org.apache.juneau.common.reflect.*;
import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.httppart.*;
/**
* Resolves method parameters and parameter types annotated with {@link
Header} on {@link RestOp}-annotated Java methods.
@@ -99,6 +98,9 @@ import org.apache.juneau.rest.httppart.*;
* </ul>
*/
public class HeaderArg implements RestOpArg {
+
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
/**
* Static creator.
*
@@ -107,7 +109,7 @@ public class HeaderArg implements RestOpArg {
* @return A new {@link HeaderArg}, or <jk>null</jk> if the parameter
is not annotated with {@link Header}.
*/
public static HeaderArg create(ParameterInfo paramInfo,
AnnotationWorkList annotations) {
- if ((! paramInfo.getParameterType().is(Value.class)) &&
(paramInfo.hasAnnotation(Header.class) ||
paramInfo.getParameterType().hasAnnotation(Header.class)))
+ if ((! paramInfo.getParameterType().is(Value.class)) &&
AP.has(Header.class, paramInfo))
return new HeaderArg(paramInfo, annotations);
return null;
}
@@ -121,12 +123,12 @@ public class HeaderArg implements RestOpArg {
*/
private static Header getMergedHeader(ParameterInfo pi, String
paramName) {
// Get the declaring class
- ClassInfo declaringClass = pi.getMethod().getDeclaringClass();
+ var declaringClass = pi.getMethod().getDeclaringClass();
if (declaringClass == null)
return null;
// Find @Rest annotation on the class
- Rest restAnnotation =
declaringClass.getAnnotations(Rest.class).findFirst().map(AnnotationInfo::inner).orElse(null);
+ var restAnnotation =
declaringClass.getAnnotations(Rest.class).findFirst().map(AnnotationInfo::inner).orElse(null);
if (restAnnotation == null)
return null;
@@ -140,13 +142,11 @@ public class HeaderArg implements RestOpArg {
}
}
- if (classLevelHeader == null)
- return null;
+ if (classLevelHeader == null)
+ return null;
- // Get parameter-level @Header
- Header paramHeader = opt(pi.getAllAnnotation(Header.class)).map(x ->
x.inner()).orElse(null);
- if (paramHeader == null)
- paramHeader =
pi.getParameterType().getAnnotations(Header.class).findFirst().map(AnnotationInfo::inner).orElse(null);
+ // Get parameter-level @Header
+ var paramHeader =
AnnotationProvider.INSTANCE.find(Header.class, pi).findFirst().map(x ->
x.inner()).orElse(null);
if (paramHeader == null) {
// No parameter-level @Header, use class-level as-is
@@ -213,13 +213,13 @@ public class HeaderArg implements RestOpArg {
this.name = findName(pi).orElseThrow(() -> new ArgException(pi,
"@Header used without name or value"));
// Check for class-level defaults and merge if found
- Header mergedHeader = getMergedHeader(pi, name);
+ var mergedHeader = getMergedHeader(pi, name);
// Use merged header annotation for all lookups
this.def = nn(mergedHeader) && ! mergedHeader.def().isEmpty() ?
mergedHeader.def() : findDef(pi).orElse(null);
this.type = pi.getParameterType();
this.schema = nn(mergedHeader) ?
HttpPartSchema.create(mergedHeader) : HttpPartSchema.create(Header.class, pi);
- Class<? extends HttpPartParser> pp = schema.getParser();
+ var pp = schema.getParser();
this.partParser = nn(pp) ?
HttpPartParser.creator().type(pp).apply(annotations).create() : null;
this.multi = schema.getCollectionFormat() ==
HttpPartCollectionFormat.MULTI;
@@ -230,14 +230,14 @@ public class HeaderArg implements RestOpArg {
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override /* Overridden from RestOpArg */
public Object resolve(RestOpSession opSession) throws Exception {
- RestRequest req = opSession.getRequest();
- HttpPartParserSession ps = partParser == null ?
req.getPartParserSession() : partParser.getPartSession();
- RequestHeaders rh = req.getHeaders();
- BeanSession bs = req.getBeanSession();
- ClassMeta<?> cm = bs.getClassMeta(type.innerType());
+ var req = opSession.getRequest();
+ var ps = partParser == null ? req.getPartParserSession() :
partParser.getPartSession();
+ var rh = req.getHeaders();
+ var bs = req.getBeanSession();
+ var cm = bs.getClassMeta(type.innerType());
if (multi) {
- Collection c = cm.isArray() ? list() :
(Collection)(cm.canCreateNewInstance() ? cm.newInstance() : new JsonList());
+ var c = cm.isArray() ? list() :
(Collection)(cm.canCreateNewInstance() ? cm.newInstance() : new JsonList());
rh.stream(name).map(x ->
x.parser(ps).schema(schema).as(cm.getElementType()).orElse(null)).forEach(x ->
c.add(x));
return cm.isArray() ? toArray(c,
cm.getElementType().getInnerClass()) : c;
}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/MethodArg.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/MethodArg.java
index 5d4ee3a2ae..9d11298405 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/MethodArg.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/MethodArg.java
@@ -40,6 +40,8 @@ import org.apache.juneau.rest.annotation.*;
*/
public class MethodArg implements RestOpArg {
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
/**
* Static creator.
*
@@ -47,7 +49,7 @@ public class MethodArg implements RestOpArg {
* @return A new {@link MethodArg}, or <jk>null</jk> if the parameter
isn't annotated with {@link Method}.
*/
public static MethodArg create(ParameterInfo paramInfo) {
- if (paramInfo.hasAnnotation(Method.class))
+ if (AP.has(Method.class, paramInfo))
return new MethodArg();
return null;
}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathArg.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathArg.java
index fed7eab5f2..c002ee49a8 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathArg.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathArg.java
@@ -26,7 +26,6 @@ import java.lang.reflect.*;
import org.apache.juneau.*;
import org.apache.juneau.annotation.*;
import org.apache.juneau.collections.*;
-import org.apache.juneau.common.utils.*;
import org.apache.juneau.http.annotation.*;
import org.apache.juneau.httppart.*;
import org.apache.juneau.common.reflect.*;
@@ -56,6 +55,9 @@ import org.apache.juneau.rest.util.*;
* </ul>
*/
public class PathArg implements RestOpArg {
+
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
/**
* Static creator.
*
@@ -65,7 +67,7 @@ public class PathArg implements RestOpArg {
* @return A new {@link PathArg}, or <jk>null</jk> if the parameter is
not annotated with {@link Path}.
*/
public static PathArg create(ParameterInfo paramInfo,
AnnotationWorkList annotations, UrlPathMatcher pathMatcher) {
- if (paramInfo.hasAnnotation(Path.class) ||
paramInfo.getParameterType().hasAnnotation(Path.class))
+ if (AP.has(Path.class, paramInfo))
return new PathArg(paramInfo, annotations, pathMatcher);
return null;
}
@@ -79,12 +81,12 @@ public class PathArg implements RestOpArg {
*/
private static Path getMergedPath(ParameterInfo pi, String paramName) {
// Get the declaring class
- ClassInfo declaringClass = pi.getMethod().getDeclaringClass();
+ var declaringClass = pi.getMethod().getDeclaringClass();
if (declaringClass == null)
return null;
// Find @Rest annotation on the class
- Rest restAnnotation =
declaringClass.getAnnotations(Rest.class).findFirst().map(AnnotationInfo::inner).orElse(null);
+ var restAnnotation =
declaringClass.getAnnotations(Rest.class).findFirst().map(AnnotationInfo::inner).orElse(null);
if (restAnnotation == null)
return null;
@@ -98,13 +100,11 @@ public class PathArg implements RestOpArg {
}
}
- if (classLevelPath == null)
- return null;
+ if (classLevelPath == null)
+ return null;
- // Get parameter-level @Path
- Path paramPath = opt(pi.getAllAnnotation(Path.class)).map(x ->
x.inner()).orElse(null);
- if (paramPath == null)
- paramPath =
pi.getParameterType().getAnnotations(Path.class).findFirst().map(AnnotationInfo::inner).orElse(null);
+ // Get parameter-level @Path
+ var paramPath = AP.find(Path.class, pi).findFirst().map(x ->
x.inner()).orElse(null);
if (paramPath == null) {
// No parameter-level @Path, use class-level as-is
@@ -151,11 +151,8 @@ public class PathArg implements RestOpArg {
}
private final HttpPartParser partParser;
-
private final HttpPartSchema schema;
-
private final String name, def;
-
private final Type type;
/**
@@ -170,50 +167,52 @@ public class PathArg implements RestOpArg {
this.name = getName(paramInfo, pathMatcher);
// Check for class-level defaults and merge if found
- Path mergedPath = getMergedPath(paramInfo, name);
+ var mergedPath = getMergedPath(paramInfo, name);
// Use merged path annotation for all lookups
- String pathDef = nn(mergedPath) ? mergedPath.def() : null;
+ var pathDef = nn(mergedPath) ? mergedPath.def() : null;
this.def = nn(pathDef) && ne(NONE, pathDef) ? pathDef :
findDef(paramInfo).orElse(null);
this.type = paramInfo.getParameterType().innerType();
this.schema = nn(mergedPath) ?
HttpPartSchema.create(mergedPath) : HttpPartSchema.create(Path.class,
paramInfo);
- Class<? extends HttpPartParser> pp = schema.getParser();
+ var pp = schema.getParser();
this.partParser = nn(pp) ?
HttpPartParser.creator().type(pp).apply(annotations).create() : null;
}
@Override /* Overridden from RestOpArg */
public Object resolve(RestOpSession opSession) throws Exception {
- RestRequest req = opSession.getRequest();
+ var req = opSession.getRequest();
if (name.equals("*")) {
var m = new JsonMap();
req.getPathParams().stream().forEach(x ->
m.put(x.getName(), x.getValue()));
return req.getBeanSession().convertToType(m, type);
}
- HttpPartParserSession ps = partParser == null ?
req.getPartParserSession() : partParser.getPartSession();
+ var ps = partParser == null ? req.getPartParserSession() :
partParser.getPartSession();
return
req.getPathParams().get(name).parser(ps).schema(schema).def(def).as(type).orElse(null);
}
private static String getName(ParameterInfo pi, UrlPathMatcher
pathMatcher) {
- String p = findName(pi).orElse(null);
+ var p = findName(pi).orElse(null);
if (nn(p))
return p;
if (nn(pathMatcher)) {
- int idx = 0;
- int i = pi.getIndex();
- MethodInfo mi = pi.getMethod();
-
- for (int j = 0; j < i; j++)
- if (nn(mi.getParameter(j).getAllAnnotation(Path.class)))
- idx++;
+ int idx = 0;
+ int i = pi.getIndex();
+ var mi = pi.getMethod();
+
+ for (int j = 0; j < i; j++) {
+ var hasAnnotation =
AnnotationProvider.INSTANCE.find(Path.class,
mi.getParameter(j)).findAny().isPresent();
+ if (hasAnnotation)
+ idx++;
+ }
- String[] vars = pathMatcher.getVars();
+ var vars = pathMatcher.getVars();
if (vars.length <= idx)
throw new ArgException(pi, "Number of attribute
parameters exceeds the number of URL pattern variables. vars.length={0},
idx={1}", vars.length, idx);
// Check for {#} variables.
var idxs = String.valueOf(idx);
for (var var : vars)
- if (StringUtils.isNumeric(var) &&
var.equals(idxs))
+ if (isNumeric(var) && var.equals(idxs))
return var;
return pathMatcher.getVars()[idx];
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathRemainderArg.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathRemainderArg.java
index d79d204049..ea51522e53 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathRemainderArg.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathRemainderArg.java
@@ -59,6 +59,9 @@ import org.apache.juneau.rest.util.*;
* @since 9.2.0
*/
public class PathRemainderArg implements RestOpArg {
+
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
/**
* Static creator.
*
@@ -68,7 +71,7 @@ public class PathRemainderArg implements RestOpArg {
* @return A new {@link PathRemainderArg}, or <jk>null</jk> if the
parameter is not annotated with {@link PathRemainder}.
*/
public static PathRemainderArg create(ParameterInfo paramInfo,
AnnotationWorkList annotations, UrlPathMatcher pathMatcher) {
- if (paramInfo.hasAnnotation(PathRemainder.class) ||
paramInfo.getParameterType().hasAnnotation(PathRemainder.class))
+ if (AP.has(PathRemainder.class, paramInfo))
return new PathRemainderArg(paramInfo, annotations);
return null;
}
@@ -89,14 +92,14 @@ public class PathRemainderArg implements RestOpArg {
this.def = findDef(paramInfo).orElse(null);
this.type = paramInfo.getParameterType().innerType();
this.schema = HttpPartSchema.create(PathRemainder.class,
paramInfo);
- Class<? extends HttpPartParser> pp = schema.getParser();
+ var pp = schema.getParser();
this.partParser = nn(pp) ?
HttpPartParser.creator().type(pp).apply(annotations).create() : null;
}
@Override /* Overridden from RestOpArg */
public Object resolve(RestOpSession opSession) throws Exception {
- RestRequest req = opSession.getRequest();
- HttpPartParserSession ps = partParser == null ?
req.getPartParserSession() : partParser.getPartSession();
+ var req = opSession.getRequest();
+ var ps = partParser == null ? req.getPartParserSession() :
partParser.getPartSession();
// The path remainder is stored under the name "/*"
return
req.getPathParams().get("/*").parser(ps).schema(schema).def(def).as(type).orElse(null);
}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/QueryArg.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/QueryArg.java
index 2f76c8f1d8..d00a01fb08 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/QueryArg.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/QueryArg.java
@@ -57,6 +57,9 @@ import org.apache.juneau.rest.httppart.*;
* </ul>
*/
public class QueryArg implements RestOpArg {
+
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
/**
* Static creator.
*
@@ -65,7 +68,7 @@ public class QueryArg implements RestOpArg {
* @return A new {@link QueryArg}, or <jk>null</jk> if the parameter is
not annotated with {@link Query}.
*/
public static QueryArg create(ParameterInfo paramInfo,
AnnotationWorkList annotations) {
- if (paramInfo.hasAnnotation(Query.class) ||
paramInfo.getParameterType().hasAnnotation(Query.class))
+ if (AP.has(Query.class, paramInfo))
return new QueryArg(paramInfo, annotations);
return null;
}
@@ -79,12 +82,12 @@ public class QueryArg implements RestOpArg {
*/
private static Query getMergedQuery(ParameterInfo pi, String paramName)
{
// Get the declaring class
- ClassInfo declaringClass = pi.getMethod().getDeclaringClass();
+ var declaringClass = pi.getMethod().getDeclaringClass();
if (declaringClass == null)
return null;
// Find @Rest annotation on the class
- Rest restAnnotation =
declaringClass.getAnnotations(Rest.class).findFirst().map(AnnotationInfo::inner).orElse(null);
+ var restAnnotation =
declaringClass.getAnnotations(Rest.class).findFirst().map(AnnotationInfo::inner).orElse(null);
if (restAnnotation == null)
return null;
@@ -98,13 +101,11 @@ public class QueryArg implements RestOpArg {
}
}
- if (classLevelQuery == null)
- return null;
+ if (classLevelQuery == null)
+ return null;
- // Get parameter-level @Query
- Query paramQuery = opt(pi.getAllAnnotation(Query.class)).map(x ->
x.inner()).orElse(null);
- if (paramQuery == null)
- paramQuery =
pi.getParameterType().getAnnotations(Query.class).findFirst().map(AnnotationInfo::inner).orElse(null);
+ // Get parameter-level @Query
+ var paramQuery = AP.find(Query.class, pi).findFirst().map(x ->
x.inner()).orElse(null);
if (paramQuery == null) {
// No parameter-level @Query, use class-level as-is
@@ -151,13 +152,9 @@ public class QueryArg implements RestOpArg {
}
private final boolean multi;
-
private final HttpPartParser partParser;
-
private final HttpPartSchema schema;
-
private final String name, def;
-
private final ClassInfo type;
/**
@@ -171,13 +168,13 @@ public class QueryArg implements RestOpArg {
this.name = findName(pi).orElseThrow(() -> new ArgException(pi,
"@Query used without name or value"));
// Check for class-level defaults and merge if found
- Query mergedQuery = getMergedQuery(pi, name);
+ var mergedQuery = getMergedQuery(pi, name);
// Use merged query annotation for all lookups
this.def = nn(mergedQuery) && ! mergedQuery.def().isEmpty() ?
mergedQuery.def() : findDef(pi).orElse(null);
this.type = pi.getParameterType();
this.schema = nn(mergedQuery) ?
HttpPartSchema.create(mergedQuery) : HttpPartSchema.create(Query.class, pi);
- Class<? extends HttpPartParser> pp = schema.getParser();
+ var pp = schema.getParser();
this.partParser = nn(pp) ?
HttpPartParser.creator().type(pp).apply(annotations).create() : null;
this.multi = schema.getCollectionFormat() ==
HttpPartCollectionFormat.MULTI;
@@ -188,14 +185,14 @@ public class QueryArg implements RestOpArg {
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override /* Overridden from RestOpArg */
public Object resolve(RestOpSession opSession) throws Exception {
- RestRequest req = opSession.getRequest();
- HttpPartParserSession ps = partParser == null ?
req.getPartParserSession() : partParser.getPartSession();
- RequestQueryParams rh = req.getQueryParams();
- BeanSession bs = req.getBeanSession();
- ClassMeta<?> cm = bs.getClassMeta(type.innerType());
+ var req = opSession.getRequest();
+ var ps = partParser == null ? req.getPartParserSession() :
partParser.getPartSession();
+ var rh = req.getQueryParams();
+ var bs = req.getBeanSession();
+ var cm = bs.getClassMeta(type.innerType());
if (multi) {
- Collection c = cm.isArray() ? list() :
(Collection)(cm.canCreateNewInstance() ? cm.newInstance() : new JsonList());
+ var c = cm.isArray() ? list() :
(Collection)(cm.canCreateNewInstance() ? cm.newInstance() : new JsonList());
rh.getAll(name).stream().map(x ->
x.parser(ps).schema(schema).as(cm.getElementType()).orElse(null)).forEach(x ->
c.add(x));
return cm.isArray() ? toArray(c,
cm.getElementType().getInnerClass()) : c;
}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/RequestBeanArg.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/RequestBeanArg.java
index b39ac1c4fe..b14966f58c 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/RequestBeanArg.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/RequestBeanArg.java
@@ -42,6 +42,9 @@ import org.apache.juneau.rest.annotation.*;
* </ul>
*/
public class RequestBeanArg implements RestOpArg {
+
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
/**
* Static creator.
*
@@ -50,7 +53,7 @@ public class RequestBeanArg implements RestOpArg {
* @return A new {@link RequestBeanArg}, or <jk>null</jk> if the
parameter is not annotated with {@link Request}.
*/
public static RequestBeanArg create(ParameterInfo paramInfo,
AnnotationWorkList annotations) {
- if (paramInfo.hasAnnotation(Request.class))
+ if (AP.has(Request.class, paramInfo))
return new RequestBeanArg(paramInfo, annotations);
return null;
}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/ResponseBeanArg.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/ResponseBeanArg.java
index 855eed42d9..d50e8b51ee 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/ResponseBeanArg.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/ResponseBeanArg.java
@@ -42,6 +42,9 @@ import org.apache.juneau.rest.annotation.*;
* </ul>
*/
public class ResponseBeanArg implements RestOpArg {
+
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
/**
* Static creator.
*
@@ -50,7 +53,7 @@ public class ResponseBeanArg implements RestOpArg {
* @return A new {@link ResponseBeanArg}, or <jk>null</jk> if the
parameter is not annotated with {@link Response}.
*/
public static ResponseBeanArg create(ParameterInfo paramInfo,
AnnotationWorkList annotations) {
- if (paramInfo.hasAnnotation(Response.class) ||
paramInfo.getParameterType().hasAnnotation(Response.class))
+ if (AP.has(Response.class, paramInfo))
return new ResponseBeanArg(paramInfo, annotations);
return null;
}
@@ -68,7 +71,7 @@ public class ResponseBeanArg implements RestOpArg {
protected ResponseBeanArg(ParameterInfo paramInfo, AnnotationWorkList
annotations) {
this.type = paramInfo.getParameterType().innerType();
this.meta = ResponseBeanMeta.create(paramInfo, annotations);
- Class<?> c = type instanceof Class ? (Class<?>)type : type
instanceof ParameterizedType ? (Class<?>)((ParameterizedType)type).getRawType()
: null;
+ var c = type instanceof Class ? (Class<?>)type : type
instanceof ParameterizedType ? (Class<?>)((ParameterizedType)type).getRawType()
: null;
if (c != Value.class)
throw new ArgException(paramInfo, "Type must be
Value<?> on parameter annotated with @Response annotation");
}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/ResponseCodeArg.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/ResponseCodeArg.java
index 4b75077be1..0f7c4b90f1 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/ResponseCodeArg.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/ResponseCodeArg.java
@@ -35,6 +35,8 @@ import org.apache.juneau.rest.annotation.*;
*/
public class ResponseCodeArg implements RestOpArg {
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
/**
* Static creator.
*
@@ -42,7 +44,7 @@ public class ResponseCodeArg implements RestOpArg {
* @return A new {@link ResponseCodeArg}, or <jk>null</jk> if the
parameter is not annotated with {@link StatusCode}.
*/
public static ResponseCodeArg create(ParameterInfo paramInfo) {
- if (paramInfo.hasAnnotation(StatusCode.class) ||
paramInfo.getParameterType().hasAnnotation(StatusCode.class))
+ if (AP.has(StatusCode.class, paramInfo))
return new ResponseCodeArg(paramInfo);
return null;
}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/ResponseHeaderArg.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/ResponseHeaderArg.java
index 95a495b835..6003a9cf97 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/ResponseHeaderArg.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/ResponseHeaderArg.java
@@ -48,6 +48,9 @@ import org.apache.juneau.rest.httppart.*;
* </ul>
*/
public class ResponseHeaderArg implements RestOpArg {
+
+ private static AnnotationProvider AP = AnnotationProvider.INSTANCE;
+
/**
* Static creator.
*
@@ -56,7 +59,7 @@ public class ResponseHeaderArg implements RestOpArg {
* @return A new {@link ResponseHeaderArg}, or <jk>null</jk> if the
parameter is not annotated with {@link Header}.
*/
public static ResponseHeaderArg create(ParameterInfo paramInfo,
AnnotationWorkList annotations) {
- if (paramInfo.getParameterType().is(Value.class) &&
(paramInfo.hasAnnotation(Header.class) ||
paramInfo.getParameterType().hasAnnotation(Header.class)))
+ if (paramInfo.getParameterType().is(Value.class) &&
AP.has(Header.class, paramInfo))
return new ResponseHeaderArg(paramInfo, annotations);
return null;
}
@@ -77,10 +80,10 @@ public class ResponseHeaderArg implements RestOpArg {
this.type = pi.getParameterType().innerType();
var schema = HttpPartSchema.create(Header.class, pi);
- Class<? extends HttpPartSerializer> ps = schema.getSerializer();
+ var ps = schema.getSerializer();
this.meta = new ResponsePartMeta(HttpPartType.HEADER, schema,
nn(ps) ? HttpPartSerializer.creator().type(ps).apply(annotations).create() :
null);
- Class<?> c = type instanceof Class ? (Class<?>)type : type
instanceof ParameterizedType ? (Class<?>)((ParameterizedType)type).getRawType()
: null;
+ var c = type instanceof Class ? (Class<?>)type : type
instanceof ParameterizedType ? (Class<?>)((ParameterizedType)type).getRawType()
: null;
if (c != Value.class)
throw new ArgException(pi, "Type must be Value<?> on
parameter annotated with @Header annotation");
}
@@ -90,12 +93,12 @@ public class ResponseHeaderArg implements RestOpArg {
public Object resolve(final RestOpSession opSession) throws Exception {
Value<Object> v = new Value();
v.listener(o -> {
- RestRequest req = opSession.getRequest();
- RestResponse res = opSession.getResponse();
- ResponsePartMeta rpm =
req.getOpContext().getResponseHeaderMeta(o);
+ var req = opSession.getRequest();
+ var res = opSession.getResponse();
+ var rpm = req.getOpContext().getResponseHeaderMeta(o);
if (rpm == null)
rpm = ResponseHeaderArg.this.meta;
- HttpPartSerializerSession pss = rpm.getSerializer() ==
null ? req.getPartSerializerSession() : rpm.getSerializer().getPartSession();
+ var pss = rpm.getSerializer() == null ?
req.getPartSerializerSession() : rpm.getSerializer().getPartSession();
res.setHeader(new SerializedHeader(name, o, pss,
rpm.getSchema(), false));
});
return v;
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 542af9b730..c49862aa88 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
@@ -146,6 +146,8 @@ public class BasicSwaggerProviderSession {
InputStream is = ff.getStream(rci.getNameSimple() + ".json",
locale).orElse(null);
+ var ap = this.context.getBeanContext().getAnnotationProvider();
+
Predicate<String> ne = Utils::isNotEmpty;
Predicate<Collection<?>> nec = Utils::isNotEmpty;
Predicate<Map<?,?>> nem = Utils::isNotEmpty;
@@ -159,7 +161,7 @@ public class BasicSwaggerProviderSession {
List<Rest> restAnnotations = list();
context.getAnnotationProvider().forEachClassAnnotation(Rest.class, rci, x ->
true, x -> restAnnotations.add(x));
for (var rr : restAnnotations) {
-
+
JsonMap sInfo = omSwagger.getMap("info", true);
sInfo
@@ -382,45 +384,45 @@ public class BasicSwaggerProviderSession {
ClassInfo pt = mpi.getParameterType();
Type type = pt.innerType();
- if (mpi.hasAnnotation(Content.class) ||
pt.hasAnnotation(Content.class)) {
+ if (ap.has(Content.class, mpi)) {
JsonMap param = paramMap.getMap(BODY +
".body", true).append("in", BODY);
JsonMap schema =
getSchema(param.getMap("schema"), type, bs);
-
rstream(mpi.getAllAnnotations(Schema.class)).map(AnnotationInfo::inner).forEach(x
-> merge(schema, x));
-
rstream(mpi.getAllAnnotations(Content.class)).map(AnnotationInfo::inner).forEach(x
-> merge(schema, x.schema()));
+ ap.findTopDown(Schema.class,
mpi).map(AnnotationInfo::inner).forEach(x -> merge(schema, x));
+ ap.findTopDown(Content.class,
mpi).map(AnnotationInfo::inner).forEach(x -> merge(schema, x.schema()));
pushupSchemaFields(BODY, param, schema);
param.appendIf(nem, "schema", schema);
param.putIfAbsent("required", true);
addBodyExamples(sm, param, false, type,
locale);
- } else if (mpi.hasAnnotation(Query.class) ||
pt.hasAnnotation(Query.class)) {
+ } else if (ap.has(Query.class, mpi)) {
String name =
QueryAnnotation.findName(mpi).orElse(null);
JsonMap param = paramMap.getMap(QUERY +
"." + name, true).append("name", name).append("in", QUERY);
-
rstream(mpi.getAllAnnotations(Schema.class)).map(AnnotationInfo::inner).forEach(x
-> merge(param, x));
-
rstream(mpi.getAllAnnotations(Query.class)).map(AnnotationInfo::inner).forEach(x
-> merge(param, x.schema()));
+ ap.findTopDown(Schema.class,
mpi).map(AnnotationInfo::inner).forEach(x -> merge(param, x));
+ ap.findTopDown(Query.class,
mpi).map(AnnotationInfo::inner).forEach(x -> merge(param, x.schema()));
pushupSchemaFields(QUERY, param,
getSchema(param.getMap("schema"), type, bs));
addParamExample(sm, param, QUERY, type);
- } else if (mpi.hasAnnotation(FormData.class) ||
pt.hasAnnotation(FormData.class)) {
+ } else if (ap.has(FormData.class, mpi)) {
String name =
FormDataAnnotation.findName(mpi).orElse(null);
JsonMap param =
paramMap.getMap(FORM_DATA + "." + name, true).append("name", name).append("in",
FORM_DATA);
-
rstream(mpi.getAllAnnotations(Schema.class)).map(AnnotationInfo::inner).forEach(x
-> merge(param, x));
-
rstream(mpi.getAllAnnotations(FormData.class)).map(AnnotationInfo::inner).forEach(x
-> merge(param, x.schema()));
+ ap.findTopDown(Schema.class,
mpi).map(AnnotationInfo::inner).forEach(x -> merge(param, x));
+ ap.findTopDown(FormData.class,
mpi).map(AnnotationInfo::inner).forEach(x -> merge(param, x.schema()));
pushupSchemaFields(FORM_DATA, param,
getSchema(param.getMap("schema"), type, bs));
addParamExample(sm, param, FORM_DATA,
type);
- } else if (mpi.hasAnnotation(Header.class) ||
pt.hasAnnotation(Header.class)) {
+ } else if (ap.has(Header.class, mpi)) {
String name =
HeaderAnnotation.findName(mpi).orElse(null);
JsonMap param = paramMap.getMap(HEADER
+ "." + name, true).append("name", name).append("in", HEADER);
-
rstream(mpi.getAllAnnotations(Schema.class)).map(AnnotationInfo::inner).forEach(x
-> merge(param, x));
-
rstream(mpi.getAllAnnotations(Header.class)).map(AnnotationInfo::inner).forEach(x
-> merge(param, x.schema()));
+ ap.findTopDown(Schema.class,
mpi).map(AnnotationInfo::inner).forEach(x -> merge(param, x));
+ ap.findTopDown(Header.class,
mpi).map(AnnotationInfo::inner).forEach(x -> merge(param, x.schema()));
pushupSchemaFields(HEADER, param,
getSchema(param.getMap("schema"), type, bs));
addParamExample(sm, param, HEADER,
type);
- } else if (mpi.hasAnnotation(Path.class) ||
pt.hasAnnotation(Path.class)) {
+ } else if (ap.has(Path.class, mpi)) {
String name =
PathAnnotation.findName(mpi).orElse(null);
JsonMap param = paramMap.getMap(PATH +
"." + name, true).append("name", name).append("in", PATH);
-
rstream(mpi.getAllAnnotations(Schema.class)).map(AnnotationInfo::inner).forEach(x
-> merge(param, x));
-
rstream(mpi.getAllAnnotations(Path.class)).map(AnnotationInfo::inner).forEach(x
-> merge(param, x.schema()));
+ ap.findTopDown(Schema.class,
mpi).map(AnnotationInfo::inner).forEach(x -> merge(param, x));
+ ap.findTopDown(Path.class,
mpi).map(AnnotationInfo::inner).forEach(x -> merge(param, x.schema()));
pushupSchemaFields(PATH, param,
getSchema(param.getMap("schema"), type, bs));
addParamExample(sm, param, PATH, type);
param.putIfAbsent("required", true);
@@ -519,13 +521,11 @@ public class BasicSwaggerProviderSession {
ClassInfo pt = mpi.getParameterType();
- if (pt.is(Value.class) &&
(mpi.hasAnnotation(Header.class) || pt.hasAnnotation(Header.class))) {
+ if (pt.is(Value.class) && (ap.has(Header.class,
mpi))) {
List<Header> la = list();
-
rstream(mpi.getAllAnnotations(Header.class)).map(AnnotationInfo::inner).forEach(x
-> la.add(x));
- rstream(pt.getAnnotations()).map(x ->
x.cast(Header.class)).filter(Objects::nonNull).map(AnnotationInfo::inner).forEach(x
-> la.add(x));
+ ap.findTopDown(Header.class,
mpi).map(AnnotationInfo::inner).forEach(x -> la.add(x));
List<StatusCode> la2 = list();
-
rstream(mpi.getAllAnnotations(StatusCode.class)).map(AnnotationInfo::inner).forEach(x
-> la2.add(x));
- rstream(pt.getAnnotations()).map(x ->
x.cast(StatusCode.class)).filter(Objects::nonNull).map(AnnotationInfo::inner).forEach(x
-> la2.add(x));
+ ap.findTopDown(StatusCode.class,
mpi).map(AnnotationInfo::inner).forEach(x -> la2.add(x));
Set<Integer> codes = getCodes(la2, 200);
String name =
HeaderAnnotation.findName(mpi).orElse(null);
Type type =
Value.unwrap(mpi.getParameterType().innerType());
@@ -533,20 +533,18 @@ public class BasicSwaggerProviderSession {
if (! isMulti(a)) {
for (var code : codes) {
JsonMap header
= responses.getMap(String.valueOf(code), true).getMap("headers",
true).getMap(name, true);
-
rstream(mpi.getAllAnnotations(Schema.class)).map(AnnotationInfo::inner).forEach(x
-> merge(header, x));
+
ap.findTopDown(Schema.class, mpi).map(AnnotationInfo::inner).forEach(x ->
merge(header, x));
merge(header,
a.schema());
pushupSchemaFields(RESPONSE_HEADER, header, getSchema(header, type, bs));
}
}
}
-
- } else if (mpi.hasAnnotation(Response.class) ||
pt.hasAnnotation(Response.class)) {
+
+ } else if (ap.has(Response.class, mpi)) {
List<Response> la = list();
-
rstream(mpi.getAllAnnotations(Response.class)).map(AnnotationInfo::inner).forEach(x
-> la.add(x));
- rstream(pt.getAnnotations()).map(x ->
x.cast(Response.class)).filter(Objects::nonNull).map(AnnotationInfo::inner).forEach(x
-> la.add(x));
+ ap.findTopDown(Response.class,
mpi).map(AnnotationInfo::inner).forEach(x -> la.add(x));
List<StatusCode> la2 = list();
-
rstream(mpi.getAllAnnotations(StatusCode.class)).map(AnnotationInfo::inner).forEach(x
-> la2.add(x));
- rstream(pt.getAnnotations()).map(x ->
x.cast(StatusCode.class)).filter(Objects::nonNull).map(AnnotationInfo::inner).forEach(x
-> la2.add(x));
+ ap.findTopDown(StatusCode.class,
mpi).map(AnnotationInfo::inner).forEach(x -> la2.add(x));
Set<Integer> codes = getCodes(la2, 200);
Type type =
Value.unwrap(mpi.getParameterType().innerType());
for (var a : la) {
@@ -554,7 +552,7 @@ public class BasicSwaggerProviderSession {
JsonMap om =
responses.getMap(String.valueOf(code), true);
merge(om, a);
JsonMap schema =
getSchema(om.getMap("schema"), type, bs);
-
rstream(mpi.getAllAnnotations(Schema.class)).map(AnnotationInfo::inner).forEach(x
-> merge(schema, x));
+
ap.findTopDown(Schema.class, mpi).map(AnnotationInfo::inner).forEach(x ->
merge(schema, x));
la.forEach(x ->
merge(schema, x.schema()));
pushupSchemaFields(RESPONSE, om, schema);
om.appendIf(nem,
"schema", schema);
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/common/reflect/FieldInfo_AnnotationInfos_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/FieldInfo_AnnotationInfos_Test.java
index 7dfec97350..3a47c4d5ec 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/common/reflect/FieldInfo_AnnotationInfos_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/FieldInfo_AnnotationInfos_Test.java
@@ -19,7 +19,7 @@ import java.lang.annotation.*;
import org.junit.jupiter.api.*;
/**
- * Tests for {@link FieldInfo#getDeclaredAnnotations()} methods.
+ * Tests for {@link FieldInfo#getAnnotations()} methods.
*/
public class FieldInfo_AnnotationInfos_Test {
@@ -60,18 +60,18 @@ public class FieldInfo_AnnotationInfos_Test {
var field3 = ci.getPublicField(x ->
x.getName().equals("field3")).get();
// field1 has 2 annotations
- var annotations1 = field1.getDeclaredAnnotations();
+ var annotations1 = field1.getAnnotations();
assertEquals(2, annotations1.size());
assertTrue(annotations1.stream().anyMatch(a ->
a.hasSimpleName("TestAnnotation1")));
assertTrue(annotations1.stream().anyMatch(a ->
a.hasSimpleName("TestAnnotation2")));
// field2 has 1 annotation
- var annotations2 = field2.getDeclaredAnnotations();
+ var annotations2 = field2.getAnnotations();
assertEquals(1, annotations2.size());
assertTrue(annotations2.stream().anyMatch(a ->
a.hasSimpleName("TestAnnotation1")));
// field3 has no annotations
- var annotations3 = field3.getDeclaredAnnotations();
+ var annotations3 = field3.getAnnotations();
assertEquals(0, annotations3.size());
}
@@ -82,24 +82,24 @@ public class FieldInfo_AnnotationInfos_Test {
var field2 = ci.getPublicField(x ->
x.getName().equals("field2")).get();
// Test filtering by type for field1
- var ann1_type1 =
field1.getDeclaredAnnotations(TestAnnotation1.class).toList();
+ var ann1_type1 =
field1.getAnnotations(TestAnnotation1.class).toList();
assertEquals(1, ann1_type1.size());
assertEquals("test1", ann1_type1.get(0).getValue().get());
- var ann1_type2 =
field1.getDeclaredAnnotations(TestAnnotation2.class).toList();
+ var ann1_type2 =
field1.getAnnotations(TestAnnotation2.class).toList();
assertEquals(1, ann1_type2.size());
assertEquals(42, ann1_type2.get(0).getInt("value").get());
// Test filtering by type that doesn't exist
- var ann1_type3 =
field1.getDeclaredAnnotations(TestAnnotation3.class).toList();
+ var ann1_type3 =
field1.getAnnotations(TestAnnotation3.class).toList();
assertEquals(0, ann1_type3.size());
// Test filtering for field2
- var ann2_type1 =
field2.getDeclaredAnnotations(TestAnnotation1.class).toList();
+ var ann2_type1 =
field2.getAnnotations(TestAnnotation1.class).toList();
assertEquals(1, ann2_type1.size());
assertEquals("test2", ann2_type1.get(0).getValue().get());
- var ann2_type2 =
field2.getDeclaredAnnotations(TestAnnotation2.class).toList();
+ var ann2_type2 =
field2.getAnnotations(TestAnnotation2.class).toList();
assertEquals(0, ann2_type2.size());
}
@@ -109,8 +109,8 @@ public class FieldInfo_AnnotationInfos_Test {
var field1 = ci.getPublicField(x ->
x.getName().equals("field1")).get();
// Calling getDeclaredAnnotationInfos() multiple times should
return the same list instance
- var annotations1 = field1.getDeclaredAnnotations();
- var annotations2 = field1.getDeclaredAnnotations();
+ var annotations1 = field1.getAnnotations();
+ var annotations2 = field1.getAnnotations();
assertSame(annotations1, annotations2);
}
}
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/common/reflect/ParamInfoTest.java
b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/ParamInfoTest.java
index c90fbbebf5..3d505e776c 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/common/reflect/ParamInfoTest.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/ParamInfoTest.java
@@ -43,7 +43,7 @@ class ParamInfoTest extends TestBase {
public static void beforeAll() {
// Save original system property value
originalDisableParamNameDetection =
System.getProperty("juneau.disableParamNameDetection");
-
+
// Set to true to ensure consistent behavior regardless of JVM
compiler settings
System.setProperty("juneau.disableParamNameDetection", "true");
ParameterInfo.reset();
@@ -212,96 +212,25 @@ class ParamInfoTest extends TestBase {
return pi.getAnnotations(type).map(x -> x.inner()).toList();
}
- @Test void getDeclaredAnnotation() {
- check("@CA(5)", cb_a1.getDeclaredAnnotation(CA.class));
- check("@CA(5)", cb_a2.getDeclaredAnnotation(CA.class));
- check(null, cc_a1.getDeclaredAnnotation(CA.class));
- check("@CA(6)", cc_a2.getDeclaredAnnotation(CA.class));
- }
-
- @Test void getDeclaredAnnotation_constructor() {
- check("@CA(9)", cc_cc.getDeclaredAnnotation(CA.class));
- }
-
- @Test void getDeclaredAnnotation_notFound() {
- check(null, cb_a1.getDeclaredAnnotation(DA.class));
- }
-
- @Test void getDeclaredAnnotation_notFound_constructor() {
- check(null, cc_cc.getDeclaredAnnotation(DA.class));
- }
-
- @Test void getDeclaredAnnotation_null() {
- check(null, cb_a1.getDeclaredAnnotation(null));
- }
-
- @Test void getDeclaredAnnotation_null_constructor() {
- check(null, cc_cc.getDeclaredAnnotation(null));
- }
-
- @Test void getAnnotationsParentFirst() {
- check("@CA(4),@CA(3),@CA(2),@CA(1),@CA(5)", annotations(cb_a1,
CA.class));
- check("@CA(4),@CA(3),@CA(2),@CA(1),@CA(5)", annotations(cb_a2,
CA.class));
- check("@CA(4),@CA(3),@CA(2),@CA(1),@CA(5)", annotations(cc_a1,
CA.class));
- check("@CA(4),@CA(3),@CA(2),@CA(1),@CA(5),@CA(6)",
annotations(cc_a2, CA.class));
- }
-
- @Test void getAnnotationsParentFirst_notFound() {
- check("", annotations(cb_a1, DA.class));
- }
-
- @Test void getAnnotationsParentFirst_constructor() {
- check("@CA(4),@CA(3),@CA(2),@CA(1),@CA(9)", annotations(cc_cc,
CA.class));
- }
-
- @Test void getAnnotationsParentFirst_notFound_constructor() {
- check("", annotations(cc_cc, DA.class));
- }
-
- @Test void getAllAnnotationInfo() {
- check("@CA(5)", cb_a1.getAllAnnotation(CA.class).inner());
- check("@CA(5)", cb_a2.getAllAnnotation(CA.class).inner());
- check("@CA(5)", cc_a1.getAllAnnotation(CA.class).inner());
- check("@CA(6)", cc_a2.getAllAnnotation(CA.class).inner());
- }
-
- @Test void getAllAnnotationInfo_notFound() {
- var ai = cb_a1.getAllAnnotation(DA.class);
- check(null, ai == null ? null : ai.inner());
- }
-
- @Test void getAllAnnotationInfo_constructor() {
- check("@CA(9)", cc_cc.getAllAnnotation(CA.class).inner());
- }
-
- @Test void getAllAnnotationInfo_notFound_constructor() {
- var ai = cc_cc.getAllAnnotation(DA.class);
- check(null, ai == null ? null : ai.inner());
- }
-
- @Test void getAllAnnotationInfo_twice() {
- check("@CA(5)", cb_a1.getAllAnnotation(CA.class).inner());
- check("@CA(5)", cb_a1.getAllAnnotation(CA.class).inner());
- }
-
- @Test void getAllAnnotationInfo_twice_constructor() {
- check("@CA(9)", cc_cc.getAllAnnotation(CA.class).inner());
- check("@CA(9)", cc_cc.getAllAnnotation(CA.class).inner());
- }
-
- @Test void hasAnnotation() {
- assertTrue(cb_a1.hasAnnotation(CA.class));
- assertTrue(cb_a2.hasAnnotation(CA.class));
- assertTrue(cc_a1.hasAnnotation(CA.class));
- assertTrue(cc_a2.hasAnnotation(CA.class));
- assertFalse(cb_a1.hasAnnotation(DA.class));
- }
-
- @Test void hasAnnotation_constructor() {
- assertTrue(cc_cc.hasAnnotation(CA.class));
- assertFalse(cc_cc.hasAnnotation(DA.class));
- }
-
+// @Test void getAnnotationsParentFirst() {
+// check("@CA(4),@CA(3),@CA(2),@CA(1),@CA(5)", annotations(cb_a1,
CA.class));
+// check("@CA(4),@CA(3),@CA(2),@CA(1),@CA(5)", annotations(cb_a2,
CA.class));
+// check("@CA(4),@CA(3),@CA(2),@CA(1),@CA(5)", annotations(cc_a1,
CA.class));
+// check("@CA(4),@CA(3),@CA(2),@CA(1),@CA(5),@CA(6)",
annotations(cc_a2, CA.class));
+// }
+//
+// @Test void getAnnotationsParentFirst_notFound() {
+// check("", annotations(cb_a1, DA.class));
+// }
+//
+// @Test void getAnnotationsParentFirst_constructor() {
+// check("@CA(4),@CA(3),@CA(2),@CA(1),@CA(9)", annotations(cc_cc,
CA.class));
+// }
+//
+// @Test void getAnnotationsParentFirst_notFound_constructor() {
+// check("", annotations(cc_cc, DA.class));
+// }
+//
@Target({PARAMETER,TYPE})
@Retention(RUNTIME)
@Inherited
@@ -328,24 +257,14 @@ class ParamInfoTest extends TestBase {
db_a1 = db.getMethod(x ->
x.hasName("a1")).get().getParameter(0), // NOSONAR
dc_a1 = dc.getMethod(x ->
x.hasName("a1")).get().getParameter(0); // NOSONAR
- @Test void getAnnotationsParentFirst_inherited() {
- check("@DA(4),@DA(3),@DA(2),@DA(1),@DA(0)", annotations(db_a1,
DA.class));
- check("@DA(4),@DA(3),@DA(2),@DA(1),@DA(0),@DA(5)",
annotations(dc_a1, DA.class));
- }
-
- @Test void getAnnotationsParentFirst_inherited_notFound() {
- check("", annotations(db_a1, CA.class));
- }
-
- @Test void getAllAnnotationInfo_inherited() {
- check("@DA(0)", db_a1.getAllAnnotation(DA.class).inner());
- check("@DA(5)", dc_a1.getAllAnnotation(DA.class).inner());
- }
-
- @Test void getAllAnnotationInfo_inherited_notFound() {
- var ai = db_a1.getAllAnnotation(CA.class);
- check(null, ai == null ? null : ai.inner());
- }
+// @Test void getAnnotationsParentFirst_inherited() {
+// check("@DA(4),@DA(3),@DA(2),@DA(1),@DA(0)", annotations(db_a1,
DA.class));
+// check("@DA(4),@DA(3),@DA(2),@DA(1),@DA(0),@DA(5)",
annotations(dc_a1, DA.class));
+// }
+//
+// @Test void getAnnotationsParentFirst_inherited_notFound() {
+// check("", annotations(db_a1, CA.class));
+// }
//-----------------------------------------------------------------------------------------------------------------
// Other methods.
@@ -649,176 +568,4 @@ class ParamInfoTest extends TestBase {
assertEquals("param1", matching.get(1).getName());
}
}
-
-
//-----------------------------------------------------------------------------------------------------------------
- // getAllAnnotations() / getAllAnnotation()
-
//-----------------------------------------------------------------------------------------------------------------
-
- @Nested
- class FindAnnotationsTests {
-
- // Annotations for testing
- @Documented
- @Target({PARAMETER, TYPE})
- @Retention(RUNTIME)
- public @interface FA1 {
- int value();
- }
-
- @Documented
- @Target({PARAMETER, TYPE})
- @Retention(RUNTIME)
- public @interface FA2 {
- String value();
- }
-
- // Test finding annotation on parameter itself
- public static class F1 {
- public void test(@FA1(1) String x) {} // NOSONAR
- }
-
- @Test void findOnParameter() throws Exception {
- var mi = MethodInfo.of(F1.class.getMethod("test",
String.class));
- var pi = mi.getParameter(0);
- var infos = pi.getAllAnnotations(FA1.class);
- assertEquals(1, infos.size());
- assertEquals(1, infos.get(0).inner().value());
- }
-
- @Test void findOnParameter_single() throws Exception {
- var mi = MethodInfo.of(F1.class.getMethod("test",
String.class));
- var pi = mi.getParameter(0);
- var info = pi.getAllAnnotation(FA1.class);
- assertNotNull(info);
- assertEquals(1, info.inner().value());
- }
-
- // Test finding annotation from matching method parameters
- public interface F2 {
- void test(@FA1(2) String x);
- }
-
- public static class F3 implements F2 {
- @Override public void test(String x) {} // NOSONAR
- }
-
- @Test void findFromMatchingMethod() throws Exception {
- var mi = MethodInfo.of(F3.class.getMethod("test",
String.class));
- var pi = mi.getParameter(0);
- var infos = pi.getAllAnnotations(FA1.class);
- assertEquals(1, infos.size());
- assertEquals(2, infos.get(0).inner().value());
- }
-
- // Test finding annotation from parameter type
- @FA1(3)
- public static class F4Type {}
-
- public static class F5 {
- public void test(F4Type x) {} // NOSONAR
- }
-
- @Test void findFromParameterType() throws Exception {
- var mi = MethodInfo.of(F5.class.getMethod("test",
F4Type.class));
- var pi = mi.getParameter(0);
- var infos = pi.getAllAnnotations(FA1.class);
- assertEquals(1, infos.size());
- assertEquals(3, infos.get(0).inner().value());
- }
-
- // Test finding multiple annotations from hierarchy
- public interface F6 {
- void test(@FA1(4) String x);
- }
-
- public static class F7 {
- public void test(@FA1(5) String x) {} // NOSONAR
- }
-
- public static class F8 extends F7 implements F6 {
- @Override public void test(@FA1(6) String x) {} //
NOSONAR
- }
-
- @Test void findMultipleFromHierarchy() throws Exception {
- var mi = MethodInfo.of(F8.class.getMethod("test",
String.class));
- var pi = mi.getParameter(0);
- var infos = pi.getAllAnnotations(FA1.class);
- assertEquals(3, infos.size());
- assertEquals(6, infos.get(0).inner().value()); // F8
- assertEquals(4, infos.get(1).inner().value()); // F6
- assertEquals(5, infos.get(2).inner().value()); // F7
- }
-
- @Test void findMultipleFromHierarchy_single() throws Exception {
- var mi = MethodInfo.of(F8.class.getMethod("test",
String.class));
- var pi = mi.getParameter(0);
- var info = pi.getAllAnnotation(FA1.class);
- assertNotNull(info);
- assertEquals(6, info.inner().value()); // Returns first
(F8)
- }
-
- // Test finding annotation from constructor parameters
- public static class F9 {
- public F9(@FA1(7) String x) {} // NOSONAR
- }
-
- public static class F10 extends F9 {
- public F10(@FA1(8) String x) { super(x); } // NOSONAR
- }
-
- @Test void findFromMatchingConstructor() throws Exception {
- var ci =
ConstructorInfo.of(F10.class.getConstructor(String.class));
- var pi = ci.getParameter(0);
- var infos = pi.getAllAnnotations(FA1.class);
- assertEquals(2, infos.size());
- assertEquals(8, infos.get(0).inner().value()); // F10
- assertEquals(7, infos.get(1).inner().value()); // F9
- }
-
- // Test not found
- public static class F11 {
- public void test(String x) {} // NOSONAR
- }
-
- @Test void notFound() throws Exception {
- var mi = MethodInfo.of(F11.class.getMethod("test",
String.class));
- var pi = mi.getParameter(0);
- var infos = pi.getAllAnnotations(FA1.class);
- assertEquals(0, infos.size());
- }
-
- @Test void notFound_single() throws Exception {
- var mi = MethodInfo.of(F11.class.getMethod("test",
String.class));
- var pi = mi.getParameter(0);
- var info = pi.getAllAnnotation(FA1.class);
- assertNull(info);
- }
-
- // Test parameter annotation takes precedence over type
annotation
- @FA1(9)
- public static class F12Type {}
-
- public static class F13 {
- public void test(@FA1(10) F12Type x) {} // NOSONAR
- }
-
- @Test void parameterAnnotationBeforeTypeAnnotation() throws
Exception {
- var mi = MethodInfo.of(F13.class.getMethod("test",
F12Type.class));
- var pi = mi.getParameter(0);
- var infos = pi.getAllAnnotations(FA1.class);
- assertEquals(2, infos.size());
- assertEquals(10, infos.get(0).inner().value()); //
Parameter annotation first
- assertEquals(9, infos.get(1).inner().value()); // Type
annotation second
- }
- }
-
-
//-----------------------------------------------------------------------------------------------------------------
- // Helpers
-
//-----------------------------------------------------------------------------------------------------------------
-
- private static <T extends Annotation> List<T> annotations(ParameterInfo
pi, Class<T> a) {
- List<T> l = list();
-
rstream(pi.getAllAnnotations(a)).map(AnnotationInfo::inner).forEach(l::add);
- return l;
- }
}
\ No newline at end of file
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/reflect/ParamInfoTest.java
b/juneau-utest/src/test/java/org/apache/juneau/reflect/ParamInfoTest.java
deleted file mode 100644
index eb3cd7420c..0000000000
--- a/juneau-utest/src/test/java/org/apache/juneau/reflect/ParamInfoTest.java
+++ /dev/null
@@ -1,364 +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.reflect;
-
-import static java.lang.annotation.ElementType.*;
-import static java.lang.annotation.RetentionPolicy.*;
-import static org.apache.juneau.common.utils.CollectionUtils.*;
-import static org.apache.juneau.common.utils.Utils.*;
-import static org.junit.jupiter.api.Assertions.*;
-
-import java.lang.annotation.*;
-import java.util.*;
-import java.util.function.*;
-import java.util.stream.*;
-
-import org.apache.juneau.*;
-import org.apache.juneau.annotation.*;
-import org.apache.juneau.common.reflect.*;
-import org.junit.jupiter.api.*;
-
-/**
- * ParamInfo tests.
- */
-class ParamInfoTest extends TestBase {
-
- @Documented
- @Target(METHOD)
- @Retention(RUNTIME)
- @Inherited
- public static @interface A {
- String value();
- }
-
- @Documented
- @Target(METHOD)
- @Retention(RUNTIME)
- @Inherited
- public static @interface AX {
- String value();
- }
-
- private static void check(String expected, Object o) {
- assertEquals(expected, TO_STRING.apply(o));
- }
-
- private static final Function<Object,String> TO_STRING = new
Function<>() {
- @Override
- public String apply(Object t) {
- if (t == null)
- return null;
- if (t instanceof List)
- return
((List<?>)t).stream().map(this).collect(Collectors.joining(","));
- if (isArray(t))
- return StreamSupport.stream(toList(t,
Object.class).spliterator(), false).map(this).collect(Collectors.joining(","));
- if (t instanceof MethodInfo)
- return
((MethodInfo)t).getDeclaringClass().getNameSimple() + '.' +
((MethodInfo)t).getShortName();
- if (t instanceof CA)
- return "@CA(" + ((CA)t).value() + ")";
- if (t instanceof DA)
- return "@DA(" + ((DA)t).value() + ")";
- if (t instanceof ClassInfo)
- return ((ClassInfo)t).getNameSimple();
- return t.toString();
- }
- };
-
-
//-----------------------------------------------------------------------------------------------------------------
- // Instantiation.
-
//-----------------------------------------------------------------------------------------------------------------
-
- static class B {
- public B(int a, String b) {}
- public void a1(int a, String b) {} // NOSONAR
- void a2(int a, String b) {} // NOSONAR
- }
-
- static ClassInfo b = ClassInfo.of(B.class);
- static ParameterInfo
- b_b_a = b.getPublicConstructor(x ->
x.hasParameterTypes(int.class, String.class)).get().getParameter(0), // NOSONAR
- b_b_b = b.getPublicConstructor(x ->
x.hasParameterTypes(int.class, String.class)).get().getParameter(1), // NOSONAR
- b_a1_a = b.getMethod(x ->
x.hasName("a1")).get().getParameter(0), // NOSONAR
- b_a1_b = b.getMethod(x ->
x.hasName("a1")).get().getParameter(1), // NOSONAR
- b_a2_a = b.getMethod(x ->
x.hasName("a2")).get().getParameter(0), // NOSONAR
- b_a2_b = b.getMethod(x ->
x.hasName("a2")).get().getParameter(1); // NOSONAR
-
- @Test void getIndex() {
- assertEquals(0, b_b_a.getIndex());
- assertEquals(1, b_b_b.getIndex());
- assertEquals(0, b_a1_a.getIndex());
- assertEquals(1, b_a1_b.getIndex());
- assertEquals(0, b_a2_a.getIndex());
- assertEquals(1, b_a2_b.getIndex());
- }
-
- @Test void getMethod() {
- check("B.a1(int,String)", b_a1_a.getMethod());
- check("B.a1(int,String)", b_a1_b.getMethod());
- check("B.a2(int,String)", b_a2_a.getMethod());
- check("B.a2(int,String)", b_a2_b.getMethod());
- }
-
- @Test void getMethod_onConstrutor() {
- check(null, b_b_a.getMethod());
- check(null, b_b_b.getMethod());
- }
-
- @Test void getConstructor() {
- check("B(int,String)", b_b_a.getConstructor());
- check("B(int,String)", b_b_b.getConstructor());
- }
-
- @Test void getConstructor_onMethod() {
- check(null, b_a1_a.getConstructor());
- check(null, b_a1_b.getConstructor());
- check(null, b_a2_a.getConstructor());
- check(null, b_a2_b.getConstructor());
- }
-
- @Test void getParameterType() {
- check("int", b_b_a.getParameterType());
- check("String", b_b_b.getParameterType());
- check("int", b_a1_a.getParameterType());
- check("String", b_a1_b.getParameterType());
- check("int", b_a2_a.getParameterType());
- check("String", b_a2_b.getParameterType());
-
- }
-
-
//-----------------------------------------------------------------------------------------------------------------
- // Annotations.
-
//-----------------------------------------------------------------------------------------------------------------
-
- @Target({PARAMETER,TYPE})
- @Retention(RUNTIME)
- public static @interface CA {
- public String value();
- }
- @CA("1") public static class C1 extends C2 {}
- @CA("2") public static class C2 implements C3, C4 {}
- @CA("3") public interface C3 {}
- @CA("4") public interface C4 {}
-
- public interface CB {
- void a1(@CA("5") C1 x);
- void a2(@CA("5") C1 x);
- }
- public static class CC implements CB {
- public CC(@CA("9") C1 x) {}
- @Override
- public void a1(C1 x) {} // NOSONAR
- @Override
- public void a2(@CA("6") C1 x) {} // NOSONAR
- }
- static ClassInfo
- cb = ClassInfo.of(CB.class),
- cc = ClassInfo.of(CC.class);
- static ParameterInfo
- cc_cc = cc.getPublicConstructor(x ->
x.hasParameterTypes(C1.class)).get().getParameter(0), // NOSONAR
- cb_a1 = cb.getMethod(x ->
x.hasName("a1")).get().getParameter(0), // NOSONAR
- cb_a2 = cb.getMethod(x ->
x.hasName("a2")).get().getParameter(0), // NOSONAR
- cc_a1 = cc.getMethod(x ->
x.hasName("a1")).get().getParameter(0), // NOSONAR
- cc_a2 = cc.getMethod(x ->
x.hasName("a2")).get().getParameter(0); // NOSONAR
-
- @Test void getDeclaredAnnotations() {
- check("@CA(5)", declaredAnnotations(cb_a1, CA.class));
- check("@CA(5)", declaredAnnotations(cb_a2, CA.class));
- check("", declaredAnnotations(cc_a1, CA.class));
- check("@CA(6)", declaredAnnotations(cc_a2, CA.class));
- }
-
- @Test void getDeclaredAnnotations_constructor() {
- check("@CA(9)", declaredAnnotations(cc_cc, CA.class));
- }
-
- private static <T extends Annotation> List<T>
declaredAnnotations(ParameterInfo pi, Class<T> type) {
- return pi.getAnnotations(type).map(x -> x.inner()).toList();
- }
-
- @Test void getDeclaredAnnotation() {
- check("@CA(5)", cb_a1.getDeclaredAnnotation(CA.class));
- check("@CA(5)", cb_a2.getDeclaredAnnotation(CA.class));
- check(null, cc_a1.getDeclaredAnnotation(CA.class));
- check("@CA(6)", cc_a2.getDeclaredAnnotation(CA.class));
- }
-
- @Test void getDeclaredAnnotation_constructor() {
- check("@CA(9)", cc_cc.getDeclaredAnnotation(CA.class));
- }
-
- @Test void getDeclaredAnnotation_notFound() {
- check(null, cb_a1.getDeclaredAnnotation(DA.class));
- }
-
- @Test void getDeclaredAnnotation_notFound_constructor() {
- check(null, cc_cc.getDeclaredAnnotation(DA.class));
- }
-
- @Test void getDeclaredAnnotation_null() {
- check(null, cb_a1.getDeclaredAnnotation(null));
- }
-
- @Test void getDeclaredAnnotation_null_constructor() {
- check(null, cc_cc.getDeclaredAnnotation(null));
- }
-
- @Test void getAnnotationsParentFirst() {
- check("@CA(4),@CA(3),@CA(2),@CA(1),@CA(5)", annotations(cb_a1,
CA.class));
- check("@CA(4),@CA(3),@CA(2),@CA(1),@CA(5)", annotations(cb_a2,
CA.class));
- check("@CA(4),@CA(3),@CA(2),@CA(1),@CA(5)", annotations(cc_a1,
CA.class));
- check("@CA(4),@CA(3),@CA(2),@CA(1),@CA(5),@CA(6)",
annotations(cc_a2, CA.class));
- }
-
- @Test void getAnnotationsParentFirst_notFound() {
- check("", annotations(cb_a1, DA.class));
- }
-
- @Test void getAnnotationsParentFirst_constructor() {
- check("@CA(4),@CA(3),@CA(2),@CA(1),@CA(9)", annotations(cc_cc,
CA.class));
- }
-
- @Test void getAnnotationsParentFirst_notFound_constructor() {
- check("", annotations(cc_cc, DA.class));
- }
-
- @Test void getAllAnnotationInfo() {
- check("@CA(5)", cb_a1.getAllAnnotation(CA.class).inner());
- check("@CA(5)", cb_a2.getAllAnnotation(CA.class).inner());
- check("@CA(5)", cc_a1.getAllAnnotation(CA.class).inner());
- check("@CA(6)", cc_a2.getAllAnnotation(CA.class).inner());
- }
-
- @Test void getAllAnnotationInfo_notFound() {
- var ai = cb_a1.getAllAnnotation(DA.class);
- check(null, ai == null ? null : ai.inner());
- }
-
- @Test void getAllAnnotationInfo_constructor() {
- check("@CA(9)", cc_cc.getAllAnnotation(CA.class).inner());
- }
-
- @Test void getAllAnnotationInfo_notFound_constructor() {
- var ai = cc_cc.getAllAnnotation(DA.class);
- check(null, ai == null ? null : ai.inner());
- }
-
- @Test void getAllAnnotationInfo_twice() {
- check("@CA(5)", cb_a1.getAllAnnotation(CA.class).inner());
- check("@CA(5)", cb_a1.getAllAnnotation(CA.class).inner());
- }
-
- @Test void getAllAnnotationInfo_twice_constructor() {
- check("@CA(9)", cc_cc.getAllAnnotation(CA.class).inner());
- check("@CA(9)", cc_cc.getAllAnnotation(CA.class).inner());
- }
-
- @Test void hasAnnotation() {
- assertTrue(cb_a1.hasAnnotation(CA.class));
- assertTrue(cb_a2.hasAnnotation(CA.class));
- assertTrue(cc_a1.hasAnnotation(CA.class));
- assertTrue(cc_a2.hasAnnotation(CA.class));
- assertFalse(cb_a1.hasAnnotation(DA.class));
- }
-
- @Test void hasAnnotation_constructor() {
- assertTrue(cc_cc.hasAnnotation(CA.class));
- assertFalse(cc_cc.hasAnnotation(DA.class));
- }
-
- @Target({PARAMETER,TYPE})
- @Retention(RUNTIME)
- @Inherited
- public static @interface DA {
- public String value();
- }
- @DA("1") public static class D1 extends D2 {}
- @DA("2") public static class D2 implements D3, D4 {}
- @DA("3") public interface D3 {}
- @DA("4") public interface D4 {}
-
- public interface DB {
- void a1(@DA("0") D1 x);
- }
- public static class DC implements DB {
- @Override
- public void a1(@DA("5") D1 x) {} // NOSONAR
- }
-
- static ClassInfo
- db = ClassInfo.of(DB.class),
- dc = ClassInfo.of(DC.class);
- static ParameterInfo
- db_a1 = db.getMethod(x ->
x.hasName("a1")).get().getParameter(0), // NOSONAR
- dc_a1 = dc.getMethod(x ->
x.hasName("a1")).get().getParameter(0); // NOSONAR
-
- @Test void getAnnotationsParentFirst_inherited() {
- check("@DA(4),@DA(3),@DA(2),@DA(1),@DA(0)", annotations(db_a1,
DA.class));
- check("@DA(4),@DA(3),@DA(2),@DA(1),@DA(0),@DA(5)",
annotations(dc_a1, DA.class));
- }
-
- @Test void getAnnotationsParentFirst_inherited_notFound() {
- check("", annotations(db_a1, CA.class));
- }
-
- @Test void getAllAnnotationInfo_inherited() {
- check("@DA(0)", db_a1.getAllAnnotation(DA.class).inner());
- check("@DA(5)", dc_a1.getAllAnnotation(DA.class).inner());
- }
-
- @Test void getAllAnnotationInfo_inherited_notFound() {
- var ai = db_a1.getAllAnnotation(CA.class);
- check(null, ai == null ? null : ai.inner());
- }
-
-
//-----------------------------------------------------------------------------------------------------------------
- // Other methods.
-
//-----------------------------------------------------------------------------------------------------------------
-
- static class E {
- public void a1(int a, @Name("b") int b) {} // NOSONAR
- }
-
- static ClassInfo e = ClassInfo.of(E.class);
- static ParameterInfo
- e_a1_a = e.getMethod(x ->
x.hasName("a1")).get().getParameter(0), // NOSONAR
- e_a1_b = e.getMethod(x ->
x.hasName("a1")).get().getParameter(1); // NOSONAR
-
- @Test void hasName() {
- e_a1_a.hasName(); // This might be true or false based on the
JVM compiler used.
- assertTrue(e_a1_b.hasName());
- }
-
- @Test void getName() {
- e_a1_a.getName(); // This might be null or a value based on
the JVM compiler used.
- assertEquals("b", e_a1_b.getName());
- }
-
- @Test void toString2() {
- assertEquals("a1[1]", e_a1_b.toString());
- }
-
-
//-----------------------------------------------------------------------------------------------------------------
- // Helpers
-
//-----------------------------------------------------------------------------------------------------------------
-
- private static <T extends Annotation> List<T> annotations(ParameterInfo
pi, Class<T> a) {
- List<T> l = list();
-
rstream(pi.getAllAnnotations(a)).map(AnnotationInfo::inner).forEach(l::add);
- return l;
- }
-}
\ No newline at end of file