Browse Source

Exception fine-tuning and general polishing

Issue: SPR-13067
pull/840/merge
Juergen Hoeller 9 years ago
parent
commit
aedef43a9a
  1. 34
      spring-core/src/main/java/org/springframework/core/annotation/AbstractAliasAwareAnnotationAttributeExtractor.java
  2. 4
      spring-core/src/main/java/org/springframework/core/annotation/AnnotationConfigurationException.java
  3. 14
      spring-core/src/main/java/org/springframework/core/annotation/DefaultAnnotationAttributeExtractor.java
  4. 22
      spring-core/src/main/java/org/springframework/core/annotation/MapAnnotationAttributeExtractor.java
  5. 6
      spring-test/src/test/java/org/springframework/test/context/jdbc/SqlScriptsTestExecutionListenerTests.java

34
spring-core/src/main/java/org/springframework/core/annotation/AbstractAliasAwareAnnotationAttributeExtractor.java

@ -55,6 +55,7 @@ abstract class AbstractAliasAwareAnnotationAttributeExtractor implements Annotat @@ -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 @@ -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 @@ -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 @@ -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 @@ -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);
}
}

4
spring-core/src/main/java/org/springframework/core/annotation/AnnotationConfigurationException.java

@ -16,6 +16,8 @@ @@ -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; @@ -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

14
spring-core/src/main/java/org/springframework/core/annotation/DefaultAnnotationAttributeExtractor.java

@ -46,20 +46,22 @@ class DefaultAnnotationAttributeExtractor extends AbstractAliasAwareAnnotationAt @@ -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();
}
}

22
spring-core/src/main/java/org/springframework/core/annotation/MapAnnotationAttributeExtractor.java

@ -52,23 +52,26 @@ class MapAnnotationAttributeExtractor extends AbstractAliasAwareAnnotationAttrib @@ -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 @@ -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)) {

6
spring-test/src/test/java/org/springframework/test/context/jdbc/SqlScriptsTestExecutionListenerTests.java

@ -1,5 +1,5 @@ @@ -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 { @@ -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…
Cancel
Save