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 a2eaca8 JUNEAU-197
a2eaca8 is described below
commit a2eaca8d0a8146f4f73adf8d29f620847ee7c099
Author: JamesBognar <[email protected]>
AuthorDate: Mon Mar 9 09:54:33 2020 -0400
JUNEAU-197
@BeanConfig(bpi) does not override @Bean(bpi)
---
.../org/apache/juneau/utils/ReflectionMapTest.java | 12 ++
.../main/java/org/apache/juneau/BeanContext.java | 180 ++++++++++++++-------
.../main/java/org/apache/juneau/MetaProvider.java | 80 +++++++--
.../org/apache/juneau/utils/ReflectionMap.java | 120 ++++++++++++++
4 files changed, 328 insertions(+), 64 deletions(-)
diff --git
a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/utils/ReflectionMapTest.java
b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/utils/ReflectionMapTest.java
index 4a9a499..9213d00 100644
---
a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/utils/ReflectionMapTest.java
+++
b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/utils/ReflectionMapTest.java
@@ -64,6 +64,18 @@ public class ReflectionMapTest {
assertFalse(A1_SIMPLE.find(c, Long.class).isPresent());
assertFalse(A1b_SIMPLE.find(c, Long.class).isPresent());
assertFalse(A1_FULL.find(c, Long.class).isPresent());
+
+ assertEquals(match_A1_SIMPLE, !A1_SIMPLE.findAll(c,
null).isEmpty());
+ assertEquals(match_A1b_SIMPLE, !A1b_SIMPLE.findAll(c,
null).isEmpty());
+ assertEquals(match_A1_FULL, !A1_FULL.findAll(c,
null).isEmpty());
+
+ assertEquals(match_A1_SIMPLE, !A1_SIMPLE.findAll(c,
Integer.class).isEmpty());
+ assertEquals(match_A1b_SIMPLE, !A1b_SIMPLE.findAll(c,
Integer.class).isEmpty());
+ assertEquals(match_A1_FULL, !A1_FULL.findAll(c,
Integer.class).isEmpty());
+
+ assertFalse(A1_SIMPLE.find(c, Long.class).isPresent());
+ assertFalse(A1b_SIMPLE.find(c, Long.class).isPresent());
+ assertFalse(A1_FULL.find(c, Long.class).isPresent());
}
@Test
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
index 0fb6e53..726265c 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
@@ -3228,24 +3228,33 @@ public class BeanContext extends Context implements
MetaProvider {
private static final boolean DISABLE_ANNOTATION_CACHING = !
Boolean.getBoolean("juneau.disableAnnotationCaching");
- private TwoKeyConcurrentCache<Class<?>,Class<? extends
Annotation>,Optional<Annotation>> classAnnotationCache = new
TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
- private TwoKeyConcurrentCache<Class<?>,Class<? extends
Annotation>,Optional<Annotation>> declaredClassAnnotationCache = new
TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
- private TwoKeyConcurrentCache<Method,Class<? extends
Annotation>,Optional<Annotation>> methodAnnotationCache = new
TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
- private TwoKeyConcurrentCache<Field,Class<? extends
Annotation>,Optional<Annotation>> fieldAnnotationCache = new
TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
- private TwoKeyConcurrentCache<Constructor<?>,Class<? extends
Annotation>,Optional<Annotation>> constructorAnnotationCache = new
TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
+ 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<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);
@Override /* MetaProvider */
- public <A extends Annotation> A getAnnotation(Class<A> a, Class<?> c) {
+ public <A extends Annotation> List<A> getAnnotations(Class<A> a,
Class<?> c) {
if (a == null || c == null)
- return null;
- if (DISABLE_ANNOTATION_CACHING)
- return (A)annotations.find(c,
a).orElse(c.getAnnotation(a));
- Optional<Annotation> aa = classAnnotationCache.get(c, a);
+ return emptyList();
+ List<Annotation> aa = classAnnotationCache.get(c, a);
if (aa == null) {
- aa = Optional.ofNullable((A)annotations.find(c,
a).orElse(c.getAnnotation(a)));
+ A x = c.getAnnotation(a);
+ List<Annotation> l = new ArrayList<>(x == null ? 0 : 1);
+ if (x != null)
+ l.add(x);
+ annotations.appendAll(c, a, l);
+ aa = unmodifiableList(l);
classAnnotationCache.put(c, a, aa);
}
- return (A)aa.orElse(null);
+ return (List<A>)aa;
+ }
+
+ @Override
+ public <A extends Annotation> A getAnnotation(Class<A> a, Class<?> c) {
+ List<A> aa = getAnnotations(a, c);
+ return aa.isEmpty() ? null : aa.get(0);
}
/**
@@ -3256,22 +3265,36 @@ public class BeanContext extends Context implements
MetaProvider {
* @param c The class to search on.
* @return The annotation, or <jk>null</jk> if not found.
*/
+ public <A extends Annotation> List<A> getAnnotations(Class<A> a,
ClassInfo c) {
+ return getAnnotations(a, c == null ? null : c.inner());
+ }
+
public <A extends Annotation> A getAnnotation(Class<A> a, ClassInfo c) {
- return getAnnotation(a, c == null ? null : c.inner());
+ List<A> aa = getAnnotations(a, c);
+ return aa.isEmpty() ? null : aa.get(0);
}
@Override /* MetaProvider */
- public <A extends Annotation> A getDeclaredAnnotation(Class<A> a,
Class<?> c) {
+ public <A extends Annotation> List<A> getDeclaredAnnotations(Class<A>
a, Class<?> c) {
if (a == null || c == null)
- return null;
- if (DISABLE_ANNOTATION_CACHING)
- return (A)annotations.find(c,
a).orElse(c.getDeclaredAnnotation(a));
- Optional<Annotation> aa = declaredClassAnnotationCache.get(c,
a);
+ return emptyList();
+ List<Annotation> aa = declaredClassAnnotationCache.get(c, a);
if (aa == null) {
- aa = Optional.ofNullable((A)annotations.find(c,
a).orElse(c.getDeclaredAnnotation(a)));
+ A x = c.getDeclaredAnnotation(a);
+ List<Annotation> l = new ArrayList<>(x == null ? 0 : 1);
+ if (x != null)
+ l.add(x);
+ annotations.appendAll(c, a, l);
+ aa = unmodifiableList(l);
declaredClassAnnotationCache.put(c, a, aa);
}
- return (A)aa.orElse(null);
+ return (List<A>)aa;
+ }
+
+ @Override
+ public <A extends Annotation> A getDeclaredAnnotation(Class<A> a,
Class<?> c) {
+ List<A> aa = getDeclaredAnnotations(a, c);
+ return aa.isEmpty() ? null : aa.get(0);
}
/**
@@ -3282,22 +3305,36 @@ public class BeanContext extends Context implements
MetaProvider {
* @param c The class to search on.
* @return The annotation, or <jk>null</jk> if not found.
*/
+ public <A extends Annotation> List<A> getDeclaredAnnotations(Class<A>
a, ClassInfo c) {
+ return getDeclaredAnnotations(a, c == null ? null : c.inner());
+ }
+
public <A extends Annotation> A getDeclaredAnnotation(Class<A> a,
ClassInfo c) {
- return getDeclaredAnnotation(a, c == null ? null : c.inner());
+ List<A> aa = getDeclaredAnnotations(a, c);
+ return aa.isEmpty() ? null : aa.get(0);
}
@Override /* MetaProvider */
- public <A extends Annotation> A getAnnotation(Class<A> a, Method m) {
+ public <A extends Annotation> List<A> getAnnotations(Class<A> a, Method
m) {
if (a == null || m == null)
- return null;
- if (DISABLE_ANNOTATION_CACHING)
- return (A)annotations.find(m,
a).orElse(m.getAnnotation(a));
- Optional<Annotation> aa = methodAnnotationCache.get(m, a);
+ return emptyList();
+ List<Annotation> aa = methodAnnotationCache.get(m, a);
if (aa == null) {
- aa = Optional.ofNullable((A)annotations.find(m,
a).orElse(m.getAnnotation(a)));
+ A x = m.getAnnotation(a);
+ List<Annotation> l = new ArrayList<>(x == null ? 0 : 1);
+ if (x != null)
+ l.add(x);
+ annotations.appendAll(m, a, l);
+ aa = unmodifiableList(l);
methodAnnotationCache.put(m, a, aa);
}
- return (A)aa.orElse(null);
+ return (List<A>)aa;
+ }
+
+ @Override
+ public <A extends Annotation> A getAnnotation(Class<A> a, Method m) {
+ List<A> aa = getAnnotations(a, m);
+ return aa.isEmpty() ? null : aa.get(0);
}
/**
@@ -3308,22 +3345,36 @@ public class BeanContext extends Context implements
MetaProvider {
* @param m The method to search on.
* @return The annotation, or <jk>null</jk> if not found.
*/
+ public <A extends Annotation> List<A> getAnnotations(Class<A> a,
MethodInfo m) {
+ return getAnnotations(a, m == null ? null : m.inner());
+ }
+
public <A extends Annotation> A getAnnotation(Class<A> a, MethodInfo m)
{
- return getAnnotation(a, m == null ? null : m.inner());
+ List<A> aa = getAnnotations(a, m);
+ return aa.isEmpty() ? null : aa.get(0);
}
@Override /* MetaProvider */
- public <A extends Annotation> A getAnnotation(Class<A> a, Field f) {
+ public <A extends Annotation> List<A> getAnnotations(Class<A> a, Field
f) {
if (a == null || f == null)
- return null;
- if (DISABLE_ANNOTATION_CACHING)
- return (A)annotations.find(f,
a).orElse(f.getAnnotation(a));
- Optional<Annotation> aa = fieldAnnotationCache.get(f, a);
+ return emptyList();
+ List<Annotation> aa = fieldAnnotationCache.get(f, a);
if (aa == null) {
- aa = Optional.ofNullable((A)annotations.find(f,
a).orElse(f.getAnnotation(a)));
+ A x = f.getAnnotation(a);
+ List<Annotation> l = new ArrayList<>(x == null ? 0 : 1);
+ if (x != null)
+ l.add(x);
+ annotations.appendAll(f, a, l);
+ aa = unmodifiableList(l);
fieldAnnotationCache.put(f, a, aa);
}
- return (A)aa.orElse(null);
+ return (List<A>)aa;
+ }
+
+ @Override
+ public <A extends Annotation> A getAnnotation(Class<A> a, Field f) {
+ List<A> aa = getAnnotations(a, f);
+ return aa.isEmpty() ? null : aa.get(0);
}
/**
@@ -3334,22 +3385,36 @@ public class BeanContext extends Context implements
MetaProvider {
* @param f The field to search on.
* @return The annotation, or <jk>null</jk> if not found.
*/
+ public <A extends Annotation> List<A> getAnnotations(Class<A> a,
FieldInfo f) {
+ return getAnnotations(a, f == null ? null: f.inner());
+ }
+
public <A extends Annotation> A getAnnotation(Class<A> a, FieldInfo f) {
- return getAnnotation(a, f == null ? null: f.inner());
+ List<A> aa = getAnnotations(a, f);
+ return aa.isEmpty() ? null : aa.get(0);
}
@Override /* MetaProvider */
- public <A extends Annotation> A getAnnotation(Class<A> a,
Constructor<?> c) {
+ public <A extends Annotation> List<A> getAnnotations(Class<A> a,
Constructor<?> c) {
if (a == null || c == null)
- return null;
- if (DISABLE_ANNOTATION_CACHING)
- return (A)annotations.find(c,
a).orElse(c.getAnnotation(a));
- Optional<Annotation> aa = constructorAnnotationCache.get(c, a);
+ return emptyList();
+ List<Annotation> aa = constructorAnnotationCache.get(c, a);
if (aa == null) {
- aa = Optional.ofNullable((A)annotations.find(c,
a).orElse(c.getAnnotation(a)));
+ A x = c.getAnnotation(a);
+ List<Annotation> l = new ArrayList<>(x == null ? 0 : 1);
+ if (x != null)
+ l.add(x);
+ annotations.appendAll(c, a, l);
+ aa = unmodifiableList(l);
constructorAnnotationCache.put(c, a, aa);
}
- return (A)aa.orElse(null);
+ return (List<A>)aa;
+ }
+
+ @Override
+ public <A extends Annotation> A getAnnotation(Class<A> a,
Constructor<?> c) {
+ List<A> aa = getAnnotations(a, c);
+ return aa.isEmpty() ? null : aa.get(0);
}
/**
@@ -3360,8 +3425,13 @@ public class BeanContext extends Context implements
MetaProvider {
* @param c The constructor to search on.
* @return The annotation, or <jk>null</jk> if not found.
*/
+ public <A extends Annotation> List<A> getAnnotations(Class<A> a,
ConstructorInfo c) {
+ return getAnnotations(a, c == null ? null : c.inner());
+ }
+
public <A extends Annotation> A getAnnotation(Class<A> a,
ConstructorInfo c) {
- return getAnnotation(a, c == null ? null : c.inner());
+ List<A> aa = getAnnotations(a, c);
+ return aa.isEmpty() ? null : aa.get(0);
}
/**
@@ -3372,7 +3442,7 @@ public class BeanContext extends Context implements
MetaProvider {
* @return <jk>true</jk> if the annotation exists on the specified
class.
*/
public <A extends Annotation> boolean hasAnnotation(Class<A> a,
Class<?> c) {
- return getAnnotation(a, c) != null;
+ return getAnnotations(a, c).size() > 0;
}
/**
@@ -3383,7 +3453,7 @@ public class BeanContext extends Context implements
MetaProvider {
* @return <jk>true</jk> if the annotation exists on the specified
class.
*/
public <A extends Annotation> boolean hasAnnotation(Class<A> a,
ClassInfo c) {
- return getAnnotation(a, c == null ? null : c.inner()) != null;
+ return getAnnotations(a, c == null ? null : c.inner()).size() >
0;
}
/**
@@ -3394,7 +3464,7 @@ public class BeanContext extends Context implements
MetaProvider {
* @return <jk>true</jk> if the annotation exists on the specified
class.
*/
public <A extends Annotation> boolean hasDeclaredAnnotation(Class<A> a,
Class<?> c) {
- return getDeclaredAnnotation(a, c) != null;
+ return getDeclaredAnnotations(a, c).size() > 0;
}
/**
@@ -3405,7 +3475,7 @@ public class BeanContext extends Context implements
MetaProvider {
* @return <jk>true</jk> if the annotation exists on the specified
class.
*/
public <A extends Annotation> boolean hasDeclaredAnnotation(Class<A> a,
ClassInfo c) {
- return getDeclaredAnnotation(a, c == null ? null : c.inner())
!= null;
+ return getDeclaredAnnotations(a, c == null ? null :
c.inner()).size() > 0;
}
/**
@@ -3416,7 +3486,7 @@ public class BeanContext extends Context implements
MetaProvider {
* @return <jk>true</jk> if the annotation exists on the specified
method.
*/
public <A extends Annotation> boolean hasAnnotation(Class<A> a, Method
m) {
- return getAnnotation(a, m) != null;
+ return getAnnotations(a, m).size() > 0;
}
/**
@@ -3427,7 +3497,7 @@ public class BeanContext extends Context implements
MetaProvider {
* @return <jk>true</jk> if the annotation exists on the specified
method.
*/
public <A extends Annotation> boolean hasAnnotation(Class<A> a,
MethodInfo m) {
- return getAnnotation(a, m == null ? null : m.inner()) != null;
+ return getAnnotations(a, m == null ? null : m.inner()).size() >
0;
}
/**
@@ -3438,7 +3508,7 @@ public class BeanContext extends Context implements
MetaProvider {
* @return <jk>true</jk> if the annotation exists on the specified
field.
*/
public <A extends Annotation> boolean hasAnnotation(Class<A> a, Field
f) {
- return getAnnotation(a, f) != null;
+ return getAnnotations(a, f).size() > 0;
}
/**
@@ -3449,7 +3519,7 @@ public class BeanContext extends Context implements
MetaProvider {
* @return <jk>true</jk> if the annotation exists on the specified
field.
*/
public <A extends Annotation> boolean hasAnnotation(Class<A> a,
FieldInfo f) {
- return getAnnotation(a, f == null ? null : f.inner()) != null;
+ return getAnnotations(a, f == null ? null : f.inner()).size() >
0;
}
/**
@@ -3460,7 +3530,7 @@ public class BeanContext extends Context implements
MetaProvider {
* @return <jk>true</jk> if the annotation exists on the specified
constructor.
*/
public <A extends Annotation> boolean hasAnnotation(Class<A> a,
Constructor<?> c) {
- return getAnnotation(a, c) != null;
+ return getAnnotations(a, c).size() > 0;
}
/**
@@ -3471,7 +3541,7 @@ public class BeanContext extends Context implements
MetaProvider {
* @return <jk>true</jk> if the annotation exists on the specified
constructor.
*/
public <A extends Annotation> boolean hasAnnotation(Class<A> a,
ConstructorInfo c) {
- return getAnnotation(a, c == null ? null : c.inner()) != null;
+ return getAnnotations(a, c == null ? null : c.inner()).size() >
0;
}
//-----------------------------------------------------------------------------------------------------------------
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 8454b2a..63a43c1 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
@@ -14,6 +14,8 @@ package org.apache.juneau;
import java.lang.annotation.*;
import java.lang.reflect.*;
+import java.util.*;
+import static java.util.Collections.*;
/**
* Parent interface for all class/method language-specific metadata providers.
@@ -26,28 +28,73 @@ public interface MetaProvider {
public static MetaProvider DEFAULT = new MetaProvider() {
@Override /* MetaProvider */
- public <A extends Annotation> A getAnnotation(Class<A> a,
Class<?> c) {
- return a == null || c == null ? null :
c.getAnnotation(a);
+ public <A extends Annotation> List<A> getAnnotations(Class<A>
a, Class<?> c) {
+ if (a == null || c == null)
+ return emptyList();
+ A aa = c.getAnnotation(a);
+ return aa == null ? emptyList() : singletonList(aa);
}
@Override /* MetaProvider */
- public <A extends Annotation> A getDeclaredAnnotation(Class<A>
a, Class<?> c) {
- return a == null || c == null ? null :
c.getDeclaredAnnotation(a);
+ public <A extends Annotation> List<A>
getDeclaredAnnotations(Class<A> a, Class<?> c) {
+ if (a == null || c == null)
+ return emptyList();
+ A aa = c.getDeclaredAnnotation(a);
+ return aa == null ? emptyList() : singletonList(aa);
}
@Override /* MetaProvider */
- public <A extends Annotation> A getAnnotation(Class<A> a,
Method m) {
- return a == null || m == null ? null :
m.getAnnotation(a);
+ public <A extends Annotation> List<A> getAnnotations(Class<A>
a, Method m) {
+ if (a == null || m == null)
+ return emptyList();
+ A aa = m.getAnnotation(a);
+ return aa == null ? emptyList() : singletonList(aa);
}
@Override /* MetaProvider */
- public <A extends Annotation> A getAnnotation(Class<A> a, Field
f) {
- return a == null || f == null ? null :
f.getAnnotation(a);
+ public <A extends Annotation> List<A> getAnnotations(Class<A>
a, Field f) {
+ if (a == null || f == null)
+ return emptyList();
+ A aa = f.getAnnotation(a);
+ return aa == null ? emptyList() : singletonList(aa);
}
@Override /* MetaProvider */
+ public <A extends Annotation> List<A> getAnnotations(Class<A>
a, Constructor<?> c) {
+ if (a == null || c == null)
+ return emptyList();
+ A aa = c.getAnnotation(a);
+ return aa == null ? emptyList() : singletonList(aa);
+ }
+
+ @Override
+ public <A extends Annotation> A getAnnotation(Class<A> a,
Class<?> c) {
+ List<A> l = getAnnotations(a, c);
+ return l.isEmpty() ? null : l.get(0);
+ }
+
+ @Override
+ public <A extends Annotation> A getDeclaredAnnotation(Class<A>
a, Class<?> c) {
+ List<A> l = getAnnotations(a, c);
+ return l.isEmpty() ? null : l.get(0);
+ }
+
+ @Override
+ public <A extends Annotation> A getAnnotation(Class<A> a,
Method m) {
+ List<A> l = getAnnotations(a, m);
+ return l.isEmpty() ? null : l.get(0);
+ }
+
+ @Override
+ public <A extends Annotation> A getAnnotation(Class<A> a, Field
f) {
+ List<A> l = getAnnotations(a, f);
+ return l.isEmpty() ? null : l.get(0);
+ }
+
+ @Override
public <A extends Annotation> A getAnnotation(Class<A> a,
Constructor<?> c) {
- return a == null || c == null ? null :
c.getAnnotation(a);
+ List<A> l = getAnnotations(a, c);
+ return l.isEmpty() ? null : l.get(0);
}
};
@@ -59,6 +106,9 @@ public interface MetaProvider {
* @param c The class to search on.
* @return The annotation, or <jk>null</jk> if not found.
*/
+ <A extends Annotation> List<A> getAnnotations(Class<A> a, Class<?> c);
+
+ // TEMPORARY
<A extends Annotation> A getAnnotation(Class<A> a, Class<?> c);
/**
@@ -69,6 +119,9 @@ public interface MetaProvider {
* @param c The class to search on.
* @return The annotation, or <jk>null</jk> if not found.
*/
+ <A extends Annotation> List<A> getDeclaredAnnotations(Class<A> a,
Class<?> c);
+
+ // TEMPORARY
<A extends Annotation> A getDeclaredAnnotation(Class<A> a, Class<?> c);
/**
@@ -79,6 +132,9 @@ public interface MetaProvider {
* @param m The method to search on.
* @return The annotation, or <jk>null</jk> if not found.
*/
+ <A extends Annotation> List<A> getAnnotations(Class<A> a, Method m);
+
+ // TEMPORARY
<A extends Annotation> A getAnnotation(Class<A> a, Method m);
/**
@@ -89,6 +145,9 @@ public interface MetaProvider {
* @param f The field to search on.
* @return The annotation, or <jk>null</jk> if not found.
*/
+ <A extends Annotation> List<A> getAnnotations(Class<A> a, Field f);
+
+ // TEMPORARY
<A extends Annotation> A getAnnotation(Class<A> a, Field f);
/**
@@ -99,5 +158,8 @@ public interface MetaProvider {
* @param c The constructor to search on.
* @return The annotation, or <jk>null</jk> if not found.
*/
+ <A extends Annotation> List<A> getAnnotations(Class<A> a,
Constructor<?> c);
+
+ // TEMPORARY
<A extends Annotation> A getAnnotation(Class<A> a, Constructor<?> c);
}
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/ReflectionMap.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/ReflectionMap.java
index 85aa2d0..85150b4 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/ReflectionMap.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/ReflectionMap.java
@@ -263,6 +263,36 @@ public class ReflectionMap<V> {
}
/**
+ * Finds all values in this map that matches the specified class.
+ *
+ * @param c The class to test for.
+ * @param ofType Only return objects of the specified type.
+ * @return A modifiable list of matching values. Never <jk>null</jk>.
+ */
+ public List<V> findAll(Class<?> c, Class<? extends V> ofType) {
+ return appendAll(c, ofType, null);
+ }
+
+ /**
+ * Finds all values in this map that matches the specified class.
+ *
+ * @param c The class to test for.
+ * @param ofType Only return objects of the specified type.
+ * @param l The list to append values to. Can be <jk>null</jk>.
+ * @return The same list passed in or a new modifiable list if
<jk>null</jk>.
+ */
+ public List<V> appendAll(Class<?> c, Class<? extends V> ofType, List<V>
l) {
+ if (l == null)
+ l = AList.create();
+ if (! noClassEntries)
+ for (ClassEntry<V> e : classEntries)
+ if (e.matches(c))
+ if (ofType == null ||
ofType.isInstance(e.value))
+ l.add(e.value);
+ return l;
+ }
+
+ /**
* Finds first value in this map that matches the specified method.
*
* @param m The method to test for.
@@ -279,6 +309,36 @@ public class ReflectionMap<V> {
}
/**
+ * Finds all values in this map that matches the specified method.
+ *
+ * @param m The method to test for.
+ * @param ofType Only return objects of the specified type.
+ * @return A modifiable list of matching values. Never <jk>null</jk>.
+ */
+ public List<V> findAll(Method m, Class<? extends V> ofType) {
+ return appendAll(m, ofType, null);
+ }
+
+ /**
+ * Finds all values in this map that matches the specified method.
+ *
+ * @param m The method to test for.
+ * @param ofType Only return objects of the specified type.
+ * @param l The list to append values to. Can be <jk>null</jk>.
+ * @return The same list passed in or a new modifiable list if
<jk>null</jk>.
+ */
+ public List<V> appendAll(Method m, Class<? extends V> ofType, List<V>
l) {
+ if (l == null)
+ l = AList.create();
+ if (! noMethodEntries)
+ for (MethodEntry<V> e : methodEntries)
+ if (e.matches(m))
+ if (ofType == null ||
ofType.isInstance(e.value))
+ l.add(e.value);
+ return l;
+ }
+
+ /**
* Finds first value in this map that matches the specified field.
*
* @param f The field to test for.
@@ -295,6 +355,36 @@ public class ReflectionMap<V> {
}
/**
+ * Finds all values in this map that matches the specified field.
+ *
+ * @param f The field to test for.
+ * @param ofType Only return objects of the specified type.
+ * @return A modifiable list of matching values. Never <jk>null</jk>.
+ */
+ public List<V> findAll(Field f, Class<? extends V> ofType) {
+ return appendAll(f, ofType, null);
+ }
+
+ /**
+ * Finds all values in this map that matches the specified field.
+ *
+ * @param f The field to test for.
+ * @param ofType Only return objects of the specified type.
+ * @param l The list to append values to. Can be <jk>null</jk>.
+ * @return The same list passed in or a new modifiable list if
<jk>null</jk>.
+ */
+ public List<V> appendAll(Field f, Class<? extends V> ofType, List<V> l)
{
+ if (l == null)
+ l = AList.create();
+ if (! noFieldEntries)
+ for (FieldEntry<V> e : fieldEntries)
+ if (e.matches(f))
+ if (ofType == null ||
ofType.isInstance(e.value))
+ l.add(e.value);
+ return l == null ? new ArrayList<>(0) : l;
+ }
+
+ /**
* Finds first value in this map that matches the specified constructor.
*
* @param c The constructor to test for.
@@ -310,6 +400,36 @@ public class ReflectionMap<V> {
return Optional.empty();
}
+ /**
+ * Finds all values in this map that matches the specified constructor.
+ *
+ * @param c The constructor to test for.
+ * @param ofType Only return objects of the specified type.
+ * @return A modifiable list of matching values. Never <jk>null</jk>.
+ */
+ public List<V> findAll(Constructor<?> c, Class<? extends V> ofType) {
+ return appendAll(c, ofType, null);
+ }
+
+ /**
+ * Finds all values in this map that matches the specified constructor.
+ *
+ * @param c The constructor to test for.
+ * @param ofType Only return objects of the specified type.
+ * @param l The list to append values to. Can be <jk>null</jk>.
+ * @return The same list passed in or a new modifiable list if
<jk>null</jk>.
+ */
+ public List<V> appendAll(Constructor<?> c, Class<? extends V> ofType,
List<V> l) {
+ if (l == null)
+ l = AList.create();
+ if (! noConstructorEntries)
+ for (ConstructorEntry<V> e : constructorEntries)
+ if (e.matches(c))
+ if (ofType == null ||
ofType.isInstance(e.value))
+ l.add(e.value);
+ return l;
+ }
+
static class ClassEntry<V> {
final String simpleName, fullName;
final V value;