@Configuration parsing fully relies on Spring's MetadataReader abstraction now
This commit is contained in:
@@ -231,19 +231,46 @@ public abstract class AnnotationUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the given annotation's attributes as a Map.
|
||||
* Retrieve the given annotation's attributes as a Map,
|
||||
* preserving all attribute types as-is.
|
||||
* @param annotation the annotation to retrieve the attributes for
|
||||
* @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) {
|
||||
return getAnnotationAttributes(annotation, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* (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) {
|
||||
Map<String, Object> attrs = new HashMap<String, Object>();
|
||||
Method[] methods = annotation.annotationType().getDeclaredMethods();
|
||||
for (int j = 0; j < methods.length; j++) {
|
||||
Method method = methods[j];
|
||||
for (Method method : methods) {
|
||||
if (method.getParameterTypes().length == 0 && method.getReturnType() != void.class) {
|
||||
try {
|
||||
attrs.put(method.getName(), method.invoke(annotation));
|
||||
Object value = method.invoke(annotation);
|
||||
if (filterClasses) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
attrs.put(method.getName(), value);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not obtain annotation attribute values", ex);
|
||||
|
||||
@@ -45,9 +45,20 @@ public interface AnnotationMetadata extends ClassMetadata {
|
||||
*/
|
||||
boolean hasAnnotation(String annotationType);
|
||||
|
||||
/**
|
||||
* Retrieve the attributes of the annotation of the given type,
|
||||
* if any (i.e. if defined on the underlying class).
|
||||
* @param annotationType the annotation type to look for
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* Return the names of all meta-annotation types defined on the
|
||||
* given annotation type of the underlying class.
|
||||
* @param annotationType the meta-annotation type to look for
|
||||
* @return the meta-annotation type names
|
||||
*/
|
||||
Set<String> getMetaAnnotationTypes(String annotationType);
|
||||
@@ -61,26 +72,20 @@ public interface AnnotationMetadata extends ClassMetadata {
|
||||
boolean hasMetaAnnotation(String metaAnnotationType);
|
||||
|
||||
/**
|
||||
* Retrieve the attributes of the annotation of the given type,
|
||||
* if any (i.e. if defined on the underlying class).
|
||||
* @param annotationType the annotation type to look for
|
||||
* @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.
|
||||
* Retrieve the method metadata for all methods that are annotated
|
||||
* with at least one annotation type.
|
||||
* @return a Set of {@link MethodMetadata} for methods that have annotations.
|
||||
* The return value will be an empty set if no annotated methods are found.
|
||||
*/
|
||||
Map<String, Object> getAnnotationAttributes(String annotationType);
|
||||
|
||||
|
||||
// TODO return null would be more consistent with other methods if no match is found
|
||||
Set<MethodMetadata> getAnnotatedMethods();
|
||||
|
||||
/**
|
||||
* Retrieve the method meta-data for all methods that have the
|
||||
* Retrieve the method metadata for all methods that have the
|
||||
* given annotation type.
|
||||
* @param annotationType the annotation type to look for
|
||||
* @return a Set of (@link MethodMetadata) for methods that
|
||||
* have a matching annotation. The return value will be an
|
||||
* empty set if no methods match the annotation type.
|
||||
* @return a Set of {@link MethodMetadata} for methods that have a matching
|
||||
* annotation. The return value will be an empty set if no methods match
|
||||
* the annotation type.
|
||||
*/
|
||||
Set<MethodMetadata> getAnnotatedMethods(String annotationType);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
@@ -49,6 +49,11 @@ public interface ClassMetadata {
|
||||
*/
|
||||
boolean isConcrete();
|
||||
|
||||
/**
|
||||
* Return whether the underlying class is marked as 'final'.
|
||||
*/
|
||||
boolean isFinal();
|
||||
|
||||
/**
|
||||
* Determine whether the underlying class is independent,
|
||||
* i.e. whether it is a top-level class or a nested class
|
||||
|
||||
@@ -20,41 +20,60 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Interface that defines abstract access to the annotations of a specific
|
||||
* class, in a form that does not require that class to be loaded yet.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see StandardMethodMetadata
|
||||
* @see AnnotationMetadata#getAnnotatedMethods
|
||||
*/
|
||||
public interface MethodMetadata {
|
||||
|
||||
int getModifiers();
|
||||
|
||||
boolean isStatic();
|
||||
|
||||
/**
|
||||
* Return the name of the method.
|
||||
*/
|
||||
String getMethodName();
|
||||
|
||||
//TODO does the method return type have a generic wildcard or generic type parameters?
|
||||
|
||||
// annotation metadata
|
||||
|
||||
Set<String> getAnnotationTypes();
|
||||
|
||||
boolean hasAnnotation(String annotationType);
|
||||
|
||||
Map<String, Object> getAnnotationAttributes(String annotationType);
|
||||
|
||||
/**
|
||||
* Determine whether the underlying class has an annotation that
|
||||
* is itself annotated with the meta-annotation of the given type.
|
||||
* @param metaAnnotationType the meta-annotation type to look for
|
||||
* @return whether a matching meta-annotation is defined
|
||||
*/
|
||||
boolean hasMetaAnnotation(String metaAnnotationType);
|
||||
|
||||
/**
|
||||
* Return the names of all meta-annotation types defined on the
|
||||
* given annotation type of the underlying class.
|
||||
* @return the meta-annotation type names
|
||||
*/
|
||||
Set<String> getMetaAnnotationTypes(String annotationType);
|
||||
|
||||
Set<String> getAnnotationTypesWithMetaAnnotation(String qualifierClassName);
|
||||
/**
|
||||
* Return whether the underlying method is declared as 'static'.
|
||||
*/
|
||||
boolean isStatic();
|
||||
|
||||
/**
|
||||
* Return whether the underlying method is marked as 'final'.
|
||||
*/
|
||||
boolean isFinal();
|
||||
|
||||
/**
|
||||
* Return whether the underlying method is overridable,
|
||||
* i.e. not marked as static, final or private.
|
||||
*/
|
||||
boolean isOverridable();
|
||||
|
||||
/**
|
||||
* Return the names of all annotation types defined on the underlying method.
|
||||
* @return the annotation type names, or an empty Set if none found
|
||||
*/
|
||||
Set<String> getAnnotationTypes();
|
||||
|
||||
/**
|
||||
* Determine whether the underlying method has an annotation of the given
|
||||
* type defined.
|
||||
* @param annotationType the annotation type to look for
|
||||
* @return whether a matching annotation is defined
|
||||
*/
|
||||
boolean hasAnnotation(String annotationType);
|
||||
|
||||
/**
|
||||
* Retrieve the attributes of the annotation of the given type,
|
||||
* if any (i.e. if defined on the underlying method).
|
||||
* @param annotationType the annotation type to look for
|
||||
* @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);
|
||||
|
||||
}
|
||||
|
||||
@@ -35,6 +35,10 @@ import org.springframework.core.annotation.AnnotationUtils;
|
||||
*/
|
||||
public class StandardAnnotationMetadata extends StandardClassMetadata implements AnnotationMetadata {
|
||||
|
||||
/**
|
||||
* Create a new StandardAnnotationMetadata wrapper for the given Class.
|
||||
* @param introspectedClass the Class to introspect
|
||||
*/
|
||||
public StandardAnnotationMetadata(Class introspectedClass) {
|
||||
super(introspectedClass);
|
||||
}
|
||||
@@ -59,6 +63,16 @@ public class StandardAnnotationMetadata extends StandardClassMetadata implements
|
||||
return false;
|
||||
}
|
||||
|
||||
public Map<String, Object> getAnnotationAttributes(String annotationType) {
|
||||
Annotation[] anns = getIntrospectedClass().getAnnotations();
|
||||
for (Annotation ann : anns) {
|
||||
if (ann.annotationType().getName().equals(annotationType)) {
|
||||
return AnnotationUtils.getAnnotationAttributes(ann, true);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Set<String> getMetaAnnotationTypes(String annotationType) {
|
||||
Annotation[] anns = getIntrospectedClass().getAnnotations();
|
||||
for (Annotation ann : anns) {
|
||||
@@ -87,25 +101,25 @@ public class StandardAnnotationMetadata extends StandardClassMetadata implements
|
||||
return false;
|
||||
}
|
||||
|
||||
public Map<String, Object> getAnnotationAttributes(String annotationType) {
|
||||
Annotation[] anns = getIntrospectedClass().getAnnotations();
|
||||
for (Annotation ann : anns) {
|
||||
if (ann.annotationType().getName().equals(annotationType)) {
|
||||
return AnnotationUtils.getAnnotationAttributes(ann);
|
||||
public Set<MethodMetadata> getAnnotatedMethods() {
|
||||
Method[] methods = getIntrospectedClass().getDeclaredMethods();
|
||||
Set<MethodMetadata> annotatedMethods = new LinkedHashSet<MethodMetadata>();
|
||||
for (Method method : methods) {
|
||||
if (method.getAnnotations().length > 0) {
|
||||
annotatedMethods.add(new StandardMethodMetadata(method));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return annotatedMethods;
|
||||
}
|
||||
|
||||
public Set<MethodMetadata> getAnnotatedMethods(String annotationType) {
|
||||
Method[] methods = getIntrospectedClass().getMethods();
|
||||
Method[] methods = getIntrospectedClass().getDeclaredMethods();
|
||||
Set<MethodMetadata> annotatedMethods = new LinkedHashSet<MethodMetadata>();
|
||||
for (Method method : methods) {
|
||||
Annotation[] methodAnnotations = method.getAnnotations();
|
||||
for (Annotation ann : methodAnnotations) {
|
||||
if (ann.annotationType().getName().equals(annotationType)) {
|
||||
MethodMetadata mm = new StandardMethodMetadata(method);
|
||||
annotatedMethods.add(mm);
|
||||
annotatedMethods.add(new StandardMethodMetadata(method));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
@@ -18,6 +18,8 @@ package org.springframework.core.type;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link ClassMetadata} implementation that uses standard reflection
|
||||
* to introspect a given <code>Class</code>.
|
||||
@@ -30,57 +32,69 @@ public class StandardClassMetadata implements ClassMetadata {
|
||||
private final Class introspectedClass;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new StandardClassMetadata wrapper for the given Class.
|
||||
* @param introspectedClass the Class to introspect
|
||||
*/
|
||||
public StandardClassMetadata(Class introspectedClass) {
|
||||
Assert.notNull(introspectedClass, "Class must not be null");
|
||||
this.introspectedClass = introspectedClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the underlying Class.
|
||||
*/
|
||||
public final Class getIntrospectedClass() {
|
||||
return this.introspectedClass;
|
||||
}
|
||||
|
||||
|
||||
public String getClassName() {
|
||||
return getIntrospectedClass().getName();
|
||||
return this.introspectedClass.getName();
|
||||
}
|
||||
|
||||
public boolean isInterface() {
|
||||
return getIntrospectedClass().isInterface();
|
||||
return this.introspectedClass.isInterface();
|
||||
}
|
||||
|
||||
public boolean isAbstract() {
|
||||
return Modifier.isAbstract(getIntrospectedClass().getModifiers());
|
||||
return Modifier.isAbstract(this.introspectedClass.getModifiers());
|
||||
}
|
||||
|
||||
public boolean isConcrete() {
|
||||
return !(isInterface() || isAbstract());
|
||||
}
|
||||
|
||||
public boolean isFinal() {
|
||||
return Modifier.isFinal(this.introspectedClass.getModifiers());
|
||||
}
|
||||
|
||||
public boolean isIndependent() {
|
||||
return (!hasEnclosingClass() ||
|
||||
(getIntrospectedClass().getDeclaringClass() != null &&
|
||||
Modifier.isStatic(getIntrospectedClass().getModifiers())));
|
||||
(this.introspectedClass.getDeclaringClass() != null &&
|
||||
Modifier.isStatic(this.introspectedClass.getModifiers())));
|
||||
}
|
||||
|
||||
public boolean hasEnclosingClass() {
|
||||
return (getIntrospectedClass().getEnclosingClass() != null);
|
||||
return (this.introspectedClass.getEnclosingClass() != null);
|
||||
}
|
||||
|
||||
public String getEnclosingClassName() {
|
||||
Class enclosingClass = getIntrospectedClass().getEnclosingClass();
|
||||
Class enclosingClass = this.introspectedClass.getEnclosingClass();
|
||||
return (enclosingClass != null ? enclosingClass.getName() : null);
|
||||
}
|
||||
|
||||
public boolean hasSuperClass() {
|
||||
return (getIntrospectedClass().getSuperclass() != null);
|
||||
return (this.introspectedClass.getSuperclass() != null);
|
||||
}
|
||||
|
||||
public String getSuperClassName() {
|
||||
Class superClass = getIntrospectedClass().getSuperclass();
|
||||
Class superClass = this.introspectedClass.getSuperclass();
|
||||
return (superClass != null ? superClass.getName() : null);
|
||||
}
|
||||
|
||||
public String[] getInterfaceNames() {
|
||||
Class[] ifcs = getIntrospectedClass().getInterfaces();
|
||||
Class[] ifcs = this.introspectedClass.getInterfaces();
|
||||
String[] ifcNames = new String[ifcs.length];
|
||||
for (int i = 0; i < ifcs.length; i++) {
|
||||
ifcNames[i] = ifcs[i].getName();
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.springframework.core.type;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashSet;
|
||||
@@ -28,52 +27,62 @@ import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link MethodMetadata} implementation that uses standard reflection
|
||||
* to introspect a given <code>Method</code>.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StandardMethodMetadata implements MethodMetadata {
|
||||
|
||||
private final Method introspectedMethod;
|
||||
|
||||
public StandardMethodMetadata(Method method) {
|
||||
Assert.notNull(method, "Method must not be null");
|
||||
introspectedMethod = method;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new StandardMethodMetadata wrapper for the given Method.
|
||||
* @param introspectedMethod the Method to introspect
|
||||
*/
|
||||
public StandardMethodMetadata(Method introspectedMethod) {
|
||||
Assert.notNull(introspectedMethod, "Method must not be null");
|
||||
this.introspectedMethod = introspectedMethod;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the underlying Method.
|
||||
*/
|
||||
public final Method getIntrospectedMethod() {
|
||||
return this.introspectedMethod;
|
||||
}
|
||||
|
||||
|
||||
public Map<String, Object> getAnnotationAttributes(String annotationType) {
|
||||
Annotation[] anns = getIntrospectedMethod().getAnnotations();
|
||||
for (Annotation ann : anns) {
|
||||
if (ann.annotationType().getName().equals(annotationType)) {
|
||||
return AnnotationUtils.getAnnotationAttributes(ann);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
public String getMethodName() {
|
||||
return this.introspectedMethod.getName();
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return Modifier.isStatic(this.introspectedMethod.getModifiers());
|
||||
}
|
||||
|
||||
public boolean isFinal() {
|
||||
return Modifier.isFinal(this.introspectedMethod.getModifiers());
|
||||
}
|
||||
|
||||
public boolean isOverridable() {
|
||||
return (!isStatic() && !isFinal() && !Modifier.isPrivate(this.introspectedMethod.getModifiers()));
|
||||
}
|
||||
|
||||
public Set<String> getAnnotationTypes() {
|
||||
Set<String> types = new HashSet<String>();
|
||||
Annotation[] anns = getIntrospectedMethod().getAnnotations();
|
||||
Annotation[] anns = this.introspectedMethod.getAnnotations();
|
||||
for (Annotation ann : anns) {
|
||||
types.add(ann.annotationType().getName());
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
public String getMethodName() {
|
||||
return introspectedMethod.getName();
|
||||
}
|
||||
|
||||
public int getModifiers() {
|
||||
return introspectedMethod.getModifiers();
|
||||
}
|
||||
|
||||
public boolean hasAnnotation(String annotationType) {
|
||||
Annotation[] anns = getIntrospectedMethod().getAnnotations();
|
||||
Annotation[] anns = this.introspectedMethod.getAnnotations();
|
||||
for (Annotation ann : anns) {
|
||||
if (ann.annotationType().getName().equals(annotationType)) {
|
||||
return true;
|
||||
@@ -82,44 +91,14 @@ public class StandardMethodMetadata implements MethodMetadata {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return Modifier.isStatic(getIntrospectedMethod().getModifiers());
|
||||
}
|
||||
|
||||
public Set<String> getMetaAnnotationTypes(String annotationType) {
|
||||
Annotation[] anns = getIntrospectedMethod().getAnnotations();
|
||||
public Map<String, Object> getAnnotationAttributes(String annotationType) {
|
||||
Annotation[] anns = this.introspectedMethod.getAnnotations();
|
||||
for (Annotation ann : anns) {
|
||||
if (ann.annotationType().getName().equals(annotationType)) {
|
||||
Set<String> types = new HashSet<String>();
|
||||
Annotation[] metaAnns = ann.annotationType().getAnnotations();
|
||||
for (Annotation meta : metaAnns) {
|
||||
types.add(meta.annotationType().getName());
|
||||
}
|
||||
return types;
|
||||
return AnnotationUtils.getAnnotationAttributes(ann, true);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean hasMetaAnnotation(String metaAnnotationType) {
|
||||
//TODO can refactor into shared (utility) method with StandardAnnotationMetadata
|
||||
Annotation[] anns = getIntrospectedMethod().getAnnotations();
|
||||
for (Annotation ann : anns) {
|
||||
Annotation[] metaAnns = ann.annotationType().getAnnotations();
|
||||
for (Annotation meta : metaAnns) {
|
||||
if (meta.annotationType().getName().equals(metaAnnotationType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Set<String> getAnnotationTypesWithMetaAnnotation(String qualifierClassName) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.core.type.classreading;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.asm.AnnotationVisitor;
|
||||
import org.springframework.asm.Type;
|
||||
import org.springframework.asm.commons.EmptyVisitor;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* ASM visitor which looks for the annotations defined on a class or method.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
final class AnnotationAttributesReadingVisitor implements AnnotationVisitor {
|
||||
|
||||
private final String annotationType;
|
||||
|
||||
private final Map<String, Map<String, Object>> annotationMap;
|
||||
|
||||
private final Map<String, Set<String>> metaAnnotationMap;
|
||||
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
private final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
|
||||
|
||||
|
||||
public AnnotationAttributesReadingVisitor(
|
||||
String annotationType, Map<String, Map<String, Object>> attributesMap,
|
||||
Map<String, Set<String>> metaAnnotationMap, ClassLoader classLoader) {
|
||||
|
||||
this.annotationType = annotationType;
|
||||
this.annotationMap = attributesMap;
|
||||
this.metaAnnotationMap = metaAnnotationMap;
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
|
||||
public void visit(String name, Object value) {
|
||||
Object valueToUse = value;
|
||||
if (valueToUse instanceof Type) {
|
||||
valueToUse = ((Type) value).getClassName();
|
||||
}
|
||||
this.attributes.put(name, valueToUse);
|
||||
}
|
||||
|
||||
public void visitEnum(String name, String desc, String value) {
|
||||
Object valueToUse = value;
|
||||
try {
|
||||
Class<?> enumType = this.classLoader.loadClass(Type.getType(desc).getClassName());
|
||||
Field enumConstant = ReflectionUtils.findField(enumType, value);
|
||||
if (enumConstant != null) {
|
||||
valueToUse = enumConstant.get(null);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Class not found - can't resolve class reference in annotation attribute.
|
||||
}
|
||||
this.attributes.put(name, valueToUse);
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitAnnotation(String name, String desc) {
|
||||
return new EmptyVisitor();
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitArray(final String attrName) {
|
||||
return new AnnotationVisitor() {
|
||||
public void visit(String name, Object value) {
|
||||
Object newValue = value;
|
||||
if (newValue instanceof Type) {
|
||||
newValue = ((Type) value).getClassName();
|
||||
}
|
||||
Object existingValue = attributes.get(attrName);
|
||||
if (existingValue != null) {
|
||||
newValue = ObjectUtils.addObjectToArray((Object[]) existingValue, newValue);
|
||||
}
|
||||
else {
|
||||
Object[] newArray = (Object[]) Array.newInstance(newValue.getClass(), 1);
|
||||
newArray[0] = newValue;
|
||||
newValue = newArray;
|
||||
}
|
||||
attributes.put(attrName, newValue);
|
||||
}
|
||||
public void visitEnum(String name, String desc, String value) {
|
||||
}
|
||||
public AnnotationVisitor visitAnnotation(String name, String desc) {
|
||||
return new EmptyVisitor();
|
||||
}
|
||||
public AnnotationVisitor visitArray(String name) {
|
||||
return new EmptyVisitor();
|
||||
}
|
||||
public void visitEnd() {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void visitEnd() {
|
||||
try {
|
||||
Class<?> annotationClass = this.classLoader.loadClass(this.annotationType);
|
||||
// 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)) {
|
||||
this.attributes.put(attributeName, defaultValue);
|
||||
}
|
||||
}
|
||||
// Register annotations that the annotation type is annotated with.
|
||||
if (this.metaAnnotationMap != null) {
|
||||
Annotation[] metaAnnotations = annotationClass.getAnnotations();
|
||||
Set<String> metaAnnotationTypeNames = new HashSet<String>();
|
||||
for (Annotation metaAnnotation : metaAnnotations) {
|
||||
metaAnnotationTypeNames.add(metaAnnotation.annotationType().getName());
|
||||
}
|
||||
this.metaAnnotationMap.put(this.annotationType, metaAnnotationTypeNames);
|
||||
}
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// Class not found - can't determine meta-annotations.
|
||||
}
|
||||
this.annotationMap.put(this.annotationType, this.attributes);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,12 +16,7 @@
|
||||
|
||||
package org.springframework.core.type.classreading;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
@@ -30,11 +25,8 @@ import java.util.Set;
|
||||
import org.springframework.asm.AnnotationVisitor;
|
||||
import org.springframework.asm.MethodVisitor;
|
||||
import org.springframework.asm.Type;
|
||||
import org.springframework.asm.commons.EmptyVisitor;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.core.type.MethodMetadata;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* ASM class visitor which looks for the class name and implemented types as
|
||||
@@ -45,9 +37,9 @@ import org.springframework.util.ReflectionUtils;
|
||||
* @author Mark Fisher
|
||||
* @since 2.5
|
||||
*/
|
||||
class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor implements AnnotationMetadata {
|
||||
final class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor implements AnnotationMetadata {
|
||||
|
||||
private final Map<String, Map<String, Object>> attributesMap = new LinkedHashMap<String, Map<String, Object>>();
|
||||
private final Map<String, Map<String, Object>> annotationMap = new LinkedHashMap<String, Map<String, Object>>();
|
||||
|
||||
private final Map<String, Set<String>> metaAnnotationMap = new LinkedHashMap<String, Set<String>>();
|
||||
|
||||
@@ -63,109 +55,28 @@ class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor imple
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
||||
MethodMetadataReadingVisitor md = new MethodMetadataReadingVisitor(classLoader, name, access);
|
||||
methodMetadataSet.add(md);
|
||||
return md;
|
||||
MethodMetadataReadingVisitor mm = new MethodMetadataReadingVisitor(name, access, this.classLoader);
|
||||
this.methodMetadataSet.add(mm);
|
||||
return mm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(final String desc, boolean visible) {
|
||||
final String className = Type.getType(desc).getClassName();
|
||||
final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
|
||||
return new AnnotationVisitor() {
|
||||
public void visit(String name, Object value) {
|
||||
// Explicitly defined annotation attribute value.
|
||||
Object valueToUse = value;
|
||||
if (value instanceof Type) {
|
||||
try {
|
||||
valueToUse = classLoader.loadClass(((Type) value).getClassName());
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// Class not found - can't resolve class reference in annotation attribute.
|
||||
}
|
||||
}
|
||||
attributes.put(name, valueToUse);
|
||||
}
|
||||
public void visitEnum(String name, String desc, String value) {
|
||||
Object valueToUse = value;
|
||||
try {
|
||||
Class<?> enumType = classLoader.loadClass(Type.getType(desc).getClassName());
|
||||
Field enumConstant = ReflectionUtils.findField(enumType, value);
|
||||
if (enumConstant != null) {
|
||||
valueToUse = enumConstant.get(null);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Class not found - can't resolve class reference in annotation attribute.
|
||||
}
|
||||
attributes.put(name, valueToUse);
|
||||
}
|
||||
public AnnotationVisitor visitAnnotation(String name, String desc) {
|
||||
return new EmptyVisitor();
|
||||
}
|
||||
public AnnotationVisitor visitArray(final String attrName) {
|
||||
return new AnnotationVisitor() {
|
||||
public void visit(String name, Object value) {
|
||||
Object newValue = value;
|
||||
Object existingValue = attributes.get(attrName);
|
||||
if (existingValue != null) {
|
||||
newValue = ObjectUtils.addObjectToArray((Object[]) existingValue, newValue);
|
||||
}
|
||||
else {
|
||||
Object[] newArray = (Object[]) Array.newInstance(newValue.getClass(), 1);
|
||||
newArray[0] = newValue;
|
||||
newValue = newArray;
|
||||
}
|
||||
attributes.put(attrName, newValue);
|
||||
}
|
||||
public void visitEnum(String name, String desc, String value) {
|
||||
}
|
||||
public AnnotationVisitor visitAnnotation(String name, String desc) {
|
||||
return new EmptyVisitor();
|
||||
}
|
||||
public AnnotationVisitor visitArray(String name) {
|
||||
return new EmptyVisitor();
|
||||
}
|
||||
public void visitEnd() {
|
||||
}
|
||||
};
|
||||
}
|
||||
public void visitEnd() {
|
||||
try {
|
||||
Class<?> annotationClass = classLoader.loadClass(className);
|
||||
// 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 && !attributes.containsKey(attributeName)) {
|
||||
attributes.put(attributeName, defaultValue);
|
||||
}
|
||||
}
|
||||
// Register annotations that the annotation type is annotated with.
|
||||
Annotation[] metaAnnotations = annotationClass.getAnnotations();
|
||||
Set<String> metaAnnotationTypeNames = new HashSet<String>();
|
||||
for (Annotation metaAnnotation : metaAnnotations) {
|
||||
metaAnnotationTypeNames.add(metaAnnotation.annotationType().getName());
|
||||
}
|
||||
metaAnnotationMap.put(className, metaAnnotationTypeNames);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// Class not found - can't determine meta-annotations.
|
||||
}
|
||||
attributesMap.put(className, attributes);
|
||||
|
||||
}
|
||||
};
|
||||
String className = Type.getType(desc).getClassName();
|
||||
return new AnnotationAttributesReadingVisitor(className, this.annotationMap, this.metaAnnotationMap, this.classLoader);
|
||||
}
|
||||
|
||||
|
||||
public Set<String> getAnnotationTypes() {
|
||||
return this.attributesMap.keySet();
|
||||
return this.annotationMap.keySet();
|
||||
}
|
||||
|
||||
public boolean hasAnnotation(String annotationType) {
|
||||
return this.attributesMap.containsKey(annotationType);
|
||||
return this.annotationMap.containsKey(annotationType);
|
||||
}
|
||||
|
||||
public Map<String, Object> getAnnotationAttributes(String annotationType) {
|
||||
return this.annotationMap.get(annotationType);
|
||||
}
|
||||
|
||||
public Set<String> getMetaAnnotationTypes(String annotationType) {
|
||||
@@ -182,17 +93,20 @@ class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor imple
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public Map<String, Object> getAnnotationAttributes(String annotationType) {
|
||||
return this.attributesMap.get(annotationType);
|
||||
public Set<MethodMetadata> getAnnotatedMethods() {
|
||||
Set<MethodMetadata> annotatedMethods = new LinkedHashSet<MethodMetadata>();
|
||||
for (MethodMetadata method : this.methodMetadataSet) {
|
||||
if (!method.getAnnotationTypes().isEmpty()) {
|
||||
annotatedMethods.add(method);
|
||||
}
|
||||
}
|
||||
return annotatedMethods;
|
||||
}
|
||||
|
||||
|
||||
public Set<MethodMetadata> getAnnotatedMethods(String annotationType) {
|
||||
Set<MethodMetadata> annotatedMethods = new LinkedHashSet<MethodMetadata>();
|
||||
for (MethodMetadata method : methodMetadataSet) {
|
||||
if (method.hasAnnotation(annotationType))
|
||||
{
|
||||
for (MethodMetadata method : this.methodMetadataSet) {
|
||||
if (method.hasAnnotation(annotationType)) {
|
||||
annotatedMethods.add(method);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
@@ -33,7 +33,7 @@ import org.springframework.core.io.ResourceLoader;
|
||||
*/
|
||||
public class CachingMetadataReaderFactory extends SimpleMetadataReaderFactory {
|
||||
|
||||
private final Map<Resource, SimpleMetadataReader> classReaderCache = new HashMap<Resource, SimpleMetadataReader>();
|
||||
private final Map<Resource, MetadataReader> classReaderCache = new HashMap<Resource, MetadataReader>();
|
||||
|
||||
|
||||
/**
|
||||
@@ -62,9 +62,9 @@ public class CachingMetadataReaderFactory extends SimpleMetadataReaderFactory {
|
||||
|
||||
|
||||
@Override
|
||||
public SimpleMetadataReader getMetadataReader(Resource resource) throws IOException {
|
||||
public MetadataReader getMetadataReader(Resource resource) throws IOException {
|
||||
synchronized (this.classReaderCache) {
|
||||
SimpleMetadataReader metadataReader = this.classReaderCache.get(resource);
|
||||
MetadataReader metadataReader = this.classReaderCache.get(resource);
|
||||
if (metadataReader == null) {
|
||||
metadataReader = super.getMetadataReader(resource);
|
||||
this.classReaderCache.put(resource, metadataReader);
|
||||
|
||||
@@ -45,6 +45,8 @@ class ClassMetadataReadingVisitor implements ClassVisitor, ClassMetadata {
|
||||
|
||||
private boolean isAbstract;
|
||||
|
||||
private boolean isFinal;
|
||||
|
||||
private String enclosingClassName;
|
||||
|
||||
private boolean independentInnerClass;
|
||||
@@ -58,6 +60,7 @@ class ClassMetadataReadingVisitor implements ClassVisitor, ClassMetadata {
|
||||
this.className = ClassUtils.convertResourcePathToClassName(name);
|
||||
this.isInterface = ((access & Opcodes.ACC_INTERFACE) != 0);
|
||||
this.isAbstract = ((access & Opcodes.ACC_ABSTRACT) != 0);
|
||||
this.isFinal = ((access & Opcodes.ACC_FINAL) != 0);
|
||||
if (supername != null) {
|
||||
this.superClassName = ClassUtils.convertResourcePathToClassName(supername);
|
||||
}
|
||||
@@ -122,6 +125,10 @@ class ClassMetadataReadingVisitor implements ClassVisitor, ClassMetadata {
|
||||
return !(this.isInterface || this.isAbstract);
|
||||
}
|
||||
|
||||
public boolean isFinal() {
|
||||
return this.isFinal;
|
||||
}
|
||||
|
||||
public boolean isIndependent() {
|
||||
return (this.enclosingClassName == null || this.independentInnerClass);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.core.type.classreading;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.core.type.ClassMetadata;
|
||||
|
||||
@@ -28,13 +29,19 @@ import org.springframework.core.type.ClassMetadata;
|
||||
*/
|
||||
public interface MetadataReader {
|
||||
|
||||
/**
|
||||
* Return the resource reference for the class file.
|
||||
*/
|
||||
Resource getResource();
|
||||
|
||||
/**
|
||||
* Read basic class metadata for the underlying class.
|
||||
*/
|
||||
ClassMetadata getClassMetadata();
|
||||
|
||||
/**
|
||||
* Read full annotation metadata for the underlying class.
|
||||
* Read full annotation metadata for the underlying class,
|
||||
* including metadata for annotated methods.
|
||||
*/
|
||||
AnnotationMetadata getAnnotationMetadata();
|
||||
|
||||
|
||||
@@ -16,13 +16,7 @@
|
||||
|
||||
package org.springframework.core.type.classreading;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -32,139 +26,68 @@ import org.springframework.asm.Opcodes;
|
||||
import org.springframework.asm.Type;
|
||||
import org.springframework.asm.commons.EmptyVisitor;
|
||||
import org.springframework.core.type.MethodMetadata;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* ASM method visitor which looks for the annotations defined on the method,
|
||||
* exposing them through the {@link org.springframework.core.type.MethodMetadata}
|
||||
* interface.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
class MethodMetadataReadingVisitor extends MethodAdapter implements MethodMetadata {
|
||||
final class MethodMetadataReadingVisitor extends MethodAdapter implements MethodMetadata {
|
||||
|
||||
private ClassLoader classLoader;
|
||||
private final String name;
|
||||
|
||||
private String name;
|
||||
private final int access;
|
||||
|
||||
private int access;
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
private boolean isStatic;
|
||||
|
||||
private final Map<String, Map<String, Object>> attributesMap = new LinkedHashMap<String, Map<String, Object>>();
|
||||
|
||||
private final Map<String, Set<String>> metaAnnotationMap = new LinkedHashMap<String, Set<String>>();
|
||||
private final Map<String, Map<String, Object>> annotationMap = new LinkedHashMap<String, Map<String, Object>>();
|
||||
|
||||
|
||||
public MethodMetadataReadingVisitor(ClassLoader classLoader, String name, int access) {
|
||||
public MethodMetadataReadingVisitor(String name, int access, ClassLoader classLoader) {
|
||||
super(new EmptyVisitor());
|
||||
this.classLoader = classLoader;
|
||||
this.name = name;
|
||||
this.access = access;
|
||||
this.isStatic = ((access & Opcodes.ACC_STATIC) != 0);
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
|
||||
public Map<String, Object> getAnnotationAttributes(String annotationType) {
|
||||
return this.attributesMap.get(annotationType);
|
||||
public String getMethodName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return ((this.access & Opcodes.ACC_STATIC) != 0);
|
||||
}
|
||||
|
||||
public boolean isFinal() {
|
||||
return ((this.access & Opcodes.ACC_FINAL) != 0);
|
||||
}
|
||||
|
||||
public boolean isOverridable() {
|
||||
return (!isStatic() && !isFinal() && ((this.access & Opcodes.ACC_PRIVATE) == 0));
|
||||
}
|
||||
|
||||
public Set<String> getAnnotationTypes() {
|
||||
return this.attributesMap.keySet();
|
||||
}
|
||||
|
||||
public String getMethodName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getModifiers() {
|
||||
return access;
|
||||
return this.annotationMap.keySet();
|
||||
}
|
||||
|
||||
public boolean hasAnnotation(String annotationType) {
|
||||
return this.attributesMap.containsKey(annotationType);
|
||||
return this.annotationMap.containsKey(annotationType);
|
||||
}
|
||||
|
||||
public Set<String> getMetaAnnotationTypes(String annotationType) {
|
||||
return this.metaAnnotationMap.get(annotationType);
|
||||
}
|
||||
|
||||
public boolean hasMetaAnnotation(String metaAnnotationType) {
|
||||
Collection<Set<String>> allMetaTypes = this.metaAnnotationMap.values();
|
||||
for (Set<String> metaTypes : allMetaTypes) {
|
||||
if (metaTypes.contains(metaAnnotationType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return this.isStatic;
|
||||
}
|
||||
|
||||
public Set<String> getAnnotationTypesWithMetaAnnotation(String metaAnnotationType) {
|
||||
Set<String> annotationTypes = new LinkedHashSet<String>();
|
||||
for (Map.Entry<String, Set<String>> entry : metaAnnotationMap.entrySet()) {
|
||||
String attributeType = entry.getKey();
|
||||
Set<String> metaAttributes = entry.getValue();
|
||||
if (metaAttributes.contains(metaAnnotationType)) {
|
||||
annotationTypes.add(attributeType);
|
||||
}
|
||||
}
|
||||
return annotationTypes;
|
||||
public Map<String, Object> getAnnotationAttributes(String annotationType) {
|
||||
return this.annotationMap.get(annotationType);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(final String desc, boolean visible) {
|
||||
final String className = Type.getType(desc).getClassName();
|
||||
final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
|
||||
return new EmptyVisitor() {
|
||||
@Override
|
||||
public void visit(String name, Object value) {
|
||||
// Explicitly defined annotation attribute value.
|
||||
attributes.put(name, value);
|
||||
}
|
||||
@Override
|
||||
public void visitEnum(String name, String desc, String value) {
|
||||
Object valueToUse = value;
|
||||
try {
|
||||
Class<?> enumType = classLoader.loadClass(Type.getType(desc).getClassName());
|
||||
Field enumConstant = ReflectionUtils.findField(enumType, value);
|
||||
if (enumConstant != null) {
|
||||
valueToUse = enumConstant.get(null);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Class not found - can't resolve class reference in annotation attribute.
|
||||
}
|
||||
attributes.put(name, valueToUse);
|
||||
}
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
try {
|
||||
Class<?> annotationClass = classLoader.loadClass(className);
|
||||
// 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 && !attributes.containsKey(attributeName)) {
|
||||
attributes.put(attributeName, defaultValue);
|
||||
}
|
||||
}
|
||||
// Register annotations that the annotation type is annotated with.
|
||||
Annotation[] metaAnnotations = annotationClass.getAnnotations();
|
||||
Set<String> metaAnnotationTypeNames = new HashSet<String>();
|
||||
for (Annotation metaAnnotation : metaAnnotations) {
|
||||
metaAnnotationTypeNames.add(metaAnnotation.annotationType().getName());
|
||||
}
|
||||
metaAnnotationMap.put(className, metaAnnotationTypeNames);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// Class not found
|
||||
}
|
||||
attributesMap.put(className, attributes);
|
||||
}
|
||||
};
|
||||
String className = Type.getType(desc).getClassName();
|
||||
return new AnnotationAttributesReadingVisitor(className, this.annotationMap, null, this.classLoader);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,7 +16,11 @@
|
||||
|
||||
package org.springframework.core.type.classreading;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.springframework.asm.ClassReader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.core.type.ClassMetadata;
|
||||
|
||||
@@ -30,7 +34,9 @@ import org.springframework.core.type.ClassMetadata;
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5
|
||||
*/
|
||||
public class SimpleMetadataReader implements MetadataReader {
|
||||
final class SimpleMetadataReader implements MetadataReader {
|
||||
|
||||
private final Resource resource;
|
||||
|
||||
private final ClassReader classReader;
|
||||
|
||||
@@ -41,27 +47,23 @@ public class SimpleMetadataReader implements MetadataReader {
|
||||
private AnnotationMetadata annotationMetadata;
|
||||
|
||||
|
||||
SimpleMetadataReader(ClassReader classReader, ClassLoader classLoader) {
|
||||
this.classReader = classReader;
|
||||
SimpleMetadataReader(Resource resource, ClassLoader classLoader) throws IOException {
|
||||
this.resource = resource;
|
||||
InputStream is = this.resource.getInputStream();
|
||||
try {
|
||||
this.classReader = new ClassReader(is);
|
||||
}
|
||||
finally {
|
||||
is.close();
|
||||
}
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the underlying ASM ClassReader.
|
||||
*/
|
||||
public final ClassReader getClassReader() {
|
||||
return this.classReader;
|
||||
public Resource getResource() {
|
||||
return this.resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the underlying ClassLoader.
|
||||
*/
|
||||
public final ClassLoader getClassLoader() {
|
||||
return this.classLoader;
|
||||
}
|
||||
|
||||
|
||||
public ClassMetadata getClassMetadata() {
|
||||
if (this.classMetadata == null) {
|
||||
ClassMetadataReadingVisitor visitor = new ClassMetadataReadingVisitor();
|
||||
|
||||
@@ -17,9 +17,7 @@
|
||||
package org.springframework.core.type.classreading;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.springframework.asm.ClassReader;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
@@ -72,20 +70,14 @@ public class SimpleMetadataReaderFactory implements MetadataReaderFactory {
|
||||
}
|
||||
|
||||
|
||||
public SimpleMetadataReader getMetadataReader(String className) throws IOException {
|
||||
public MetadataReader getMetadataReader(String className) throws IOException {
|
||||
String resourcePath = ResourceLoader.CLASSPATH_URL_PREFIX +
|
||||
ClassUtils.convertClassNameToResourcePath(className) + ClassUtils.CLASS_FILE_SUFFIX;
|
||||
return getMetadataReader(this.resourceLoader.getResource(resourcePath));
|
||||
}
|
||||
|
||||
public SimpleMetadataReader getMetadataReader(Resource resource) throws IOException {
|
||||
InputStream is = resource.getInputStream();
|
||||
try {
|
||||
return new SimpleMetadataReader(new ClassReader(is), this.resourceLoader.getClassLoader());
|
||||
}
|
||||
finally {
|
||||
is.close();
|
||||
}
|
||||
public MetadataReader getMetadataReader(Resource resource) throws IOException {
|
||||
return new SimpleMetadataReader(resource, this.resourceLoader.getClassLoader());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user