Throw exception if required meta-annotation is not present
It is a configuration error if an alias is declared via @AliasFor for an attribute in a meta-annotation and the meta-annotation is not meta-present. However, prior to this commit, the support for validating the configuration of @AliasFor in AnnotationUtils currently silently ignored such errors. This commit fixes this by throwing an AnnotationConfigurationException whenever a required meta-annotation is not present or meta-present on an annotation that declares an explicit alias for an attribute in the meta-annotation. Issue: SPR-13335
This commit is contained in:
@@ -65,18 +65,18 @@ import java.lang.annotation.Target;
|
||||
* <li>Aliased attributes must declare the same return type.</li>
|
||||
* <li>Aliased attributes must declare a default value.</li>
|
||||
* <li>Aliased attributes must declare the same default value.</li>
|
||||
* <li>The {@link #annotation} attribute may remain set to the default,
|
||||
* although setting it to the declaring class for both attributes in the
|
||||
* pair is also valid.</li>
|
||||
* <li>The {@link #annotation} attribute should remain set to the default.</li>
|
||||
* </ol>
|
||||
* </li>
|
||||
* <li><strong>Alias for attribute in meta-annotation</strong>:
|
||||
* <ol>
|
||||
* <li>The attribute that is an alias for an attribute in a meta-annotation
|
||||
* must be annotated with {@code @AliasFor}; the {@link #attribute} must
|
||||
* reference the aliased attribute in the meta-annotation; and the
|
||||
* {@link #annotation} must reference the meta-annotation.</li>
|
||||
* must be annotated with {@code @AliasFor}, and the {@link #attribute} must
|
||||
* reference the aliased attribute in the meta-annotation.</li>
|
||||
* <li>Aliased attributes must declare the same return type.</li>
|
||||
* <li>The {@link #annotation} must reference the meta-annotation.</li>
|
||||
* <li>The referenced meta-annotation must be <em>meta-present</em> on the
|
||||
* annotation class that declares {@code @AliasFor}.</li>
|
||||
* </ol>
|
||||
* </li>
|
||||
* </ul>
|
||||
|
||||
@@ -1451,6 +1451,7 @@ public abstract class AnnotationUtils {
|
||||
Assert.isTrue(!Annotation.class.equals(targetAnnotationType),
|
||||
"targetAnnotationType must not be java.lang.annotation.Annotation");
|
||||
|
||||
String attributeName = attribute.getName();
|
||||
AliasFor aliasFor = attribute.getAnnotation(AliasFor.class);
|
||||
|
||||
// Nothing to check
|
||||
@@ -1470,12 +1471,6 @@ public abstract class AnnotationUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Wrong search scope?
|
||||
if (searchWithinSameAnnotation && !sameTargetDeclared) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String attributeName = attribute.getName();
|
||||
String aliasedAttributeName = getAliasedAttributeName(aliasFor, attribute);
|
||||
|
||||
if (!StringUtils.hasText(aliasedAttributeName)) {
|
||||
@@ -1485,10 +1480,25 @@ public abstract class AnnotationUtils {
|
||||
throw new AnnotationConfigurationException(msg);
|
||||
}
|
||||
|
||||
if (sameTargetDeclared) {
|
||||
if (!sameTargetDeclared) {
|
||||
// Target annotation is not meta-present?
|
||||
if (findAnnotation(sourceAnnotationType, aliasedAnnotationType) == null) {
|
||||
String msg = String.format("@AliasFor declaration on attribute [%s] in annotation [%s] declares "
|
||||
+ "an alias for attribute [%s] in meta-annotation [%s] which is not meta-present.",
|
||||
attributeName, sourceAnnotationType.getName(), aliasedAttributeName,
|
||||
aliasedAnnotationType.getName());
|
||||
throw new AnnotationConfigurationException(msg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
aliasedAnnotationType = sourceAnnotationType;
|
||||
}
|
||||
|
||||
// Wrong search scope?
|
||||
if (searchWithinSameAnnotation && !sameTargetDeclared) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Method aliasedAttribute;
|
||||
try {
|
||||
aliasedAttribute = aliasedAnnotationType.getDeclaredMethod(aliasedAttributeName);
|
||||
|
||||
Reference in New Issue
Block a user