Exception fine-tuning and general polishing
Issue: SPR-13067
This commit is contained in:
parent
9f15f347bf
commit
aedef43a9a
|
|
@ -55,6 +55,7 @@ abstract class AbstractAliasAwareAnnotationAttributeExtractor implements Annotat
|
|||
*/
|
||||
AbstractAliasAwareAnnotationAttributeExtractor(Class<? extends Annotation> annotationType,
|
||||
AnnotatedElement annotatedElement, Object source) {
|
||||
|
||||
Assert.notNull(annotationType, "annotationType must not be null");
|
||||
Assert.notNull(source, "source must not be null");
|
||||
this.annotationType = annotationType;
|
||||
|
|
@ -63,6 +64,7 @@ abstract class AbstractAliasAwareAnnotationAttributeExtractor implements Annotat
|
|||
this.attributeAliasMap = AnnotationUtils.getAttributeAliasMap(annotationType);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final Class<? extends Annotation> getAnnotationType() {
|
||||
return this.annotationType;
|
||||
|
|
@ -84,25 +86,24 @@ abstract class AbstractAliasAwareAnnotationAttributeExtractor implements Annotat
|
|||
Object attributeValue = getRawAttributeValue(attributeMethod);
|
||||
|
||||
String aliasName = this.attributeAliasMap.get(attributeName);
|
||||
if ((aliasName != null)) {
|
||||
|
||||
if (aliasName != null) {
|
||||
Object aliasValue = getRawAttributeValue(aliasName);
|
||||
Object defaultValue = AnnotationUtils.getDefaultValue(getAnnotationType(), attributeName);
|
||||
|
||||
if (!nullSafeEquals(attributeValue, aliasValue) && !nullSafeEquals(attributeValue, defaultValue)
|
||||
&& !nullSafeEquals(aliasValue, defaultValue)) {
|
||||
String elementName = (getAnnotatedElement() == null ? "unknown element"
|
||||
: getAnnotatedElement().toString());
|
||||
String msg = String.format("In annotation [%s] declared on [%s] and synthesized from [%s], "
|
||||
+ "attribute [%s] and its alias [%s] are present with values of [%s] and [%s], "
|
||||
+ "but only one is permitted.", getAnnotationType().getName(), elementName, getSource(),
|
||||
attributeName, aliasName, nullSafeToString(attributeValue), nullSafeToString(aliasValue));
|
||||
throw new AnnotationConfigurationException(msg);
|
||||
if (!ObjectUtils.nullSafeEquals(attributeValue, aliasValue) &&
|
||||
!ObjectUtils.nullSafeEquals(attributeValue, defaultValue) &&
|
||||
!ObjectUtils.nullSafeEquals(aliasValue, defaultValue)) {
|
||||
String elementName = (getAnnotatedElement() != null ? getAnnotatedElement().toString() : "unknown element");
|
||||
throw new AnnotationConfigurationException(String.format(
|
||||
"In annotation [%s] declared on %s and synthesized from [%s], attribute '%s' and its " +
|
||||
"alias '%s' are present with values of [%s] and [%s], but only one is permitted.",
|
||||
getAnnotationType().getName(), elementName, getSource(), attributeName, aliasName,
|
||||
ObjectUtils.nullSafeToString(attributeValue), ObjectUtils.nullSafeToString(aliasValue)));
|
||||
}
|
||||
|
||||
// If the user didn't declare the annotation with an explicit value,
|
||||
// return the value of the alias.
|
||||
if (nullSafeEquals(attributeValue, defaultValue)) {
|
||||
if (ObjectUtils.nullSafeEquals(attributeValue, defaultValue)) {
|
||||
attributeValue = aliasValue;
|
||||
}
|
||||
}
|
||||
|
|
@ -110,6 +111,7 @@ abstract class AbstractAliasAwareAnnotationAttributeExtractor implements Annotat
|
|||
return attributeValue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the raw, unmodified attribute value from the underlying
|
||||
* {@linkplain #getSource source} that corresponds to the supplied
|
||||
|
|
@ -124,12 +126,4 @@ abstract class AbstractAliasAwareAnnotationAttributeExtractor implements Annotat
|
|||
*/
|
||||
protected abstract Object getRawAttributeValue(String attributeName);
|
||||
|
||||
private static boolean nullSafeEquals(Object o1, Object o2) {
|
||||
return ObjectUtils.nullSafeEquals(o1, o2);
|
||||
}
|
||||
|
||||
private static String nullSafeToString(Object obj) {
|
||||
return ObjectUtils.nullSafeToString(obj);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package org.springframework.core.annotation;
|
||||
|
||||
import org.springframework.core.NestedRuntimeException;
|
||||
|
||||
/**
|
||||
* Thrown by {@link AnnotationUtils} and <em>synthesized annotations</em>
|
||||
* if an annotation is improperly configured.
|
||||
|
|
@ -26,7 +28,7 @@ package org.springframework.core.annotation;
|
|||
* @see SynthesizedAnnotation
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class AnnotationConfigurationException extends RuntimeException {
|
||||
public class AnnotationConfigurationException extends NestedRuntimeException {
|
||||
|
||||
/**
|
||||
* Construct a new {@code AnnotationConfigurationException} with the
|
||||
|
|
|
|||
|
|
@ -46,20 +46,22 @@ class DefaultAnnotationAttributeExtractor extends AbstractAliasAwareAnnotationAt
|
|||
super(annotation.annotationType(), annotatedElement, annotation);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Annotation getSource() {
|
||||
return (Annotation) super.getSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getRawAttributeValue(Method attributeMethod) {
|
||||
ReflectionUtils.makeAccessible(attributeMethod);
|
||||
return ReflectionUtils.invokeMethod(attributeMethod, getAnnotation());
|
||||
return ReflectionUtils.invokeMethod(attributeMethod, getSource());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getRawAttributeValue(String attributeName) {
|
||||
Method attributeMethod = ReflectionUtils.findMethod(getAnnotation().annotationType(), attributeName);
|
||||
Method attributeMethod = ReflectionUtils.findMethod(getSource().annotationType(), attributeName);
|
||||
return getRawAttributeValue(attributeMethod);
|
||||
}
|
||||
|
||||
private Annotation getAnnotation() {
|
||||
return (Annotation) getSource();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,23 +52,26 @@ class MapAnnotationAttributeExtractor extends AbstractAliasAwareAnnotationAttrib
|
|||
*/
|
||||
MapAnnotationAttributeExtractor(Map<String, Object> attributes, Class<? extends Annotation> annotationType,
|
||||
AnnotatedElement annotatedElement) {
|
||||
super(annotationType, annotatedElement, enrichAndValidateAttributes(new HashMap<String, Object>(attributes), annotationType));
|
||||
|
||||
super(annotationType, annotatedElement, enrichAndValidateAttributes(attributes, annotationType));
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map<String, Object> getSource() {
|
||||
return (Map<String, Object>) super.getSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getRawAttributeValue(Method attributeMethod) {
|
||||
return getMap().get(attributeMethod.getName());
|
||||
return getSource().get(attributeMethod.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getRawAttributeValue(String attributeName) {
|
||||
return getMap().get(attributeName);
|
||||
return getSource().get(attributeName);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Object> getMap() {
|
||||
return (Map<String, Object>) getSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enrich and validate the supplied {@code attributes} map by ensuring
|
||||
|
|
@ -81,9 +84,10 @@ class MapAnnotationAttributeExtractor extends AbstractAliasAwareAnnotationAttrib
|
|||
* an {@link IllegalArgumentException} will be thrown.
|
||||
* @see AliasFor
|
||||
*/
|
||||
private static Map<String, Object> enrichAndValidateAttributes(Map<String, Object> attributes,
|
||||
Class<? extends Annotation> annotationType) {
|
||||
private static Map<String, Object> enrichAndValidateAttributes(
|
||||
Map<String, Object> original, Class<? extends Annotation> annotationType) {
|
||||
|
||||
Map<String, Object> attributes = new HashMap<String, Object>(original);
|
||||
Map<String, String> attributeAliasMap = getAttributeAliasMap(annotationType);
|
||||
|
||||
for (Method attributeMethod : getAttributeMethods(annotationType)) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
|
|
@ -75,8 +75,8 @@ public class SqlScriptsTestExecutionListenerTests {
|
|||
|
||||
exception.expect(AnnotationConfigurationException.class);
|
||||
exception.expectMessage(either(
|
||||
containsString("attribute [value] and its alias [scripts]")).or(
|
||||
containsString("attribute [scripts] and its alias [value]")));
|
||||
containsString("attribute 'value' and its alias 'scripts'")).or(
|
||||
containsString("attribute 'scripts' and its alias 'value'")));
|
||||
exception.expectMessage(either(containsString("values of [{foo}] and [{bar}]")).or(
|
||||
containsString("values of [{bar}] and [{foo}]")));
|
||||
exception.expectMessage(containsString("but only one is permitted"));
|
||||
|
|
|
|||
Loading…
Reference in New Issue