diff --git a/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java b/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java index 83230f7461..e88a4d3b72 100644 --- a/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java +++ b/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java @@ -125,8 +125,10 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware { Executor executorToUse = this.defaultExecutor; String qualifier = getExecutorQualifier(method); if (StringUtils.hasLength(qualifier)) { - Assert.notNull(this.beanFactory, "BeanFactory must be set on " + getClass().getSimpleName() + - " to access qualified executor '" + qualifier + "'"); + if (this.beanFactory == null) { + throw new IllegalStateException("BeanFactory must be set on " + getClass().getSimpleName() + + " to access qualified executor '" + qualifier + "'"); + } executorToUse = BeanFactoryAnnotationUtils.qualifiedBeanOfType( this.beanFactory, Executor.class, qualifier); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index ff8eac4403..0f950b8a25 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -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. @@ -679,7 +679,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac if (Modifier.isStatic(factoryMethod.getModifiers()) == isStatic && factoryMethod.getName().equals(mbd.getFactoryMethodName()) && factoryMethod.getParameterTypes().length >= minNrOfArgs) { - // No declared type variables to inspect, so just process the standard return type. + // Declared type variables to inspect? if (factoryMethod.getTypeParameters().length > 0) { try { // Fully resolve parameter names and argument values. @@ -833,8 +833,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac /** * Obtain a "shortcut" singleton FactoryBean instance to use for a - * {@code getObjectType()} call, without full initialization - * of the FactoryBean. + * {@code getObjectType()} call, without full initialization of the FactoryBean. * @param beanName the name of the bean * @param mbd the bean definition for the bean * @return the FactoryBean instance, or {@code null} to indicate @@ -875,8 +874,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac /** * Obtain a "shortcut" non-singleton FactoryBean instance to use for a - * {@code getObjectType()} call, without full initialization - * of the FactoryBean. + * {@code getObjectType()} call, without full initialization of the FactoryBean. * @param beanName the name of the bean * @param mbd the bean definition for the bean * @return the FactoryBean instance, or {@code null} to indicate diff --git a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationScopeMetadataResolver.java b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationScopeMetadataResolver.java index 5d4ce9c952..08220e9b74 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationScopeMetadataResolver.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationScopeMetadataResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 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. @@ -25,10 +25,10 @@ import org.springframework.util.Assert; /** * A {@link ScopeMetadataResolver} implementation that by default checks for - * the presence of Spring's {@link Scope} annotation on the bean class. + * the presence of Spring's {@link Scope @Scope} annotation on the bean class. * - *

The exact type of annotation that is checked for is configurable via the - * {@link #setScopeAnnotationType(Class)} property. + *

The exact type of annotation that is checked for is configurable via + * {@link #setScopeAnnotationType(Class)}. * * @author Mark Fisher * @author Juergen Hoeller @@ -43,7 +43,7 @@ public class AnnotationScopeMetadataResolver implements ScopeMetadataResolver { /** - * Create a new instance of the {@code AnnotationScopeMetadataResolver} class. + * Construct a new {@code AnnotationScopeMetadataResolver}. * @see #AnnotationScopeMetadataResolver(ScopedProxyMode) * @see ScopedProxyMode#NO */ @@ -52,8 +52,9 @@ public class AnnotationScopeMetadataResolver implements ScopeMetadataResolver { } /** - * Create a new instance of the {@code AnnotationScopeMetadataResolver} class. - * @param defaultProxyMode the desired scoped-proxy mode + * Construct a new {@code AnnotationScopeMetadataResolver} using the + * supplied default {@link ScopedProxyMode}. + * @param defaultProxyMode the default scoped-proxy mode */ public AnnotationScopeMetadataResolver(ScopedProxyMode defaultProxyMode) { Assert.notNull(defaultProxyMode, "'defaultProxyMode' must not be null"); @@ -63,7 +64,7 @@ public class AnnotationScopeMetadataResolver implements ScopeMetadataResolver { /** * Set the type of annotation that is checked for by this - * {@link AnnotationScopeMetadataResolver}. + * {@code AnnotationScopeMetadataResolver}. * @param scopeAnnotationType the target annotation type */ public void setScopeAnnotationType(Class scopeAnnotationType) { diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/EnableAsync.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/EnableAsync.java index e02ce9dd5c..9c9f439732 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/EnableAsync.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/EnableAsync.java @@ -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. @@ -138,11 +138,11 @@ import org.springframework.core.Ordered; public @interface EnableAsync { /** - * Indicate the 'async' annotation type to be detected at either class - * or method level. By default, both the {@link Async} annotation and - * the EJB 3.1 {@code javax.ejb.Asynchronous} annotation will be - * detected.

This setter property exists so that developers can provide - * their own (non-Spring-specific) annotation type to indicate that a method + * Indicate the 'async' annotation type to be detected at either class or + * method level. By default, both the {@link Async} annotation and the + * EJB 3.1 {@code javax.ejb.Asynchronous} annotation will be detected. + *

This setter property exists so that developers can provide their + * own (non-Spring-specific) annotation type to indicate that a method * (or all methods of a given class) should be invoked asynchronously. */ Class annotation() default Annotation.class; @@ -151,7 +151,6 @@ public @interface EnableAsync { * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed * to standard Java interface-based proxies. The default is {@code false}. * Applicable only if {@link #mode()} is set to {@link AdviceMode#PROXY}. - * *

Note that setting this attribute to {@code true} will affect all * Spring-managed beans requiring proxying, not just those marked with {@code @Async}. * For example, other beans marked with Spring's {@code @Transactional} annotation @@ -176,4 +175,5 @@ public @interface EnableAsync { * existing proxies rather than double-proxy. */ int order() default Ordered.LOWEST_PRECEDENCE; + } diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/SchedulingConfiguration.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/SchedulingConfiguration.java index 28db2a3a11..bdc33c4a8d 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/SchedulingConfiguration.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/SchedulingConfiguration.java @@ -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. @@ -23,13 +23,12 @@ import org.springframework.context.annotation.Role; import org.springframework.scheduling.config.TaskManagementConfigUtils; /** - * {@code @Configuration} class that registers a {@link - * ScheduledAnnotationBeanPostProcessor} bean capable of processing Spring's @{@link - * Scheduled} annotation. + * {@code @Configuration} class that registers a {@link ScheduledAnnotationBeanPostProcessor} + * bean capable of processing Spring's @{@link Scheduled} annotation. * - *

This configuration class is automatically imported when using the @{@link - * EnableScheduling} annotation. See {@code @EnableScheduling} Javadoc for complete usage - * details. + *

This configuration class is automatically imported when using the + * @{@link EnableScheduling} annotation. See {@code @EnableScheduling}'s javadoc + * for complete usage details. * * @author Chris Beams * @since 3.1 diff --git a/spring-context/src/main/java/org/springframework/validation/DataBinder.java b/spring-context/src/main/java/org/springframework/validation/DataBinder.java index 73b1753836..1e1172d792 100644 --- a/spring-context/src/main/java/org/springframework/validation/DataBinder.java +++ b/spring-context/src/main/java/org/springframework/validation/DataBinder.java @@ -543,7 +543,7 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter { * Return the primary Validator to apply after each binding step, if any. */ public Validator getValidator() { - return this.validators.size() > 0 ? this.validators.get(0) : null; + return (this.validators.size() > 0 ? this.validators.get(0) : null); } /** diff --git a/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java b/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java index b3881e0793..ed7ea99fef 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java @@ -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. @@ -67,17 +67,6 @@ public class EnableAsyncTests { asyncBean.work(); } - - @Configuration - @EnableAsync - static class AsyncConfig { - @Bean - public AsyncBean asyncBean() { - return new AsyncBean(); - } - } - - @Test public void withAsyncBeanWithExecutorQualifiedByName() throws ExecutionException, InterruptedException { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); @@ -95,49 +84,6 @@ public class EnableAsyncTests { assertThat(workerThread3.get().getName(), startsWith("otherExecutor-")); } - - static class AsyncBeanWithExecutorQualifiedByName { - @Async - public Future work0() { - return new AsyncResult(Thread.currentThread()); - } - - @Async("e1") - public Future work() { - return new AsyncResult(Thread.currentThread()); - } - - @Async("otherExecutor") - public Future work2() { - return new AsyncResult(Thread.currentThread()); - } - - @Async("e2") - public Future work3() { - return new AsyncResult(Thread.currentThread()); - } - } - - - static class AsyncBean { - private Thread threadOfExecution; - - @Async - public void work() { - this.threadOfExecution = Thread.currentThread(); - } - - @Async - public void fail() { - throw new UnsupportedOperationException(); - } - - public Thread getThreadOfExecution() { - return threadOfExecution; - } - } - - @Test public void asyncProcessorIsOrderedLowestPrecedenceByDefault() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); @@ -148,7 +94,6 @@ public class EnableAsyncTests { assertThat(bpp.getOrder(), is(Ordered.LOWEST_PRECEDENCE)); } - @Test public void orderAttributeIsPropagated() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); @@ -159,17 +104,6 @@ public class EnableAsyncTests { assertThat(bpp.getOrder(), is(Ordered.HIGHEST_PRECEDENCE)); } - - @Configuration - @EnableAsync(order=Ordered.HIGHEST_PRECEDENCE) - static class OrderedAsyncConfig { - @Bean - public AsyncBean asyncBean() { - return new AsyncBean(); - } - } - - @Test public void customAsyncAnnotationIsPropagated() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); @@ -188,51 +122,16 @@ public class EnableAsyncTests { assertTrue("bean was not async advised as expected", isAsyncAdvised); } - - @Configuration - @EnableAsync(annotation=CustomAsync.class) - static class CustomAsyncAnnotationConfig { - @Bean - public CustomAsyncBean asyncBean() { - return new CustomAsyncBean(); - } - } - - - @Target(ElementType.METHOD) - @Retention(RetentionPolicy.RUNTIME) - @interface CustomAsync { - } - - - static class CustomAsyncBean { - @CustomAsync - public void work() { - } - } - - /** * Fails with classpath errors on trying to classload AnnotationAsyncExecutionAspect */ - @Test(expected=BeanDefinitionStoreException.class) + @Test(expected = BeanDefinitionStoreException.class) public void aspectModeAspectJAttemptsToRegisterAsyncAspect() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AspectJAsyncAnnotationConfig.class); ctx.refresh(); } - - @Configuration - @EnableAsync(mode=AdviceMode.ASPECTJ) - static class AspectJAsyncAnnotationConfig { - @Bean - public AsyncBean asyncBean() { - return new AsyncBean(); - } - } - - @Test public void customExecutorIsPropagated() throws InterruptedException { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); @@ -257,9 +156,112 @@ public class EnableAsyncTests { } + static class AsyncBeanWithExecutorQualifiedByName { + + @Async + public Future work0() { + return new AsyncResult(Thread.currentThread()); + } + + @Async("e1") + public Future work() { + return new AsyncResult(Thread.currentThread()); + } + + @Async("otherExecutor") + public Future work2() { + return new AsyncResult(Thread.currentThread()); + } + + @Async("e2") + public Future work3() { + return new AsyncResult(Thread.currentThread()); + } + } + + + static class AsyncBean { + + private Thread threadOfExecution; + + @Async + public void work() { + this.threadOfExecution = Thread.currentThread(); + } + + @Async + public void fail() { + throw new UnsupportedOperationException(); + } + + public Thread getThreadOfExecution() { + return threadOfExecution; + } + } + + + @Configuration + @EnableAsync(annotation = CustomAsync.class) + static class CustomAsyncAnnotationConfig { + + @Bean + public CustomAsyncBean asyncBean() { + return new CustomAsyncBean(); + } + } + + + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + @interface CustomAsync { + } + + + static class CustomAsyncBean { + + @CustomAsync + public void work() { + } + } + + + @Configuration + @EnableAsync(order = Ordered.HIGHEST_PRECEDENCE) + static class OrderedAsyncConfig { + + @Bean + public AsyncBean asyncBean() { + return new AsyncBean(); + } + } + + + @Configuration + @EnableAsync(mode = AdviceMode.ASPECTJ) + static class AspectJAsyncAnnotationConfig { + + @Bean + public AsyncBean asyncBean() { + return new AsyncBean(); + } + } + + + @Configuration + @EnableAsync + static class AsyncConfig { + + @Bean + public AsyncBean asyncBean() { + return new AsyncBean(); + } + } + + @Configuration @EnableAsync static class CustomExecutorAsyncConfig implements AsyncConfigurer { + @Bean public AsyncBean asyncBean() { return new AsyncBean(); @@ -275,7 +277,7 @@ public class EnableAsyncTests { @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { - return exceptionHandler(); + return exceptionHandler(); } @Bean @@ -288,6 +290,7 @@ public class EnableAsyncTests { @Configuration @EnableAsync static class AsyncWithExecutorQualifiedByNameConfig { + @Bean public AsyncBeanWithExecutorQualifiedByName asyncBean() { return new AsyncBeanWithExecutorQualifiedByName(); @@ -295,15 +298,14 @@ public class EnableAsyncTests { @Bean public Executor e1() { - ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); - return executor; + return new ThreadPoolTaskExecutor(); } @Bean @Qualifier("e2") public Executor otherExecutor() { - ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); - return executor; + return new ThreadPoolTaskExecutor(); } } + } diff --git a/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableSchedulingTests.java b/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableSchedulingTests.java index 646f1cd366..3d866de05f 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableSchedulingTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableSchedulingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 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. @@ -41,6 +41,7 @@ import static org.junit.Assert.*; * Tests use of @EnableScheduling on @Configuration classes. * * @author Chris Beams + * @author Sam Brannen * @since 3.1 */ public class EnableSchedulingTests { @@ -50,6 +51,7 @@ public class EnableSchedulingTests { Assume.group(TestGroup.PERFORMANCE); } + @Test public void withFixedRateTask() throws InterruptedException { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); @@ -138,12 +140,17 @@ public class EnableSchedulingTests { ctx.register(AmbiguousExplicitSchedulerConfig.class); try { ctx.refresh(); - } catch (IllegalStateException ex) { + } + catch (IllegalStateException ex) { assertThat(ex.getMessage(), startsWith("More than one TaskScheduler")); throw ex; } + finally { + ctx.close(); + } } + @EnableScheduling @Configuration static class AmbiguousExplicitSchedulerConfig { @@ -236,6 +243,7 @@ public class EnableSchedulingTests { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(SchedulingEnabled_withAmbiguousTaskSchedulers_butNoActualTasks.class); ctx.refresh(); + ctx.close(); } @@ -265,10 +273,14 @@ public class EnableSchedulingTests { ctx.register(SchedulingEnabled_withAmbiguousTaskSchedulers_andSingleTask.class); try { ctx.refresh(); - } catch (IllegalStateException ex) { - assertThat(ex.getMessage(), startsWith("More than one TaskScheduler and/or")); + } + catch (IllegalStateException ex) { + assertThat(ex.getMessage(), startsWith("More than one TaskScheduler")); throw ex; } + finally { + ctx.close(); + } } @@ -295,6 +307,7 @@ public class EnableSchedulingTests { } } + @Test public void withAmbiguousTaskSchedulers_andSingleTask_disambiguatedByScheduledTaskRegistrarBean() throws InterruptedException { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); @@ -476,6 +489,7 @@ public class EnableSchedulingTests { } } + @Test public void withInitiallyDelayedFixedRateTask() throws InterruptedException { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); @@ -486,8 +500,8 @@ public class EnableSchedulingTests { AtomicInteger counter = ctx.getBean(AtomicInteger.class); ctx.close(); - assertThat(counter.get(), greaterThan(0)); // the @Scheduled method was called - assertThat(counter.get(), lessThanOrEqualTo(10)); // but not more than times the delay allows + assertThat(counter.get(), greaterThan(0)); // the @Scheduled method was called + assertThat(counter.get(), lessThanOrEqualTo(10)); // but not more than times the delay allows } diff --git a/spring-core/src/main/java/org/springframework/core/MethodParameter.java b/spring-core/src/main/java/org/springframework/core/MethodParameter.java index ef43b7d7f2..831191cfb2 100644 --- a/spring-core/src/main/java/org/springframework/core/MethodParameter.java +++ b/spring-core/src/main/java/org/springframework/core/MethodParameter.java @@ -30,8 +30,9 @@ import org.springframework.util.Assert; /** * Helper class that encapsulates the specification of a method parameter, i.e. - * a Method or Constructor plus a parameter index and a nested type index for - * a declared generic type. Useful as a specification object to pass along. + * a {@link Method} or {@link Constructor} plus a parameter index and a nested + * type index for a declared generic type. Useful as a specification object to + * pass along. * * @author Juergen Hoeller * @author Rob Harrop @@ -66,20 +67,22 @@ public class MethodParameter { /** - * Create a new MethodParameter for the given method, with nesting level 1. + * Create a new {@code MethodParameter} for the given method, with nesting level 1. * @param method the Method to specify a parameter for - * @param parameterIndex the index of the parameter + * @param parameterIndex the index of the parameter: -1 for the method + * return type; 0 for the first method parameter; 1 for the second method + * parameter, etc. */ public MethodParameter(Method method, int parameterIndex) { this(method, parameterIndex, 1); } /** - * Create a new MethodParameter for the given method. + * Create a new {@code MethodParameter} for the given method. * @param method the Method to specify a parameter for - * @param parameterIndex the index of the parameter - * (-1 for the method return type; 0 for the first method parameter, - * 1 for the second method parameter, etc) + * @param parameterIndex the index of the parameter: -1 for the method + * return type; 0 for the first method parameter; 1 for the second method + * parameter, etc. * @param nestingLevel the nesting level of the target type * (typically 1; e.g. in case of a List of Lists, 1 would indicate the * nested List, whereas 2 would indicate the element of the nested List) @@ -197,7 +200,7 @@ public class MethodParameter { /** * Return the index of the method/constructor parameter. - * @return the parameter index (never negative) + * @return the parameter index (-1 in case of the return type) */ public int getParameterIndex() { return this.parameterIndex; diff --git a/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java b/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java index 2adbae874f..6e3e227704 100644 --- a/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java +++ b/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java @@ -129,6 +129,7 @@ public class AntPathMatcher implements PathMatcher { * turn it off when encountering too many patterns to cache at runtime * (the threshold is 65536), assuming that arbitrary permutations of patterns * are coming in, with little chance for encountering a recurring pattern. + * @since 4.0.1 * @see #getStringMatcher(String) */ public void setCachePatterns(boolean cachePatterns) { @@ -413,18 +414,18 @@ public class AntPathMatcher implements PathMatcher { public Map extractUriTemplateVariables(String pattern, String path) { Map variables = new LinkedHashMap(); boolean result = doMatch(pattern, path, true, variables); - Assert.state(result, "Pattern \"" + pattern + "\" is not a match for \"" + path + "\""); + if (!result) { + throw new IllegalStateException("Pattern \"" + pattern + "\" is not a match for \"" + path + "\""); + } return variables; } /** * Combine two patterns into a new pattern. - * *

This implementation simply concatenates the two patterns, unless * the first pattern contains a file extension match (e.g., {@code *.html}). * In that case, the second pattern will be merged into the first. Otherwise, * an {@code IllegalArgumentException} will be thrown. - * *

Examples

* * @@ -442,7 +443,6 @@ public class AntPathMatcher implements PathMatcher { * * *
Pattern 1Pattern 2Result
/*.html/hotels/hotels.html
/*.html/*.txt{@code IllegalArgumentException}
- * * @param pattern1 the first pattern * @param pattern2 the second pattern * @return the combination of the two patterns @@ -484,6 +484,7 @@ public class AntPathMatcher implements PathMatcher { // simply concatenate the two patterns return concat(pattern1, pattern2); } + String extension1 = pattern1.substring(starDotPos1 + 1); int dotPos2 = pattern2.indexOf('.'); String fileName2 = (dotPos2 == -1 ? pattern2 : pattern2.substring(0, dotPos2)); @@ -508,14 +509,18 @@ public class AntPathMatcher implements PathMatcher { } /** - * Given a full path, returns a {@link Comparator} suitable for sorting patterns in order of explicitness. - *

The returned {@code Comparator} will {@linkplain java.util.Collections#sort(java.util.List, - * java.util.Comparator) sort} a list so that more specific patterns (without uri templates or wild cards) come before - * generic patterns. So given a list with the following patterns:

  1. {@code /hotels/new}
  2. - *
  3. {@code /hotels/{hotel}}
  4. {@code /hotels/*}
the returned comparator will sort this - * list so that the order will be as indicated. - *

The full path given as parameter is used to test for exact matches. So when the given path is {@code /hotels/2}, - * the pattern {@code /hotels/2} will be sorted before {@code /hotels/1}. + * Given a full path, returns a {@link Comparator} suitable for sorting patterns in order of + * explicitness. + *

This{@code Comparator} will {@linkplain java.util.Collections#sort(List, Comparator) sort} + * a list so that more specific patterns (without uri templates or wild cards) come before + * generic patterns. So given a list with the following patterns: + *

    + *
  1. {@code /hotels/new}
  2. + *
  3. {@code /hotels/{hotel}}
  4. {@code /hotels/*}
  5. + *
+ * the returned comparator will sort this list so that the order will be as indicated. + *

The full path given as parameter is used to test for exact matches. So when the given path + * is {@code /hotels/2}, the pattern {@code /hotels/2} will be sorted before {@code /hotels/1}. * @param path the full path to use for comparison * @return a comparator capable of sorting patterns in order of explicitness */ @@ -542,11 +547,11 @@ public class AntPathMatcher implements PathMatcher { public AntPathStringMatcher(String pattern) { StringBuilder patternBuilder = new StringBuilder(); - Matcher m = GLOB_PATTERN.matcher(pattern); + Matcher matcher = GLOB_PATTERN.matcher(pattern); int end = 0; - while (m.find()) { - patternBuilder.append(quote(pattern, end, m.start())); - String match = m.group(); + while (matcher.find()) { + patternBuilder.append(quote(pattern, end, matcher.start())); + String match = matcher.group(); if ("?".equals(match)) { patternBuilder.append('.'); } @@ -557,7 +562,7 @@ public class AntPathMatcher implements PathMatcher { int colonIdx = match.indexOf(':'); if (colonIdx == -1) { patternBuilder.append(DEFAULT_VARIABLE_PATTERN); - this.variableNames.add(m.group(1)); + this.variableNames.add(matcher.group(1)); } else { String variablePattern = match.substring(colonIdx + 1, match.length() - 1); @@ -568,7 +573,7 @@ public class AntPathMatcher implements PathMatcher { this.variableNames.add(variableName); } } - end = m.end(); + end = matcher.end(); } patternBuilder.append(quote(pattern, end, pattern.length())); this.pattern = Pattern.compile(patternBuilder.toString()); @@ -590,10 +595,12 @@ public class AntPathMatcher implements PathMatcher { if (matcher.matches()) { if (uriTemplateVariables != null) { // SPR-8455 - Assert.isTrue(this.variableNames.size() == matcher.groupCount(), - "The number of capturing groups in the pattern segment " + this.pattern + - " does not match the number of URI template variables it defines, which can occur if " + - " capturing groups are used in a URI template regex. Use non-capturing groups instead."); + if (this.variableNames.size() != matcher.groupCount()) { + throw new IllegalArgumentException("The number of capturing groups in the pattern segment " + + this.pattern + " does not match the number of URI template variables it defines, " + + "which can occur if capturing groups are used in a URI template regex. " + + "Use non-capturing groups instead."); + } for (int i = 1; i <= matcher.groupCount(); i++) { String name = this.variableNames.get(i - 1); String value = matcher.group(i); diff --git a/spring-expression/src/main/java/org/springframework/expression/ExpressionException.java b/spring-expression/src/main/java/org/springframework/expression/ExpressionException.java index edebcb5949..767f5cee3b 100644 --- a/spring-expression/src/main/java/org/springframework/expression/ExpressionException.java +++ b/spring-expression/src/main/java/org/springframework/expression/ExpressionException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 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. @@ -17,7 +17,7 @@ package org.springframework.expression; /** - * Super class for exceptions that can occur whilst processing expressions + * Super class for exceptions that can occur whilst processing expressions. * * @author Andy Clement * @since 3.0 @@ -27,11 +27,11 @@ public class ExpressionException extends RuntimeException { protected String expressionString; - protected int position; // -1 if not known - but should be known in all reasonable cases + protected int position; // -1 if not known - but should be known in all reasonable cases /** - * Creates a new expression exception. + * Construct a new expression exception. * @param expressionString the expression string * @param message a descriptive message */ @@ -42,7 +42,7 @@ public class ExpressionException extends RuntimeException { } /** - * Creates a new expression exception. + * Construct a new expression exception. * @param expressionString the expression string * @param position the position in the expression string where the problem occurred * @param message a descriptive message @@ -54,7 +54,7 @@ public class ExpressionException extends RuntimeException { } /** - * Creates a new expression exception. + * Construct a new expression exception. * @param position the position in the expression string where the problem occurred * @param message a descriptive message */ @@ -64,7 +64,7 @@ public class ExpressionException extends RuntimeException { } /** - * Creates a new expression exception. + * Construct a new expression exception. * @param position the position in the expression string where the problem occurred * @param message a descriptive message * @param cause the underlying cause of this exception @@ -75,21 +75,40 @@ public class ExpressionException extends RuntimeException { } /** - * Creates a new expression exception. + * Construct a new expression exception. * @param message a descriptive message */ public ExpressionException(String message) { super(message); } + /** + * Construct a new expression exception. + * @param message a descriptive message + * @param cause the underlying cause of this exception + */ public ExpressionException(String message, Throwable cause) { super(message,cause); } /** - * Return the exception message. Since Spring 4.0 this method returns the same - * result as {@link #toDetailedString()}. + * Return the expression string. + */ + public final String getExpressionString() { + return this.expressionString; + } + + /** + * Return the position in the expression string where the problem occurred. + */ + public final int getPosition() { + return this.position; + } + + /** + * Return the exception message. Since Spring 4.0 this method returns the + * same result as {@link #toDetailedString()}. * @see java.lang.Throwable#getMessage() */ @Override @@ -98,35 +117,34 @@ public class ExpressionException extends RuntimeException { } /** - * Return the exception simple message without including the expression that caused - * the failure. + * Return a detailed description of this exception, including the expression + * String and position (if available) as well as the actual exception message. + */ + public String toDetailedString() { + if (this.expressionString != null) { + StringBuilder output = new StringBuilder(); + output.append("Expression '"); + output.append(this.expressionString); + output.append("'"); + if (this.position != -1) { + output.append(" @ "); + output.append(this.position); + } + output.append(": "); + output.append(getSimpleMessage()); + return output.toString(); + } + else { + return getSimpleMessage(); + } + } + + /** + * Return the exception simple message without including the expression + * that caused the failure. */ public String getSimpleMessage() { return super.getMessage(); } - public String toDetailedString() { - StringBuilder output = new StringBuilder(); - if (this.expressionString!=null) { - output.append("Expression '"); - output.append(this.expressionString); - output.append("'"); - if (this.position!=-1) { - output.append(" @ "); - output.append(this.position); - } - output.append(": "); - } - output.append(getSimpleMessage()); - return output.toString(); - } - - public final String getExpressionString() { - return this.expressionString; - } - - public final int getPosition() { - return this.position; - } - } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/CodeFlow.java b/spring-expression/src/main/java/org/springframework/expression/spel/CodeFlow.java index 2044e9e756..5b91d9ae25 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/CodeFlow.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/CodeFlow.java @@ -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. @@ -56,7 +56,7 @@ public class CodeFlow implements Opcodes { * will be called after the main evaluation function has finished being generated. */ private List fieldAdders = null; - + /** * As SpEL ast nodes are called to generate code for the main evaluation method * they can register to add code to a static initializer in the class. Any @@ -64,19 +64,19 @@ public class CodeFlow implements Opcodes { * has finished being generated. */ private List clinitAdders = null; - + /** * Name of the class being generated. Typically used when generating code * that accesses freshly generated fields on the generated type. */ private String clazzName; - + /** * When code generation requires holding a value in a class level field, this * is used to track the next available field id (used as a name suffix). */ private int nextFieldId = 1; - + /** * When code generation requires an intermediate variable within a method, * this method records the next available variable (variable 0 is 'this'). @@ -211,7 +211,7 @@ public class CodeFlow implements Opcodes { /** * Create the JVM signature descriptor for a method. This consists of the descriptors - * for the constructor parameters surrounded with parentheses, followed by the + * for the method parameters surrounded with parentheses, followed by the * descriptor for the return type. Note the descriptors here are JVM descriptors, * unlike the other descriptor forms the compiler is using which do not include the * trailing semicolon. @@ -232,11 +232,12 @@ public class CodeFlow implements Opcodes { /** * Create the JVM signature descriptor for a constructor. This consists of the - * descriptors for the constructor parameters surrounded with parentheses. Note the + * descriptors for the constructor parameters surrounded with parentheses, followed by + * the descriptor for the return type, which is always "V". Note the * descriptors here are JVM descriptors, unlike the other descriptor forms the * compiler is using which do not include the trailing semicolon. * @param ctor the constructor - * @return a String signature descriptor (e.g. "(ILjava/lang/String;)") + * @return a String signature descriptor (e.g. "(ILjava/lang/String;)V") */ public static String createSignatureDescriptor(Constructor ctor) { Class[] params = ctor.getParameterTypes(); @@ -657,7 +658,7 @@ public class CodeFlow implements Opcodes { } return descriptors; } - + /** * Called after the main expression evaluation method has been generated, this * method will callback any registered FieldAdders or ClinitAdders to add any @@ -695,7 +696,7 @@ public class CodeFlow implements Opcodes { } /** - * Register a ClinitAdder which will add code to the static + * Register a ClinitAdder which will add code to the static * initializer in the generated class to support the code * produced by an ast nodes primary generateCode() method. */ @@ -717,11 +718,11 @@ public class CodeFlow implements Opcodes { public String getClassname() { return clazzName; } - + public interface FieldAdder { public void generateField(ClassWriter cw, CodeFlow codeflow); } - + public interface ClinitAdder { public void generateCode(MethodVisitor mv, CodeFlow codeflow); } @@ -743,11 +744,11 @@ public class CodeFlow implements Opcodes { } else { mv.visitLdcInsn(value); - } + } } /** - * Produce appropriate bytecode to store a stack item in an array. The + * Produce appropriate bytecode to store a stack item in an array. The * instruction to use varies depending on whether the type * is a primitive or reference type. * @param mv where to insert the bytecode @@ -781,7 +782,7 @@ public class CodeFlow implements Opcodes { public static int arrayCodeFor(String arraytype) { switch (arraytype.charAt(0)) { case 'I': return T_INT; - case 'J': return T_LONG; + case 'J': return T_LONG; case 'F': return T_FLOAT; case 'D': return T_DOUBLE; case 'B': return T_BYTE; @@ -805,9 +806,9 @@ public class CodeFlow implements Opcodes { } return false; } - + /** - * Produce the correct bytecode to build an array. The opcode to use and the + * Produce the correct bytecode to build an array. The opcode to use and the * signature to pass along with the opcode can vary depending on the signature * of the array type. * @param mv the methodvisitor into which code should be inserted @@ -825,7 +826,8 @@ public class CodeFlow implements Opcodes { // is [[I then we want [I and not [I; if (CodeFlow.isReferenceTypeArray(arraytype)) { mv.visitTypeInsn(ANEWARRAY, arraytype+";"); - } else { + } + else { mv.visitTypeInsn(ANEWARRAY, arraytype); } } @@ -835,5 +837,4 @@ public class CodeFlow implements Opcodes { } } - } diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/config/InitializeDatabaseIntegrationTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/config/InitializeDatabaseIntegrationTests.java index 286a897f2e..723707add1 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/config/InitializeDatabaseIntegrationTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/config/InitializeDatabaseIntegrationTests.java @@ -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. @@ -37,8 +37,10 @@ import static org.junit.Assert.*; public class InitializeDatabaseIntegrationTests { private String enabled; + private ClassPathXmlApplicationContext context; + @Before public void init() { enabled = System.setProperty("ENABLED", "true"); @@ -48,7 +50,8 @@ public class InitializeDatabaseIntegrationTests { public void after() { if (enabled != null) { System.setProperty("ENABLED", enabled); - } else { + } + else { System.clearProperty("ENABLED"); } if (context != null) { @@ -56,6 +59,7 @@ public class InitializeDatabaseIntegrationTests { } } + @Test public void testCreateEmbeddedDatabase() throws Exception { context = new ClassPathXmlApplicationContext("org/springframework/jdbc/config/jdbc-initialize-config.xml"); @@ -107,13 +111,15 @@ public class InitializeDatabaseIntegrationTests { } private void assertCorrectSetup(DataSource dataSource) { - JdbcTemplate t = new JdbcTemplate(dataSource); - assertEquals(1, t.queryForObject("select count(*) from T_TEST", Integer.class).intValue()); + JdbcTemplate jt = new JdbcTemplate(dataSource); + assertEquals(1, jt.queryForObject("select count(*) from T_TEST", Integer.class).intValue()); } + public static class CacheData implements InitializingBean { private JdbcTemplate jdbcTemplate; + private List> cache; public void setDataSource(DataSource dataSource) { @@ -128,7 +134,6 @@ public class InitializeDatabaseIntegrationTests { public void afterPropertiesSet() throws Exception { cache = jdbcTemplate.queryForList("SELECT * FROM T_TEST"); } - } } diff --git a/spring-jms/src/main/java/org/springframework/jms/core/JmsMessagingTemplate.java b/spring-jms/src/main/java/org/springframework/jms/core/JmsMessagingTemplate.java index 467c0812e5..7a22c041a1 100644 --- a/spring-jms/src/main/java/org/springframework/jms/core/JmsMessagingTemplate.java +++ b/spring-jms/src/main/java/org/springframework/jms/core/JmsMessagingTemplate.java @@ -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. @@ -120,7 +120,7 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate * to convert the payload of the message. *

Consider configuring a {@link MessagingMessageConverter} with a different * {@link MessagingMessageConverter#setPayloadConverter(MessageConverter) payload converter} - * for more advanced scenario. + * for more advanced scenarios. * @see org.springframework.jms.support.converter.MessagingMessageConverter */ public void setJmsMessageConverter(MessageConverter jmsMessageConverter) { diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java index f910fd4308..a5e0efca8c 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java @@ -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. @@ -40,8 +40,8 @@ import org.springframework.jms.support.destination.DynamicDestinationResolver; import org.springframework.util.Assert; /** - * An abstract {@link MessageListener} adapter providing the necessary infrastructure - * to extract the payload of a {@link Message} + * An abstract JMS {@link MessageListener} adapter providing the necessary + * infrastructure to extract the payload of a JMS {@link Message}. * * @author Juergen Hoeller * @author Stephane Nicoll @@ -217,7 +217,7 @@ public abstract class AbstractAdaptableMessageListener return message; } catch (JMSException ex) { - throw new MessageConversionException("Could not unmarshal message", ex); + throw new MessageConversionException("Could not convert JMS message", ex); } } @@ -246,10 +246,12 @@ public abstract class AbstractAdaptableMessageListener sendResponse(session, destination, response); } catch (Exception ex) { - throw new ReplyFailureException("Failed to send reply with payload '" + result + "'", ex); + throw new ReplyFailureException("Failed to send reply with payload [" + result + "]", ex); } } + else { + // No JMS Session available if (logger.isWarnEnabled()) { logger.warn("Listener method returned result [" + result + "]: not generating response message for it because of no JMS Session given"); diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapter.java b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapter.java index 1c8573a428..0791f4c400 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapter.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapter.java @@ -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. @@ -77,7 +77,7 @@ public class MessagingMessageListenerAdapter extends AbstractAdaptableMessageLis return (Message) getMessagingMessageConverter().fromMessage(jmsMessage); } catch (JMSException ex) { - throw new MessageConversionException("Could not unmarshal message", ex); + throw new MessageConversionException("Could not convert JMS message", ex); } } @@ -90,8 +90,8 @@ public class MessagingMessageListenerAdapter extends AbstractAdaptableMessageLis return this.handlerMethod.invoke(message, jmsMessage, session); } catch (MessagingException ex) { - throw new ListenerExecutionFailedException(createMessagingErrorMessage("Listener method could not " + - "be invoked with the incoming message"), ex); + throw new ListenerExecutionFailedException( + createMessagingErrorMessage("Listener method could not be invoked with incoming message"), ex); } catch (Exception ex) { throw new ListenerExecutionFailedException("Listener method '" + diff --git a/spring-messaging/src/main/java/org/springframework/messaging/converter/MessageConverter.java b/spring-messaging/src/main/java/org/springframework/messaging/converter/MessageConverter.java index 89fc91d781..d86ee9fe2f 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/converter/MessageConverter.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/converter/MessageConverter.java @@ -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. @@ -31,11 +31,11 @@ import org.springframework.messaging.MessageHeaders; public interface MessageConverter { /** - * Convert the payload of a {@link Message} from serialized form to a typed Object of - * the specified target class. The {@link MessageHeaders#CONTENT_TYPE} header should - * indicate the MIME type to convert from. - *

If the converter does not support the specified media type or cannot perform the - * conversion, it should return {@code null}. + * Convert the payload of a {@link Message} from a serialized form to a typed Object + * of the specified target class. The {@link MessageHeaders#CONTENT_TYPE} header + * should indicate the MIME type to convert from. + *

If the converter does not support the specified media type or cannot perform + * the conversion, it should return {@code null}. * @param message the input message * @param targetClass the target class for the conversion * @return the result of the conversion, or {@code null} if the converter cannot @@ -47,15 +47,15 @@ public interface MessageConverter { * Create a {@link Message} whose payload is the result of converting the given * payload Object to serialized form. The optional {@link MessageHeaders} parameter * may contain a {@link MessageHeaders#CONTENT_TYPE} header to specify the target - * media type for the conversion and it may contain additional headers to be added to - * the message. - *

If the converter does not support the specified media type or cannot perform the - * conversion, it should return {@code null}. + * media type for the conversion and it may contain additional headers to be added + * to the message. + *

If the converter does not support the specified media type or cannot perform + * the conversion, it should return {@code null}. * @param payload the Object to convert - * @param header optional headers for the message, may be {@code null} - * @return the new message or {@code null} if the converter does not support the + * @param headers optional headers for the message (may be {@code null}) + * @return the new message, or {@code null} if the converter does not support the * Object type or the target media type */ - Message toMessage(Object payload, MessageHeaders header); + Message toMessage(Object payload, MessageHeaders headers); } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/DefaultMessageHandlerMethodFactory.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/DefaultMessageHandlerMethodFactory.java index a7c2e989c0..6ff383b235 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/DefaultMessageHandlerMethodFactory.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/DefaultMessageHandlerMethodFactory.java @@ -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. @@ -37,8 +37,8 @@ import org.springframework.validation.Validator; * The default {@link MessageHandlerMethodFactory} implementation creating an * {@link InvocableHandlerMethod} with the necessary * {@link HandlerMethodArgumentResolver} instances to detect and process - * most of the use cases defined by - * {@link org.springframework.messaging.handler.annotation.MessageMapping MessageMapping} + * most of the use cases defined by + * {@link org.springframework.messaging.handler.annotation.MessageMapping MessageMapping}. * *

Extra method argument resolvers can be added to customize the method * signature that can be handled. diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolver.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolver.java index 58b9729600..d13658cc9e 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolver.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolver.java @@ -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. @@ -22,10 +22,11 @@ import org.springframework.core.MethodParameter; import org.springframework.core.ResolvableType; import org.springframework.messaging.Message; import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver; +import org.springframework.util.ClassUtils; /** - * A {@link HandlerMethodArgumentResolver} for {@link Message} parameters. Validates - * that the generic type of the payload matches with the message value. + * A {@link HandlerMethodArgumentResolver} for {@link Message} parameters. + * Validates that the generic type of the payload matches with the message value. * * @author Rossen Stoyanchev * @author Stephane Nicoll @@ -33,7 +34,6 @@ import org.springframework.messaging.handler.invocation.HandlerMethodArgumentRes */ public class MessageMethodArgumentResolver implements HandlerMethodArgumentResolver { - @Override public boolean supportsParameter(MethodParameter parameter) { return Message.class.isAssignableFrom(parameter.getParameterType()); @@ -41,22 +41,19 @@ public class MessageMethodArgumentResolver implements HandlerMethodArgumentResol @Override public Object resolveArgument(MethodParameter parameter, Message message) throws Exception { - Class paramType = parameter.getParameterType(); - if (!paramType.isAssignableFrom(message.getClass())) { throw new MethodArgumentTypeMismatchException(message, parameter, - "The actual message type [" + message.getClass().getName() + "] " + - "does not match the expected type [" + paramType.getName() + "]"); + "The actual message type [" + ClassUtils.getQualifiedName(message.getClass()) + "] " + + "does not match the expected type [" + ClassUtils.getQualifiedName(paramType) + "]"); } Class expectedPayloadType = getPayloadType(parameter); Object payload = message.getPayload(); - - if (expectedPayloadType != null && !expectedPayloadType.isInstance(payload)) { + if (payload != null && expectedPayloadType != null && !expectedPayloadType.isInstance(payload)) { throw new MethodArgumentTypeMismatchException(message, parameter, - "The expected Message payload type [" + expectedPayloadType.getName() + - "] does not match the actual payload type [" + payload.getClass().getName() + "]"); + "The expected Message payload type [" + ClassUtils.getQualifiedName(expectedPayloadType) + + "] does not match the actual payload type [" + ClassUtils.getQualifiedName(payload.getClass()) + "]"); } return message; diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java index db2e8f43ca..c6345d89f6 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java @@ -455,7 +455,9 @@ public abstract class AbstractMethodMessageHandler processHandlerMethodException(handlerMethod, ex, message); } catch (Throwable ex) { - logger.error("Error while processing message " + message, ex); + if (logger.isErrorEnabled()) { + logger.error("Error while processing message " + message, ex); + } } } @@ -495,9 +497,7 @@ public abstract class AbstractMethodMessageHandler protected abstract AbstractExceptionHandlerMethodResolver createExceptionHandlerMethodResolverFor(Class beanType); protected void handleNoMatch(Set ts, String lookupDestination, Message message) { - if (logger.isDebugEnabled()) { - logger.debug("No matching methods."); - } + logger.debug("No matching methods."); } @Override diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/SimpMessageSendingOperations.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/SimpMessageSendingOperations.java index c8005573d3..953d871560 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/SimpMessageSendingOperations.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/SimpMessageSendingOperations.java @@ -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. @@ -46,7 +46,6 @@ public interface SimpMessageSendingOperations extends MessageSendingOperationsBy default headers are interpreted as native headers (e.g. STOMP) and * are saved under a special key in the resulting Spring * {@link org.springframework.messaging.Message Message}. In effect when the * message leaves the application, the provided headers are included with it * and delivered to the destination (e.g. the STOMP client or broker). - * *

If the map already contains the key * {@link org.springframework.messaging.support.NativeMessageHeaderAccessor#NATIVE_HEADERS "nativeHeaders"} * or was prepared with @@ -69,36 +66,31 @@ public interface SimpMessageSendingOperations extends MessageSendingOperations * SimpMessageHeaderAccessor accessor = SimpMessageHeaderAccessor.create(); * accessor.setContentType(MimeTypeUtils.TEXT_PLAIN); * accessor.setNativeHeader("foo", "bar"); * accessor.setLeaveMutable(true); * MessageHeaders headers = accessor.getMessageHeaders(); - * * messagingTemplate.convertAndSendToUser(user, destination, payload, headers); * - * *

Note: if the {@code MessageHeaders} are mutable as in * the above example, implementations of this interface should take notice and * update the headers in the same instance (rather than copy or re-create it) * and then set it immutable before sending the final message. - * - * @param user the user that should receive the message, must not be {@code null} - * @param destination the destination to send the message to, must not be {@code null} - * @param payload the payload to send, may be {@code null} - * @param headers the message headers, may be {@code null} + * @param user the user that should receive the message (must not be {@code null}) + * @param destination the destination to send the message to (must not be {@code null}) + * @param payload the payload to send (may be {@code null}) + * @param headers the message headers (may be {@code null}) */ void convertAndSendToUser(String user, String destination, Object payload, Map headers) throws MessagingException; /** * Send a message to the given user. - * - * @param user the user that should receive the message, must not be {@code null} - * @param destination the destination to send the message to, must not be {@code null} - * @param payload the payload to send, may be {@code null} + * @param user the user that should receive the message (must not be {@code null}) + * @param destination the destination to send the message to (must not be {@code null}) + * @param payload the payload to send (may be {@code null}) * @param postProcessor a postProcessor to post-process or modify the created message */ void convertAndSendToUser(String user, String destination, Object payload, @@ -106,12 +98,10 @@ public interface SimpMessageSendingOperations extends MessageSendingOperationsSee {@link #convertAndSend(Object, Object, java.util.Map)} for important * notes regarding the input headers. - * - * @param user the user that should receive the message. - * @param destination the destination to send the message to. + * @param user the user that should receive the message + * @param destination the destination to send the message to * @param payload the payload to send * @param headers the message headers * @param postProcessor a postProcessor to post-process or modify the created message diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandler.java index e1ae458065..3f5bf1c7f8 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandler.java @@ -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. @@ -35,16 +35,16 @@ import org.springframework.messaging.simp.user.DestinationUserNameProvider; import org.springframework.messaging.support.MessageHeaderInitializer; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; /** * A {@link HandlerMethodReturnValueHandler} for sending to destinations specified in a * {@link SendTo} or {@link SendToUser} method-level annotations. * *

The value returned from the method is converted, and turned to a {@link Message} and - * sent through the provided {@link MessageChannel}. The - * message is then enriched with the sessionId of the input message as well as the - * destination from the annotation(s). If multiple destinations are specified, a copy of - * the message is sent to each destination. + * sent through the provided {@link MessageChannel}. The message is then enriched with the + * session id of the input message as well as the destination from the annotation(s). + * If multiple destinations are specified, a copy of the message is sent to each destination. * * @author Rossen Stoyanchev * @since 4.0 @@ -108,7 +108,6 @@ public class SendToMethodReturnValueHandler implements HandlerMethodReturnValueH /** * Configure a {@link MessageHeaderInitializer} to apply to the headers of all * messages sent to the client outbound channel. - * *

By default this property is not set. */ public void setHeaderInitializer(MessageHeaderInitializer headerInitializer) { @@ -125,8 +124,8 @@ public class SendToMethodReturnValueHandler implements HandlerMethodReturnValueH @Override public boolean supportsReturnType(MethodParameter returnType) { - if ((returnType.getMethodAnnotation(SendTo.class) != null) || - (returnType.getMethodAnnotation(SendToUser.class) != null)) { + if (returnType.getMethodAnnotation(SendTo.class) != null || + returnType.getMethodAnnotation(SendToUser.class) != null) { return true; } return (!this.annotationRequired); @@ -137,10 +136,11 @@ public class SendToMethodReturnValueHandler implements HandlerMethodReturnValueH if (returnValue == null) { return; } + MessageHeaders headers = message.getHeaders(); String sessionId = SimpMessageHeaderAccessor.getSessionId(headers); - SendToUser sendToUser = returnType.getMethodAnnotation(SendToUser.class); + if (sendToUser != null) { boolean broadcast = sendToUser.broadcast(); String user = getUserName(message, headers); @@ -188,7 +188,9 @@ public class SendToMethodReturnValueHandler implements HandlerMethodReturnValueH } String name = DestinationPatternsMessageCondition.LOOKUP_DESTINATION_HEADER; String destination = (String) message.getHeaders().get(name); - Assert.hasText(destination, "No lookup destination header in " + message); + if (!StringUtils.hasText(destination)) { + throw new IllegalStateException("No lookup destination header in " + message); + } return (destination.startsWith("/") ? new String[] {defaultPrefix + destination} : new String[] {defaultPrefix + "/" + destination}); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SubscriptionMethodReturnValueHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SubscriptionMethodReturnValueHandler.java index 8317e5ffc4..752debd4db 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SubscriptionMethodReturnValueHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SubscriptionMethodReturnValueHandler.java @@ -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. @@ -102,13 +102,14 @@ public class SubscriptionMethodReturnValueHandler implements HandlerMethodReturn String sessionId = SimpMessageHeaderAccessor.getSessionId(headers); String subscriptionId = SimpMessageHeaderAccessor.getSubscriptionId(headers); - Assert.state(subscriptionId != null, - "No subscriptionId in message=" + message + ", method=" + returnType.getMethod()); + if (subscriptionId == null) { + throw new IllegalStateException( + "No subscriptionId in " + message + " returned by: " + returnType.getMethod()); + } if (logger.isDebugEnabled()) { logger.debug("Reply to @SubscribeMapping: " + returnValue); } - this.messagingTemplate.convertAndSend(destination, returnValue, createHeaders(sessionId, subscriptionId)); } diff --git a/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolverTests.java b/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolverTests.java index 7c6523e7a2..f4b7e2baf4 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolverTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolverTests.java @@ -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. @@ -145,6 +145,7 @@ public class MessageMethodArgumentResolverTests { assertSame(message, this.resolver.resolveArgument(parameter, message)); } + @SuppressWarnings("unused") private void handleMessage( Message wildcardPayload, diff --git a/spring-test/src/main/java/org/springframework/test/context/junit4/SpringJUnit4ClassRunner.java b/spring-test/src/main/java/org/springframework/test/context/junit4/SpringJUnit4ClassRunner.java index ed7ce56443..2d6a77109a 100644 --- a/spring-test/src/main/java/org/springframework/test/context/junit4/SpringJUnit4ClassRunner.java +++ b/spring-test/src/main/java/org/springframework/test/context/junit4/SpringJUnit4ClassRunner.java @@ -88,8 +88,8 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner { private static final Method withRulesMethod; static { - withRulesMethod = ReflectionUtils.findMethod(SpringJUnit4ClassRunner.class, "withRules", FrameworkMethod.class, - Object.class, Statement.class); + withRulesMethod = ReflectionUtils.findMethod(SpringJUnit4ClassRunner.class, "withRules", + FrameworkMethod.class, Object.class, Statement.class); if (withRulesMethod == null) { throw new IllegalStateException( "Failed to find withRules() method: SpringJUnit4ClassRunner requires JUnit 4.9 or higher."); @@ -101,7 +101,7 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner { /** - * Constructs a new {@code SpringJUnit4ClassRunner} and initializes a + * Construct a new {@code SpringJUnit4ClassRunner} and initialize a * {@link TestContextManager} to provide Spring testing functionality to * standard JUnit tests. * @param clazz the test class to be run @@ -110,13 +110,13 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner { public SpringJUnit4ClassRunner(Class clazz) throws InitializationError { super(clazz); if (logger.isDebugEnabled()) { - logger.debug("SpringJUnit4ClassRunner constructor called with [" + clazz + "]."); + logger.debug("SpringJUnit4ClassRunner constructor called with [" + clazz + "]"); } this.testContextManager = createTestContextManager(clazz); } /** - * Creates a new {@link TestContextManager} for the supplied test class. + * Create a new {@link TestContextManager} for the supplied test class. *

Can be overridden by subclasses. * @param clazz the test class to be managed */ @@ -132,9 +132,9 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner { } /** - * Returns a description suitable for an ignored test class if the test is + * Return a description suitable for an ignored test class if the test is * disabled via {@code @IfProfileValue} at the class-level, and - * otherwise delegates to the parent implementation. + * otherwise delegate to the parent implementation. * @see ProfileValueUtils#isTestEnabledInThisEnvironment(Class) */ @Override @@ -146,10 +146,10 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner { } /** - * Check whether the test is enabled in the first place. This prevents - * classes with a non-matching {@code @IfProfileValue} annotation from - * running altogether, even skipping the execution of - * {@code prepareTestInstance()} {@code TestExecutionListener} methods. + * Check whether the test is enabled in the current execution environment. + *

This prevents classes with a non-matching {@code @IfProfileValue} + * annotation from running altogether, even skipping the execution of + * {@code prepareTestInstance()} methods in {@code TestExecutionListeners}. * @see ProfileValueUtils#isTestEnabledInThisEnvironment(Class) * @see org.springframework.test.annotation.IfProfileValue * @see org.springframework.test.context.TestExecutionListener @@ -164,9 +164,9 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner { } /** - * Wraps the {@link Statement} returned by the parent implementation with a - * {@link RunBeforeTestClassCallbacks} statement, thus preserving the - * default functionality but adding support for the Spring TestContext + * Wrap the {@link Statement} returned by the parent implementation with a + * {@code RunBeforeTestClassCallbacks} statement, thus preserving the + * default JUnit functionality while adding support for the Spring TestContext * Framework. * @see RunBeforeTestClassCallbacks */ @@ -177,9 +177,9 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner { } /** - * Wraps the {@link Statement} returned by the parent implementation with a - * {@link RunAfterTestClassCallbacks} statement, thus preserving the default - * functionality but adding support for the Spring TestContext Framework. + * Wrap the {@link Statement} returned by the parent implementation with a + * {@code RunAfterTestClassCallbacks} statement, thus preserving the default + * JUnit functionality while adding support for the Spring TestContext Framework. * @see RunAfterTestClassCallbacks */ @Override @@ -189,10 +189,10 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner { } /** - * Delegates to the parent implementation for creating the test instance and - * then allows the {@link #getTestContextManager() TestContextManager} to + * Delegate to the parent implementation for creating the test instance and + * then allow the {@link #getTestContextManager() TestContextManager} to * prepare the test instance before returning it. - * @see TestContextManager#prepareTestInstance(Object) + * @see TestContextManager#prepareTestInstance */ @Override protected Object createTest() throws Exception { @@ -202,7 +202,7 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner { } /** - * Performs the same logic as + * Perform the same logic as * {@link BlockJUnit4ClassRunner#runChild(FrameworkMethod, RunNotifier)}, * except that tests are determined to be ignored by * {@link #isTestMethodIgnored(FrameworkMethod)}. @@ -226,25 +226,26 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner { } /** - * Augments the default JUnit behavior - * {@link #withPotentialRepeat(FrameworkMethod, Object, Statement) with - * potential repeats} of the entire execution chain. - *

Furthermore, support for timeouts has been moved down the execution chain - * in order to include execution of {@link org.junit.Before @Before} - * and {@link org.junit.After @After} methods within the timed - * execution. Note that this differs from the default JUnit behavior of - * executing {@code @Before} and {@code @After} methods - * in the main thread while executing the actual test method in a separate - * thread. Thus, the end effect is that {@code @Before} and - * {@code @After} methods will be executed in the same thread as - * the test method. As a consequence, JUnit-specified timeouts will work - * fine in combination with Spring transactions. Note that JUnit-specific - * timeouts still differ from Spring-specific timeouts in that the former - * execute in a separate thread while the latter simply execute in the main - * thread (like regular tests). + * Augment the default JUnit behavior + * {@linkplain #withPotentialRepeat with potential repeats} of the entire + * execution chain. + *

Furthermore, support for timeouts has been moved down the execution + * chain in order to include execution of {@link org.junit.Before @Before} + * and {@link org.junit.After @After} methods within the timed execution. + * Note that this differs from the default JUnit behavior of executing + * {@code @Before} and {@code @After} methods in the main thread while + * executing the actual test method in a separate thread. Thus, the net + * effect is that {@code @Before} and {@code @After} methods will be + * executed in the same thread as the test method. As a consequence, + * JUnit-specified timeouts will work fine in combination with Spring + * transactions. However, JUnit-specific timeouts still differ from + * Spring-specific timeouts in that the former execute in a separate + * thread while the latter simply execute in the main thread (like regular + * tests). * @see #possiblyExpectingExceptions(FrameworkMethod, Object, Statement) * @see #withBefores(FrameworkMethod, Object, Statement) * @see #withAfters(FrameworkMethod, Object, Statement) + * @see #withRulesReflectively(FrameworkMethod, Object, Statement) * @see #withPotentialRepeat(FrameworkMethod, Object, Statement) * @see #withPotentialTimeout(FrameworkMethod, Object, Statement) */ @@ -253,7 +254,6 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner { Object testInstance; try { testInstance = new ReflectiveCallable() { - @Override protected Object runReflectiveCall() throws Throwable { return createTest(); @@ -271,7 +271,6 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner { statement = withRulesReflectively(frameworkMethod, testInstance, statement); statement = withPotentialRepeat(frameworkMethod, testInstance, statement); statement = withPotentialTimeout(frameworkMethod, testInstance, statement); - return statement; } @@ -283,19 +282,19 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner { } /** - * Returns {@code true} if {@link Ignore @Ignore} is present for the supplied - * {@link FrameworkMethod test method} or if the test method is disabled via - * {@code @IfProfileValue}. + * Return {@code true} if {@link Ignore @Ignore} is present for the supplied + * {@linkplain FrameworkMethod test method} or if the test method is disabled + * via {@code @IfProfileValue}. * @see ProfileValueUtils#isTestEnabledInThisEnvironment(Method, Class) */ protected boolean isTestMethodIgnored(FrameworkMethod frameworkMethod) { Method method = frameworkMethod.getMethod(); - return (method.isAnnotationPresent(Ignore.class) || !ProfileValueUtils.isTestEnabledInThisEnvironment(method, - getTestClass().getJavaClass())); + return (method.isAnnotationPresent(Ignore.class) || + !ProfileValueUtils.isTestEnabledInThisEnvironment(method, getTestClass().getJavaClass())); } /** - * Performs the same logic as + * Perform the same logic as * {@link BlockJUnit4ClassRunner#possiblyExpectingExceptions(FrameworkMethod, Object, Statement)} * except that the expected exception is retrieved using * {@link #getExpectedException(FrameworkMethod)}. @@ -303,29 +302,30 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner { @Override protected Statement possiblyExpectingExceptions(FrameworkMethod frameworkMethod, Object testInstance, Statement next) { Class expectedException = getExpectedException(frameworkMethod); - return expectedException != null ? new ExpectException(next, expectedException) : next; + return (expectedException != null ? new ExpectException(next, expectedException) : next); } /** - * Get the {@code exception} that the supplied {@link FrameworkMethod + * Get the {@code exception} that the supplied {@linkplain FrameworkMethod * test method} is expected to throw. *

Supports JUnit's {@link Test#expected() @Test(expected=...)} annotation. + *

Can be overridden by subclasses. * @return the expected exception, or {@code null} if none was specified */ protected Class getExpectedException(FrameworkMethod frameworkMethod) { - Test testAnnotation = frameworkMethod.getAnnotation(Test.class); - Class junitExpectedException = (testAnnotation != null - && testAnnotation.expected() != Test.None.class ? testAnnotation.expected() : null); - - return junitExpectedException; + Test test = frameworkMethod.getAnnotation(Test.class); + return (test != null && test.expected() != Test.None.class ? test.expected() : null); } /** - * Supports both Spring's {@link Timed @Timed} and JUnit's - * {@link Test#timeout() @Test(timeout=...)} annotations, but not both - * simultaneously. Returns either a {@link SpringFailOnTimeout}, a - * {@link FailOnTimeout}, or the unmodified, supplied {@link Statement} as - * appropriate. + * Perform the same logic as + * {@link BlockJUnit4ClassRunner#withPotentialTimeout(FrameworkMethod, Object, Statement)} + * but with additional support for Spring's {@code @Timed} annotation. + *

Supports both Spring's {@link org.springframework.test.annotation.Timed @Timed} + * and JUnit's {@link Test#timeout() @Test(timeout=...)} annotations, but not both + * simultaneously. + * @return either a {@link SpringFailOnTimeout}, a {@link FailOnTimeout}, + * or the supplied {@link Statement} as appropriate * @see #getSpringTimeout(FrameworkMethod) * @see #getJUnitTimeout(FrameworkMethod) */ @@ -335,10 +335,9 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner { long springTimeout = getSpringTimeout(frameworkMethod); long junitTimeout = getJUnitTimeout(frameworkMethod); if (springTimeout > 0 && junitTimeout > 0) { - String msg = "Test method [" + frameworkMethod.getMethod() - + "] has been configured with Spring's @Timed(millis=" + springTimeout - + ") and JUnit's @Test(timeout=" + junitTimeout - + ") annotations. Only one declaration of a 'timeout' is permitted per test method."; + String msg = String.format("Test method [%s] has been configured with Spring's @Timed(millis=%s) and " + + "JUnit's @Test(timeout=%s) annotations, but only one declaration of a 'timeout' is " + + "permitted per test method.", frameworkMethod.getMethod(), springTimeout, junitTimeout); logger.error(msg); throw new IllegalStateException(msg); } @@ -356,37 +355,37 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner { } /** - * Retrieves the configured JUnit {@code timeout} from the {@link Test @Test} - * annotation on the supplied {@link FrameworkMethod test method}. - * @return the timeout, or {@code 0} if none was specified. + * Retrieve the configured JUnit {@code timeout} from the {@link Test @Test} + * annotation on the supplied {@linkplain FrameworkMethod test method}. + * @return the timeout, or {@code 0} if none was specified */ protected long getJUnitTimeout(FrameworkMethod frameworkMethod) { - Test testAnnotation = frameworkMethod.getAnnotation(Test.class); - return (testAnnotation != null && testAnnotation.timeout() > 0 ? testAnnotation.timeout() : 0); + Test test = frameworkMethod.getAnnotation(Test.class); + return (test != null && test.timeout() > 0 ? test.timeout() : 0); } /** - * Retrieves the configured Spring-specific {@code timeout} from the - * {@link Timed @Timed} annotation on the supplied - * {@link FrameworkMethod test method}. - * @return the timeout, or {@code 0} if none was specified. + * Retrieve the configured Spring-specific {@code timeout} from the + * {@link org.springframework.test.annotation.Timed @Timed} annotation + * on the supplied {@linkplain FrameworkMethod test method}. + * @return the timeout, or {@code 0} if none was specified */ protected long getSpringTimeout(FrameworkMethod frameworkMethod) { - AnnotationAttributes annAttrs = AnnotatedElementUtils.getAnnotationAttributes(frameworkMethod.getMethod(), - Timed.class.getName()); + AnnotationAttributes annAttrs = AnnotatedElementUtils.getAnnotationAttributes( + frameworkMethod.getMethod(), Timed.class.getName()); if (annAttrs == null) { return 0; } else { long millis = annAttrs. getNumber("millis").longValue(); - return millis > 0 ? millis : 0; + return (millis > 0 ? millis : 0); } } /** - * Wraps the {@link Statement} returned by the parent implementation with a - * {@link RunBeforeTestMethodCallbacks} statement, thus preserving the - * default functionality but adding support for the Spring TestContext + * Wrap the {@link Statement} returned by the parent implementation with a + * {@code RunBeforeTestMethodCallbacks} statement, thus preserving the + * default functionality while adding support for the Spring TestContext * Framework. * @see RunBeforeTestMethodCallbacks */ @@ -394,13 +393,13 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner { protected Statement withBefores(FrameworkMethod frameworkMethod, Object testInstance, Statement statement) { Statement junitBefores = super.withBefores(frameworkMethod, testInstance, statement); return new RunBeforeTestMethodCallbacks(junitBefores, testInstance, frameworkMethod.getMethod(), - getTestContextManager()); + getTestContextManager()); } /** - * Wraps the {@link Statement} returned by the parent implementation with a - * {@link RunAfterTestMethodCallbacks} statement, thus preserving the - * default functionality but adding support for the Spring TestContext + * Wrap the {@link Statement} returned by the parent implementation with a + * {@code RunAfterTestMethodCallbacks} statement, thus preserving the + * default functionality while adding support for the Spring TestContext * Framework. * @see RunAfterTestMethodCallbacks */ @@ -408,13 +407,13 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner { protected Statement withAfters(FrameworkMethod frameworkMethod, Object testInstance, Statement statement) { Statement junitAfters = super.withAfters(frameworkMethod, testInstance, statement); return new RunAfterTestMethodCallbacks(junitAfters, testInstance, frameworkMethod.getMethod(), - getTestContextManager()); + getTestContextManager()); } /** - * Supports Spring's {@link Repeat @Repeat} annotation by returning a - * {@link SpringRepeat} statement initialized with the configured repeat - * count or {@code 1} if no repeat count is configured. + * Wrap the supplied {@link Statement} with a {@code SpringRepeat} statement. + *

Supports Spring's {@link org.springframework.test.annotation.Repeat @Repeat} + * annotation. * @see SpringRepeat */ protected Statement withPotentialRepeat(FrameworkMethod frameworkMethod, Object testInstance, Statement next) { diff --git a/spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java b/spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java index 89a25afbdd..0379c8aa4e 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java +++ b/spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java @@ -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. @@ -511,7 +511,7 @@ public abstract class AbstractPlatformTransactionManager implements PlatformTran } /** - * Create a rae TransactionStatus instance for the given arguments. + * Create a TransactionStatus instance for the given arguments. */ protected DefaultTransactionStatus newTransactionStatus( TransactionDefinition definition, Object transaction, boolean newTransaction, diff --git a/spring-web/src/main/java/org/springframework/http/HttpHeaders.java b/spring-web/src/main/java/org/springframework/http/HttpHeaders.java index f13cdb182f..5f55ae0373 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpHeaders.java +++ b/spring-web/src/main/java/org/springframework/http/HttpHeaders.java @@ -1,11 +1,11 @@ /* - * 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -785,7 +785,7 @@ public class HttpHeaders implements MultiValueMap, Serializable try { return simpleDateFormat.parse(headerValue).getTime(); } - catch (ParseException e) { + catch (ParseException ex) { // ignore } } @@ -811,8 +811,8 @@ public class HttpHeaders implements MultiValueMap, Serializable */ @Override public String getFirst(String headerName) { - List headerValues = headers.get(headerName); - return headerValues != null ? headerValues.get(0) : null; + List headerValues = this.headers.get(headerName); + return (headerValues != null ? headerValues.get(0) : null); } /** @@ -825,7 +825,7 @@ public class HttpHeaders implements MultiValueMap, Serializable */ @Override public void add(String headerName, String headerValue) { - List headerValues = headers.get(headerName); + List headerValues = this.headers.get(headerName); if (headerValues == null) { headerValues = new LinkedList(); this.headers.put(headerName, headerValues); @@ -845,7 +845,7 @@ public class HttpHeaders implements MultiValueMap, Serializable public void set(String headerName, String headerValue) { List headerValues = new LinkedList(); headerValues.add(headerValue); - headers.put(headerName, headerValues); + this.headers.put(headerName, headerValues); } @Override @@ -858,7 +858,7 @@ public class HttpHeaders implements MultiValueMap, Serializable @Override public Map toSingleValueMap() { LinkedHashMap singleValueMap = new LinkedHashMap(this.headers.size()); - for (Entry> entry : headers.entrySet()) { + for (Entry> entry : this.headers.entrySet()) { singleValueMap.put(entry.getKey(), entry.getValue().get(0)); } return singleValueMap; diff --git a/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java b/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java index 95470113e3..47e236105e 100644 --- a/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java +++ b/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java @@ -153,12 +153,14 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat this.messageConverters.add(new AtomFeedHttpMessageConverter()); this.messageConverters.add(new RssChannelHttpMessageConverter()); } + if (jackson2XmlPresent) { - messageConverters.add(new MappingJackson2XmlHttpMessageConverter()); + this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter()); } else if (jaxb2Present) { this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter()); } + if (jackson2Present) { this.messageConverters.add(new MappingJackson2HttpMessageConverter()); } diff --git a/spring-web/src/main/java/org/springframework/web/method/support/HandlerMethodArgumentResolverComposite.java b/spring-web/src/main/java/org/springframework/web/method/support/HandlerMethodArgumentResolverComposite.java index 9d7ba31a2e..904af697a3 100644 --- a/spring-web/src/main/java/org/springframework/web/method/support/HandlerMethodArgumentResolverComposite.java +++ b/spring-web/src/main/java/org/springframework/web/method/support/HandlerMethodArgumentResolverComposite.java @@ -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. @@ -26,7 +26,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.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; @@ -61,7 +60,7 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu */ @Override public boolean supportsParameter(MethodParameter parameter) { - return getArgumentResolver(parameter) != null; + return (getArgumentResolver(parameter) != null); } /** @@ -73,7 +72,9 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter); - Assert.notNull(resolver, "Unknown parameter type [" + parameter.getParameterType().getName() + "]"); + if (resolver == null) { + throw new IllegalArgumentException("Unknown parameter type [" + parameter.getParameterType().getName() + "]"); + } return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/ModelAndViewResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/ModelAndViewResolver.java index 072a85de52..2f30a689e5 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/ModelAndViewResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/ModelAndViewResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 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. @@ -23,39 +23,36 @@ import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.servlet.ModelAndView; /** - * SPI for resolving custom return values from a specific handler method. Typically implemented to detect special return - * types, resolving well-known result values for them. + * SPI for resolving custom return values from a specific handler method. + * Typically implemented to detect special return types, resolving + * well-known result values for them. * *

A typical implementation could look like as follows: * *

  * public class MyModelAndViewResolver implements ModelAndViewResolver {
  *
- *   public ModelAndView resolveModelAndView(Method handlerMethod,
- *		   			Class handlerType,
- *		   			Object returnValue,
- *		 			ExtendedModelMap implicitModel,
- *		 			NativeWebRequest webRequest) {
- *     if (returnValue instanceof MySpecialRetVal.class)) {
- *       return new MySpecialRetVal(returnValue);
+ *     public ModelAndView resolveModelAndView(Method handlerMethod, Class handlerType,
+ *             Object returnValue, ExtendedModelMap implicitModel, NativeWebRequest webRequest) {
+ *         if (returnValue instanceof MySpecialRetVal.class)) {
+ *             return new MySpecialRetVal(returnValue);
+ *         }
+ *         return UNRESOLVED;
  *     }
- *     return UNRESOLVED;
- *   }
  * }
* * @author Arjen Poutsma - * @see org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#setCustomModelAndViewResolvers - * @see org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter#setCustomModelAndViewResolvers * @since 3.0 */ public interface ModelAndViewResolver { - /** Marker to be returned when the resolver does not know how to handle the given method parameter. */ + /** + * Marker to be returned when the resolver does not know how to handle the given method parameter. + */ ModelAndView UNRESOLVED = new ModelAndView(); - ModelAndView resolveModelAndView(Method handlerMethod, - Class handlerType, - Object returnValue, - ExtendedModelMap implicitModel, - NativeWebRequest webRequest); + + ModelAndView resolveModelAndView(Method handlerMethod, Class handlerType, Object returnValue, + ExtendedModelMap implicitModel, NativeWebRequest webRequest); + } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/ResponseStatusExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/ResponseStatusExceptionResolver.java index 6bff5bd8d2..28fcb63d5a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/ResponseStatusExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/ResponseStatusExceptionResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 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. @@ -29,10 +29,13 @@ import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver; /** - * Implementation of the {@link org.springframework.web.servlet.HandlerExceptionResolver HandlerExceptionResolver} - * interface that uses the {@link ResponseStatus @ResponseStatus} annotation to map exceptions to HTTP status codes. + * A {@link org.springframework.web.servlet.HandlerExceptionResolver + * HandlerExceptionResolver} that uses the {@link ResponseStatus @ResponseStatus} + * annotation to map exceptions to HTTP status codes. * - *

This exception resolver is enabled by default in the {@link org.springframework.web.servlet.DispatcherServlet}. + *

This exception resolver is enabled by default in the + * {@link org.springframework.web.servlet.DispatcherServlet DispatcherServlet} + * and the MVC Java config and the MVC namespace. * * @author Arjen Poutsma * @author Rossen Stoyanchev @@ -48,6 +51,7 @@ public class ResponseStatusExceptionResolver extends AbstractHandlerExceptionRes this.messageSource = messageSource; } + @Override protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { @@ -65,16 +69,20 @@ public class ResponseStatusExceptionResolver extends AbstractHandlerExceptionRes } /** - * Template method that handles {@link ResponseStatus @ResponseStatus} annotation.

Default implementation send a - * response error using {@link HttpServletResponse#sendError(int)}, or {@link HttpServletResponse#sendError(int, - * String)} if the annotation has a {@linkplain ResponseStatus#reason() reason}. Returns an empty ModelAndView. + * Template method that handles {@link ResponseStatus @ResponseStatus} annotation. + *

The default implementation sends a response error using + * {@link HttpServletResponse#sendError(int)} or + * {@link HttpServletResponse#sendError(int, String)} if the annotation has a + * {@linkplain ResponseStatus#reason() reason} and then returns an empty ModelAndView. * @param responseStatus the annotation * @param request current HTTP request * @param response current HTTP response - * @param handler the executed handler, or {@code null} if none chosen at the time of the exception - * (for example, if multipart resolution failed) - * @param ex the exception that got thrown during handler execution - * @return a corresponding ModelAndView to forward to, or {@code null} for default processing + * @param handler the executed handler, or {@code null} if none chosen at the + * time of the exception (for example, if multipart resolution failed) + * @param ex the exception that got thrown during handler execution or the + * exception that has the ResponseStatus annotation if found on the cause. + * @return a corresponding ModelAndView to forward to, or {@code null} + * for default processing */ protected ModelAndView resolveResponseStatus(ResponseStatus responseStatus, HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PatternsRequestCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PatternsRequestCondition.java index 4ccd60391e..43f5b49614 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PatternsRequestCondition.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PatternsRequestCondition.java @@ -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. @@ -103,8 +103,8 @@ public final class PatternsRequestCondition extends AbstractRequestCondition fileExtensions) { this.patterns = Collections.unmodifiableSet(prependLeadingSlash(patterns)); - this.pathHelper = urlPathHelper != null ? urlPathHelper : new UrlPathHelper(); - this.pathMatcher = pathMatcher != null ? pathMatcher : new AntPathMatcher(); + this.pathHelper = (urlPathHelper != null ? urlPathHelper : new UrlPathHelper()); + this.pathMatcher = (pathMatcher != null ? pathMatcher : new AntPathMatcher()); this.useSuffixPatternMatch = useSuffixPatternMatch; this.useTrailingSlashMatch = useTrailingSlashMatch; if (fileExtensions != null) { @@ -220,7 +220,6 @@ public final class PatternsRequestCondition extends AbstractRequestCondition - *

  • {@link PatternsRequestCondition} - *
  • {@link RequestMethodsRequestCondition} - *
  • {@link ParamsRequestCondition} - *
  • {@link HeadersRequestCondition} - *
  • {@link ConsumesRequestCondition} - *
  • {@link ProducesRequestCondition} - *
  • {@code RequestCondition} (optional, custom request condition) + *
  • {@link PatternsRequestCondition} + *
  • {@link RequestMethodsRequestCondition} + *
  • {@link ParamsRequestCondition} + *
  • {@link HeadersRequestCondition} + *
  • {@link ConsumesRequestCondition} + *
  • {@link ProducesRequestCondition} + *
  • {@code RequestCondition} (optional, custom request condition) * * * @author Arjen Poutsma @@ -266,21 +266,21 @@ public final class RequestMappingInfo implements RequestConditionThe serialization view specified in the annotation will be passed in to - * the {@code MappingJackson2HttpMessageConverter} which will then use it to - * serialize the response body with. + *

    The serialization view specified in the annotation will be passed in to the + * {@link org.springframework.http.converter.json.MappingJackson2HttpMessageConverter} + * which will then use it to serialize the response body with. * *

    Note that despite {@code @JsonView} allowing for more than one class to * be specified, the use for a response body advice is only supported with @@ -40,6 +40,7 @@ import org.springframework.http.server.ServerHttpResponse; * * @author Rossen Stoyanchev * @since 4.1 + * @see com.fasterxml.jackson.annotation.JsonView * @see com.fasterxml.jackson.databind.ObjectMapper#writerWithView(Class) */ public class JsonViewResponseBodyAdvice extends AbstractMappingJacksonResponseBodyAdvice { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java index 0d746b6094..2c87b61dda 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java @@ -99,13 +99,13 @@ import org.springframework.web.util.WebUtils; /** * An {@link AbstractHandlerMethodAdapter} that supports {@link HandlerMethod}s - * with the signature -- method argument and return types, defined in + * with their method argument and return type signature, as defined via * {@code @RequestMapping}. * *

    Support for custom argument and return value types can be added via * {@link #setCustomArgumentResolvers} and {@link #setCustomReturnValueHandlers}. - * Or alternatively to re-configure all argument and return value types use - * {@link #setArgumentResolvers} and {@link #setReturnValueHandlers(List)}. + * Or alternatively, to re-configure all argument and return value types, + * use {@link #setArgumentResolvers} and {@link #setReturnValueHandlers}. * * @author Rossen Stoyanchev * @since 3.1 @@ -697,12 +697,12 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter if (session != null) { Object mutex = WebUtils.getSessionMutex(session); synchronized (mutex) { - return invokeHandleMethod(request, response, handlerMethod); + return invokeHandlerMethod(request, response, handlerMethod); } } } - return invokeHandleMethod(request, response, handlerMethod); + return invokeHandlerMethod(request, response, handlerMethod); } /** @@ -739,8 +739,8 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter * Invoke the {@link RequestMapping} handler method preparing a {@link ModelAndView} * if view resolution is required. */ - private ModelAndView invokeHandleMethod(HttpServletRequest request, - HttpServletResponse response, HandlerMethod handlerMethod) throws Exception { + private ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, + HandlerMethod handlerMethod) throws Exception { ServletWebRequest webRequest = new ServletWebRequest(request, response); @@ -756,7 +756,7 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response); asyncWebRequest.setTimeout(this.asyncRequestTimeout); - final WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); + WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); asyncManager.setTaskExecutor(this.taskExecutor); asyncManager.setAsyncWebRequest(asyncWebRequest); asyncManager.registerCallableInterceptors(this.callableInterceptors); @@ -766,7 +766,6 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter Object result = asyncManager.getConcurrentResult(); mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0]; asyncManager.clearConcurrentResult(); - if (logger.isDebugEnabled()) { logger.debug("Found concurrent result value [" + result + "]"); } @@ -774,7 +773,6 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter } requestMappingMethod.invokeAndHandle(webRequest, mavContainer); - if (asyncManager.isConcurrentHandlingStarted()) { return null; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java index 4d614e55d7..dd28d13937 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java @@ -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. @@ -127,7 +127,6 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi } - /** * Whether to use suffix pattern matching. */ @@ -229,7 +228,8 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi } /** - * Created a RequestMappingInfo from a RequestMapping annotation. + * Create a {@link RequestMappingInfo} from the supplied + * {@link RequestMapping @RequestMapping} annotation. */ protected RequestMappingInfo createRequestMappingInfo(RequestMapping annotation, RequestCondition customCondition) { String[] patterns = resolveEmbeddedValuesInPatterns(annotation.value()); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/GroovyMarkupConfig.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/GroovyMarkupConfig.java index fda4abc09b..8cdba7d9cb 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/GroovyMarkupConfig.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/GroovyMarkupConfig.java @@ -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. @@ -19,9 +19,9 @@ package org.springframework.web.servlet.view.groovy; import groovy.text.markup.MarkupTemplateEngine; /** - * Interface to be implemented by objects that configure and manage a - * Groovy MarkupTemplateEngine for automatic lookup in a web environment. - * Detected and used by GroovyMarkupView. + * Interface to be implemented by objects that configure and manage a Groovy + * {@link MarkupTemplateEngine} for automatic lookup in a web environment. + * Detected and used by {@link GroovyMarkupView}. * * @author Brian Clozel * @since 4.1 diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/GroovyMarkupConfigurer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/GroovyMarkupConfigurer.java index b85c92219f..69a5cb36ef 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/GroovyMarkupConfigurer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/GroovyMarkupConfigurer.java @@ -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. @@ -46,7 +46,6 @@ import org.springframework.util.StringUtils; * * @Bean * public GroovyMarkupConfig groovyMarkupConfigurer() { - * * GroovyMarkupConfigurer configurer = new GroovyMarkupConfigurer(); * configurer.setResourceLoaderPath("classpath:/WEB-INF/groovymarkup/"); * return configurer; @@ -79,7 +78,7 @@ import org.springframework.util.StringUtils; * @author Rossen Stoyanchev * @since 4.1 * @see GroovyMarkupView - * @see + * @see * Groovy Markup Template engine documentation */ public class GroovyMarkupConfigurer extends TemplateConfiguration diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/GroovyMarkupView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/GroovyMarkupView.java index cd8d1b7497..290d96c7b6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/GroovyMarkupView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/GroovyMarkupView.java @@ -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. @@ -35,8 +35,7 @@ import org.springframework.web.servlet.view.AbstractTemplateView; import org.springframework.web.util.NestedServletException; /** - * An {@link org.springframework.web.servlet.view.AbstractTemplateView AbstractTemplateView} - * based on Groovy XML/XHTML markup templates. + * An {@link AbstractTemplateView} subclass based on Groovy XML/XHTML markup templates. * *

    Spring's Groovy Markup Template support requires Groovy 2.3.1 and higher. * @@ -45,7 +44,7 @@ import org.springframework.web.util.NestedServletException; * @since 4.1 * @see GroovyMarkupViewResolver * @see GroovyMarkupConfigurer - * @see + * @see * Groovy Markup Template engine documentation */ public class GroovyMarkupView extends AbstractTemplateView { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/GroovyMarkupViewResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/GroovyMarkupViewResolver.java index e1b4bb98c4..79c5f87a16 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/GroovyMarkupViewResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/GroovyMarkupViewResolver.java @@ -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. @@ -21,10 +21,9 @@ import java.util.Locale; import org.springframework.web.servlet.view.AbstractTemplateViewResolver; /** - * Convenience subclass of - * {@link org.springframework.web.servlet.view.AbstractTemplateViewResolver} - * that supports {@link GroovyMarkupView} (i.e. Groovy XML/XHTML markup templates) - * and custom subclasses of it. + * Convenience subclass of @link AbstractTemplateViewResolver} that supports + * {@link GroovyMarkupView} (i.e. Groovy XML/XHTML markup templates) and + * custom subclasses of it. * *

    The view class for all views created by this resolver can be specified * via the {@link #setViewClass(Class)} property. diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/package-info.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/package-info.java index 0853ca1217..74a6188dde 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/package-info.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/groovy/package-info.java @@ -1,6 +1,6 @@ /** * Support classes for the integration of - * + * * Groovy Templates as Spring web view technology. * Contains a View implementation for Groovy templates. */ diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/InfoReceiver.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/InfoReceiver.java index ae8ba7bf01..2f74c8404a 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/InfoReceiver.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/InfoReceiver.java @@ -1,3 +1,19 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.web.socket.sockjs.client; import java.net.URI; @@ -15,10 +31,9 @@ public interface InfoReceiver { /** * Perform an HTTP request to the SockJS "Info" URL. * and return the resulting JSON response content, or raise an exception. - * * @param infoUrl the URL to obtain SockJS server information from * @return the body of the response */ String executeInfoRequest(URI infoUrl); -} \ No newline at end of file +} diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/Transport.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/Transport.java index 840858d85f..f3705f6682 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/Transport.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/Transport.java @@ -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. @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.web.socket.sockjs.client; +package org.springframework.web.socket.sockjs.client; import java.util.List; @@ -40,7 +40,6 @@ public interface Transport { /** * Connect the transport. - * * @param request the transport request. * @param webSocketHandler the application handler to delegate lifecycle events to. * @return a future to indicate success or failure to connect. diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/XhrTransport.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/XhrTransport.java index 955ed8899b..cf053aeaf0 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/XhrTransport.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/XhrTransport.java @@ -1,3 +1,19 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.web.socket.sockjs.client; import java.net.URI; @@ -8,8 +24,7 @@ import org.springframework.web.socket.TextMessage; * A SockJS {@link Transport} that uses HTTP requests to simulate a WebSocket * interaction. The {@code connect} method of the base {@code Transport} interface * is used to receive messages from the server while the - * {@link #executeSendRequest(java.net.URI, org.springframework.web.socket.TextMessage) - * executeSendRequest(URI, TextMessage)} method here is used to send messages. + * {@link #executeSendRequest} method here is used to send messages. * * @author Rossen Stoyanchev * @since 4.1 @@ -20,7 +35,6 @@ public interface XhrTransport extends Transport, InfoReceiver { * An {@code XhrTransport} supports both the "xhr_streaming" and "xhr" SockJS * server transports. From a client perspective there is no implementation * difference. - * *

    By default an {@code XhrTransport} will be used with "xhr_streaming" * first and then with "xhr", if the streaming fails to connect. In some * cases it may be useful to suppress streaming so that only "xhr" is used. diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/messaging/StompWebSocketIntegrationTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/messaging/StompWebSocketIntegrationTests.java index 55d9003829..ef0b04af11 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/messaging/StompWebSocketIntegrationTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/messaging/StompWebSocketIntegrationTests.java @@ -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. @@ -83,13 +83,12 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration @Override protected Class[] getAnnotatedConfigClasses() { - return new Class[] { TestMessageBrokerConfiguration.class, TestMessageBrokerConfigurer.class }; + return new Class[] {TestMessageBrokerConfiguration.class, TestMessageBrokerConfigurer.class}; } @Test public void sendMessageToController() throws Exception { - TextMessage message = create(StompCommand.SEND).headers("destination:/app/simple").build(); WebSocketSession session = doHandshake(new TestClientWebSocketHandler(0, message), "/ws").get(); @@ -104,10 +103,8 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration @Test public void sendMessageToControllerAndReceiveReplyViaTopic() throws Exception { - TextMessage message1 = create(StompCommand.SUBSCRIBE) .headers("id:subs1", "destination:/topic/increment").build(); - TextMessage message2 = create(StompCommand.SEND) .headers("destination:/app/increment").body("5").build(); @@ -126,7 +123,6 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration @Test public void sendMessageToBrokerAndReceiveReplyViaTopic() throws Exception { - TextMessage m1 = create(StompCommand.SUBSCRIBE).headers("id:subs1", "destination:/topic/foo").build(); TextMessage m2 = create(StompCommand.SEND).headers("destination:/topic/foo").body("5").build(); @@ -148,7 +144,6 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration @Test public void sendSubscribeToControllerAndReceiveReply() throws Exception { - String destHeader = "destination:/app/number"; TextMessage message = create(StompCommand.SUBSCRIBE).headers("id:subs1", destHeader).build(); @@ -168,7 +163,6 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration @Test public void handleExceptionAndSendToUser() throws Exception { - String destHeader = "destination:/user/queue/error"; TextMessage m1 = create(StompCommand.SUBSCRIBE).headers("id:subs1", destHeader).build(); TextMessage m2 = create(StompCommand.SEND).headers("destination:/app/exception").build(); @@ -178,7 +172,6 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration try { assertTrue(clientHandler.latch.await(2, TimeUnit.SECONDS)); - String payload = clientHandler.actual.get(0).getPayload(); assertTrue(payload.startsWith("MESSAGE\n")); assertTrue(payload.contains("destination:/user/queue/error\n")); @@ -191,10 +184,8 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration @Test public void webSocketScope() throws Exception { - TextMessage message1 = create(StompCommand.SUBSCRIBE) .headers("id:subs1", "destination:/topic/scopedBeanValue").build(); - TextMessage message2 = create(StompCommand.SEND) .headers("destination:/app/scopedBeanValue").build(); @@ -203,7 +194,6 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration try { assertTrue(clientHandler.latch.await(2, TimeUnit.SECONDS)); - String payload = clientHandler.actual.get(0).getPayload(); assertTrue(payload.startsWith("MESSAGE\n")); assertTrue(payload.contains("destination:/topic/scopedBeanValue\n")); @@ -221,6 +211,7 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration private @interface IntegrationTestController { } + @IntegrationTestController static class SimpleController { @@ -243,6 +234,7 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration } } + @IntegrationTestController static class IncrementController { @@ -257,6 +249,7 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration } } + @IntegrationTestController static class ScopedBeanController { @@ -279,6 +272,7 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration String getValue(); } + static class ScopedBeanImpl implements ScopedBean { private final String value; @@ -304,7 +298,6 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration private final CountDownLatch latch; - public TestClientWebSocketHandler(int expectedNumberOfMessages, TextMessage... messagesToSend) { this.messagesToSend = messagesToSend; this.expected = expectedNumberOfMessages; @@ -325,6 +318,7 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration } } + @Configuration @ComponentScan( basePackageClasses=StompWebSocketIntegrationTests.class, @@ -333,7 +327,7 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration static class TestMessageBrokerConfigurer extends AbstractWebSocketMessageBrokerConfigurer { @Autowired - private HandshakeHandler handshakeHandler; // can't rely on classpath for server detection + private HandshakeHandler handshakeHandler; // can't rely on classpath for server detection @Override public void registerStompEndpoints(StompEndpointRegistry registry) { @@ -353,19 +347,20 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration } } + @Configuration static class TestMessageBrokerConfiguration extends DelegatingWebSocketMessageBrokerConfiguration { @Override @Bean public AbstractSubscribableChannel clientInboundChannel() { - return new ExecutorSubscribableChannel(); // synchronous + return new ExecutorSubscribableChannel(); // synchronous } @Override @Bean public AbstractSubscribableChannel clientOutboundChannel() { - return new ExecutorSubscribableChannel(); // synchronous + return new ExecutorSubscribableChannel(); // synchronous } }