JUNEAU-169 Dynamic annotations.
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/reflection/ExecutableInfoTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/reflection/ExecutableInfoTest.java
index dd90556..7fe6310 100644
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/reflection/ExecutableInfoTest.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/reflection/ExecutableInfoTest.java
@@ -288,10 +288,12 @@
public @CA void m(int bar) {}
}
static ClassInfo c = ClassInfo.of(C.class);
- static ExecutableInfo
+ static ConstructorInfo
c_c1=c.getPublicConstructor(),
c_c2=c.getPublicConstructor(String.class),
- c_c3=c.getPublicConstructor(int.class),
+ c_c3=c.getPublicConstructor(int.class)
+ ;
+ static MethodInfo
c_m1=c.getPublicMethod("m"),
c_m2=c.getPublicMethod("m", String.class),
c_m3=c.getPublicMethod("m", int.class)
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/reflection/MethodInfoTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/reflection/MethodInfoTest.java
index 7341438..2c117ed 100644
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/reflection/MethodInfoTest.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/reflection/MethodInfoTest.java
@@ -259,11 +259,11 @@
@Test
public void getAnnotationAny() {
- check("@A(a1)", c_a1.getAnnotation(AX.class, A.class));
- check("@A(a2b)", c_a2.getAnnotation(AX.class, A.class));
- check("@A(a3)", c_a3.getAnnotation(AX.class, A.class));
- check("@A(a4)", c_a4.getAnnotation(AX.class, A.class));
- check(null, c_a5.getAnnotation(AX.class, A.class));
+ check("@A(a1)", c_a1.getAnyAnnotation(AX.class, A.class));
+ check("@A(a2b)", c_a2.getAnyAnnotation(AX.class, A.class));
+ check("@A(a3)", c_a3.getAnyAnnotation(AX.class, A.class));
+ check("@A(a4)", c_a4.getAnyAnnotation(AX.class, A.class));
+ check(null, c_a5.getAnyAnnotation(AX.class, A.class));
}
@Test
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/InvalidAnnotationException.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/InvalidAnnotationException.java
index b067148..f4367ed 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/InvalidAnnotationException.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/InvalidAnnotationException.java
@@ -44,7 +44,7 @@
*/
@SafeVarargs
public static void assertNoInvalidAnnotations(MethodInfo m, Class<? extends Annotation>...a) throws InvalidAnnotationException {
- Annotation aa = m.getAnnotation(a);
+ Annotation aa = m.getAnyAnnotation(a);
if (aa != null)
throw new InvalidAnnotationException("@{0} annotation cannot be used in a @{1} bean. Method=''{2}''", aa.getClass().getSimpleName(), m.getDeclaringClass().getSimpleName(), m);
}
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 1c9d706..804df44 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
@@ -947,7 +947,7 @@
*
* @param a
* The annotation to search for.
- * @param mp The metadata provider for finding annotations on classes and methods.
+ * @param mp The meta provider for looking up annotations on reflection objects (classes, methods, fields, constructors).
* @return
* The annotation if found, or <jk>null</jk> if not.
*/
@@ -991,7 +991,7 @@
*
* @param <T> The annotation class type.
* @param a The annotation class.
- * @param mp The metadata provider for finding annotations on classes and methods.
+ * @param mp The meta provider for looking up annotations on reflection objects (classes, methods, fields, constructors).
* @return The annotation, or <jk>null</jk> if not found.
*/
public <T extends Annotation> T getDeclaredAnnotation(Class<T> a, MetaProvider mp) {
@@ -1049,7 +1049,7 @@
*
* @param <T> The annotation to search for.
* @param a The annotation to search for.
- * @param mp The metadata provider for finding annotations.
+ * @param mp The meta provider for looking up annotations on reflection objects (classes, methods, fields, constructors).
* @return
* A list of all matching annotations found in child-to-parent order, or an empty list if none found.
*/
@@ -1074,7 +1074,7 @@
*
* @param a
* The annotation to search for.
- * @param mp The metadata provider for finding annotations.
+ * @param mp The meta provider for looking up annotations on reflection objects (classes, methods, fields, constructors).
* @return
* A list of all matching annotations found or an empty list if none found.
*/
@@ -1189,7 +1189,7 @@
* @param <T> The annotation to search for.
* @param l The list of annotations.
* @param a The annotation to search for.
- * @param mp The metadata provider for finding annotations on classes and methods.
+ * @param mp The meta provider for looking up annotations on reflection objects (classes, methods, fields, constructors).
* @return The same list.
*/
public <T extends Annotation> List<T> appendAnnotations(List<T> l, Class<T> a, MetaProvider mp) {
@@ -1237,7 +1237,7 @@
*
* @param l The list of annotations.
* @param a The annotation to search for.
- * @param mp The metadata provider for finding annotations on classes and methods.
+ * @param mp The meta provider for looking up annotations on reflection objects (classes, methods, fields, constructors).
* @return The same list.
*/
public <T extends Annotation> List<T> appendAnnotationsParentFirst(List<T> l, Class<T> a, MetaProvider mp) {
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ConstructorInfo.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ConstructorInfo.java
index 36c01b9..1a81b60 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ConstructorInfo.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ConstructorInfo.java
@@ -12,6 +12,7 @@
// ***************************************************************************************************************************
package org.apache.juneau.reflect;
+import java.lang.annotation.*;
import java.lang.reflect.*;
import org.apache.juneau.*;
@@ -77,6 +78,48 @@
return (Constructor<T>)c;
}
+
+ //-----------------------------------------------------------------------------------------------------------------
+ // Annotations
+ //-----------------------------------------------------------------------------------------------------------------
+
+ /**
+ * Finds the annotation of the specified type defined on this constructor.
+ *
+ * @param a
+ * The annotation to search for.
+ * @return
+ * The annotation if found, or <jk>null</jk> if not.
+ */
+ public final <T extends Annotation> T getAnnotation(Class<T> a) {
+ return getAnnotation(a, MetaProvider.DEFAULT);
+ }
+
+ /**
+ * Finds the annotation of the specified type defined on this constructor.
+ *
+ * @param a
+ * The annotation to search for.
+ * @param mp
+ * The meta provider for looking up annotations on classes/methods/fields.
+ * @return
+ * The first annotation found, or <jk>null</jk> if it doesn't exist.
+ */
+ public final <T extends Annotation> T getAnnotation(Class<T> a, MetaProvider mp) {
+ return mp.getAnnotation(a, c);
+ }
+
+ /**
+ * Returns <jk>true</jk> if the specified annotation is present on this constructor.
+ *
+ * @param a The annotation to check for.
+ * @return <jk>true</jk> if the specified annotation is present on this constructor.
+ */
+ public final boolean hasAnnotation(Class<? extends Annotation> a) {
+ return getAnnotation(a) != null;
+ }
+
+
//-----------------------------------------------------------------------------------------------------------------
// Other methods
//-----------------------------------------------------------------------------------------------------------------
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 08313e4..08d84f1 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
@@ -17,7 +17,6 @@
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.util.*;
-import java.util.concurrent.*;
import org.apache.juneau.*;
import org.apache.juneau.internal.*;
@@ -36,7 +35,6 @@
private Class<?>[] rawParamTypes, rawExceptionTypes;
private Type[] rawGenericParamTypes;
private Parameter[] rawParameters;
- private Map<Class<?>,Optional<Annotation>> annotationMap;
/**
* Constructor.
@@ -303,57 +301,6 @@
return e.getParameterAnnotations()[index];
}
- /**
- * Returns <jk>true</jk> if the specified annotation is present on this method.
- *
- * @param a The annotation to check for.
- * @return <jk>true</jk> if the specified annotation is present on this method.
- */
- public final boolean hasAnnotation(Class<? extends Annotation> a) {
- return getAnnotation(a) != null;
- }
-
- /**
- * Finds the annotation of the specified type defined on this executable.
- *
- * <p>
- * If this is a method and the annotation cannot be found on the immediate method, searches methods with the same
- * signature on the parent classes or interfaces.
- * <br>The search is performed in child-to-parent order.
- *
- * @param a
- * The annotation to search for.
- * @return
- * The annotation if found, or <jk>null</jk> if not.
- */
- @SuppressWarnings("unchecked")
- public final <T extends Annotation> T getAnnotation(Class<T> a) {
- if (a == null)
- return null;
- Optional<Annotation> o = annotationMap().get(a);
- if (o == null) {
- o = Optional.ofNullable(findAnnotation(a));
- annotationMap().put(a, o);
- }
- return o.isPresent() ? (T)o.get() : null;
- }
-
- /**
- * Searched for the specified annotation on the method.
- *
- * @param a The annotation to search for on the method.
- * @return The annotation if found.
- */
- protected <T extends Annotation> T findAnnotation(Class<T> a) {
- return e.getAnnotation(a);
- }
-
- private synchronized Map<Class<?>,Optional<Annotation>> annotationMap() {
- if (annotationMap == null)
- annotationMap = new ConcurrentHashMap<>();
- return annotationMap;
- }
-
//-----------------------------------------------------------------------------------------------------------------
// Exceptions
//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/FieldInfo.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/FieldInfo.java
index 055641a..3a39b0a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/FieldInfo.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/FieldInfo.java
@@ -98,9 +98,18 @@
* @return The annotation, or <jk>null</jk> if not found.
*/
public <T extends Annotation> T getAnnotation(Class<T> a) {
- if (a == null)
- return null;
- return f.getAnnotation(a);
+ return getAnnotation(a, MetaProvider.DEFAULT);
+ }
+
+ /**
+ * Returns the specified annotation on this field.
+ *
+ * @param a The annotation to look for.
+ * @param mp The meta provider for looking up annotations on reflection objects (classes, methods, fields, constructors).
+ * @return The annotation, or <jk>null</jk> if not found.
+ */
+ public <T extends Annotation> T getAnnotation(Class<T> a, MetaProvider mp) {
+ return mp.getAnnotation(a, f);
}
/**
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 0cac994..3bbbe6e 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
@@ -151,6 +151,58 @@
//-----------------------------------------------------------------------------------------------------------------
/**
+ * Finds the annotation of the specified type defined on this method.
+ *
+ * <p>
+ * If this is a method and the annotation cannot be found on the immediate method, searches methods with the same
+ * signature on the parent classes or interfaces.
+ * <br>The search is performed in child-to-parent order.
+ *
+ * @param a
+ * The annotation to search for.
+ * @return
+ * The annotation if found, or <jk>null</jk> if not.
+ */
+ public final <T extends Annotation> T getAnnotation(Class<T> a) {
+ return getAnnotation(a, MetaProvider.DEFAULT);
+ }
+
+ /**
+ * Finds the annotation of the specified type defined on this method.
+ *
+ * <p>
+ * Searches all methods with the same signature on the parent classes or interfaces
+ * and the return type on the method.
+ *
+ * @param a
+ * The annotation to search for.
+ * @param mp
+ * The meta provider for looking up annotations on classes/methods/fields.
+ * @return
+ * The first annotation found, or <jk>null</jk> if it doesn't exist.
+ */
+ public final <T extends Annotation> T getAnnotation(Class<T> a, MetaProvider mp) {
+ if (a == null)
+ return null;
+ for (Method m2 : getMatching()) {
+ T t = mp.getAnnotation(a, m2);
+ if (t != null)
+ return t;
+ }
+ return null;
+ }
+
+ /**
+ * Returns <jk>true</jk> if the specified annotation is present on this method.
+ *
+ * @param a The annotation to check for.
+ * @return <jk>true</jk> if the specified annotation is present on this method.
+ */
+ public final boolean hasAnnotation(Class<? extends Annotation> a) {
+ return getAnnotation(a) != null;
+ }
+
+ /**
* Returns all annotations of the specified type defined on the specified method.
*
* <p>
@@ -226,7 +278,7 @@
* @return <jk>true</jk> if this method does not have any of the specified annotations.
*/
@SafeVarargs
- public final Annotation getAnnotation(Class<? extends Annotation>...c) {
+ public final Annotation getAnyAnnotation(Class<? extends Annotation>...c) {
for (Class<? extends Annotation> cc : c) {
Annotation a = getAnnotation(cc);
if (a != null)
@@ -304,16 +356,6 @@
return false;
}
- @Override
- @SuppressWarnings("unchecked")
- protected <T extends Annotation> T findAnnotation(Class<T> a) {
- for (Method m2 : getMatching())
- for (Annotation a2 : m2.getAnnotations())
- if (a.isInstance(a2))
- return (T)a2;
- return null;
- }
-
AnnotationList appendAnnotationList(AnnotationList al) {
ClassInfo c = this.declaringClass;
for (ClassInfo ci : c.getParents()) {
@@ -387,7 +429,7 @@
/**
* Returns the generic return type of this method as a {@link ClassInfo} object.
- *
+ *
* <p>
* Unwraps the type if it's a {@link Value}.
*