From 2ea7fcde3eee85af6537e7280e15fb24b7436d9c Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 23 Mar 2016 18:39:29 +0100 Subject: [PATCH] Polishing (cherry picked from commit 9af12d2) --- .../scheduling/annotation/Async.java | 4 +- .../groovy/GroovyScriptFactoryTests.java | 8 +- .../core/annotation/AnnotationUtils.java | 10 +- .../test/annotation/Commit.java | 9 +- .../test/annotation/DirtiesContext.java | 80 ++++++----- .../test/annotation/IfProfileValue.java | 8 +- .../test/annotation/Repeat.java | 11 +- .../test/annotation/Rollback.java | 11 +- .../test/annotation/Timed.java | 11 +- .../test/context/jdbc/MergedSqlConfig.java | 74 +++++----- .../test/context/jdbc/Sql.java | 14 +- .../test/context/jdbc/SqlConfig.java | 9 +- .../test/context/jdbc/SqlGroup.java | 9 +- .../context/transaction/AfterTransaction.java | 9 +- .../transaction/BeforeTransaction.java | 9 +- .../test/context/web/WebAppConfiguration.java | 12 +- .../test/util/MetaAnnotationUtils.java | 11 +- .../TransactionalEventListenerFactory.java | 2 +- .../AbstractHttpMessageConverter.java | 2 +- .../web/method/annotation/ModelFactory.java | 126 +++++++++--------- ...dlerMethodReturnValueHandlerComposite.java | 7 +- .../servlet/support/WebContentGenerator.java | 7 +- .../server/standard/SpringConfigurator.java | 8 +- 23 files changed, 216 insertions(+), 235 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/Async.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/Async.java index b8b32d82fce..bd58fec696c 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/Async.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/Async.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2016 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. @@ -56,7 +56,7 @@ public @interface Async { * bean definition. *

When specified on a class level {@code @Async} annotation, indicates that the * given executor should be used for all methods within the class. Method level use - * of {@link Async#value} always overrides any value set at the class level. + * of {@code Async#value} always overrides any value set at the class level. * @since 3.1.2 */ String value() default ""; diff --git a/spring-context/src/test/java/org/springframework/scripting/groovy/GroovyScriptFactoryTests.java b/spring-context/src/test/java/org/springframework/scripting/groovy/GroovyScriptFactoryTests.java index 4859ad58700..9ab27884430 100644 --- a/spring-context/src/test/java/org/springframework/scripting/groovy/GroovyScriptFactoryTests.java +++ b/spring-context/src/test/java/org/springframework/scripting/groovy/GroovyScriptFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 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. @@ -445,8 +445,7 @@ public class GroovyScriptFactoryTests { assertTrue(ctx.getBeansOfType(Messenger.class).values().contains(messenger)); } - @Test - // Test for SPR-6268 + @Test // SPR-6268 public void testRefreshableFromTagProxyTargetClass() throws Exception { ApplicationContext ctx = new ClassPathXmlApplicationContext("groovy-with-xsd-proxy-target-class.xml", getClass()); @@ -464,8 +463,7 @@ public class GroovyScriptFactoryTests { assertNotNull(AnnotationUtils.findAnnotation(messenger.getClass(), Component.class)); } - @Test - // Test for SPR-6268 + @Test // SPR-6268 public void testProxyTargetClassNotAllowedIfNotGroovy() throws Exception { try { new ClassPathXmlApplicationContext("jruby-with-xsd-proxy-target-class.xml", getClass()); diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java index ea634b5cac0..c47c801863d 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java @@ -71,11 +71,11 @@ import org.springframework.util.StringUtils; * meta-present on the other annotation. * *

Meta-annotation Support

- *

Most {@code find*()} methods and some {@code get*()} methods in this - * class provide support for finding annotations used as meta-annotations. - * Consult the Javadoc for each method in this class for details. For support - * for meta-annotations with attribute overrides in - * composed annotations, use {@link AnnotatedElementUtils} instead. + *

Most {@code find*()} methods and some {@code get*()} methods in this class + * provide support for finding annotations used as meta-annotations. Consult the + * javadoc for each method in this class for details. For fine-grained support for + * meta-annotations with attribute overrides in composed annotations, + * consider using {@link AnnotatedElementUtils}'s more specific methods instead. * *

Attribute Aliases

*

All public methods in this class that return annotations, arrays of diff --git a/spring-test/src/main/java/org/springframework/test/annotation/Commit.java b/spring-test/src/main/java/org/springframework/test/annotation/Commit.java index 79205810e52..e23c254fba6 100644 --- a/spring-test/src/main/java/org/springframework/test/annotation/Commit.java +++ b/spring-test/src/main/java/org/springframework/test/annotation/Commit.java @@ -17,12 +17,11 @@ package org.springframework.test.annotation; import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.*; - /** * {@code @Commit} is a test annotation that is used to indicate that a * test-managed transaction should be committed after @@ -49,9 +48,9 @@ import static java.lang.annotation.RetentionPolicy.*; * @see Rollback * @see org.springframework.test.context.transaction.TransactionalTestExecutionListener */ +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) @Documented -@Retention(RUNTIME) -@Target({ TYPE, METHOD }) @Rollback(false) public @interface Commit { } diff --git a/spring-test/src/main/java/org/springframework/test/annotation/DirtiesContext.java b/spring-test/src/main/java/org/springframework/test/annotation/DirtiesContext.java index 73bf379df39..88be564e38c 100644 --- a/spring-test/src/main/java/org/springframework/test/annotation/DirtiesContext.java +++ b/spring-test/src/main/java/org/springframework/test/annotation/DirtiesContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 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. @@ -76,19 +76,48 @@ import java.lang.annotation.Target; * @see org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener * @see org.springframework.test.context.support.DirtiesContextTestExecutionListener */ +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) @Documented @Inherited -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE, ElementType.METHOD }) public @interface DirtiesContext { + /** + * The mode to use when a test method is annotated with + * {@code @DirtiesContext}. + *

Defaults to {@link MethodMode#AFTER_METHOD AFTER_METHOD}. + *

Setting the method mode on an annotated test class has no meaning. + * For class-level control, use {@link #classMode} instead. + * @since 4.2 + */ + MethodMode methodMode() default MethodMode.AFTER_METHOD; + + /** + * The mode to use when a test class is annotated with + * {@code @DirtiesContext}. + *

Defaults to {@link ClassMode#AFTER_CLASS AFTER_CLASS}. + *

Setting the class mode on an annotated test method has no meaning. + * For method-level control, use {@link #methodMode} instead. + * @since 3.0 + */ + ClassMode classMode() default ClassMode.AFTER_CLASS; + + /** + * The context cache clearing mode to use when a context is + * configured as part of a hierarchy via + * {@link org.springframework.test.context.ContextHierarchy @ContextHierarchy}. + *

Defaults to {@link HierarchyMode#EXHAUSTIVE EXHAUSTIVE}. + * @since 3.2.2 + */ + HierarchyMode hierarchyMode() default HierarchyMode.EXHAUSTIVE; + + /** * Defines modes which determine how {@code @DirtiesContext} is * interpreted when used to annotate a test method. - * * @since 4.2 */ - static enum MethodMode { + enum MethodMode { /** * The associated {@code ApplicationContext} will be marked as @@ -103,13 +132,13 @@ public @interface DirtiesContext { AFTER_METHOD; } + /** * Defines modes which determine how {@code @DirtiesContext} is * interpreted when used to annotate a test class. - * * @since 3.0 */ - static enum ClassMode { + enum ClassMode { /** * The associated {@code ApplicationContext} will be marked as @@ -140,15 +169,15 @@ public @interface DirtiesContext { AFTER_CLASS; } + /** * Defines modes which determine how the context cache is cleared * when {@code @DirtiesContext} is used in a test whose context is * configured as part of a hierarchy via * {@link org.springframework.test.context.ContextHierarchy @ContextHierarchy}. - * * @since 3.2.2 */ - static enum HierarchyMode { + enum HierarchyMode { /** * The context cache will be cleared using an exhaustive algorithm @@ -174,37 +203,4 @@ public @interface DirtiesContext { CURRENT_LEVEL; } - - /** - * The mode to use when a test method is annotated with - * {@code @DirtiesContext}. - *

Defaults to {@link MethodMode#AFTER_METHOD AFTER_METHOD}. - *

Setting the method mode on an annotated test class has no meaning. - * For class-level control, use {@link #classMode} instead. - * - * @since 4.2 - */ - MethodMode methodMode() default MethodMode.AFTER_METHOD; - - /** - * The mode to use when a test class is annotated with - * {@code @DirtiesContext}. - *

Defaults to {@link ClassMode#AFTER_CLASS AFTER_CLASS}. - *

Setting the class mode on an annotated test method has no meaning. - * For method-level control, use {@link #methodMode} instead. - * - * @since 3.0 - */ - ClassMode classMode() default ClassMode.AFTER_CLASS; - - /** - * The context cache clearing mode to use when a context is - * configured as part of a hierarchy via - * {@link org.springframework.test.context.ContextHierarchy @ContextHierarchy}. - *

Defaults to {@link HierarchyMode#EXHAUSTIVE EXHAUSTIVE}. - * - * @since 3.2.2 - */ - HierarchyMode hierarchyMode() default HierarchyMode.EXHAUSTIVE; - } diff --git a/spring-test/src/main/java/org/springframework/test/annotation/IfProfileValue.java b/spring-test/src/main/java/org/springframework/test/annotation/IfProfileValue.java index f16a7d4f072..0e8716e088c 100644 --- a/spring-test/src/main/java/org/springframework/test/annotation/IfProfileValue.java +++ b/spring-test/src/main/java/org/springframework/test/annotation/IfProfileValue.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 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. @@ -95,10 +95,10 @@ import java.lang.annotation.Target; * @see org.springframework.context.annotation.Profile * @see org.springframework.test.context.ActiveProfiles */ +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) @Documented @Inherited -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE, ElementType.METHOD }) public @interface IfProfileValue { /** @@ -109,7 +109,6 @@ public @interface IfProfileValue { /** * A single, permissible {@code value} of the profile value * for the given {@link #name}. - * *

Note: Assigning values to both {@link #value} and {@link #values} * will lead to a configuration conflict. */ @@ -118,7 +117,6 @@ public @interface IfProfileValue { /** * A list of all permissible {@code values} of the profile value * for the given {@link #name}. - * *

Note: Assigning values to both {@link #value} and {@link #values} * will lead to a configuration conflict. */ diff --git a/spring-test/src/main/java/org/springframework/test/annotation/Repeat.java b/spring-test/src/main/java/org/springframework/test/annotation/Repeat.java index 1b04d64fd3a..8d649635f52 100644 --- a/spring-test/src/main/java/org/springframework/test/annotation/Repeat.java +++ b/spring-test/src/main/java/org/springframework/test/annotation/Repeat.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 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. @@ -17,12 +17,11 @@ package org.springframework.test.annotation; import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.*; - /** * Test annotation to indicate that a test method should be invoked repeatedly. * @@ -41,9 +40,9 @@ import static java.lang.annotation.RetentionPolicy.*; * @see org.springframework.test.context.junit4.rules.SpringMethodRule * @see org.springframework.test.context.junit4.statements.SpringRepeat */ +@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) +@Retention(RetentionPolicy.RUNTIME) @Documented -@Retention(RUNTIME) -@Target({ METHOD, ANNOTATION_TYPE }) public @interface Repeat { /** diff --git a/spring-test/src/main/java/org/springframework/test/annotation/Rollback.java b/spring-test/src/main/java/org/springframework/test/annotation/Rollback.java index 65333a23e34..37bf2102791 100644 --- a/spring-test/src/main/java/org/springframework/test/annotation/Rollback.java +++ b/spring-test/src/main/java/org/springframework/test/annotation/Rollback.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 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. @@ -17,12 +17,11 @@ package org.springframework.test.annotation; import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.*; - /** * {@code @Rollback} is a test annotation that is used to indicate whether * a test-managed transaction should be rolled back after @@ -54,9 +53,9 @@ import static java.lang.annotation.RetentionPolicy.*; * @see Commit * @see org.springframework.test.context.transaction.TransactionalTestExecutionListener */ +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) @Documented -@Retention(RUNTIME) -@Target({ TYPE, METHOD }) public @interface Rollback { /** diff --git a/spring-test/src/main/java/org/springframework/test/annotation/Timed.java b/spring-test/src/main/java/org/springframework/test/annotation/Timed.java index f364dab237a..7ece58fd9b0 100644 --- a/spring-test/src/main/java/org/springframework/test/annotation/Timed.java +++ b/spring-test/src/main/java/org/springframework/test/annotation/Timed.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 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. @@ -17,12 +17,11 @@ package org.springframework.test.annotation; import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.*; - /** * Test-specific annotation to indicate that a test method has to finish * execution in a {@linkplain #millis() specified time period}. @@ -45,9 +44,9 @@ import static java.lang.annotation.RetentionPolicy.*; * @see org.springframework.test.context.junit4.rules.SpringMethodRule * @see org.springframework.test.context.junit4.statements.SpringFailOnTimeout */ +@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) +@Retention(RetentionPolicy.RUNTIME) @Documented -@Retention(RUNTIME) -@Target({ METHOD, ANNOTATION_TYPE }) public @interface Timed { /** diff --git a/spring-test/src/main/java/org/springframework/test/context/jdbc/MergedSqlConfig.java b/spring-test/src/main/java/org/springframework/test/context/jdbc/MergedSqlConfig.java index 63dc1c1b713..4a59cad4f93 100644 --- a/spring-test/src/main/java/org/springframework/test/context/jdbc/MergedSqlConfig.java +++ b/spring-test/src/main/java/org/springframework/test/context/jdbc/MergedSqlConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 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. @@ -27,8 +27,8 @@ import org.springframework.util.Assert; /** * {@code MergedSqlConfig} encapsulates the merged {@link SqlConfig @SqlConfig} - * attributes declared locally via {@link Sql#config} and globally as a - * class-level annotation. + * attributes declared locally via {@link Sql#config} and globally as a class-level annotation. + * *

Explicit local configuration attributes override global configuration attributes. * * @author Sam Brannen @@ -56,23 +56,6 @@ class MergedSqlConfig { private final ErrorMode errorMode; - private static > E getEnum(AnnotationAttributes attributes, String attributeName, - E inheritedOrDefaultValue, E defaultValue) { - E value = attributes.getEnum(attributeName); - if (value == inheritedOrDefaultValue) { - value = defaultValue; - } - return value; - } - - private static String getString(AnnotationAttributes attributes, String attributeName, String defaultValue) { - String value = attributes.getString(attributeName); - if ("".equals(value)) { - value = defaultValue; - } - return value; - } - /** * Construct a {@code MergedSqlConfig} instance by merging the configuration * from the supplied local (potentially method-level) {@code @SqlConfig} annotation @@ -86,8 +69,8 @@ class MergedSqlConfig { Assert.notNull(testClass, "testClass must not be null"); // Get global attributes, if any. - AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(testClass, - SqlConfig.class.getName(), false, false); + AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes( + testClass, SqlConfig.class.getName(), false, false); // Override global attributes with local attributes. if (attributes != null) { @@ -95,7 +78,7 @@ class MergedSqlConfig { Object value = AnnotationUtils.getValue(localSqlConfig, key); if (value != null) { // Is the value explicit (i.e., not a 'default')? - if (!value.equals("") && (value != TransactionMode.DEFAULT) && (value != ErrorMode.DEFAULT)) { + if (!value.equals("") && value != TransactionMode.DEFAULT && value != ErrorMode.DEFAULT) { attributes.put(key, value); } } @@ -113,9 +96,9 @@ class MergedSqlConfig { this.separator = getString(attributes, "separator", ScriptUtils.DEFAULT_STATEMENT_SEPARATOR); this.commentPrefix = getString(attributes, "commentPrefix", ScriptUtils.DEFAULT_COMMENT_PREFIX); this.blockCommentStartDelimiter = getString(attributes, "blockCommentStartDelimiter", - ScriptUtils.DEFAULT_BLOCK_COMMENT_START_DELIMITER); + ScriptUtils.DEFAULT_BLOCK_COMMENT_START_DELIMITER); this.blockCommentEndDelimiter = getString(attributes, "blockCommentEndDelimiter", - ScriptUtils.DEFAULT_BLOCK_COMMENT_END_DELIMITER); + ScriptUtils.DEFAULT_BLOCK_COMMENT_END_DELIMITER); this.errorMode = getEnum(attributes, "errorMode", ErrorMode.DEFAULT, ErrorMode.FAIL_ON_ERROR); } @@ -187,17 +170,36 @@ class MergedSqlConfig { */ @Override public String toString() { - return new ToStringCreator(this)// - .append("dataSource", dataSource)// - .append("transactionManager", transactionManager)// - .append("transactionMode", transactionMode)// - .append("encoding", encoding)// - .append("separator", separator)// - .append("commentPrefix", commentPrefix)// - .append("blockCommentStartDelimiter", blockCommentStartDelimiter)// - .append("blockCommentEndDelimiter", blockCommentEndDelimiter)// - .append("errorMode", errorMode)// - .toString(); + return new ToStringCreator(this) + .append("dataSource", this.dataSource) + .append("transactionManager", this.transactionManager) + .append("transactionMode", this.transactionMode) + .append("encoding", this.encoding) + .append("separator", this.separator) + .append("commentPrefix", this.commentPrefix) + .append("blockCommentStartDelimiter", this.blockCommentStartDelimiter) + .append("blockCommentEndDelimiter", this.blockCommentEndDelimiter) + .append("errorMode", this.errorMode) + .toString(); + } + + + private static > E getEnum(AnnotationAttributes attributes, String attributeName, + E inheritedOrDefaultValue, E defaultValue) { + + E value = attributes.getEnum(attributeName); + if (value == inheritedOrDefaultValue) { + value = defaultValue; + } + return value; + } + + private static String getString(AnnotationAttributes attributes, String attributeName, String defaultValue) { + String value = attributes.getString(attributeName); + if ("".equals(value)) { + value = defaultValue; + } + return value; } } diff --git a/spring-test/src/main/java/org/springframework/test/context/jdbc/Sql.java b/spring-test/src/main/java/org/springframework/test/context/jdbc/Sql.java index e413b7b3e0c..65fe0a83139 100644 --- a/spring-test/src/main/java/org/springframework/test/context/jdbc/Sql.java +++ b/spring-test/src/main/java/org/springframework/test/context/jdbc/Sql.java @@ -17,16 +17,15 @@ package org.springframework.test.context.jdbc; import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.core.annotation.AliasFor; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.*; - /** * {@code @Sql} is used to annotate a test class or test method to configure * SQL {@link #scripts} and {@link #statements} to be executed against a given @@ -65,10 +64,10 @@ import static java.lang.annotation.RetentionPolicy.*; * @see org.springframework.jdbc.datasource.init.ResourceDatabasePopulator * @see org.springframework.jdbc.datasource.init.ScriptUtils */ +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) @Documented @Inherited -@Retention(RUNTIME) -@Target({TYPE, METHOD}) @Repeatable(SqlGroup.class) public @interface Sql { @@ -88,7 +87,6 @@ public @interface Sql { * {@link #value}, but it may be used instead of {@link #value}. Similarly, * this attribute may be used in conjunction with or instead of * {@link #statements}. - * *

Path Resource Semantics

*

Each path will be interpreted as a Spring * {@link org.springframework.core.io.Resource Resource}. A plain path @@ -101,7 +99,6 @@ public @interface Sql { * {@link org.springframework.util.ResourceUtils#CLASSPATH_URL_PREFIX classpath:}, * {@link org.springframework.util.ResourceUtils#FILE_URL_PREFIX file:}, * {@code http:}, etc.) will be loaded using the specified resource protocol. - * *

Default Script Detection

*

If no SQL scripts or {@link #statements} are specified, an attempt will * be made to detect a default script depending on where this @@ -116,7 +113,6 @@ public @interface Sql { * {@code com.example.MyTest}, the corresponding default script is * {@code "classpath:com/example/MyTest.testMethod.sql"}. * - * * @see #value * @see #statements */ @@ -127,13 +123,11 @@ public @interface Sql { * Inlined SQL statements to execute. *

This attribute may be used in conjunction with or instead of * {@link #scripts}. - * *

Ordering

*

Statements declared via this attribute will be executed after * statements loaded from resource {@link #scripts}. If you wish to have * inlined statements executed before scripts, simply declare multiple * instances of {@code @Sql} on the same class or method. - * * @since 4.2 * @see #scripts */ diff --git a/spring-test/src/main/java/org/springframework/test/context/jdbc/SqlConfig.java b/spring-test/src/main/java/org/springframework/test/context/jdbc/SqlConfig.java index 9c0d55a6a0a..31b8805b805 100644 --- a/spring-test/src/main/java/org/springframework/test/context/jdbc/SqlConfig.java +++ b/spring-test/src/main/java/org/springframework/test/context/jdbc/SqlConfig.java @@ -17,13 +17,12 @@ package org.springframework.test.context.jdbc; import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.*; - /** * {@code @SqlConfig} defines metadata that is used to determine how to parse * and execute SQL scripts configured via the {@link Sql @Sql} annotation. @@ -59,10 +58,10 @@ import static java.lang.annotation.RetentionPolicy.*; * @since 4.1 * @see Sql */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) @Documented @Inherited -@Retention(RUNTIME) -@Target(TYPE) public @interface SqlConfig { /** diff --git a/spring-test/src/main/java/org/springframework/test/context/jdbc/SqlGroup.java b/spring-test/src/main/java/org/springframework/test/context/jdbc/SqlGroup.java index 6e052bd607f..e5bfd24e702 100644 --- a/spring-test/src/main/java/org/springframework/test/context/jdbc/SqlGroup.java +++ b/spring-test/src/main/java/org/springframework/test/context/jdbc/SqlGroup.java @@ -17,13 +17,12 @@ package org.springframework.test.context.jdbc; import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.*; - /** * Container annotation that aggregates several {@link Sql @Sql} annotations. * @@ -39,10 +38,10 @@ import static java.lang.annotation.RetentionPolicy.*; * @since 4.1 * @see Sql */ +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) @Documented @Inherited -@Retention(RUNTIME) -@Target({TYPE, METHOD}) public @interface SqlGroup { Sql[] value(); diff --git a/spring-test/src/main/java/org/springframework/test/context/transaction/AfterTransaction.java b/spring-test/src/main/java/org/springframework/test/context/transaction/AfterTransaction.java index ea21cc7fb70..04ebe481528 100644 --- a/spring-test/src/main/java/org/springframework/test/context/transaction/AfterTransaction.java +++ b/spring-test/src/main/java/org/springframework/test/context/transaction/AfterTransaction.java @@ -17,12 +17,11 @@ package org.springframework.test.context.transaction; import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.*; - /** *

Test annotation to indicate that the annotated {@code public void} method * should be executed after a transaction is ended for a test method @@ -39,8 +38,8 @@ import static java.lang.annotation.RetentionPolicy.*; * @see org.springframework.transaction.annotation.Transactional * @see BeforeTransaction */ +@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) +@Retention(RetentionPolicy.RUNTIME) @Documented -@Retention(RUNTIME) -@Target({ METHOD, ANNOTATION_TYPE }) public @interface AfterTransaction { } diff --git a/spring-test/src/main/java/org/springframework/test/context/transaction/BeforeTransaction.java b/spring-test/src/main/java/org/springframework/test/context/transaction/BeforeTransaction.java index 05106390cab..b7110015bc5 100644 --- a/spring-test/src/main/java/org/springframework/test/context/transaction/BeforeTransaction.java +++ b/spring-test/src/main/java/org/springframework/test/context/transaction/BeforeTransaction.java @@ -17,12 +17,11 @@ package org.springframework.test.context.transaction; import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.*; - /** *

Test annotation to indicate that the annotated {@code public void} method * should be executed before a transaction is started for a test method @@ -39,8 +38,8 @@ import static java.lang.annotation.RetentionPolicy.*; * @see org.springframework.transaction.annotation.Transactional * @see AfterTransaction */ +@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) +@Retention(RetentionPolicy.RUNTIME) @Documented -@Retention(RUNTIME) -@Target({ METHOD, ANNOTATION_TYPE }) public @interface BeforeTransaction { } diff --git a/spring-test/src/main/java/org/springframework/test/context/web/WebAppConfiguration.java b/spring-test/src/main/java/org/springframework/test/context/web/WebAppConfiguration.java index b2434c5879e..e9d176109ed 100644 --- a/spring-test/src/main/java/org/springframework/test/context/web/WebAppConfiguration.java +++ b/spring-test/src/main/java/org/springframework/test/context/web/WebAppConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2016 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. @@ -31,8 +31,8 @@ import org.springframework.test.context.BootstrapWith; * should be a {@link org.springframework.web.context.WebApplicationContext * WebApplicationContext}. * - *

The mere presence of {@code @WebAppConfiguration} on a test class ensures - * that a {@code WebApplicationContext} will be loaded for the test using a default + *

The presence of {@code @WebAppConfiguration} on a test class indicates that + * a {@code WebApplicationContext} should be loaded for the test using a default * for the path to the root of the web application. To override the default, * specify an explicit resource path via the {@link #value} attribute. * @@ -49,20 +49,18 @@ import org.springframework.test.context.BootstrapWith; * @see org.springframework.test.context.ContextConfiguration * @see ServletTestExecutionListener */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) @Documented @Inherited -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) @BootstrapWith(WebTestContextBootstrapper.class) public @interface WebAppConfiguration { /** * The resource path to the root directory of the web application. - * *

A path that does not include a Spring resource prefix (e.g., {@code classpath:}, * {@code file:}, etc.) will be interpreted as a file system resource, and a * path should not end with a slash. - * *

Defaults to {@code "src/main/webapp"} as a file system resource. Note * that this is the standard directory for the root of a web application in * a project that follows the standard Maven project layout for a WAR. diff --git a/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java b/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java index 2503a998de7..9e113f5c18c 100644 --- a/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java +++ b/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 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. @@ -196,10 +196,10 @@ public abstract class MetaAnnotationUtils { for (Annotation composedAnnotation : clazz.getDeclaredAnnotations()) { if (!AnnotationUtils.isInJavaLangAnnotationPackage(composedAnnotation) && visited.add(composedAnnotation)) { UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes( - composedAnnotation.annotationType(), visited, annotationTypes); + composedAnnotation.annotationType(), visited, annotationTypes); if (descriptor != null) { return new UntypedAnnotationDescriptor(clazz, descriptor.getDeclaringClass(), composedAnnotation, - descriptor.getAnnotation()); + descriptor.getAnnotation()); } } } @@ -274,13 +274,13 @@ public abstract class MetaAnnotationUtils { private final AnnotationAttributes annotationAttributes; - public AnnotationDescriptor(Class rootDeclaringClass, T annotation) { this(rootDeclaringClass, rootDeclaringClass, null, annotation); } public AnnotationDescriptor(Class rootDeclaringClass, Class declaringClass, Annotation composedAnnotation, T annotation) { + Assert.notNull(rootDeclaringClass, "rootDeclaringClass must not be null"); Assert.notNull(annotation, "annotation must not be null"); this.rootDeclaringClass = rootDeclaringClass; @@ -362,6 +362,7 @@ public abstract class MetaAnnotationUtils { public UntypedAnnotationDescriptor(Class rootDeclaringClass, Class declaringClass, Annotation composedAnnotation, Annotation annotation) { + super(rootDeclaringClass, declaringClass, composedAnnotation, annotation); } @@ -374,7 +375,7 @@ public abstract class MetaAnnotationUtils { @Override public Annotation synthesizeAnnotation() { throw new UnsupportedOperationException( - "getMergedAnnotation() is unsupported in UntypedAnnotationDescriptor"); + "getMergedAnnotation() is unsupported in UntypedAnnotationDescriptor"); } } diff --git a/spring-tx/src/main/java/org/springframework/transaction/event/TransactionalEventListenerFactory.java b/spring-tx/src/main/java/org/springframework/transaction/event/TransactionalEventListenerFactory.java index b40fc0f9e07..19d5ab82f86 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/event/TransactionalEventListenerFactory.java +++ b/spring-tx/src/main/java/org/springframework/transaction/event/TransactionalEventListenerFactory.java @@ -41,7 +41,7 @@ public class TransactionalEventListenerFactory implements EventListenerFactory, @Override public int getOrder() { - return order; + return this.order; } diff --git a/spring-web/src/main/java/org/springframework/http/converter/AbstractHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/AbstractHttpMessageConverter.java index 68289532451..1f1e200882b 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/AbstractHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/AbstractHttpMessageConverter.java @@ -130,7 +130,7 @@ public abstract class AbstractHttpMessageConverter implements HttpMessageConv @Override public boolean canWrite(Class clazz, MediaType mediaType) { return supports(clazz) && canWrite(mediaType); - } + } /** * Returns {@code true} if the given media type includes any of the diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/ModelFactory.java b/spring-web/src/main/java/org/springframework/web/method/annotation/ModelFactory.java index 9ee2bbdea3f..9eb31c0d361 100644 --- a/spring-web/src/main/java/org/springframework/web/method/annotation/ModelFactory.java +++ b/spring-web/src/main/java/org/springframework/web/method/annotation/ModelFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2016 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. @@ -45,14 +45,14 @@ import org.springframework.web.method.support.InvocableHandlerMethod; import org.springframework.web.method.support.ModelAndViewContainer; /** - * Provides methods to initialize the {@link Model} before controller method - * invocation and to update it afterwards. + * Assist with initialization of the {@link Model} before controller method + * invocation and with updates to it after the invocation. * - *

On initialization, the model is populated with attributes from the session - * and by invoking methods annotated with {@code @ModelAttribute}. + *

On initialization the model is populated with attributes temporarily stored + * in the session and through the invocation of {@code @ModelAttribute} methods. * - *

On update, model attributes are synchronized with the session and also - * {@link BindingResult} attributes are added where missing. + *

On update model attributes are synchronized with the session and also + * {@link BindingResult} attributes are added if missing. * * @author Rossen Stoyanchev * @since 3.1 @@ -70,51 +70,51 @@ public final class ModelFactory { /** * Create a new instance with the given {@code @ModelAttribute} methods. - * @param invocableMethods the {@code @ModelAttribute} methods to invoke - * @param dataBinderFactory for preparation of {@link BindingResult} attributes - * @param sessionAttributesHandler for access to session attributes + * @param handlerMethods the {@code @ModelAttribute} methods to invoke + * @param binderFactory for preparation of {@link BindingResult} attributes + * @param attributeHandler for access to session attributes */ - public ModelFactory(List invocableMethods, WebDataBinderFactory dataBinderFactory, - SessionAttributesHandler sessionAttributesHandler) { + public ModelFactory(List handlerMethods, + WebDataBinderFactory binderFactory, SessionAttributesHandler attributeHandler) { - if (invocableMethods != null) { - for (InvocableHandlerMethod method : invocableMethods) { - this.modelMethods.add(new ModelMethod(method)); + if (handlerMethods != null) { + for (InvocableHandlerMethod handlerMethod : handlerMethods) { + this.modelMethods.add(new ModelMethod(handlerMethod)); } } - this.dataBinderFactory = dataBinderFactory; - this.sessionAttributesHandler = sessionAttributesHandler; + this.dataBinderFactory = binderFactory; + this.sessionAttributesHandler = attributeHandler; } + /** * Populate the model in the following order: *

    - *
  1. Retrieve "known" session attributes listed as {@code @SessionAttributes}. - *
  2. Invoke {@code @ModelAttribute} methods - *
  3. Find {@code @ModelAttribute} method arguments also listed as - * {@code @SessionAttributes} and ensure they're present in the model raising - * an exception if necessary. + *
  4. Retrieve "known" session attributes listed as {@code @SessionAttributes}. + *
  5. Invoke {@code @ModelAttribute} methods + *
  6. Find {@code @ModelAttribute} method arguments also listed as + * {@code @SessionAttributes} and ensure they're present in the model raising + * an exception if necessary. *
* @param request the current request - * @param mavContainer a container with the model to be initialized + * @param container a container with the model to be initialized * @param handlerMethod the method for which the model is initialized * @throws Exception may arise from {@code @ModelAttribute} methods */ - public void initModel(NativeWebRequest request, ModelAndViewContainer mavContainer, HandlerMethod handlerMethod) - throws Exception { + public void initModel(NativeWebRequest request, ModelAndViewContainer container, + HandlerMethod handlerMethod) throws Exception { Map sessionAttributes = this.sessionAttributesHandler.retrieveAttributes(request); - mavContainer.mergeAttributes(sessionAttributes); - - invokeModelAttributeMethods(request, mavContainer); + container.mergeAttributes(sessionAttributes); + invokeModelAttributeMethods(request, container); for (String name : findSessionAttributeArguments(handlerMethod)) { - if (!mavContainer.containsAttribute(name)) { + if (!container.containsAttribute(name)) { Object value = this.sessionAttributesHandler.retrieveAttribute(request, name); if (value == null) { throw new HttpSessionRequiredException("Expected session attribute '" + name + "'"); } - mavContainer.addAttribute(name, value); + container.addAttribute(name, value); } } } @@ -123,30 +123,29 @@ public final class ModelFactory { * Invoke model attribute methods to populate the model. * Attributes are added only if not already present in the model. */ - private void invokeModelAttributeMethods(NativeWebRequest request, ModelAndViewContainer mavContainer) + private void invokeModelAttributeMethods(NativeWebRequest request, ModelAndViewContainer container) throws Exception { while (!this.modelMethods.isEmpty()) { - InvocableHandlerMethod attrMethod = getNextModelMethod(mavContainer).getHandlerMethod(); - String modelName = attrMethod.getMethodAnnotation(ModelAttribute.class).value(); - if (mavContainer.containsAttribute(modelName)) { + InvocableHandlerMethod modelMethod = getNextModelMethod(container).getHandlerMethod(); + String modelName = modelMethod.getMethodAnnotation(ModelAttribute.class).value(); + if (container.containsAttribute(modelName)) { continue; } - Object returnValue = attrMethod.invokeForRequest(request, mavContainer); - - if (!attrMethod.isVoid()){ - String returnValueName = getNameForReturnValue(returnValue, attrMethod.getReturnType()); - if (!mavContainer.containsAttribute(returnValueName)) { - mavContainer.addAttribute(returnValueName, returnValue); + Object returnValue = modelMethod.invokeForRequest(request, container); + if (!modelMethod.isVoid()){ + String returnValueName = getNameForReturnValue(returnValue, modelMethod.getReturnType()); + if (!container.containsAttribute(returnValueName)) { + container.addAttribute(returnValueName, returnValue); } } } } - private ModelMethod getNextModelMethod(ModelAndViewContainer mavContainer) { + private ModelMethod getNextModelMethod(ModelAndViewContainer container) { for (ModelMethod modelMethod : this.modelMethods) { - if (modelMethod.checkDependencies(mavContainer)) { + if (modelMethod.checkDependencies(container)) { if (logger.isTraceEnabled()) { logger.trace("Selected @ModelAttribute method " + modelMethod); } @@ -157,7 +156,7 @@ public final class ModelFactory { ModelMethod modelMethod = this.modelMethods.get(0); if (logger.isTraceEnabled()) { logger.trace("Selected @ModelAttribute method (not present: " + - modelMethod.getUnresolvedDependencies(mavContainer)+ ") " + modelMethod); + modelMethod.getUnresolvedDependencies(container)+ ") " + modelMethod); } this.modelMethods.remove(modelMethod); return modelMethod; @@ -171,7 +170,8 @@ public final class ModelFactory { for (MethodParameter parameter : handlerMethod.getMethodParameters()) { if (parameter.hasParameterAnnotation(ModelAttribute.class)) { String name = getNameForParameter(parameter); - if (this.sessionAttributesHandler.isHandlerSessionAttribute(name, parameter.getParameterType())) { + Class paramType = parameter.getParameterType(); + if (this.sessionAttributesHandler.isHandlerSessionAttribute(name, paramType)) { result.add(name); } } @@ -182,36 +182,37 @@ public final class ModelFactory { /** * Derives the model attribute name for a method parameter based on: *
    - *
  1. The parameter {@code @ModelAttribute} annotation value - *
  2. The parameter type + *
  3. The parameter {@code @ModelAttribute} annotation value + *
  4. The parameter type *
* @return the derived name; never {@code null} or an empty string */ public static String getNameForParameter(MethodParameter parameter) { - ModelAttribute annot = parameter.getParameterAnnotation(ModelAttribute.class); - String attrName = (annot != null) ? annot.value() : null; - return StringUtils.hasText(attrName) ? attrName : Conventions.getVariableNameForParameter(parameter); + ModelAttribute ann = parameter.getParameterAnnotation(ModelAttribute.class); + String name = (ann != null ? ann.value() : null); + return StringUtils.hasText(name) ? name : Conventions.getVariableNameForParameter(parameter); } /** * Derive the model attribute name for the given return value using one of: *
    - *
  1. The method {@code ModelAttribute} annotation value - *
  2. The declared return type if it is more specific than {@code Object} - *
  3. The actual return value type + *
  4. The method {@code ModelAttribute} annotation value + *
  5. The declared return type if it is more specific than {@code Object} + *
  6. The actual return value type *
* @param returnValue the value returned from a method invocation * @param returnType the return type of the method * @return the model name, never {@code null} nor empty */ public static String getNameForReturnValue(Object returnValue, MethodParameter returnType) { - ModelAttribute annotation = returnType.getMethodAnnotation(ModelAttribute.class); - if (annotation != null && StringUtils.hasText(annotation.value())) { - return annotation.value(); + ModelAttribute ann = returnType.getMethodAnnotation(ModelAttribute.class); + if (ann != null && StringUtils.hasText(ann.value())) { + return ann.value(); } else { Method method = returnType.getMethod(); - Class resolvedType = GenericTypeResolver.resolveReturnType(method, returnType.getContainingClass()); + Class containingClass = returnType.getContainingClass(); + Class resolvedType = GenericTypeResolver.resolveReturnType(method, containingClass); return Conventions.getVariableNameForReturnType(method, resolvedType, returnValue); } } @@ -220,18 +221,18 @@ public final class ModelFactory { * Promote model attributes listed as {@code @SessionAttributes} to the session. * Add {@link BindingResult} attributes where necessary. * @param request the current request - * @param mavContainer contains the model to update + * @param container contains the model to update * @throws Exception if creating BindingResult attributes fails */ - public void updateModel(NativeWebRequest request, ModelAndViewContainer mavContainer) throws Exception { - ModelMap defaultModel = mavContainer.getDefaultModel(); - if (mavContainer.getSessionStatus().isComplete()){ + public void updateModel(NativeWebRequest request, ModelAndViewContainer container) throws Exception { + ModelMap defaultModel = container.getDefaultModel(); + if (container.getSessionStatus().isComplete()){ this.sessionAttributesHandler.cleanupAttributes(request); } else { this.sessionAttributesHandler.storeAttributes(request, defaultModel); } - if (!mavContainer.isRequestHandled() && mavContainer.getModel() == defaultModel) { + if (!container.isRequestHandled() && container.getModel() == defaultModel) { updateBindingResult(request, defaultModel); } } @@ -248,7 +249,7 @@ public final class ModelFactory { String bindingResultKey = BindingResult.MODEL_KEY_PREFIX + name; if (!model.containsAttribute(bindingResultKey)) { - WebDataBinder dataBinder = dataBinderFactory.createBinder(request, value, name); + WebDataBinder dataBinder = this.dataBinderFactory.createBinder(request, value, name); model.put(bindingResultKey, dataBinder.getBindingResult()); } } @@ -279,7 +280,6 @@ public final class ModelFactory { private final Set dependencies = new HashSet(); - private ModelMethod(InvocableHandlerMethod handlerMethod) { this.handlerMethod = handlerMethod; for (MethodParameter parameter : handlerMethod.getMethodParameters()) { diff --git a/spring-web/src/main/java/org/springframework/web/method/support/HandlerMethodReturnValueHandlerComposite.java b/spring-web/src/main/java/org/springframework/web/method/support/HandlerMethodReturnValueHandlerComposite.java index 36d2c25d887..847068de2ea 100644 --- a/spring-web/src/main/java/org/springframework/web/method/support/HandlerMethodReturnValueHandlerComposite.java +++ b/spring-web/src/main/java/org/springframework/web/method/support/HandlerMethodReturnValueHandlerComposite.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2016 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. @@ -24,7 +24,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.core.MethodParameter; -import org.springframework.util.Assert; import org.springframework.web.context.request.NativeWebRequest; /** @@ -76,7 +75,9 @@ public class HandlerMethodReturnValueHandlerComposite implements AsyncHandlerMet ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception { HandlerMethodReturnValueHandler handler = selectHandler(returnValue, returnType); - Assert.notNull(handler, "Unknown return value type [" + returnType.getParameterType().getName() + "]"); + if (handler == null) { + throw new IllegalArgumentException("Unknown return value type: " + returnType.getParameterType().getName()); + } handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/WebContentGenerator.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/WebContentGenerator.java index 947d77ab11c..20cf89d2c02 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/WebContentGenerator.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/WebContentGenerator.java @@ -18,14 +18,15 @@ package org.springframework.web.servlet.support; import java.util.Arrays; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; import java.util.concurrent.TimeUnit; - import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.http.CacheControl; +import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.HttpSessionRequiredException; @@ -133,8 +134,8 @@ public abstract class WebContentGenerator extends WebApplicationObjectSupport { * unrestricted for general controllers and interceptors. */ public final void setSupportedMethods(String... methods) { - if (methods != null) { - this.supportedMethods = new HashSet(Arrays.asList(methods)); + if (!ObjectUtils.isEmpty(methods)) { + this.supportedMethods = new LinkedHashSet(Arrays.asList(methods)); } else { this.supportedMethods = null; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/SpringConfigurator.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/SpringConfigurator.java index 1bd00abe229..5f13d12a497 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/SpringConfigurator.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/SpringConfigurator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2016 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. @@ -77,9 +77,9 @@ public class SpringConfigurator extends Configurator { return endpoint; } - Component annot = AnnotationUtils.findAnnotation(endpointClass, Component.class); - if ((annot != null) && wac.containsBean(annot.value())) { - T endpoint = wac.getBean(annot.value(), endpointClass); + Component ann = AnnotationUtils.findAnnotation(endpointClass, Component.class); + if (ann != null && wac.containsBean(ann.value())) { + T endpoint = wac.getBean(ann.value(), endpointClass); if (logger.isTraceEnabled()) { logger.trace("Using @ServerEndpoint singleton " + endpoint); }