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 ca2cc51 ClassInfo refactoring.
ca2cc51 is described below
commit ca2cc518b11a6747f0fd69b8f495eb5a6af2ed66
Author: JamesBognar <[email protected]>
AuthorDate: Sun Jan 23 14:25:54 2022 -0500
ClassInfo refactoring.
---
.../src/main/java/org/apache/juneau/BeanMeta.java | 4 +-
.../src/main/java/org/apache/juneau/Context.java | 39 +++++---
.../main/java/org/apache/juneau/MetaProvider.java | 34 +++++--
.../src/main/java/org/apache/juneau/Value.java | 47 +++++++++
.../java/org/apache/juneau/cp/BeanCreator.java | 6 +-
.../main/java/org/apache/juneau/cp/BeanStore.java | 24 +++--
.../juneau/http/annotation/FormDataAnnotation.java | 22 ++---
.../juneau/http/annotation/HeaderAnnotation.java | 22 ++---
.../juneau/http/annotation/PathAnnotation.java | 22 ++---
.../juneau/http/annotation/QueryAnnotation.java | 22 ++---
.../juneau/http/remote/RrpcInterfaceMeta.java | 11 +--
.../org/apache/juneau/httppart/HttpPartSchema.java | 4 +-
.../juneau/httppart/bean/ResponseBeanMeta.java | 6 +-
.../org/apache/juneau/httppart/bean/Utils.java | 2 +-
.../org/apache/juneau/internal/StringUtils.java | 2 +
.../java/org/apache/juneau/reflect/ClassInfo.java | 81 ++++++++++++---
.../org/apache/juneau/reflect/ExecutableInfo.java | 19 +---
.../java/org/apache/juneau/reflect/MethodInfo.java | 29 ++++--
.../java/org/apache/juneau/reflect/ParamInfo.java | 110 ++++++++++++++++++---
.../juneau/rest/client/remote/RemoteMeta.java | 7 +-
.../java/org/apache/juneau/rest/RestContext.java | 30 ++----
.../org/apache/juneau/rest/arg/AttributeArg.java | 18 ++--
.../org/apache/juneau/rest/arg/FormDataArg.java | 4 +-
.../java/org/apache/juneau/rest/arg/HeaderArg.java | 4 +-
.../java/org/apache/juneau/rest/arg/PathArg.java | 3 +-
.../java/org/apache/juneau/rest/arg/QueryArg.java | 4 +-
.../apache/juneau/rest/arg/ResponseHeaderArg.java | 4 +-
.../apache/juneau/rest/servlet/RestServlet.java | 11 +--
.../rest/swagger/BasicSwaggerProviderSession.java | 72 +++++++-------
.../juneau/reflection/ExecutableInfoTest.java | 6 --
30 files changed, 426 insertions(+), 243 deletions(-)
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
index 48e6af3..3fa26b7 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
@@ -234,7 +234,7 @@ public class BeanMeta<T> {
for (Beanc bc :
ctx.getAnnotations(Beanc.class, x))
if (!
bc.properties().isEmpty())
constructorArgs
= split(bc.properties());
- if (constructorArgs.length !=
x.getParamCount()) {
+ if (!
x.hasNumParams(constructorArgs.length)) {
if
(constructorArgs.length != 0)
throw new
BeanRuntimeException(c, "Number of properties defined in '@Beanc' annotation
does not match number of parameters in constructor.");
constructorArgs = new
String[x.getParamCount()];
@@ -261,7 +261,7 @@ public class BeanMeta<T> {
for (Beanc bc :
ctx.getAnnotations(Beanc.class, x))
if (!
bc.properties().isEmpty())
constructorArgs = split(bc.properties());
- if
(constructorArgs.length != x.getParamCount()) {
+ if (!
x.hasNumParams(constructorArgs.length)) {
if
(constructorArgs.length != 0)
throw
new BeanRuntimeException(c, "Number of properties defined in '@Beanc'
annotation does not match number of parameters in constructor.");
constructorArgs
= new String[x.getParamCount()];
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
index 1f9108a..82e563c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
@@ -929,7 +929,7 @@ public abstract class Context implements MetaProvider {
private static final boolean DISABLE_ANNOTATION_CACHING = !
Boolean.getBoolean("juneau.disableAnnotationCaching");
private TwoKeyConcurrentCache<Class<?>,Class<? extends
Annotation>,List<Annotation>> classAnnotationCache = new
TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
- private TwoKeyConcurrentCache<Class<?>,Class<? extends
Annotation>,List<Annotation>> declaredClassAnnotationCache = new
TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
+ private TwoKeyConcurrentCache<Class<?>,Class<? extends
Annotation>,Annotation[]> declaredClassAnnotationCache = new
TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
private TwoKeyConcurrentCache<Method,Class<? extends
Annotation>,List<Annotation>> methodAnnotationCache = new
TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
private TwoKeyConcurrentCache<Field,Class<? extends
Annotation>,List<Annotation>> fieldAnnotationCache = new
TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
private TwoKeyConcurrentCache<Constructor<?>,Class<? extends
Annotation>,List<Annotation>> constructorAnnotationCache = new
TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
@@ -958,28 +958,35 @@ public abstract class Context implements MetaProvider {
return (List<A>)aa;
}
- /**
- * Finds the specified declared annotations on the specified class.
- *
- * @param <A> The annotation type to find.
- * @param a The annotation type to find.
- * @param c The class to search on.
- * @return The annotations in an unmodifiable list, or an empty list if
not found.
- */
- @SuppressWarnings("unchecked")
@Override /* MetaProvider */
- public <A extends Annotation> List<A> getDeclaredAnnotations(Class<A>
a, Class<?> c) {
- if (a == null || c == null)
- return emptyList();
- List<Annotation> aa = declaredClassAnnotationCache.get(c, a);
+ public <A extends Annotation> void getDeclaredAnnotations(Class<A> a,
Class<?> c, Consumer<A> consumer) {
+ if (a != null && c != null)
+ for (A aa : declaredAnnotations(a, c))
+ consumer.accept(aa);
+ }
+
+ @Override /* MetaProvider */
+ public <A extends Annotation> A getDeclaredAnnotation(Class<A> a,
Class<?> c, Predicate<A> predicate) {
+ if (a != null && c != null)
+ for (A aa : declaredAnnotations(a, c))
+ if (predicate.test(aa))
+ return aa;
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ private <A extends Annotation> A[] declaredAnnotations(Class<A> a,
Class<?> c) {
+ A[] aa = (A[])declaredClassAnnotationCache.get(c, a);
if (aa == null) {
A[] x = c.getDeclaredAnnotationsByType(a);
AList<Annotation> l = new AList<>(Arrays.asList(x));
annotationMap.appendAll(c, a, l);
- aa = l.unmodifiable();
+ aa = (A[]) Array.newInstance(a, l.size());
+ for (int i = 0; i < l.size(); i++)
+ Array.set(aa, i, l.get(i));
declaredClassAnnotationCache.put(c, a, aa);
}
- return (List<A>)aa;
+ return aa;
}
/**
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MetaProvider.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MetaProvider.java
index eefa75a..dedfdb4 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MetaProvider.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MetaProvider.java
@@ -15,6 +15,7 @@ package org.apache.juneau;
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.util.*;
+import java.util.function.*;
import static java.util.Collections.*;
@@ -41,11 +42,19 @@ public interface MetaProvider {
}
@Override /* MetaProvider */
- public <A extends Annotation> List<A>
getDeclaredAnnotations(Class<A> a, Class<?> c) {
- if (a == null || c == null)
- return emptyList();
- A[] aa = c.getDeclaredAnnotationsByType(a);
- return Arrays.asList(aa);
+ public <A extends Annotation> void
getDeclaredAnnotations(Class<A> a, Class<?> c, Consumer<A> consumer) {
+ if (a != null && c != null)
+ for (A aa : c.getDeclaredAnnotationsByType(a))
+ consumer.accept(aa);
+ }
+
+ @Override /* MetaProvider */
+ public <A extends Annotation> A getDeclaredAnnotation(Class<A>
a, Class<?> c, Predicate<A> predicate) {
+ if (a != null && c != null)
+ for (A aa : c.getDeclaredAnnotationsByType(a))
+ if (predicate.test(aa))
+ return aa;
+ return null;
}
@Override /* MetaProvider */
@@ -86,12 +95,21 @@ public interface MetaProvider {
/**
* Finds the specified declared annotations on the specified class.
*
- * @param <A> The annotation type to find.
* @param a The annotation type to find.
* @param c The class to search on.
- * @return The annotations in an unmodifiable list, or an empty list if
not found.
+ * @param consumer The consumer of the annotations.
+ */
+ <A extends Annotation> void getDeclaredAnnotations(Class<A> a, Class<?>
c, Consumer<A> consumer);
+
+ /**
+ * Finds the specified declared annotations on the specified class that
match the specified predicate.
+ *
+ * @param a The annotation type to find.
+ * @param c The class to search on.
+ * @param predicate The predicate to match the annotation against.
+ * @return The matched annotation, or <jk>null</jk> if no annotations
matched.
*/
- <A extends Annotation> List<A> getDeclaredAnnotations(Class<A> a,
Class<?> c);
+ <A extends Annotation> A getDeclaredAnnotation(Class<A> a, Class<?> c,
Predicate<A> predicate);
/**
* Finds the specified annotations on the specified method.
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Value.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Value.java
index ae387e1..e5f9d0c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Value.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Value.java
@@ -152,6 +152,22 @@ public class Value<T> {
}
/**
+ * Sets the value if the specified predicate test passes.
+ *
+ * @param t The new value.
+ * @param p The predicate to test the value against.
+ * @return This object.
+ */
+ public Value<T> setIf(T t, Predicate<T> p) {
+ if (p.test(t)) {
+ this.t = t;
+ if (listener != null)
+ listener.onSet(t);
+ }
+ return this;
+ }
+
+ /**
* Returns the value.
*
* @return The value, or <jk>null</jk> if it is not set.
@@ -208,4 +224,35 @@ public class Value<T> {
public boolean isEmpty() {
return t == null;
}
+
+ /**
+ * Return the value if present, otherwise invoke {@code other} and
return
+ * the result of that invocation.
+ *
+ * @param other a {@code Supplier} whose result is returned if no value
+ * is present
+ * @return the value if present otherwise the result of {@code
other.get()}
+ * @throws NullPointerException if value is not present and {@code
other} is
+ * null
+ */
+ public T orElseGet(Supplier<? extends T> other) {
+ return t != null ? t : other.get();
+ }
+
+ /**
+ * Return the contained value, if present, otherwise throw an exception
+ * to be created by the provided supplier.
+ *
+ * @param exceptionSupplier The supplier which will return the
exception to
+ * be thrown
+ * @return the present value
+ * @throws X if there is no value present
+ * @throws NullPointerException if no value is present and
+ * {@code exceptionSupplier} is null
+ */
+ public <X extends Throwable> T orElseThrow(Supplier<? extends X>
exceptionSupplier) throws X {
+ if (t != null)
+ return t;
+ throw exceptionSupplier.get();
+ }
}
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreator.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreator.java
index 4e69cbb..f4a7292 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreator.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreator.java
@@ -195,7 +195,7 @@ public class BeanCreator<T> {
MethodInfo m = type.getPublicMethod(
x -> x.isStatic()
&& x.isNotDeprecated()
- && x.getParamCount() == 1
+ && x.hasNumParams(1)
&& x.getParam(0).canAccept(builder)
&& x.hasReturnType(type)
&& x.hasNoAnnotation(BeanIgnore.class)
@@ -210,7 +210,7 @@ public class BeanCreator<T> {
MethodInfo m = type.getPublicMethod(
x -> x.isStatic()
&& x.isNotDeprecated()
- && x.getParamCount() == 0
+ && x.hasNoParams()
&& x.hasReturnType(type)
&& x.hasNoAnnotation(BeanIgnore.class)
&& x.hasName("getInstance")
@@ -286,7 +286,7 @@ public class BeanCreator<T> {
if (builder == null) {
// Look for static-builder/protected-constructor pair.
for (ConstructorInfo cc2 :
type.getDeclaredConstructors()) {
- if (cc2.getParamCount() == 1 &&
cc2.isVisible(Visibility.PROTECTED)) {
+ if (cc2.hasNumParams(1) &&
cc2.isVisible(Visibility.PROTECTED)) {
Class<?> pt =
cc2.getParam(0).getParameterType().inner();
MethodInfo m = type.getPublicMethod(x
-> isStaticCreateMethod(x, pt));
if (m != null) {
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanStore.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanStore.java
index 547fcab..f2dd201 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanStore.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanStore.java
@@ -267,6 +267,19 @@ public class BeanStore {
this.type = value;
return this;
}
+
+ /**
+ * Overrides the bean store type if the predicate test passes.
+ *
+ * @param value The bean store type.
+ * @param predicate The predicate to test against.
+ * @return This object.
+ */
+ public Builder typeIf(Class<? extends BeanStore> value,
Predicate<Class<? extends BeanStore>> predicate) {
+ if (predicate.test(value))
+ this.type = value;
+ return this;
+ }
}
//-----------------------------------------------------------------------------------------------------------------
@@ -674,17 +687,12 @@ public class BeanStore {
// Helper methods
//-----------------------------------------------------------------------------------------------------------------
private String findBeanName(ParamInfo pi) {
- Optional<Annotation> namedAnnotation =
pi.getAnnotations(Annotation.class).stream().filter(x->isNamedAnnotation(x.annotationType())).findFirst();
- if (namedAnnotation.isPresent())
- return AnnotationInfo.of((ClassInfo)null,
namedAnnotation.get()).getValue(String.class, "value").orElse(null);
+ Annotation n = pi.getAnnotation(Annotation.class, x ->
x.annotationType().getSimpleName().equals("Named"));
+ if (n != null)
+ return AnnotationInfo.of((ClassInfo)null,
n).getValue(String.class, "value").orElse(null);
return null;
}
- private boolean isNamedAnnotation(Class<?> c) {
- String s = c.getSimpleName();
- return s.equals("Named");
- }
-
private void assertCanWrite() {
if (readOnly)
throw runtimeException("Method cannot be used because
BeanStore is read-only.");
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 5a069ac..898b944 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
@@ -14,15 +14,14 @@ package org.apache.juneau.http.annotation;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
-import static org.apache.juneau.internal.StringUtils.*;
-
import java.lang.annotation.*;
import java.lang.reflect.*;
-import java.util.*;
+import java.util.function.*;
import org.apache.juneau.*;
import org.apache.juneau.annotation.*;
import org.apache.juneau.httppart.*;
+import org.apache.juneau.internal.*;
import org.apache.juneau.reflect.*;
import org.apache.juneau.svl.*;
@@ -87,16 +86,15 @@ public class FormDataAnnotation {
* <p>
* The last matching name found is returned.
*
- * @param lists The lists to search.
- * @return The last matching name, or {@link Optional#empty()} if not
found.
+ * @param pi The parameter.
+ * @return The last matching name, or {@link Value#empty()} if not
found.
*/
- @SafeVarargs
- public static Optional<String> findName(List<FormData>...lists) {
- String n = null;
- for (List<FormData> l : lists)
- for (FormData h : l)
- n = firstNonEmpty(h.name(), h.value(), n);
- return Optional.ofNullable(n);
+ public static Value<String> findName(ParamInfo pi) {
+ Value<String> n = Value.empty();
+ Predicate<String> t = StringUtils::isNotEmpty;
+ pi.getAnnotations(FormData.class, x -> n.setIf(x.value(),
t).setIf(x.name(), t));
+ pi.getParameterType().getAnnotations(FormData.class, x ->
n.setIf(x.value(), t).setIf(x.name(), t));
+ return n;
}
//-----------------------------------------------------------------------------------------------------------------
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 cd7f740..b7413e7 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
@@ -14,15 +14,14 @@ package org.apache.juneau.http.annotation;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
-import static org.apache.juneau.internal.StringUtils.*;
-
import java.lang.annotation.*;
import java.lang.reflect.*;
-import java.util.*;
+import java.util.function.*;
import org.apache.juneau.*;
import org.apache.juneau.annotation.*;
import org.apache.juneau.httppart.*;
+import org.apache.juneau.internal.*;
import org.apache.juneau.reflect.*;
import org.apache.juneau.svl.*;
@@ -87,16 +86,15 @@ public class HeaderAnnotation {
* <p>
* The last matching name found is returned.
*
- * @param lists The lists to search.
- * @return The last matching name, or {@link Optional#empty()} if not
found.
+ * @param pi The parameter.
+ * @return The last matching name, or {@link Value#empty()} if not
found.
*/
- @SafeVarargs
- public static Optional<String> findName(List<Header>...lists) {
- String n = null;
- for (List<Header> l : lists)
- for (Header h : l)
- n = firstNonEmpty(h.name(), h.value(), n);
- return Optional.ofNullable(n);
+ public static Value<String> findName(ParamInfo pi) {
+ Value<String> n = Value.empty();
+ Predicate<String> t = StringUtils::isNotEmpty;
+ pi.getAnnotations(Header.class, x -> n.setIf(x.value(),
t).setIf(x.name(), t));
+ pi.getParameterType().getAnnotations(Header.class, x ->
n.setIf(x.value(), t).setIf(x.name(), t));
+ return n;
}
//-----------------------------------------------------------------------------------------------------------------
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 3803028..5f22375 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
@@ -14,15 +14,14 @@ package org.apache.juneau.http.annotation;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
-import static org.apache.juneau.internal.StringUtils.*;
-
import java.lang.annotation.*;
import java.lang.reflect.*;
-import java.util.*;
+import java.util.function.*;
import org.apache.juneau.*;
import org.apache.juneau.annotation.*;
import org.apache.juneau.httppart.*;
+import org.apache.juneau.internal.*;
import org.apache.juneau.reflect.*;
import org.apache.juneau.svl.*;
@@ -87,16 +86,15 @@ public class PathAnnotation {
* <p>
* The last matching name found is returned.
*
- * @param lists The lists to search.
- * @return The last matching name, or {@link Optional#empty()} if not
found.
+ * @param pi The parameter.
+ * @return The last matching name, or {@link Value#empty()} if not
found.
*/
- @SafeVarargs
- public static Optional<String> findName(List<Path>...lists) {
- String n = null;
- for (List<Path> l : lists)
- for (Path h : l)
- n = firstNonEmpty(h.name(), h.value(), n);
- return Optional.ofNullable(n);
+ public static Value<String> findName(ParamInfo pi) {
+ Value<String> n = Value.empty();
+ Predicate<String> t = StringUtils::isNotEmpty;
+ pi.getAnnotations(Path.class, x -> n.setIf(x.value(),
t).setIf(x.name(), t));
+ pi.getParameterType().getAnnotations(Path.class, x ->
n.setIf(x.value(), t).setIf(x.name(), t));
+ return n;
}
//-----------------------------------------------------------------------------------------------------------------
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 c73a751..603f804 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
@@ -14,15 +14,14 @@ package org.apache.juneau.http.annotation;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
-import static org.apache.juneau.internal.StringUtils.*;
-
import java.lang.annotation.*;
import java.lang.reflect.*;
-import java.util.*;
+import java.util.function.*;
import org.apache.juneau.*;
import org.apache.juneau.annotation.*;
import org.apache.juneau.httppart.*;
+import org.apache.juneau.internal.*;
import org.apache.juneau.reflect.*;
import org.apache.juneau.svl.*;
@@ -87,16 +86,15 @@ public class QueryAnnotation {
* <p>
* The last matching name found is returned.
*
- * @param lists The lists to search.
- * @return The last matching name, or {@link Optional#empty()} if not
found.
+ * @param pi The parameter.
+ * @return The last matching name, or {@link Value#empty()} if not
found.
*/
- @SafeVarargs
- public static Optional<String> findName(List<Query>...lists) {
- String n = null;
- for (List<Query> l : lists)
- for (Query h : l)
- n = firstNonEmpty(h.name(), h.value(), n);
- return Optional.ofNullable(n);
+ public static Value<String> findName(ParamInfo pi) {
+ Value<String> n = Value.empty();
+ Predicate<String> t = StringUtils::isNotEmpty;
+ pi.getAnnotations(Query.class, x -> n.setIf(x.value(),
t).setIf(x.name(), t));
+ pi.getParameterType().getAnnotations(Query.class, x ->
n.setIf(x.value(), t).setIf(x.name(), t));
+ return n;
}
//-----------------------------------------------------------------------------------------------------------------
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RrpcInterfaceMeta.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RrpcInterfaceMeta.java
index e13e861..38b9781 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RrpcInterfaceMeta.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RrpcInterfaceMeta.java
@@ -16,6 +16,7 @@ import static org.apache.juneau.internal.StringUtils.*;
import java.lang.reflect.*;
import java.util.*;
+import org.apache.juneau.*;
import org.apache.juneau.collections.*;
import org.apache.juneau.reflect.*;
@@ -49,16 +50,14 @@ public class RrpcInterfaceMeta {
*/
public RrpcInterfaceMeta(Class<?> c, String uri) {
this.c = c;
- String path = "";
+ Value<String> path = Value.of("");
ClassInfo ci = ClassInfo.of(c);
- for (Remote r : ci.getAnnotations(Remote.class))
- if (! r.path().isEmpty())
- path = trimSlashes(r.path());
+ ci.getAnnotations(Remote.class, x -> { if (!
x.path().isEmpty()) path.set(trimSlashes(x.path()));});
AMap<Method,RrpcInterfaceMethodMeta> methods = AMap.create();
ci.getPublicMethods(
- x -> true,
+ x -> true,
x -> methods.put(x.inner(), new
RrpcInterfaceMethodMeta(uri, x.inner()))
);
@@ -68,7 +67,7 @@ public class RrpcInterfaceMeta {
this.methods = methods.unmodifiable();
this.methodsByPath = methodsByPath.unmodifiable();
- this.path = path;
+ this.path = path.get();
}
/**
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
index 4b7c486..c9860db 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
@@ -686,9 +686,7 @@ public class HttpPartSchema {
Builder apply(Class<? extends Annotation> c,
java.lang.reflect.Type t) {
if (t instanceof Class<?>) {
- ClassInfo ci = ClassInfo.of((Class<?>)t);
- for (Annotation a : ci.getAnnotations(c))
- apply(a);
+ ClassInfo.of((Class<?>)t).getAnnotations(c, x
-> apply(x));
} else if (Value.isType(t)) {
apply(c, Value.getParameterType(t));
}
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 f96b7a0..2859c21 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
@@ -55,8 +55,8 @@ public class ResponseBeanMeta {
return null;
Builder b = new Builder(annotations);
b.apply(ci.innerType());
- ci.getAnnotations(Response.class).forEach(x -> b.apply(x));
- ci.getAnnotations(StatusCode.class).forEach(x -> b.apply(x));
+ ci.getAnnotations(Response.class, x -> b.apply(x));
+ ci.getAnnotations(StatusCode.class, x -> b.apply(x));
return b.build();
}
@@ -167,7 +167,7 @@ public class ResponseBeanMeta {
assertReturnType(m, Header.class,
int.class, Integer.class);
statusMethod =
ResponseBeanPropertyMeta.create(RESPONSE_STATUS, m);
} else if (m.hasAnnotation(Body.class)) {
- if (m.getParamCount() == 0)
+ if (m.hasNoParams())
assertReturnNotVoid(m,
Header.class);
else
assertArgType(m, Header.class,
OutputStream.class, Writer.class);
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/Utils.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/Utils.java
index fb4f03d..ddd9331 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/Utils.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/Utils.java
@@ -28,7 +28,7 @@ import org.apache.juneau.reflect.*;
class Utils {
static void assertNoArgs(MethodInfo m, Class<?> a) throws
InvalidAnnotationException {
- if (m.getParamCount() != 0)
+ if (m.hasParams())
throw new InvalidAnnotationException("Method with @{0}
annotation cannot have arguments. Method=''{1}''", a.getSimpleName(), m);
}
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
index 30183d9..00818b2 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
@@ -1785,6 +1785,8 @@ public final class StringUtils {
public static String trimSlashes(String s) {
if (s == null)
return null;
+ if (s.length() == 0)
+ return s;
while (endsWith(s, '/'))
s = s.substring(0, s.length()-1);
while (s.length() > 0 && s.charAt(0) == '/')
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
index cc52b7a..884ed00 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
@@ -950,7 +950,20 @@ public final class ClassInfo {
* A list of all matching annotations found or an empty list if
none found.
*/
public <T extends Annotation> List<T> getAnnotations(Class<T> a) {
- return appendAnnotations(new ArrayList<>(), a);
+ List<T> l = new ArrayList<>();
+ getAnnotations(a, x -> l.add(x));
+ return l;
+ }
+
+ /**
+ * Returns the first matching annotation of the specified type defined
on the specified class or parent classes/interfaces in parent-to-child order.
+ *
+ * @param a The annotation to search for.
+ * @param predicate The predicate to test against.
+ * @return This object.
+ */
+ public <T extends Annotation> T getAnnotation(Class<T> a, Predicate<T>
predicate) {
+ return getAnnotation(predicate, a, MetaProvider.DEFAULT);
}
/**
@@ -1035,7 +1048,7 @@ public final class ClassInfo {
/**
* Finds and appends the specified annotation on the specified class
and superclasses/interfaces to the specified
- * list.
+ * consumer.
*
* <p>
* Annotations are appended in the following orders:
@@ -1046,12 +1059,12 @@ public final class ClassInfo {
* <li>On this class.
* </ol>
*
- * @param l The list of annotations.
+ * @param consumer The consumer of the annotations.
* @param a The annotation to search for.
* @return The same list.
*/
- public <T extends Annotation> List<T> appendAnnotations(List<T> l,
Class<T> a) {
- return appendAnnotations(l, a, MetaProvider.DEFAULT);
+ public <T extends Annotation> ClassInfo getAnnotations(Class<T> a,
Consumer<T> consumer) {
+ return getAnnotations(a, MetaProvider.DEFAULT, consumer);
}
/**
@@ -1073,16 +1086,58 @@ public final class ClassInfo {
* @return The same list.
*/
public <T extends Annotation> List<T> appendAnnotations(List<T> l,
Class<T> a, MetaProvider mp) {
- addIfNotNull(l, getPackageAnnotation(a));
+ getAnnotations(a, mp, x -> l.add(x));
+ return l;
+ }
+
+ /**
+ * Finds and consumes the specified annotation on the specified class
and superclasses/interfaces to the specified
+ * consumer.
+ *
+ * <p>
+ * Annotations are appended in the following orders:
+ * <ol>
+ * <li>On the package of this class.
+ * <li>On interfaces ordered child-to-parent.
+ * <li>On parent classes ordered child-to-parent.
+ * <li>On this class.
+ * </ol>
+ *
+ * @param consumer The consumer of the annotations.
+ * @param a The annotation to search for.
+ * @param mp The meta provider for looking up annotations on reflection
objects (classes, methods, fields, constructors).
+ * @return This object.
+ */
+ public <T extends Annotation> ClassInfo getAnnotations(Class<T> a,
MetaProvider mp, Consumer<T> consumer) {
+ T t2 = getPackageAnnotation(a);
+ if (t2 != null)
+ consumer.accept(t2);
ClassInfo[] interfaces = _getInterfaces();
for (int i = interfaces.length-1; i >= 0; i--)
- for (T t : mp.getDeclaredAnnotations(a,
interfaces[i].inner()))
- l.add(t);
+ mp.getDeclaredAnnotations(a, interfaces[i].inner(),
consumer);
ClassInfo[] parents = _getParents();
for (int i = parents.length-1; i >= 0; i--)
- for (T t : mp.getDeclaredAnnotations(a,
parents[i].inner()))
- l.add(t);
- return l;
+ mp.getDeclaredAnnotations(a, parents[i].inner(),
consumer);
+ return this;
+ }
+
+ private <T extends Annotation> T getAnnotation(Predicate<T> p, Class<T>
a, MetaProvider mp) {
+ T t2 = getPackageAnnotation(a);
+ if (t2 != null && p.test(t2))
+ return t2;
+ ClassInfo[] interfaces = _getInterfaces();
+ for (int i = interfaces.length-1; i >= 0; i--) {
+ T o = mp.getDeclaredAnnotation(a,
interfaces[i].inner(), p);
+ if (o != null)
+ return o;
+ }
+ ClassInfo[] parents = _getParents();
+ for (int i = parents.length-1; i >= 0; i--) {
+ T o = mp.getDeclaredAnnotation(a, parents[i].inner(),
p);
+ if (o != null)
+ return o;
+ }
+ return null;
}
/**
@@ -1180,10 +1235,10 @@ public final class ClassInfo {
if (a == null)
return null;
- for (T t : mp.getDeclaredAnnotations(a, c))
+ T t = mp.getDeclaredAnnotation(a, c, x -> true);
+ if (t != null)
return t;
- T t;
ClassInfo sci = getParent();
if (sci != null) {
t = sci.getLastAnnotation(a, mp);
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ExecutableInfo.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ExecutableInfo.java
index 857c5d5..0843196 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ExecutableInfo.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ExecutableInfo.java
@@ -38,7 +38,7 @@ public abstract class ExecutableInfo {
private ParamInfo[] params;
private ClassInfo[] paramTypes, exceptionInfos;
- private Class<?>[] rawParamTypes, rawExceptionTypes;
+ private Class<?>[] rawParamTypes;
private Type[] rawGenericParamTypes;
private Parameter[] rawParameters;
@@ -345,18 +345,9 @@ public abstract class ExecutableInfo {
return new UnmodifiableArray<>(_getExceptionTypes());
}
- /**
- * Returns the raw exception types on this executable.
- *
- * @return The raw exception types on this executable.
- */
- public final Class<?>[] getRawExceptionTypes() {
- return _getRawExceptionTypes().clone();
- }
-
private ClassInfo[] _getExceptionTypes() {
if (exceptionInfos == null) {
- Class<?>[] exceptionTypes = _getRawExceptionTypes();
+ Class<?>[] exceptionTypes = e.getExceptionTypes();
ClassInfo[] l = new ClassInfo[exceptionTypes.length];
for (int i = 0; i < exceptionTypes.length; i++)
l[i] = ClassInfo.of(exceptionTypes[i]);
@@ -365,12 +356,6 @@ public abstract class ExecutableInfo {
return exceptionInfos;
}
- private Class<?>[] _getRawExceptionTypes() {
- if (rawExceptionTypes == null)
- rawExceptionTypes = e.getExceptionTypes();
- return rawExceptionTypes;
- }
-
//-----------------------------------------------------------------------------------------------------------------
// Characteristics
//-----------------------------------------------------------------------------------------------------------------
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/MethodInfo.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/MethodInfo.java
index dc65932..83123b4 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/MethodInfo.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/MethodInfo.java
@@ -304,15 +304,32 @@ public final class MethodInfo extends ExecutableInfo
implements Comparable<Metho
* @param a The annotation.
* @return The same list.
*/
- @SuppressWarnings("unchecked")
public <T extends Annotation> List<T> appendAnnotations(List<T> l,
Class<T> a) {
- declaringClass.appendAnnotations(l, a);
+ getAnnotations(a, x -> l.add(x));
+ return l;
+ }
+
+ /**
+ * Consumes all annotations of the specified type defined on the
specified method.
+ *
+ * <p>
+ * Searches all methods with the same signature on the parent classes
or interfaces
+ * and the return type on the method.
+ * <br>Results are parent-to-child ordered.
+ *
+ * @param a The annotation to search for.
+ * @param consumer The consumer of the annotation.
+ * @return This object.
+ */
+ @SuppressWarnings("unchecked")
+ public <T extends Annotation> MethodInfo getAnnotations(Class<T> a,
Consumer<T> consumer) {
+ declaringClass.getAnnotations(a, consumer);
for (Method m2 : getMatchingParentFirst())
- for (Annotation a2 : m2.getDeclaredAnnotations())
+ for (Annotation a2 : m2.getDeclaredAnnotations())
if (a.isInstance(a2))
- l.add((T)a2);
-
getReturnType().unwrap(Value.class,Optional.class).appendAnnotations(l, a);
- return l;
+ consumer.accept((T)a2);
+
getReturnType().unwrap(Value.class,Optional.class).getAnnotations(a, consumer);
+ return this;
}
/**
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ParamInfo.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ParamInfo.java
index 4e21d03..add7ed2 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ParamInfo.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ParamInfo.java
@@ -16,6 +16,7 @@ import java.lang.annotation.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.*;
+import java.util.function.*;
import org.apache.juneau.*;
import org.apache.juneau.annotation.*;
@@ -181,49 +182,130 @@ public final class ParamInfo {
* <p>
* Results are in parent-to-child order.
*
- * @param a
- * The annotation to search for.
- * @return
- * A list of all matching annotations found or an empty list if
none found.
+ * @param a The annotation to search for.
+ * @return A list of all matching annotations found or an empty list if
none found.
*/
public <T extends Annotation> List<T> getAnnotations(Class<T> a) {
return appendAnnotations(new ArrayList<>(), a, true);
}
- @SuppressWarnings("unchecked")
+ /**
+ * Consumes all annotations of the specified type defined on this
method parameter.
+ *
+ * <p>
+ * Searches all methods with the same signature on the parent classes
or interfaces
+ * and the return type on the method.
+ * <p>
+ * Results are in parent-to-child order.
+ *
+ * @param a The annotation to search for.
+ * @param consumer The consumer for the annotations.
+ * @return This object.
+ */
+ public <T extends Annotation> ParamInfo getAnnotations(Class<T> a,
Consumer<T> consumer) {
+ return getAnnotations(a, true, consumer);
+ }
+
+ /**
+ * Returns the first annotation of the specified type defined on this
method parameter that matches the specified predicate.
+ *
+ * <p>
+ * Searches all methods with the same signature on the parent classes
or interfaces
+ * and the return type on the method.
+ * <p>
+ * Results are in parent-to-child order.
+ *
+ * @param a The annotation to search for.
+ * @param predicate The consumer for the annotations.
+ * @return A list of all matching annotations found or an empty list if
none found.
+ */
+ public <T extends Annotation> T getAnnotation(Class<T> a, Predicate<T>
predicate) {
+ return getAnnotation(a, true, predicate);
+ }
+
private <T extends Annotation> List<T> appendAnnotations(List<T> l,
Class<T> a, boolean parentFirst) {
+ getAnnotations(a, parentFirst, x -> l.add(x));
+ return l;
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T extends Annotation> ParamInfo getAnnotations(Class<T> a,
boolean parentFirst, Consumer<T> consumer) {
if (eInfo.isConstructor) {
ClassInfo ci =
eInfo.getParamType(index).unwrap(Value.class,Optional.class);
Annotation[] annotations =
eInfo.getParameterAnnotations(index);
if (parentFirst) {
- ci.appendAnnotations(l, a);
+ ci.getAnnotations(a, consumer);
for (Annotation a2 : annotations)
if (a.isInstance(a2))
- l.add((T)a2);
+ consumer.accept((T)a2);
} else {
for (Annotation a2 : annotations)
if (a.isInstance(a2))
- l.add((T)a2);
- ci.appendAnnotations(l, a);
+ consumer.accept((T)a2);
+ ci.getAnnotations(a, consumer);
}
} else {
MethodInfo mi = (MethodInfo)eInfo;
ClassInfo ci =
eInfo.getParamType(index).unwrap(Value.class,Optional.class);
if (parentFirst) {
- ci.appendAnnotations(l, a);
+ ci.getAnnotations(a, consumer);
for (Method m2 : mi.getMatchingParentFirst())
for (Annotation a2 :
m2.getParameterAnnotations()[index])
if (a.isInstance(a2))
- l.add((T)a2);
+ consumer.accept((T)a2);
} else {
for (Method m2 : mi.getMatching())
for (Annotation a2 :
m2.getParameterAnnotations()[index])
if (a.isInstance(a2))
- l.add((T)a2);
- ci.appendAnnotations(l, a);
+ consumer.accept((T)a2);
+ ci.getAnnotations(a, consumer);
}
}
- return l;
+ return this;
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T extends Annotation> T getAnnotation(Class<T> a, boolean
parentFirst, Predicate<T> predicate) {
+ if (eInfo.isConstructor) {
+ ClassInfo ci =
eInfo.getParamType(index).unwrap(Value.class,Optional.class);
+ Annotation[] annotations =
eInfo.getParameterAnnotations(index);
+ if (parentFirst) {
+ T o = ci.getAnnotation(a, predicate);
+ if (o != null)
+ return o;
+ for (Annotation a2 : annotations)
+ if (a.isInstance(a2) &&
predicate.test((T)a2))
+ return (T)a2;
+ } else {
+ for (Annotation a2 : annotations)
+ if (a.isInstance(a2) &&
predicate.test((T)a2))
+ return (T)a2;
+ T o = ci.getAnnotation(a, predicate);
+ if (o != null)
+ return o;
+ }
+ } else {
+ MethodInfo mi = (MethodInfo)eInfo;
+ ClassInfo ci =
eInfo.getParamType(index).unwrap(Value.class,Optional.class);
+ if (parentFirst) {
+ T o = ci.getAnnotation(a, predicate);
+ if (o != null)
+ return o;
+ for (Method m2 : mi.getMatchingParentFirst())
+ for (Annotation a2 :
m2.getParameterAnnotations()[index])
+ if (a.isInstance(a2) &&
predicate.test((T)a2))
+ return (T)a2;
+ } else {
+ for (Method m2 : mi.getMatching())
+ for (Annotation a2 :
m2.getParameterAnnotations()[index])
+ if (a.isInstance(a2) &&
predicate.test((T)a2))
+ return (T)a2;
+ T o = ci.getAnnotation(a, predicate);
+ if (o != null)
+ return o;
+ }
+ }
+ return null;
}
private synchronized Map<Class<?>,Optional<Annotation>> annotationMap()
{
diff --git
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteMeta.java
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteMeta.java
index bd2bb1a..e213f78 100644
---
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteMeta.java
+++
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteMeta.java
@@ -51,14 +51,15 @@ public class RemoteMeta {
String path = "";
ClassInfo ci = ClassInfo.of(c);
- for (Remote r : ci.getAnnotations(Remote.class))
+ List<Remote> remotes = ci.getAnnotations(Remote.class);
+ for (Remote r : remotes)
if (! r.path().isEmpty())
path = trimSlashes(r.path());
String versionHeader = "Client-Version", clientVersion = null;
HeaderList.Builder headersBuilder =
HeaderList.create().resolving();
- for (Remote r : ci.getAnnotations(Remote.class)) {
+ for (Remote r : remotes) {
if (! r.path().isEmpty())
path = trimSlashes(resolve(r.path()));
for (String h : r.headers())
@@ -82,7 +83,7 @@ public class RemoteMeta {
AMap<Method,RemoteOperationMeta> operations = AMap.create();
String path2 = path;
ci.getPublicMethods(
- x -> true,
+ x -> true,
x -> operations.put(x.inner(), new
RemoteOperationMeta(path2, x.inner(), "GET"))
);
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 d23492f..faa8320 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
@@ -172,11 +172,7 @@ public class RestContext extends Context {
public static Builder create(Class<?> resourceClass, RestContext
parentContext, ServletConfig servletConfig) throws ServletException {
Value<Class<? extends Builder>> v = Value.of(Builder.class);
- ClassInfo.of(resourceClass)
- .getAnnotations(Rest.class)
- .stream()
- .filter(x -> x.builder() != Builder.Null.class)
- .forEach(x -> v.set(x.builder()));
+ ClassInfo.ofc(resourceClass).getAnnotations(Rest.class, x ->
v.setIf(x.builder(), x2 -> x2 != Builder.Null.class));
if (v.get() == Builder.class)
return new Builder(resourceClass, parentContext,
servletConfig);
@@ -588,13 +584,7 @@ public class RestContext extends Context {
);
// Apply @Rest(beanStore).
- ClassInfo.of(resourceClass)
- .getAnnotations(Rest.class)
- .stream()
- .map(x -> x.beanStore())
- .filter(x -> x != BeanStore.Null.class)
- .reduce((x1,x2)->x2)
- .ifPresent(x -> v.get().type(x));
+ ClassInfo.of(resourceClass).getAnnotations(Rest.class,
x -> v.get().typeIf(x.beanStore(), y -> y != BeanStore.Null.class));
// Replace with builder from: public [static]
BeanStore.Builder createBeanStore(<args>)
v.get().build()
@@ -874,15 +864,13 @@ public class RestContext extends Context {
// Find our config file. It's the last non-empty
@RestResource(config).
VarResolver vr =
beanStore.getBean(VarResolver.class).orElseThrow(()->runtimeException("VarResolver
not found."));
- String cf = ClassInfo
- .of(resourceClass)
- .getAnnotations(Rest.class)
- .stream()
- .map(x -> x.config())
- .filter(x -> ! x.isEmpty())
- .reduce((x1,x2)->x2)
- .map(x -> vr.resolve(x))
- .orElse("");
+ Value<String> cfv = Value.empty();
+ Consumer<Rest> consumer = x -> {
+ if (! x.config().isEmpty())
+ cfv.set(vr.resolve(x.config()));
+ };
+ ClassInfo.of(resourceClass).getAnnotations(Rest.class,
consumer);
+ String cf = cfv.orElse("");
// If not specified or value is set to SYSTEM_DEFAULT,
use system default config.
if (v.isEmpty() && "SYSTEM_DEFAULT".equals(cf))
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 ec0d87f..927f4d7 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
@@ -12,8 +12,8 @@
//
***************************************************************************************************************************
package org.apache.juneau.rest.arg;
-import static org.apache.juneau.internal.StringUtils.*;
-
+import org.apache.juneau.*;
+import org.apache.juneau.internal.*;
import org.apache.juneau.reflect.*;
import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
@@ -65,14 +65,16 @@ public class AttributeArg implements RestOpArg {
}
private String getName(ParamInfo paramInfo) {
- String n = null;
+ Value<String> n = Value.empty();
for (Attr h : paramInfo.getAnnotations(Attr.class))
- n = firstNonEmpty(h.name(), h.value(), n);
- for (Attr h :
paramInfo.getParameterType().getAnnotations(Attr.class))
- n = firstNonEmpty(h.name(), h.value(), n);
- if (n == null)
+ n.setIf(h.name(),
StringUtils::isNotEmpty).setIf(h.value(), StringUtils::isNotEmpty);
+ paramInfo.getParameterType().getAnnotations(Attr.class, x -> {
+ n.setIf(x.name(), StringUtils::isNotEmpty);
+ n.setIf(x.value(), StringUtils::isNotEmpty);
+ });
+ if (n.isEmpty())
throw new ArgException(paramInfo, "@Attr used without
name or value");
- return n;
+ return n.get();
}
@Override /* RestOpArg */
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 5088ea9..da68e3b 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
@@ -79,9 +79,7 @@ public class FormDataArg implements RestOpArg {
* @param annotations The annotations to apply to any new part parsers.
*/
protected FormDataArg(ParamInfo pi, AnnotationWorkList annotations) {
- ClassInfo pt = pi.getParameterType();
-
- this.name = findName(pi.getAnnotations(FormData.class),
pt.getAnnotations(FormData.class)).orElseThrow(()->new ArgException(pi,
"@FormData used without name or value"));
+ this.name = findName(pi).orElseThrow(()->new ArgException(pi,
"@FormData used without name or value"));
this.type = pi.getParameterType();
this.schema = HttpPartSchema.create(FormData.class, pi);
this.partParser = ofNullable(schema.getParser()).map(x ->
HttpPartParser.creator().type(x).apply(annotations).create()).orElse(null);
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 79c7741..83c6e59 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
@@ -120,9 +120,7 @@ public class HeaderArg implements RestOpArg {
* @param annotations The annotations to apply to any new part parsers.
*/
protected HeaderArg(ParamInfo pi, AnnotationWorkList annotations) {
- ClassInfo pt = pi.getParameterType();
-
- this.name = findName(pi.getAnnotations(Header.class),
pt.getAnnotations(Header.class)).orElseThrow(() -> new ArgException(pi,
"@Header used without name or value"));
+ this.name = findName(pi).orElseThrow(() -> new ArgException(pi,
"@Header used without name or value"));
this.type = pi.getParameterType();
this.schema = HttpPartSchema.create(Header.class, pi);
this.partParser = ofNullable(schema.getParser()).map(x ->
HttpPartParser.creator().type(x).apply(annotations).create()).orElse(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 87210e8..042b186 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
@@ -84,8 +84,7 @@ public class PathArg implements RestOpArg {
}
private String getName(ParamInfo pi, UrlPathMatcher pathMatcher) {
- ClassInfo pt = pi.getParameterType();
- String p = findName(pi.getAnnotations(Path.class),
pt.getAnnotations(Path.class)).orElse(null);
+ String p = findName(pi).orElse(null);
if (p != null)
return p;
if (pathMatcher != 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 acf6eb8..742745c 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
@@ -78,9 +78,7 @@ public class QueryArg implements RestOpArg {
* @param annotations The annotations to apply to any new part parsers.
*/
protected QueryArg(ParamInfo pi, AnnotationWorkList annotations) {
- ClassInfo pt = pi.getParameterType();
-
- this.name =
QueryAnnotation.findName(pi.getAnnotations(Query.class),
pt.getAnnotations(Query.class)).orElseThrow(() -> new ArgException(pi, "@Query
used without name or value"));
+ this.name = QueryAnnotation.findName(pi).orElseThrow(() -> new
ArgException(pi, "@Query used without name or value"));
this.type = pi.getParameterType();
this.schema = HttpPartSchema.create(Query.class, pi);
this.partParser = ofNullable(schema.getParser()).map(x ->
HttpPartParser.creator().type(x).apply(annotations).create()).orElse(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 64734a2..082ac0d 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
@@ -68,9 +68,7 @@ public class ResponseHeaderArg implements RestOpArg {
* @param annotations The annotations to apply to any new part parsers.
*/
protected ResponseHeaderArg(ParamInfo pi, AnnotationWorkList
annotations) {
- ClassInfo pt = pi.getParameterType();
-
- this.name = findName(pi.getAnnotations(Header.class),
pt.getAnnotations(Header.class)).orElseThrow(() -> new ArgException(pi,
"@Header used without name or value"));
+ this.name = findName(pi).orElseThrow(() -> new ArgException(pi,
"@Header used without name or value"));
this.type = pi.getParameterType().innerType();
HttpPartSchema schema = HttpPartSchema.create(Header.class, pi);
this.meta = new ResponsePartMeta(HttpPartType.HEADER, schema,
ofNullable(schema.getSerializer()).map(x ->
HttpPartSerializer.creator().type(x).apply(annotations).create()).orElse(null));
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestServlet.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestServlet.java
index 20cdddd..62e7137 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestServlet.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestServlet.java
@@ -36,6 +36,7 @@ import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.converter.*;
import org.apache.juneau.rest.guard.*;
import org.apache.juneau.rest.matcher.*;
+import org.apache.juneau.*;
import org.apache.juneau.cp.*;
import org.apache.juneau.http.response.*;
@@ -128,13 +129,9 @@ public abstract class RestServlet extends HttpServlet {
if (context != null)
return context.getFullPath();
ClassInfo ci = ClassInfo.of(getClass());
- String path = "";
- for (Rest rr : ci.getAnnotations(Rest.class))
- if (! rr.path().isEmpty())
- path = trimSlashes(rr.path());
- if (! path.isEmpty())
- return path;
- return "";
+ Value<String> path = Value.empty();
+ ci.getAnnotations(Rest.class, x ->
path.setIf(trimSlashes(x.path()), StringUtils::isNotEmpty));
+ return path.orElse("");
}
//-----------------------------------------------------------------------------------------------------------------
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 cbd83bf..a0018b9 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
@@ -320,52 +320,52 @@ public class BasicSwaggerProviderSession {
if (mpi.hasAnnotation(Body.class) ||
pt.hasAnnotation(Body.class)) {
OMap param = paramMap.getMap(BODY +
".body", true).a("in", BODY);
OMap schema =
getSchema(param.getMap("schema"), type, bs);
-
pt.getAnnotations(Schema.class).forEach(x -> merge(schema, x));
-
mpi.getAnnotations(Schema.class).forEach(x -> merge(schema, x));
- pt.getAnnotations(Body.class).forEach(x
-> merge(schema, x.schema()));
-
mpi.getAnnotations(Body.class).forEach(x -> merge(schema, x.schema()));
+ pt.getAnnotations(Schema.class, x ->
merge(schema, x));
+ mpi.getAnnotations(Schema.class, x ->
merge(schema, x));
+ pt.getAnnotations(Body.class, x ->
merge(schema, x.schema()));
+ mpi.getAnnotations(Body.class, x ->
merge(schema, x.schema()));
pushupSchemaFields(BODY, param, schema);
param.appendIf(true, true, true,
"schema", schema);
param.putIfAbsent("required", true);
addBodyExamples(sm, param, false, type,
locale);
} else if (mpi.hasAnnotation(Query.class) ||
pt.hasAnnotation(Query.class)) {
- String name =
QueryAnnotation.findName(mpi.getAnnotations(Query.class),
pt.getAnnotations(Query.class)).orElse(null);
+ String name =
QueryAnnotation.findName(mpi).orElse(null);
OMap param = paramMap.getMap(QUERY +
"." + name, true).a("name", name).a("in", QUERY);
-
pt.getAnnotations(Schema.class).forEach(x -> merge(param, x));
-
pt.getAnnotations(Query.class).forEach(x -> merge(param, x.schema()));
-
mpi.getAnnotations(Schema.class).forEach(x -> merge(param, x));
-
mpi.getAnnotations(Query.class).forEach(x -> merge(param, x.schema()));
+ pt.getAnnotations(Schema.class, x ->
merge(param, x));
+ pt.getAnnotations(Query.class, x ->
merge(param, x.schema()));
+ mpi.getAnnotations(Schema.class, x ->
merge(param, x));
+ mpi.getAnnotations(Query.class, 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)) {
- String name =
FormDataAnnotation.findName(mpi.getAnnotations(FormData.class),
pt.getAnnotations(FormData.class)).orElse(null);
+ String name =
FormDataAnnotation.findName(mpi).orElse(null);
OMap param = paramMap.getMap(FORM_DATA
+ "." + name, true).a("name", name).a("in", FORM_DATA);
-
pt.getAnnotations(Schema.class).forEach(x -> merge(param, x));
-
pt.getAnnotations(FormData.class).forEach(x -> merge(param, x.schema()));
-
mpi.getAnnotations(Schema.class).forEach(x -> merge(param, x));
-
mpi.getAnnotations(FormData.class).forEach(x -> merge(param, x.schema()));
+ pt.getAnnotations(Schema.class, x ->
merge(param, x));
+ pt.getAnnotations(FormData.class, x ->
merge(param, x.schema()));
+ mpi.getAnnotations(Schema.class, x ->
merge(param, x));
+ mpi.getAnnotations(FormData.class, 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)) {
- String name =
HeaderAnnotation.findName(mpi.getAnnotations(Header.class),
pt.getAnnotations(Header.class)).orElse(null);
+ String name =
HeaderAnnotation.findName(mpi).orElse(null);
OMap param = paramMap.getMap(HEADER +
"." + name, true).a("name", name).a("in", HEADER);
-
pt.getAnnotations(Schema.class).forEach(x -> merge(param, x));
-
pt.getAnnotations(Header.class).forEach(x -> merge(param, x.schema()));
-
mpi.getAnnotations(Schema.class).forEach(x -> merge(param, x));
-
mpi.getAnnotations(Header.class).forEach(x -> merge(param, x.schema()));
+ pt.getAnnotations(Schema.class, x ->
merge(param, x));
+ pt.getAnnotations(Header.class, x ->
merge(param, x.schema()));
+ mpi.getAnnotations(Schema.class, x ->
merge(param, x));
+ mpi.getAnnotations(Header.class, 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)) {
- String name =
PathAnnotation.findName(mpi.getAnnotations(Path.class),
pt.getAnnotations(Path.class)).orElse(null);
+ String name =
PathAnnotation.findName(mpi).orElse(null);
OMap param = paramMap.getMap(PATH + "."
+ name, true).a("name", name).a("in", PATH);
-
pt.getAnnotations(Schema.class).forEach(x -> merge(param, x));
- pt.getAnnotations(Path.class).forEach(x
-> merge(param, x.schema()));
-
mpi.getAnnotations(Schema.class).forEach(x -> merge(param, x));
-
mpi.getAnnotations(Path.class).forEach(x -> merge(param, x.schema()));
+ pt.getAnnotations(Schema.class, x ->
merge(param, x));
+ pt.getAnnotations(Path.class, x ->
merge(param, x.schema()));
+ mpi.getAnnotations(Schema.class, x ->
merge(param, x));
+ mpi.getAnnotations(Path.class, x ->
merge(param, x.schema()));
pushupSchemaFields(PATH, param,
getSchema(param.getMap("schema"), type, bs));
addParamExample(sm, param, PATH, type);
param.putIfAbsent("required", true);
@@ -387,7 +387,7 @@ public class BasicSwaggerProviderSession {
OMap om =
responses.getMap(String.valueOf(code), true);
merge(om, a);
OMap schema =
getSchema(om.getMap("schema"), m.getGenericReturnType(), bs);
-
eci.getAnnotations(Schema.class).forEach(x -> merge(schema, x));
+
eci.getAnnotations(Schema.class, x -> merge(schema, x));
pushupSchemaFields(RESPONSE, om, schema);
om.appendIf(true, true,
true, "schema", schema);
}
@@ -402,8 +402,8 @@ public class BasicSwaggerProviderSession {
String ha = a.name();
for (Integer code :
codes) {
OMap header =
responses.getMap(String.valueOf(code), true).getMap("headers", true).getMap(ha,
true);
-
ecmi.getAnnotations(Schema.class).forEach(x -> merge(header, x));
-
ecmi.getReturnType().unwrap(Value.class,Optional.class).getAnnotations(Schema.class).forEach(x
-> merge(header, x));
+
ecmi.getAnnotations(Schema.class, x -> merge(header, x));
+
ecmi.getReturnType().unwrap(Value.class,Optional.class).getAnnotations(Schema.class,
x -> merge(header, x));
pushupSchemaFields(RESPONSE_HEADER, header, getSchema(header.getMap("schema"),
ecmi.getReturnType().unwrap(Value.class,Optional.class).innerType(), bs));
}
}
@@ -420,7 +420,7 @@ public class BasicSwaggerProviderSession {
OMap om =
responses.getMap(String.valueOf(code), true);
merge(om, a);
OMap schema =
getSchema(om.getMap("schema"), m.getGenericReturnType(), bs);
-
mi.getAnnotations(Schema.class).forEach(x -> merge(schema, x));
+ mi.getAnnotations(Schema.class,
x -> merge(schema, x));
pushupSchemaFields(RESPONSE,
om, schema);
om.appendIf(true, true, true,
"schema", schema);
addBodyExamples(sm, om, true,
m.getGenericReturnType(), locale);
@@ -436,8 +436,8 @@ public class BasicSwaggerProviderSession {
if (! isMulti(a)) {
for (Integer
code : codes) {
OMap
header = responses.getMap(String.valueOf(code), true).getMap("headers",
true).getMap(ha, true);
-
ecmi.getAnnotations(Schema.class).forEach(x -> merge(header, x));
-
ecmi.getReturnType().unwrap(Value.class,Optional.class).getAnnotations(Schema.class).forEach(x
-> merge(header, x));
+
ecmi.getAnnotations(Schema.class, x -> merge(header, x));
+
ecmi.getReturnType().unwrap(Value.class,Optional.class).getAnnotations(Schema.class,
x -> merge(header, x));
merge(header, a.schema());
pushupSchemaFields(RESPONSE_HEADER, header, getSchema(header,
ecmi.getReturnType().innerType(), bs));
}
@@ -449,7 +449,7 @@ public class BasicSwaggerProviderSession {
OMap om = responses.getMap("200", true);
ClassInfo pt2 =
ClassInfo.of(m.getGenericReturnType());
OMap schema = getSchema(om.getMap("schema"),
m.getGenericReturnType(), bs);
- pt2.getAnnotations(Schema.class).forEach(x ->
merge(schema, x));
+ pt2.getAnnotations(Schema.class, x ->
merge(schema, x));
pushupSchemaFields(RESPONSE, om, schema);
om.appendIf(true, true, true, "schema", schema);
addBodyExamples(sm, om, true,
m.getGenericReturnType(), locale);
@@ -464,14 +464,14 @@ public class BasicSwaggerProviderSession {
List<Header> la =
AList.of(mpi.getAnnotations(Header.class)).a(pt.getAnnotations(Header.class));
List<StatusCode> la2 =
AList.of(mpi.getAnnotations(StatusCode.class)).a(pt.getAnnotations(StatusCode.class));
Set<Integer> codes = getCodes(la2, 200);
- String name =
HeaderAnnotation.findName(la).orElse(null);
+ String name =
HeaderAnnotation.findName(mpi).orElse(null);
Type type =
Value.unwrap(mpi.getParameterType().innerType());
for (Header a : la) {
if (! isMulti(a)) {
for (Integer code :
codes) {
OMap header =
responses.getMap(String.valueOf(code), true).getMap("headers",
true).getMap(name, true);
-
mpi.getAnnotations(Schema.class).forEach(x -> merge(header, x));
-
mpi.getParameterType().getAnnotations(Schema.class).forEach(x -> merge(header,
x));
+
mpi.getAnnotations(Schema.class, x -> merge(header, x));
+
mpi.getParameterType().getAnnotations(Schema.class, x -> merge(header, x));
merge(header,
a.schema());
pushupSchemaFields(RESPONSE_HEADER, header, getSchema(header, type, bs));
}
@@ -488,8 +488,8 @@ public class BasicSwaggerProviderSession {
OMap om =
responses.getMap(String.valueOf(code), true);
merge(om, a);
OMap schema =
getSchema(om.getMap("schema"), type, bs);
-
pt.getAnnotations(Schema.class).forEach(x -> merge(schema, x));
-
mpi.getAnnotations(Schema.class).forEach(x -> merge(schema, x));
+
pt.getAnnotations(Schema.class, x -> merge(schema, x));
+
mpi.getAnnotations(Schema.class, x -> merge(schema, x));
la.forEach(x ->
merge(schema, x.schema()));
pushupSchemaFields(RESPONSE, om, schema);
om.appendIf(true, true,
true, "schema", schema);
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/reflection/ExecutableInfoTest.java
b/juneau-utest/src/test/java/org/apache/juneau/reflection/ExecutableInfoTest.java
index 29ce29b..eb9defe 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/reflection/ExecutableInfoTest.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/reflection/ExecutableInfoTest.java
@@ -345,12 +345,6 @@ public class ExecutableInfoTest {
check("IOException", d_c.getExceptionTypes());
}
- @Test
- public void getRawExceptionTypes() {
- check("IOException", d_c.getRawExceptionTypes());
- check("IOException", d_m.getRawExceptionTypes());
- }
-
//-----------------------------------------------------------------------------------------------------------------
// Characteristics
//-----------------------------------------------------------------------------------------------------------------