AnnotationMetadata returns Class values by default (again), allowing for explicit retrieval of String class names where preferred (SPR-5827)
This commit is contained in:
@@ -286,20 +286,20 @@ public abstract class AnnotationUtils {
|
||||
/**
|
||||
* Retrieve the given annotation's attributes as a Map.
|
||||
* @param annotation the annotation to retrieve the attributes for
|
||||
* @param filterClasses whether to turn Class references into Strings
|
||||
* @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
|
||||
* @return the Map of annotation attributes, with attribute names as keys
|
||||
* and corresponding attribute values as values
|
||||
*/
|
||||
public static Map<String, Object> getAnnotationAttributes(Annotation annotation, boolean filterClasses) {
|
||||
public static Map<String, Object> getAnnotationAttributes(Annotation annotation, boolean classValuesAsString) {
|
||||
Map<String, Object> attrs = new HashMap<String, Object>();
|
||||
Method[] methods = annotation.annotationType().getDeclaredMethods();
|
||||
for (Method method : methods) {
|
||||
if (method.getParameterTypes().length == 0 && method.getReturnType() != void.class) {
|
||||
try {
|
||||
Object value = method.invoke(annotation);
|
||||
if (filterClasses) {
|
||||
if (classValuesAsString) {
|
||||
if (value instanceof Class) {
|
||||
value = ((Class) value).getName();
|
||||
}
|
||||
|
||||
@@ -83,6 +83,20 @@ public interface AnnotationMetadata extends ClassMetadata {
|
||||
*/
|
||||
Map<String, Object> getAnnotationAttributes(String annotationType);
|
||||
|
||||
/**
|
||||
* Retrieve the attributes of the annotation of the given type,
|
||||
* if any (i.e. if defined on the underlying class, as direct
|
||||
* annotation or as meta-annotation).
|
||||
* @param annotationType the annotation type to look for
|
||||
* @param classValuesAsString whether to convert class references to String
|
||||
* class names for exposure as values in the returned Map, instead of Class
|
||||
* references which might potentially have to be loaded first
|
||||
* @return a Map of attributes, with the attribute name as key (e.g. "value")
|
||||
* and the defined attribute value as Map value. This return value will be
|
||||
* <code>null</code> if no matching annotation is defined.
|
||||
*/
|
||||
Map<String, Object> getAnnotationAttributes(String annotationType, boolean classValuesAsString);
|
||||
|
||||
/**
|
||||
* Determine whether the underlying class has any methods that are
|
||||
* annotated (or meta-annotated) with the given annotation type.
|
||||
|
||||
@@ -114,14 +114,18 @@ public class StandardAnnotationMetadata extends StandardClassMetadata implements
|
||||
}
|
||||
|
||||
public Map<String, Object> getAnnotationAttributes(String annotationType) {
|
||||
return getAnnotationAttributes(annotationType, false);
|
||||
}
|
||||
|
||||
public Map<String, Object> getAnnotationAttributes(String annotationType, boolean classValuesAsString) {
|
||||
Annotation[] anns = getIntrospectedClass().getAnnotations();
|
||||
for (Annotation ann : anns) {
|
||||
if (ann.annotationType().getName().equals(annotationType)) {
|
||||
return AnnotationUtils.getAnnotationAttributes(ann, true);
|
||||
return AnnotationUtils.getAnnotationAttributes(ann, classValuesAsString);
|
||||
}
|
||||
for (Annotation metaAnn : ann.annotationType().getAnnotations()) {
|
||||
if (metaAnn.annotationType().getName().equals(annotationType)) {
|
||||
return AnnotationUtils.getAnnotationAttributes(metaAnn, true);
|
||||
return AnnotationUtils.getAnnotationAttributes(metaAnn, classValuesAsString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,11 +63,7 @@ final class AnnotationAttributesReadingVisitor implements AnnotationVisitor {
|
||||
|
||||
|
||||
public void visit(String name, Object value) {
|
||||
Object valueToUse = value;
|
||||
if (valueToUse instanceof Type) {
|
||||
valueToUse = ((Type) value).getClassName();
|
||||
}
|
||||
this.localAttributes.put(name, valueToUse);
|
||||
this.localAttributes.put(name, value);
|
||||
}
|
||||
|
||||
public void visitEnum(String name, String desc, String value) {
|
||||
@@ -93,9 +89,6 @@ final class AnnotationAttributesReadingVisitor implements AnnotationVisitor {
|
||||
return new AnnotationVisitor() {
|
||||
public void visit(String name, Object value) {
|
||||
Object newValue = value;
|
||||
if (newValue instanceof Type) {
|
||||
newValue = ((Type) value).getClassName();
|
||||
}
|
||||
Object existingValue = localAttributes.get(attrName);
|
||||
if (existingValue != null) {
|
||||
newValue = ObjectUtils.addObjectToArray((Object[]) existingValue, newValue);
|
||||
|
||||
@@ -97,7 +97,38 @@ final class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor
|
||||
}
|
||||
|
||||
public Map<String, Object> getAnnotationAttributes(String annotationType) {
|
||||
return this.attributeMap.get(annotationType);
|
||||
return getAnnotationAttributes(annotationType, false);
|
||||
}
|
||||
|
||||
public Map<String, Object> getAnnotationAttributes(String annotationType, boolean classValuesAsString) {
|
||||
Map<String, Object> raw = this.attributeMap.get(annotationType);
|
||||
if (raw == null) {
|
||||
return null;
|
||||
}
|
||||
Map<String, Object> result = new LinkedHashMap<String, Object>(raw.size());
|
||||
for (Map.Entry<String, Object> entry : raw.entrySet()) {
|
||||
try {
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof Type) {
|
||||
value = (classValuesAsString ? ((Type) value).getClassName() :
|
||||
this.classLoader.loadClass(((Type) value).getClassName()));
|
||||
}
|
||||
else if (value instanceof Type[]) {
|
||||
Type[] array = (Type[]) value;
|
||||
Object[] convArray = (classValuesAsString ? new String[array.length] : new Class[array.length]);
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
convArray[i] = (classValuesAsString ? array[i].getClassName() :
|
||||
this.classLoader.loadClass(array[i].getClassName()));
|
||||
}
|
||||
value = convArray;
|
||||
}
|
||||
result.put(entry.getKey(), value);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Class not found - can't resolve class reference in annotation attribute.
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean hasAnnotatedMethods(String annotationType) {
|
||||
|
||||
Reference in New Issue
Block a user