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