AnnotatedElementUtils adapts post-processed values to AnnotationAttributes as well
Issue: SPR-12065
This commit is contained in:
@@ -40,7 +40,6 @@ public class AnnotatedElementUtils {
|
||||
public static Set<String> getMetaAnnotationTypes(AnnotatedElement element, String annotationType) {
|
||||
final Set<String> types = new LinkedHashSet<String>();
|
||||
process(element, annotationType, false, new Processor<Object>() {
|
||||
|
||||
@Override
|
||||
public Object process(Annotation annotation, int metaDepth) {
|
||||
if (metaDepth > 0) {
|
||||
@@ -48,7 +47,6 @@ public class AnnotatedElementUtils {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcess(Annotation annotation, Object result) {
|
||||
}
|
||||
@@ -101,7 +99,7 @@ public class AnnotatedElementUtils {
|
||||
if (!AnnotationUtils.VALUE.equals(key)) {
|
||||
Object value = AnnotationUtils.getValue(annotation, key);
|
||||
if (value != null) {
|
||||
result.put(key, value);
|
||||
result.put(key, AnnotationUtils.adaptValue(value, classValuesAsString, nestedAnnotationsAsMap));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -109,8 +107,7 @@ public class AnnotatedElementUtils {
|
||||
});
|
||||
}
|
||||
|
||||
public static MultiValueMap<String, Object> getAllAnnotationAttributes(AnnotatedElement element,
|
||||
String annotationType) {
|
||||
public static MultiValueMap<String, Object> getAllAnnotationAttributes(AnnotatedElement element, String annotationType) {
|
||||
return getAllAnnotationAttributes(element, annotationType, false, false);
|
||||
}
|
||||
|
||||
@@ -122,8 +119,8 @@ public class AnnotatedElementUtils {
|
||||
@Override
|
||||
public Void process(Annotation annotation, int metaDepth) {
|
||||
if (annotation.annotationType().getName().equals(annotationType)) {
|
||||
for (Map.Entry<String, Object> entry : AnnotationUtils.getAnnotationAttributes(annotation,
|
||||
classValuesAsString, nestedAnnotationsAsMap).entrySet()) {
|
||||
for (Map.Entry<String, Object> entry : AnnotationUtils.getAnnotationAttributes(
|
||||
annotation, classValuesAsString, nestedAnnotationsAsMap).entrySet()) {
|
||||
attributes.add(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
@@ -163,7 +160,7 @@ public class AnnotatedElementUtils {
|
||||
|
||||
try {
|
||||
return doProcess(element, annotationType, traverseClassHierarchy, processor,
|
||||
new HashSet<AnnotatedElement>(), 0);
|
||||
new HashSet<AnnotatedElement>(), 0);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new IllegalStateException("Failed to introspect annotations: " + element, ex);
|
||||
@@ -199,8 +196,8 @@ public class AnnotatedElementUtils {
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
result = doProcess(annotation.annotationType(), annotationType, traverseClassHierarchy, processor,
|
||||
visited, metaDepth + 1);
|
||||
result = doProcess(annotation.annotationType(), annotationType, traverseClassHierarchy,
|
||||
processor, visited, metaDepth + 1);
|
||||
if (result != null) {
|
||||
processor.postProcess(annotation, result);
|
||||
return result;
|
||||
@@ -210,7 +207,7 @@ public class AnnotatedElementUtils {
|
||||
for (Annotation annotation : annotations) {
|
||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)) {
|
||||
T result = doProcess(annotation.annotationType(), annotationType, traverseClassHierarchy,
|
||||
processor, visited, metaDepth);
|
||||
processor, visited, metaDepth);
|
||||
if (result != null) {
|
||||
processor.postProcess(annotation, result);
|
||||
return result;
|
||||
@@ -220,8 +217,7 @@ public class AnnotatedElementUtils {
|
||||
if (traverseClassHierarchy && element instanceof Class) {
|
||||
Class<?> superclass = ((Class<?>) element).getSuperclass();
|
||||
if (superclass != null && !superclass.equals(Object.class)) {
|
||||
T result = doProcess(superclass, annotationType, true, processor, visited,
|
||||
metaDepth);
|
||||
T result = doProcess(superclass, annotationType, true, processor, visited, metaDepth);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
@@ -247,7 +243,7 @@ public class AnnotatedElementUtils {
|
||||
* will have a depth of 2.
|
||||
* @param annotation the annotation to process
|
||||
* @param metaDepth the depth of the annotation relative to the initial element
|
||||
* @return the result of the processing or {@code null} to continue
|
||||
* @return the result of the processing, or {@code null} to continue
|
||||
*/
|
||||
T process(Annotation annotation, int metaDepth);
|
||||
|
||||
|
||||
@@ -578,34 +578,7 @@ public abstract class AnnotationUtils {
|
||||
if (method.getParameterTypes().length == 0 && method.getReturnType() != void.class) {
|
||||
try {
|
||||
Object value = method.invoke(annotation);
|
||||
if (classValuesAsString) {
|
||||
if (value instanceof Class) {
|
||||
value = ((Class<?>) value).getName();
|
||||
}
|
||||
else if (value instanceof Class[]) {
|
||||
Class<?>[] clazzArray = (Class[]) value;
|
||||
String[] newValue = new String[clazzArray.length];
|
||||
for (int i = 0; i < clazzArray.length; i++) {
|
||||
newValue[i] = clazzArray[i].getName();
|
||||
}
|
||||
value = newValue;
|
||||
}
|
||||
}
|
||||
if (nestedAnnotationsAsMap && value instanceof Annotation) {
|
||||
attrs.put(method.getName(),
|
||||
getAnnotationAttributes((Annotation) value, classValuesAsString, true));
|
||||
}
|
||||
else if (nestedAnnotationsAsMap && value instanceof Annotation[]) {
|
||||
Annotation[] realAnnotations = (Annotation[]) value;
|
||||
AnnotationAttributes[] mappedAnnotations = new AnnotationAttributes[realAnnotations.length];
|
||||
for (int i = 0; i < realAnnotations.length; i++) {
|
||||
mappedAnnotations[i] = getAnnotationAttributes(realAnnotations[i], classValuesAsString, true);
|
||||
}
|
||||
attrs.put(method.getName(), mappedAnnotations);
|
||||
}
|
||||
else {
|
||||
attrs.put(method.getName(), value);
|
||||
}
|
||||
attrs.put(method.getName(), adaptValue(value, classValuesAsString, nestedAnnotationsAsMap));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not obtain annotation attribute values", ex);
|
||||
@@ -615,6 +588,48 @@ public abstract class AnnotationUtils {
|
||||
return attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapt the given value according to the given class and nested annotation settings.
|
||||
* @param value the annotation attribute value
|
||||
* @param classValuesAsString whether to turn Class references into Strings (for
|
||||
* compatibility with {@link org.springframework.core.type.AnnotationMetadata}
|
||||
* or to preserve them as Class references
|
||||
* @param nestedAnnotationsAsMap whether to turn nested Annotation instances into
|
||||
* {@link AnnotationAttributes} maps (for compatibility with
|
||||
* {@link org.springframework.core.type.AnnotationMetadata} or to preserve them as
|
||||
* Annotation instances
|
||||
* @return the adapted value, or the original value if no adaptation is needed
|
||||
*/
|
||||
static Object adaptValue(Object value, boolean classValuesAsString, boolean nestedAnnotationsAsMap) {
|
||||
if (classValuesAsString) {
|
||||
if (value instanceof Class) {
|
||||
value = ((Class<?>) value).getName();
|
||||
}
|
||||
else if (value instanceof Class[]) {
|
||||
Class<?>[] clazzArray = (Class[]) value;
|
||||
String[] newValue = new String[clazzArray.length];
|
||||
for (int i = 0; i < clazzArray.length; i++) {
|
||||
newValue[i] = clazzArray[i].getName();
|
||||
}
|
||||
value = newValue;
|
||||
}
|
||||
}
|
||||
if (nestedAnnotationsAsMap && value instanceof Annotation) {
|
||||
return getAnnotationAttributes((Annotation) value, classValuesAsString, true);
|
||||
}
|
||||
else if (nestedAnnotationsAsMap && value instanceof Annotation[]) {
|
||||
Annotation[] realAnnotations = (Annotation[]) value;
|
||||
AnnotationAttributes[] mappedAnnotations = new AnnotationAttributes[realAnnotations.length];
|
||||
for (int i = 0; i < realAnnotations.length; i++) {
|
||||
mappedAnnotations[i] = getAnnotationAttributes(realAnnotations[i], classValuesAsString, true);
|
||||
}
|
||||
return mappedAnnotations;
|
||||
}
|
||||
else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the <em>value</em> of the {@code "value"} attribute of a
|
||||
* single-element Annotation, given an annotation instance.
|
||||
|
||||
Reference in New Issue
Block a user