diff options
Diffstat (limited to 'spring-core/src/main/java/org/springframework/core/type/classreading')
7 files changed, 64 insertions, 100 deletions
diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/AbstractRecursiveAnnotationVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/AbstractRecursiveAnnotationVisitor.java index 2cc12717..bd42e059 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/AbstractRecursiveAnnotationVisitor.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/AbstractRecursiveAnnotationVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,7 +58,7 @@ abstract class AbstractRecursiveAnnotationVisitor extends AnnotationVisitor { @Override public AnnotationVisitor visitAnnotation(String attributeName, String asmTypeDescriptor) { String annotationType = Type.getType(asmTypeDescriptor).getClassName(); - AnnotationAttributes nestedAttributes = new AnnotationAttributes(); + AnnotationAttributes nestedAttributes = new AnnotationAttributes(annotationType, this.classLoader); this.attributes.put(attributeName, nestedAttributes); return new RecursiveAnnotationAttributesVisitor(annotationType, nestedAttributes, this.classLoader); } diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java index ab001b50..f35ecd68 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java @@ -44,8 +44,6 @@ import org.springframework.util.ObjectUtils; */ final class AnnotationAttributesReadingVisitor extends RecursiveAnnotationAttributesVisitor { - private final String annotationType; - private final MultiValueMap<String, AnnotationAttributes> attributesMap; private final Map<String, Set<String>> metaAnnotationMap; @@ -55,38 +53,41 @@ final class AnnotationAttributesReadingVisitor extends RecursiveAnnotationAttrib MultiValueMap<String, AnnotationAttributes> attributesMap, Map<String, Set<String>> metaAnnotationMap, ClassLoader classLoader) { - super(annotationType, new AnnotationAttributes(), classLoader); - this.annotationType = annotationType; + super(annotationType, new AnnotationAttributes(annotationType, classLoader), classLoader); this.attributesMap = attributesMap; this.metaAnnotationMap = metaAnnotationMap; } @Override - public void doVisitEnd(Class<?> annotationClass) { - super.doVisitEnd(annotationClass); - List<AnnotationAttributes> attributes = this.attributesMap.get(this.annotationType); - if (attributes == null) { - this.attributesMap.add(this.annotationType, this.attributes); - } - else { - attributes.add(0, this.attributes); - } - Set<Annotation> visited = new LinkedHashSet<Annotation>(); - Annotation[] metaAnnotations = AnnotationUtils.getAnnotations(annotationClass); - if (!ObjectUtils.isEmpty(metaAnnotations)) { - for (Annotation metaAnnotation : metaAnnotations) { - if (!AnnotationUtils.isInJavaLangAnnotationPackage(metaAnnotation)) { - recursivelyCollectMetaAnnotations(visited, metaAnnotation); + public void visitEnd() { + super.visitEnd(); + + Class<?> annotationClass = this.attributes.annotationType(); + if (annotationClass != null) { + List<AnnotationAttributes> attributeList = this.attributesMap.get(this.annotationType); + if (attributeList == null) { + this.attributesMap.add(this.annotationType, this.attributes); + } + else { + attributeList.add(0, this.attributes); + } + Set<Annotation> visited = new LinkedHashSet<Annotation>(); + Annotation[] metaAnnotations = AnnotationUtils.getAnnotations(annotationClass); + if (!ObjectUtils.isEmpty(metaAnnotations)) { + for (Annotation metaAnnotation : metaAnnotations) { + if (!AnnotationUtils.isInJavaLangAnnotationPackage(metaAnnotation)) { + recursivelyCollectMetaAnnotations(visited, metaAnnotation); + } } } - } - if (this.metaAnnotationMap != null) { - Set<String> metaAnnotationTypeNames = new LinkedHashSet<String>(visited.size()); - for (Annotation ann : visited) { - metaAnnotationTypeNames.add(ann.annotationType().getName()); + if (this.metaAnnotationMap != null) { + Set<String> metaAnnotationTypeNames = new LinkedHashSet<String>(visited.size()); + for (Annotation ann : visited) { + metaAnnotationTypeNames.add(ann.annotationType().getName()); + } + this.metaAnnotationMap.put(annotationClass.getName(), metaAnnotationTypeNames); } - this.metaAnnotationMap.put(annotationClass.getName(), metaAnnotationTypeNames); } } diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java index eea3d825..3b3a17dd 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java @@ -131,7 +131,8 @@ public class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisito public AnnotationAttributes getAnnotationAttributes(String annotationName, boolean classValuesAsString) { AnnotationAttributes raw = AnnotationReadingVisitorUtils.getMergedAnnotationAttributes( this.attributesMap, this.metaAnnotationMap, annotationName); - return AnnotationReadingVisitorUtils.convertClassValues(this.classLoader, raw, classValuesAsString); + return AnnotationReadingVisitorUtils.convertClassValues( + "class '" + getClassName() + "'", this.classLoader, raw, classValuesAsString); } @Override @@ -148,7 +149,7 @@ public class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisito } for (AnnotationAttributes raw : attributes) { for (Map.Entry<String, Object> entry : AnnotationReadingVisitorUtils.convertClassValues( - this.classLoader, raw, classValuesAsString).entrySet()) { + "class '" + getClassName() + "'", this.classLoader, raw, classValuesAsString).entrySet()) { allAttributes.add(entry.getKey(), entry.getValue()); } } diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationReadingVisitorUtils.java b/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationReadingVisitorUtils.java index 0d7ba35f..93c3e76d 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationReadingVisitorUtils.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationReadingVisitorUtils.java @@ -41,25 +41,29 @@ import org.springframework.util.ObjectUtils; */ abstract class AnnotationReadingVisitorUtils { - public static AnnotationAttributes convertClassValues(ClassLoader classLoader, AnnotationAttributes original, - boolean classValuesAsString) { + public static AnnotationAttributes convertClassValues(Object annotatedElement, + ClassLoader classLoader, AnnotationAttributes original, boolean classValuesAsString) { if (original == null) { return null; } - AnnotationAttributes result = new AnnotationAttributes(original.size()); - for (Map.Entry<String, Object> entry : original.entrySet()) { + AnnotationAttributes result = new AnnotationAttributes(original); + AnnotationUtils.postProcessAnnotationAttributes(annotatedElement, result, classValuesAsString); + + for (Map.Entry<String, Object> entry : result.entrySet()) { try { Object value = entry.getValue(); if (value instanceof AnnotationAttributes) { - value = convertClassValues(classLoader, (AnnotationAttributes) value, classValuesAsString); + value = convertClassValues( + annotatedElement, classLoader, (AnnotationAttributes) value, classValuesAsString); } else if (value instanceof AnnotationAttributes[]) { AnnotationAttributes[] values = (AnnotationAttributes[]) value; for (int i = 0; i < values.length; i++) { - values[i] = convertClassValues(classLoader, values[i], classValuesAsString); + values[i] = convertClassValues(annotatedElement, classLoader, values[i], classValuesAsString); } + value = values; } else if (value instanceof Type) { value = (classValuesAsString ? ((Type) value).getClassName() : @@ -67,7 +71,8 @@ abstract class AnnotationReadingVisitorUtils { } else if (value instanceof Type[]) { Type[] array = (Type[]) value; - Object[] convArray = (classValuesAsString ? new String[array.length] : new Class<?>[array.length]); + 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() : classLoader.loadClass(array[i].getClassName())); @@ -75,11 +80,11 @@ abstract class AnnotationReadingVisitorUtils { value = convArray; } else if (classValuesAsString) { - if (value instanceof Class) { + if (value instanceof Class<?>) { value = ((Class<?>) value).getName(); } - else if (value instanceof Class[]) { - Class<?>[] clazzArray = (Class[]) value; + 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(); @@ -87,13 +92,14 @@ abstract class AnnotationReadingVisitorUtils { value = newValue; } } - result.put(entry.getKey(), value); + entry.setValue(value); } catch (Exception ex) { // Class not found - can't resolve class reference in annotation attribute. result.put(entry.getKey(), ex); } } + return result; } @@ -123,13 +129,12 @@ abstract class AnnotationReadingVisitorUtils { return null; } - // To start with, we populate the results with a copy of all attribute - // values from the target annotation. A copy is necessary so that we do - // not inadvertently mutate the state of the metadata passed to this - // method. - AnnotationAttributes results = new AnnotationAttributes(attributesList.get(0)); + // To start with, we populate the result with a copy of all attribute values + // from the target annotation. A copy is necessary so that we do not + // inadvertently mutate the state of the metadata passed to this method. + AnnotationAttributes result = new AnnotationAttributes(attributesList.get(0)); - Set<String> overridableAttributeNames = new HashSet<String>(results.keySet()); + Set<String> overridableAttributeNames = new HashSet<String>(result.keySet()); overridableAttributeNames.remove(AnnotationUtils.VALUE); // Since the map is a LinkedMultiValueMap, we depend on the ordering of @@ -152,14 +157,14 @@ abstract class AnnotationReadingVisitorUtils { if (value != null) { // Store the value, potentially overriding a value from an attribute // of the same name found higher in the annotation hierarchy. - results.put(overridableAttributeName, value); + result.put(overridableAttributeName, value); } } } } } - return results; + return result; } } diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java index 00bd9cb1..9dfcfd1a 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java @@ -122,7 +122,8 @@ public class MethodMetadataReadingVisitor extends MethodVisitor implements Metho public AnnotationAttributes getAnnotationAttributes(String annotationName, boolean classValuesAsString) { AnnotationAttributes raw = AnnotationReadingVisitorUtils.getMergedAnnotationAttributes( this.attributesMap, this.metaAnnotationMap, annotationName); - return AnnotationReadingVisitorUtils.convertClassValues(this.classLoader, raw, classValuesAsString); + return AnnotationReadingVisitorUtils.convertClassValues( + "method '" + getMethodName() + "'", this.classLoader, raw, classValuesAsString); } @Override @@ -137,8 +138,9 @@ public class MethodMetadataReadingVisitor extends MethodVisitor implements Metho } MultiValueMap<String, Object> allAttributes = new LinkedMultiValueMap<String, Object>(); for (AnnotationAttributes annotationAttributes : this.attributesMap.get(annotationName)) { - for (Map.Entry<String, Object> entry : AnnotationReadingVisitorUtils.convertClassValues( - this.classLoader, annotationAttributes, classValuesAsString).entrySet()) { + AnnotationAttributes convertedAttributes = AnnotationReadingVisitorUtils.convertClassValues( + "method '" + getMethodName() + "'", this.classLoader, annotationAttributes, classValuesAsString); + for (Map.Entry<String, Object> entry : convertedAttributes.entrySet()) { allAttributes.add(entry.getKey(), entry.getValue()); } } diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/RecursiveAnnotationArrayVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/RecursiveAnnotationArrayVisitor.java index 3c5bd9a4..9c466b77 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/RecursiveAnnotationArrayVisitor.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/RecursiveAnnotationArrayVisitor.java @@ -69,7 +69,7 @@ class RecursiveAnnotationArrayVisitor extends AbstractRecursiveAnnotationVisitor @Override public AnnotationVisitor visitAnnotation(String attributeName, String asmTypeDescriptor) { String annotationType = Type.getType(asmTypeDescriptor).getClassName(); - AnnotationAttributes nestedAttributes = new AnnotationAttributes(); + AnnotationAttributes nestedAttributes = new AnnotationAttributes(annotationType, this.classLoader); this.allNestedAttributes.add(nestedAttributes); return new RecursiveAnnotationAttributesVisitor(annotationType, nestedAttributes, this.classLoader); } diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/RecursiveAnnotationAttributesVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/RecursiveAnnotationAttributesVisitor.java index 0d2176f0..ff7b92fb 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/RecursiveAnnotationAttributesVisitor.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/RecursiveAnnotationAttributesVisitor.java @@ -16,10 +16,6 @@ package org.springframework.core.type.classreading; -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; - import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.annotation.AnnotationUtils; @@ -30,7 +26,7 @@ import org.springframework.core.annotation.AnnotationUtils; */ class RecursiveAnnotationAttributesVisitor extends AbstractRecursiveAnnotationVisitor { - private final String annotationType; + protected final String annotationType; public RecursiveAnnotationAttributesVisitor( @@ -42,49 +38,8 @@ class RecursiveAnnotationAttributesVisitor extends AbstractRecursiveAnnotationVi @Override - public final void visitEnd() { - try { - Class<?> annotationClass = this.classLoader.loadClass(this.annotationType); - doVisitEnd(annotationClass); - } - catch (ClassNotFoundException ex) { - logger.debug("Failed to class-load type while reading annotation metadata. " + - "This is a non-fatal error, but certain annotation metadata may be unavailable.", ex); - } - } - - protected void doVisitEnd(Class<?> annotationClass) { - registerDefaultValues(annotationClass); - } - - private void registerDefaultValues(Class<?> annotationClass) { - // Only do defaults scanning for public annotations; we'd run into - // IllegalAccessExceptions otherwise, and we don't want to mess with - // accessibility in a SecurityManager environment. - if (Modifier.isPublic(annotationClass.getModifiers())) { - // Check declared default values of attributes in the annotation type. - Method[] annotationAttributes = annotationClass.getMethods(); - for (Method annotationAttribute : annotationAttributes) { - String attributeName = annotationAttribute.getName(); - Object defaultValue = annotationAttribute.getDefaultValue(); - if (defaultValue != null && !this.attributes.containsKey(attributeName)) { - if (defaultValue instanceof Annotation) { - defaultValue = AnnotationAttributes.fromMap(AnnotationUtils.getAnnotationAttributes( - (Annotation) defaultValue, false, true)); - } - else if (defaultValue instanceof Annotation[]) { - Annotation[] realAnnotations = (Annotation[]) defaultValue; - AnnotationAttributes[] mappedAnnotations = new AnnotationAttributes[realAnnotations.length]; - for (int i = 0; i < realAnnotations.length; i++) { - mappedAnnotations[i] = AnnotationAttributes.fromMap( - AnnotationUtils.getAnnotationAttributes(realAnnotations[i], false, true)); - } - defaultValue = mappedAnnotations; - } - this.attributes.put(attributeName, defaultValue); - } - } - } + public void visitEnd() { + AnnotationUtils.registerDefaultValues(this.attributes); } } |