ClassMetadata exposes isAnnotation() now, and correctly returns false from hasSuperClass() for interfaces and annotations

Issue: SPR-11711
This commit is contained in:
Juergen Hoeller
2014-05-30 18:14:36 +02:00
parent 4372dac002
commit b4954780aa
4 changed files with 112 additions and 27 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 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.
@@ -38,6 +38,12 @@ public interface ClassMetadata {
*/
boolean isInterface();
/**
* Return whether the underlying class represents an annotation.
* @since 4.1
*/
boolean isAnnotation();
/**
* Return whether the underlying class is marked as abstract.
*/
@@ -100,6 +106,7 @@ public interface ClassMetadata {
* access, and private classes and interfaces declared by the class, but excludes
* inherited classes and interfaces. An empty array is returned if no member classes
* or interfaces exist.
* @since 3.1
*/
String[] getMemberClassNames();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 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.
@@ -60,6 +60,11 @@ public class StandardClassMetadata implements ClassMetadata {
return this.introspectedClass.isInterface();
}
@Override
public boolean isAnnotation() {
return this.introspectedClass.isAnnotation();
}
@Override
public boolean isAbstract() {
return Modifier.isAbstract(this.introspectedClass.getModifiers());

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 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.
@@ -47,6 +47,8 @@ class ClassMetadataReadingVisitor extends ClassVisitor implements ClassMetadata
private boolean isInterface;
private boolean isAnnotation;
private boolean isAbstract;
private boolean isFinal;
@@ -71,9 +73,10 @@ class ClassMetadataReadingVisitor extends ClassVisitor implements ClassMetadata
public void visit(int version, int access, String name, String signature, String supername, String[] interfaces) {
this.className = ClassUtils.convertResourcePathToClassName(name);
this.isInterface = ((access & Opcodes.ACC_INTERFACE) != 0);
this.isAnnotation = ((access & Opcodes.ACC_ANNOTATION) != 0);
this.isAbstract = ((access & Opcodes.ACC_ABSTRACT) != 0);
this.isFinal = ((access & Opcodes.ACC_FINAL) != 0);
if (supername != null) {
if (supername != null && !this.isInterface) {
this.superClassName = ClassUtils.convertResourcePathToClassName(supername);
}
this.interfaces = new String[interfaces.length];
@@ -146,6 +149,11 @@ class ClassMetadataReadingVisitor extends ClassVisitor implements ClassMetadata
return this.isInterface;
}
@Override
public boolean isAnnotation() {
return this.isAnnotation;
}
@Override
public boolean isAbstract() {
return this.isAbstract;

View File

@@ -18,6 +18,7 @@ package org.springframework.core.type;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -79,6 +80,89 @@ public class AnnotationMetadataTests {
doTestSubClassAnnotationInfo(metadata);
}
private void doTestSubClassAnnotationInfo(AnnotationMetadata metadata) {
assertThat(metadata.getClassName(), is(AnnotatedComponentSubClass.class.getName()));
assertThat(metadata.isInterface(), is(false));
assertThat(metadata.isAnnotation(), is(false));
assertThat(metadata.isAbstract(), is(false));
assertThat(metadata.isConcrete(), is(true));
assertThat(metadata.hasSuperClass(), is(true));
assertThat(metadata.getSuperClassName(), is(AnnotatedComponent.class.getName()));
assertThat(metadata.getInterfaceNames().length, is(0));
assertThat(metadata.isAnnotated(Component.class.getName()), is(false));
assertThat(metadata.isAnnotated(Scope.class.getName()), is(false));
assertThat(metadata.isAnnotated(SpecialAttr.class.getName()), is(false));
assertThat(metadata.hasAnnotation(Component.class.getName()), is(false));
assertThat(metadata.hasAnnotation(Scope.class.getName()), is(false));
assertThat(metadata.hasAnnotation(SpecialAttr.class.getName()), is(false));
assertThat(metadata.getAnnotationTypes().size(), is(0));
assertThat(metadata.getAnnotationAttributes(Component.class.getName()), nullValue());
assertThat(metadata.getAnnotatedMethods(DirectAnnotation.class.getName()).size(), equalTo(0));
assertThat(metadata.isAnnotated(IsAnnotatedAnnotation.class.getName()), equalTo(false));
assertThat(metadata.getAllAnnotationAttributes(DirectAnnotation.class.getName()), nullValue());
}
@Test
public void standardAnnotationMetadataForInterface() throws Exception {
AnnotationMetadata metadata = new StandardAnnotationMetadata(AnnotationMetadata.class, true);
doTestMetadataForInterfaceClass(metadata);
}
@Test
public void asmAnnotationMetadataForInterface() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(AnnotationMetadata.class.getName());
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
doTestMetadataForInterfaceClass(metadata);
}
private void doTestMetadataForInterfaceClass(AnnotationMetadata metadata) {
assertThat(metadata.getClassName(), is(AnnotationMetadata.class.getName()));
assertThat(metadata.isInterface(), is(true));
assertThat(metadata.isAnnotation(), is(false));
assertThat(metadata.isAbstract(), is(true));
assertThat(metadata.isConcrete(), is(false));
assertThat(metadata.hasSuperClass(), is(false));
assertThat(metadata.getSuperClassName(), nullValue());
assertThat(metadata.getInterfaceNames().length, is(2));
assertThat(metadata.getInterfaceNames()[0], is(ClassMetadata.class.getName()));
assertThat(metadata.getInterfaceNames()[1], is(AnnotatedTypeMetadata.class.getName()));
assertThat(metadata.getAnnotationTypes().size(), is(0));
}
@Test
public void standardAnnotationMetadataForAnnotation() throws Exception {
AnnotationMetadata metadata = new StandardAnnotationMetadata(Component.class, true);
doTestMetadataForAnnotationClass(metadata);
}
@Test
public void asmAnnotationMetadataForAnnotation() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(Component.class.getName());
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
doTestMetadataForAnnotationClass(metadata);
}
private void doTestMetadataForAnnotationClass(AnnotationMetadata metadata) {
assertThat(metadata.getClassName(), is(Component.class.getName()));
assertThat(metadata.isInterface(), is(true));
assertThat(metadata.isAnnotation(), is(true));
assertThat(metadata.isAbstract(), is(true));
assertThat(metadata.isConcrete(), is(false));
assertThat(metadata.hasSuperClass(), is(false));
assertThat(metadata.getSuperClassName(), nullValue());
assertThat(metadata.getInterfaceNames().length, is(1));
assertThat(metadata.getInterfaceNames()[0], is(Annotation.class.getName()));
assertThat(metadata.isAnnotated(Documented.class.getName()), is(true));
assertThat(metadata.isAnnotated(Scope.class.getName()), is(false));
assertThat(metadata.isAnnotated(SpecialAttr.class.getName()), is(false));
assertThat(metadata.hasAnnotation(Documented.class.getName()), is(true));
assertThat(metadata.hasAnnotation(Scope.class.getName()), is(false));
assertThat(metadata.hasAnnotation(SpecialAttr.class.getName()), is(false));
assertThat(metadata.getAnnotationTypes().size(), is(3));
}
/**
* In order to preserve backward-compatibility, {@link StandardAnnotationMetadata}
* defaults to return nested annotations and annotation arrays as actual
@@ -89,7 +173,6 @@ public class AnnotationMetadataTests {
@Test
public void standardAnnotationMetadata_nestedAnnotationsAsMap_false() throws Exception {
AnnotationMetadata metadata = new StandardAnnotationMetadata(AnnotatedComponent.class);
AnnotationAttributes specialAttrs = (AnnotationAttributes) metadata.getAnnotationAttributes(SpecialAttr.class.getName());
Annotation[] nestedAnnoArray = (Annotation[]) specialAttrs.get("nestedAnnoArray");
assertThat(nestedAnnoArray[0], instanceOf(NestedAnno.class));
@@ -97,9 +180,7 @@ public class AnnotationMetadataTests {
@Test
public void metaAnnotationOverridesUsingStandardAnnotationMetadata() {
AnnotationMetadata metadata = new StandardAnnotationMetadata(
ComposedConfigurationWithAttributeOverridesClass.class);
AnnotationMetadata metadata = new StandardAnnotationMetadata(ComposedConfigurationWithAttributeOverridesClass.class);
assertMetaAnnotationOverrides(metadata);
}
@@ -108,7 +189,6 @@ public class AnnotationMetadataTests {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(ComposedConfigurationWithAttributeOverridesClass.class.getName());
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
assertMetaAnnotationOverrides(metadata);
}
@@ -184,6 +264,7 @@ public class AnnotationMetadataTests {
private void doTestAnnotationInfo(AnnotationMetadata metadata) {
assertThat(metadata.getClassName(), is(AnnotatedComponent.class.getName()));
assertThat(metadata.isInterface(), is(false));
assertThat(metadata.isAnnotation(), is(false));
assertThat(metadata.isAbstract(), is(false));
assertThat(metadata.isConcrete(), is(true));
assertThat(metadata.hasSuperClass(), is(true));
@@ -283,21 +364,6 @@ public class AnnotationMetadataTests {
}
}
private void doTestSubClassAnnotationInfo(AnnotationMetadata metadata) {
assertThat(metadata.getClassName(), is(AnnotatedComponentSubClass.class.getName()));
assertThat(metadata.isAnnotated(Component.class.getName()), is(false));
assertThat(metadata.isAnnotated(Scope.class.getName()), is(false));
assertThat(metadata.isAnnotated(SpecialAttr.class.getName()), is(false));
assertThat(metadata.hasAnnotation(Component.class.getName()), is(false));
assertThat(metadata.hasAnnotation(Scope.class.getName()), is(false));
assertThat(metadata.hasAnnotation(SpecialAttr.class.getName()), is(false));
assertThat(metadata.getAnnotationTypes().size(), is(0));
assertThat(metadata.getAnnotationAttributes(Component.class.getName()), nullValue());
assertThat(metadata.getAnnotatedMethods(DirectAnnotation.class.getName()).size(), equalTo(0));
assertThat(metadata.isAnnotated(IsAnnotatedAnnotation.class.getName()), equalTo(false));
assertThat(metadata.getAllAnnotationAttributes(DirectAnnotation.class.getName()), nullValue());
}
private void doTestMethodAnnotationInfo(AnnotationMetadata classMetadata) {
Set<MethodMetadata> methods = classMetadata.getAnnotatedMethods(TestAutowired.class.getName());
assertThat(methods.size(), is(1));
@@ -310,7 +376,7 @@ public class AnnotationMetadataTests {
// -------------------------------------------------------------------------
public static enum SomeEnum {
LABEL1, LABEL2, DEFAULT;
LABEL1, LABEL2, DEFAULT
}
@Target({})
@@ -406,9 +472,8 @@ public class AnnotationMetadataTests {
}
}
@SuppressWarnings({ "serial" })
@SuppressWarnings("serial")
private static class AnnotatedComponentSubClass extends AnnotatedComponent {
}
@Target(ElementType.TYPE)