Merge branch '3.2.x'

* 3.2.x: (28 commits)
  Hide 'doc' changes from jdiff reports
  Document @Bean 'lite' mode vs @Configuration
  Final preparations for 3.2.2
  Remove Tiles 3 configuration method
  Polishing
  Extracted buildRequestAttributes template method from FrameworkServlet
  Added "beforeExistingAdvisors" flag to AbstractAdvisingBeanPostProcessor
  Minor refinements along the way of researching static CGLIB callbacks
  Compare Kind references before checking log levels
  Polish Javadoc in RequestAttributes
  Fix copy-n-paste errors in NativeWebRequest
  Fix issue with restoring included attributes
  Add additional test for daylight savings glitch
  Document context hierarchy support in the TCF
  Fix test for daylight savings glitch
  Make the methodParameter field of HandlerMethod final
  Disable AsyncTests in spring-test-mvc
  Reformat the testing chapter
  Document context hierarchy support in the TCF
  Document context hierarchy support in the TCF
  ...
This commit is contained in:
Phillip Webb
2013-03-13 14:01:46 -07:00
267 changed files with 8384 additions and 6246 deletions

View File

@@ -20,6 +20,7 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
@@ -240,14 +241,58 @@ public abstract class AnnotationUtils {
* if not found
* @see Class#isAnnotationPresent(Class)
* @see Class#getDeclaredAnnotations()
* @see #findAnnotationDeclaringClassForTypes(List, Class)
* @see #isAnnotationDeclaredLocally(Class, Class)
*/
public static Class<?> findAnnotationDeclaringClass(Class<? extends Annotation> annotationType, Class<?> clazz) {
Assert.notNull(annotationType, "Annotation type must not be null");
if (clazz == null || clazz.equals(Object.class)) {
return null;
}
return (isAnnotationDeclaredLocally(annotationType, clazz)) ? clazz :
findAnnotationDeclaringClass(annotationType, clazz.getSuperclass());
return (isAnnotationDeclaredLocally(annotationType, clazz)) ? clazz : findAnnotationDeclaringClass(
annotationType, clazz.getSuperclass());
}
/**
* Find the first {@link Class} in the inheritance hierarchy of the specified
* {@code clazz} (including the specified {@code clazz} itself) which declares
* at least one of the specified {@code annotationTypes}, or {@code null} if
* none of the specified annotation types could be found.
* <p>If the supplied {@code clazz} is {@code null}, {@code null} will be
* returned.
* <p>If the supplied {@code clazz} is an interface, only the interface itself
* will be checked; the inheritance hierarchy for interfaces will not be traversed.
* <p>The standard {@link Class} API does not provide a mechanism for determining
* which class in an inheritance hierarchy actually declares one of several
* candidate {@linkplain Annotation annotations}, so we need to handle this
* explicitly.
* @param annotationTypes the list of Class objects corresponding to the
* annotation types
* @param clazz the Class object corresponding to the class on which to check
* for the annotations, or {@code null}
* @return the first {@link Class} in the inheritance hierarchy of the specified
* {@code clazz} which declares an annotation of at least one of the specified
* {@code annotationTypes}, or {@code null} if not found
* @see Class#isAnnotationPresent(Class)
* @see Class#getDeclaredAnnotations()
* @see #findAnnotationDeclaringClass(Class, Class)
* @see #isAnnotationDeclaredLocally(Class, Class)
* @since 3.2.2
*/
public static Class<?> findAnnotationDeclaringClassForTypes(List<Class<? extends Annotation>> annotationTypes,
Class<?> clazz) {
Assert.notEmpty(annotationTypes, "The list of annotation types must not be empty");
if (clazz == null || clazz.equals(Object.class)) {
return null;
}
for (Class<? extends Annotation> annotationType : annotationTypes) {
if (isAnnotationDeclaredLocally(annotationType, clazz)) {
return clazz;
}
}
return findAnnotationDeclaringClassForTypes(annotationTypes, clazz.getSuperclass());
}
/**
@@ -348,8 +393,8 @@ public abstract class AnnotationUtils {
* and corresponding attribute values as values
* @since 3.1.1
*/
public static AnnotationAttributes getAnnotationAttributes(
Annotation annotation, boolean classValuesAsString, boolean nestedAnnotationsAsMap) {
public static AnnotationAttributes getAnnotationAttributes(Annotation annotation, boolean classValuesAsString,
boolean nestedAnnotationsAsMap) {
AnnotationAttributes attrs = new AnnotationAttributes();
Method[] methods = annotation.annotationType().getDeclaredMethods();
@@ -371,15 +416,15 @@ public abstract class AnnotationUtils {
}
}
if (nestedAnnotationsAsMap && value instanceof Annotation) {
attrs.put(method.getName(), getAnnotationAttributes(
(Annotation)value, classValuesAsString, nestedAnnotationsAsMap));
attrs.put(method.getName(),
getAnnotationAttributes((Annotation) value, classValuesAsString, nestedAnnotationsAsMap));
}
else if (nestedAnnotationsAsMap && value instanceof Annotation[]) {
Annotation[] realAnnotations = (Annotation[])value;
Annotation[] realAnnotations = (Annotation[]) value;
AnnotationAttributes[] mappedAnnotations = new AnnotationAttributes[realAnnotations.length];
for (int i = 0; i < realAnnotations.length; i++) {
mappedAnnotations[i] = getAnnotationAttributes(
realAnnotations[i], classValuesAsString, nestedAnnotationsAsMap);
mappedAnnotations[i] = getAnnotationAttributes(realAnnotations[i], classValuesAsString,
nestedAnnotationsAsMap);
}
attrs.put(method.getName(), mappedAnnotations);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 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.
@@ -16,21 +16,26 @@
package org.springframework.core.annotation;
import static org.junit.Assert.*;
import static org.springframework.core.annotation.AnnotationUtils.*;
import java.lang.annotation.Annotation;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import static org.junit.Assert.*;
import static org.springframework.core.annotation.AnnotationUtils.*;
/**
* Unit tests for {@link AnnotationUtils}.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Sam Brannen
@@ -102,23 +107,91 @@ public class AnnotationUtilsTests {
assertNull(findAnnotationDeclaringClass(Transactional.class, NonAnnotatedClass.class));
// inherited class-level annotation; note: @Transactional is inherited
assertEquals(InheritedAnnotationInterface.class, findAnnotationDeclaringClass(Transactional.class,
InheritedAnnotationInterface.class));
assertEquals(InheritedAnnotationInterface.class,
findAnnotationDeclaringClass(Transactional.class, InheritedAnnotationInterface.class));
assertNull(findAnnotationDeclaringClass(Transactional.class, SubInheritedAnnotationInterface.class));
assertEquals(InheritedAnnotationClass.class, findAnnotationDeclaringClass(Transactional.class,
InheritedAnnotationClass.class));
assertEquals(InheritedAnnotationClass.class, findAnnotationDeclaringClass(Transactional.class,
SubInheritedAnnotationClass.class));
assertEquals(InheritedAnnotationClass.class,
findAnnotationDeclaringClass(Transactional.class, InheritedAnnotationClass.class));
assertEquals(InheritedAnnotationClass.class,
findAnnotationDeclaringClass(Transactional.class, SubInheritedAnnotationClass.class));
// non-inherited class-level annotation; note: @Order is not inherited,
// but findAnnotationDeclaringClass() should still find it.
assertEquals(NonInheritedAnnotationInterface.class, findAnnotationDeclaringClass(Order.class,
NonInheritedAnnotationInterface.class));
// but findAnnotationDeclaringClass() should still find it on classes.
assertEquals(NonInheritedAnnotationInterface.class,
findAnnotationDeclaringClass(Order.class, NonInheritedAnnotationInterface.class));
assertNull(findAnnotationDeclaringClass(Order.class, SubNonInheritedAnnotationInterface.class));
assertEquals(NonInheritedAnnotationClass.class, findAnnotationDeclaringClass(Order.class,
NonInheritedAnnotationClass.class));
assertEquals(NonInheritedAnnotationClass.class, findAnnotationDeclaringClass(Order.class,
SubNonInheritedAnnotationClass.class));
assertEquals(NonInheritedAnnotationClass.class,
findAnnotationDeclaringClass(Order.class, NonInheritedAnnotationClass.class));
assertEquals(NonInheritedAnnotationClass.class,
findAnnotationDeclaringClass(Order.class, SubNonInheritedAnnotationClass.class));
}
@Test
public void findAnnotationDeclaringClassForTypesWithSingleCandidateType() {
// no class-level annotation
List<Class<? extends Annotation>> transactionalCandidateList = Arrays.<Class<? extends Annotation>> asList(Transactional.class);
assertNull(findAnnotationDeclaringClassForTypes(transactionalCandidateList, NonAnnotatedInterface.class));
assertNull(findAnnotationDeclaringClassForTypes(transactionalCandidateList, NonAnnotatedClass.class));
// inherited class-level annotation; note: @Transactional is inherited
assertEquals(InheritedAnnotationInterface.class,
findAnnotationDeclaringClassForTypes(transactionalCandidateList, InheritedAnnotationInterface.class));
assertNull(findAnnotationDeclaringClassForTypes(transactionalCandidateList,
SubInheritedAnnotationInterface.class));
assertEquals(InheritedAnnotationClass.class,
findAnnotationDeclaringClassForTypes(transactionalCandidateList, InheritedAnnotationClass.class));
assertEquals(InheritedAnnotationClass.class,
findAnnotationDeclaringClassForTypes(transactionalCandidateList, SubInheritedAnnotationClass.class));
// non-inherited class-level annotation; note: @Order is not inherited,
// but findAnnotationDeclaringClassForTypes() should still find it on classes.
List<Class<? extends Annotation>> orderCandidateList = Arrays.<Class<? extends Annotation>> asList(Order.class);
assertEquals(NonInheritedAnnotationInterface.class,
findAnnotationDeclaringClassForTypes(orderCandidateList, NonInheritedAnnotationInterface.class));
assertNull(findAnnotationDeclaringClassForTypes(orderCandidateList, SubNonInheritedAnnotationInterface.class));
assertEquals(NonInheritedAnnotationClass.class,
findAnnotationDeclaringClassForTypes(orderCandidateList, NonInheritedAnnotationClass.class));
assertEquals(NonInheritedAnnotationClass.class,
findAnnotationDeclaringClassForTypes(orderCandidateList, SubNonInheritedAnnotationClass.class));
}
@Test
public void findAnnotationDeclaringClassForTypesWithMultipleCandidateTypes() {
List<Class<? extends Annotation>> candidates = Arrays.<Class<? extends Annotation>> asList(Transactional.class,
Order.class);
// no class-level annotation
assertNull(findAnnotationDeclaringClassForTypes(candidates, NonAnnotatedInterface.class));
assertNull(findAnnotationDeclaringClassForTypes(candidates, NonAnnotatedClass.class));
// inherited class-level annotation; note: @Transactional is inherited
assertEquals(InheritedAnnotationInterface.class,
findAnnotationDeclaringClassForTypes(candidates, InheritedAnnotationInterface.class));
assertNull(findAnnotationDeclaringClassForTypes(candidates, SubInheritedAnnotationInterface.class));
assertEquals(InheritedAnnotationClass.class,
findAnnotationDeclaringClassForTypes(candidates, InheritedAnnotationClass.class));
assertEquals(InheritedAnnotationClass.class,
findAnnotationDeclaringClassForTypes(candidates, SubInheritedAnnotationClass.class));
// non-inherited class-level annotation; note: @Order is not inherited,
// but findAnnotationDeclaringClassForTypes() should still find it on classes.
assertEquals(NonInheritedAnnotationInterface.class,
findAnnotationDeclaringClassForTypes(candidates, NonInheritedAnnotationInterface.class));
assertNull(findAnnotationDeclaringClassForTypes(candidates, SubNonInheritedAnnotationInterface.class));
assertEquals(NonInheritedAnnotationClass.class,
findAnnotationDeclaringClassForTypes(candidates, NonInheritedAnnotationClass.class));
assertEquals(NonInheritedAnnotationClass.class,
findAnnotationDeclaringClassForTypes(candidates, SubNonInheritedAnnotationClass.class));
// class hierarchy mixed with @Transactional and @Order declarations
assertEquals(TransactionalClass.class,
findAnnotationDeclaringClassForTypes(candidates, TransactionalClass.class));
assertEquals(TransactionalAndOrderedClass.class,
findAnnotationDeclaringClassForTypes(candidates, TransactionalAndOrderedClass.class));
assertEquals(TransactionalAndOrderedClass.class,
findAnnotationDeclaringClassForTypes(candidates, SubTransactionalAndOrderedClass.class));
}
@Test
@@ -216,18 +289,18 @@ public class AnnotationUtilsTests {
}
@Component(value="meta1")
@Component(value = "meta1")
@Retention(RetentionPolicy.RUNTIME)
@interface Meta1 {
}
@Component(value="meta2")
@Component(value = "meta2")
@Retention(RetentionPolicy.RUNTIME)
@interface Meta2 {
}
@Meta1
@Component(value="local")
@Component(value = "local")
@Meta2
static class HasLocalAndMetaComponentAnnotation {
}
@@ -332,6 +405,16 @@ public class AnnotationUtilsTests {
public static class SubNonInheritedAnnotationClass extends NonInheritedAnnotationClass {
}
@Transactional
public static class TransactionalClass {
}
@Order
public static class TransactionalAndOrderedClass {
}
public static class SubTransactionalAndOrderedClass extends TransactionalAndOrderedClass {
}
public static interface InterfaceWithAnnotatedMethod {
@@ -353,10 +436,12 @@ public class AnnotationUtilsTests {
}
}
public abstract static class AbstractDoesNotImplementInterfaceWithAnnotatedMethod implements InterfaceWithAnnotatedMethod {
public abstract static class AbstractDoesNotImplementInterfaceWithAnnotatedMethod implements
InterfaceWithAnnotatedMethod {
}
public static class SubOfAbstractImplementsInterfaceWithAnnotatedMethod extends AbstractDoesNotImplementInterfaceWithAnnotatedMethod {
public static class SubOfAbstractImplementsInterfaceWithAnnotatedMethod extends
AbstractDoesNotImplementInterfaceWithAnnotatedMethod {
@Override
public void foo() {

View File

@@ -16,14 +16,6 @@
package org.springframework.util;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
@@ -36,6 +28,10 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.InOrder;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.BDDMockito.*;
/**
* Tests for {@link StreamUtils}.
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 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.
@@ -16,12 +16,6 @@
package org.springframework.util.xml;
import static org.mockito.BDDMockito.willAnswer;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import java.io.InputStream;
import javax.xml.stream.XMLInputFactory;
@@ -44,6 +38,8 @@ import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.AttributesImpl;
import org.xml.sax.helpers.XMLReaderFactory;
import static org.mockito.BDDMockito.*;
public abstract class AbstractStaxXMLReaderTestCase {
protected static XMLInputFactory inputFactory;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 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.
@@ -16,11 +16,9 @@
package org.springframework.util.xml;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import java.io.InputStream;
import java.io.StringReader;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
@@ -29,6 +27,8 @@ import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.helpers.AttributesImpl;
import static org.mockito.BDDMockito.*;
public class StaxEventXMLReaderTests extends AbstractStaxXMLReaderTestCase {
public static final String CONTENT = "<root xmlns='http://springframework.org/spring-ws'><child/></root>";

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 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.
@@ -18,23 +18,22 @@ package org.springframework.util.xml;
import java.io.InputStream;
import java.io.StringReader;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import static org.junit.Assert.*;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import org.junit.Test;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import static org.junit.Assert.*;
import static org.mockito.Matchers.*;
import static org.mockito.BDDMockito.*;
public class StaxStreamXMLReaderTests extends AbstractStaxXMLReaderTestCase {
public static final String CONTENT = "<root xmlns='http://springframework.org/spring-ws'><child/></root>";