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;

Reply via email to