diff --git a/spring-beans/src/main/java/org/springframework/beans/GenericTypeAwarePropertyDescriptor.java b/spring-beans/src/main/java/org/springframework/beans/GenericTypeAwarePropertyDescriptor.java index 096bae5a61..7edc86dc0d 100644 --- a/spring-beans/src/main/java/org/springframework/beans/GenericTypeAwarePropertyDescriptor.java +++ b/spring-beans/src/main/java/org/springframework/beans/GenericTypeAwarePropertyDescriptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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,13 +46,13 @@ class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor { private final Method writeMethod; - private final Class propertyEditorClass; - private volatile Set ambiguousWriteMethods; + private MethodParameter writeMethodParameter; + private Class propertyType; - private MethodParameter writeMethodParameter; + private final Class propertyEditorClass; public GenericTypeAwarePropertyDescriptor(Class beanClass, String propertyName, @@ -60,8 +60,11 @@ class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor { throws IntrospectionException { super(propertyName, null, null); + + if (beanClass == null) { + throw new IntrospectionException("Bean class must not be null"); + } this.beanClass = beanClass; - this.propertyEditorClass = propertyEditorClass; Method readMethodToUse = BridgeMethodResolver.findBridgedMethod(readMethod); Method writeMethodToUse = BridgeMethodResolver.findBridgedMethod(writeMethod); @@ -93,8 +96,11 @@ class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor { this.ambiguousWriteMethods = ambiguousCandidates; } } + + this.propertyEditorClass = propertyEditorClass; } + public Class getBeanClass() { return this.beanClass; } @@ -120,9 +126,15 @@ class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor { return this.writeMethod; } - @Override - public Class getPropertyEditorClass() { - return this.propertyEditorClass; + public synchronized MethodParameter getWriteMethodParameter() { + if (this.writeMethod == null) { + return null; + } + if (this.writeMethodParameter == null) { + this.writeMethodParameter = new MethodParameter(this.writeMethod, 0); + GenericTypeResolver.resolveParameterType(this.writeMethodParameter, this.beanClass); + } + return this.writeMethodParameter; } @Override @@ -144,15 +156,9 @@ class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor { return this.propertyType; } - public synchronized MethodParameter getWriteMethodParameter() { - if (this.writeMethod == null) { - return null; - } - if (this.writeMethodParameter == null) { - this.writeMethodParameter = new MethodParameter(this.writeMethod, 0); - GenericTypeResolver.resolveParameterType(this.writeMethodParameter, this.beanClass); - } - return this.writeMethodParameter; + @Override + public Class getPropertyEditorClass() { + return this.propertyEditorClass; } } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java index 597ba82dcd..811ee97dae 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java @@ -238,7 +238,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean if (requiredConstructor != null) { throw new BeanCreationException(beanName, "Invalid autowire-marked constructor: " + candidate + - ". Found another constructor with 'required' Autowired annotation: " + + ". Found constructor with 'required' Autowired annotation already: " + requiredConstructor); } if (candidate.getParameterTypes().length == 0) { @@ -250,7 +250,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean if (!candidates.isEmpty()) { throw new BeanCreationException(beanName, "Invalid autowire-marked constructors: " + candidates + - ". Found another constructor with 'required' Autowired annotation: " + + ". Found constructor with 'required' Autowired annotation: " + candidate); } requiredConstructor = candidate; @@ -484,14 +484,14 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean value = resolvedCachedArgument(beanName, this.cachedFieldValue); } else { - DependencyDescriptor descriptor = new DependencyDescriptor(field, this.required); + DependencyDescriptor desc = new DependencyDescriptor(field, this.required); Set autowiredBeanNames = new LinkedHashSet(1); TypeConverter typeConverter = beanFactory.getTypeConverter(); - value = beanFactory.resolveDependency(descriptor, beanName, autowiredBeanNames, typeConverter); + value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter); synchronized (this) { if (!this.cached) { if (value != null || this.required) { - this.cachedFieldValue = descriptor; + this.cachedFieldValue = desc; registerDependentBeans(beanName, autowiredBeanNames); if (autowiredBeanNames.size() == 1) { String autowiredBeanName = autowiredBeanNames.iterator().next(); diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java index 7181f0b8a1..9f91ae11a0 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,14 +16,6 @@ package org.springframework.beans.factory.annotation; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - import java.io.Serializable; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -33,6 +25,7 @@ import java.util.List; import java.util.Map; import org.junit.Test; + import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.FactoryBean; @@ -49,16 +42,15 @@ import org.springframework.tests.sample.beans.NestedTestBean; import org.springframework.tests.sample.beans.TestBean; import org.springframework.util.SerializationTestUtils; +import static org.junit.Assert.*; /** - * Unit tests for {@link AutowiredAnnotationBeanPostProcessor}. - * * @author Juergen Hoeller * @author Mark Fisher * @author Sam Brannen * @author Chris Beams */ -public final class AutowiredAnnotationBeanPostProcessorTests { +public class AutowiredAnnotationBeanPostProcessorTests { @Test public void testIncompleteBeanDefinition() { @@ -963,7 +955,6 @@ public final class AutowiredAnnotationBeanPostProcessorTests { private TestBean testBean2; - @Autowired public void setTestBean2(TestBean testBean2) { if (this.testBean2 != null) { diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassEnhancer.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassEnhancer.java index 00ae26a94e..ea26af6fb8 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassEnhancer.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassEnhancer.java @@ -287,7 +287,7 @@ class ConfigurationClassEnhancer { "result in a failure to process annotations such as @Autowired, " + "@Resource and @PostConstruct within the method's declaring " + "@Configuration class. Add the 'static' modifier to this method to avoid " + - "these container lifecycle issues; see @Bean Javadoc for complete details", + "these container lifecycle issues; see @Bean javadoc for complete details", beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName())); } return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs); diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java b/spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java index 97ffbbda25..9f78f660bd 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java @@ -194,7 +194,7 @@ public class GenericConversionService implements ConfigurableConversionService { } - // subclassing hooks + // Protected template methods /** * Template method to convert a null source. diff --git a/spring-core/src/test/java/org/springframework/core/convert/support/GenericConversionServiceTests.java b/spring-core/src/test/java/org/springframework/core/convert/support/GenericConversionServiceTests.java index bae5132e75..8af4f8601f 100644 --- a/spring-core/src/test/java/org/springframework/core/convert/support/GenericConversionServiceTests.java +++ b/spring-core/src/test/java/org/springframework/core/convert/support/GenericConversionServiceTests.java @@ -57,11 +57,13 @@ import static org.junit.Assert.*; * @author Keith Donald * @author Juergen Hoeller * @author Phillip Webb + * @author David Haraburda */ public class GenericConversionServiceTests { private GenericConversionService conversionService = new GenericConversionService(); + @Test public void canConvert() { assertFalse(conversionService.canConvert(String.class, Integer.class)); @@ -749,6 +751,13 @@ public class GenericConversionServiceTests { assertEquals("A", result); } + @Test + public void testSubclassOfEnumToString() throws Exception { + conversionService.addConverter(new EnumToStringConverter(conversionService)); + String result = conversionService.convert(EnumWithSubclass.FIRST, String.class); + assertEquals("FIRST", result); + } + @Test public void testEnumWithInterfaceToStringConversion() { // SPR-9692 @@ -846,6 +855,7 @@ public class GenericConversionServiceTests { @ExampleAnnotation public String annotatedString; + @Retention(RetentionPolicy.RUNTIME) public static @interface ExampleAnnotation { } @@ -888,8 +898,7 @@ public class GenericConversionServiceTests { } @Override - public Object convert(Object source, TypeDescriptor sourceType, - TypeDescriptor targetType) { + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { return null; } @@ -932,6 +941,7 @@ public class GenericConversionServiceTests { String getCode(); } + public static enum MyEnum implements MyEnumInterface { A { @@ -943,6 +953,17 @@ public class GenericConversionServiceTests { } + public enum EnumWithSubclass { + + FIRST { + @Override + public String toString() { + return "1st"; + } + } + } + + public static class MyStringToRawCollectionConverter implements Converter { @Override @@ -951,6 +972,7 @@ public class GenericConversionServiceTests { } } + public static class MyStringToGenericCollectionConverter implements Converter> { @Override @@ -959,6 +981,7 @@ public class GenericConversionServiceTests { } } + private static class MyEnumInterfaceToStringConverter implements Converter { @Override @@ -967,6 +990,7 @@ public class GenericConversionServiceTests { } } + public static class MyStringToStringCollectionConverter implements Converter> { @Override @@ -975,6 +999,7 @@ public class GenericConversionServiceTests { } } + public static class MyStringToIntegerCollectionConverter implements Converter> { @Override diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplate.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplate.java index d8258cefc9..f1aea7da1f 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplate.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -52,6 +52,8 @@ import org.springframework.util.Assert; * exposed to allow for convenient access to the traditional * {@link org.springframework.jdbc.core.JdbcTemplate} methods. * + *

NOTE: An instance of this class is thread-safe once configured. + * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.0 @@ -320,7 +322,7 @@ public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations } public int[] batchUpdate(String sql, SqlParameterSource[] batchArgs) { - ParsedSql parsedSql = this.getParsedSql(sql); + ParsedSql parsedSql = getParsedSql(sql); return NamedParameterBatchUpdateUtils.executeBatchUpdateWithNamedParameters(parsedSql, batchArgs, getJdbcOperations()); } diff --git a/spring-web/src/main/java/org/springframework/http/client/AbstractClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/AbstractClientHttpRequest.java index bf73ff61ef..2ad7cb0438 100644 --- a/spring-web/src/main/java/org/springframework/http/client/AbstractClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/AbstractClientHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2014 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,7 +23,8 @@ import org.springframework.http.HttpHeaders; import org.springframework.util.Assert; /** - * Abstract base for {@link ClientHttpRequest} that makes sure that headers and body are not written multiple times. + * Abstract base for {@link ClientHttpRequest} that makes sure that headers + * and body are not written multiple times. * * @author Arjen Poutsma * @since 3.0 diff --git a/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java index 3aa31d9b83..97cfde4b85 100644 --- a/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,13 +27,13 @@ import org.springframework.http.HttpMethod; import org.springframework.util.Assert; /** - * {@link ClientHttpRequestFactory} implementation that uses standard J2SE facilities. + * {@link ClientHttpRequestFactory} implementation that uses standard JDK facilities. * * @author Arjen Poutsma * @author Juergen Hoeller * @since 3.0 * @see java.net.HttpURLConnection - * @see CommonsClientHttpRequestFactory + * @see HttpComponentsClientHttpRequestFactory */ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory { @@ -107,14 +107,12 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory } /** - * Set if the underlying URLConnection can be set to 'output streaming' mode. When - * output streaming is enabled, authentication and redirection cannot be handled - * automatically. If output streaming is disabled the - * {@link HttpURLConnection#setFixedLengthStreamingMode(int) - * setFixedLengthStreamingMode} and - * {@link HttpURLConnection#setChunkedStreamingMode(int) setChunkedStreamingMode} - * methods of the underlying connection will never be called. - *

Default is {@code true}. + * Set if the underlying URLConnection can be set to 'output streaming' mode. + * Default is {@code true}. + *

When output streaming is enabled, authentication and redirection cannot be handled automatically. + * If output streaming is disabled, the {@link HttpURLConnection#setFixedLengthStreamingMode} and + * {@link HttpURLConnection#setChunkedStreamingMode} methods of the underlying connection will never + * be called. * @param outputStreaming if output streaming is enabled */ public void setOutputStreaming(boolean outputStreaming) { @@ -129,8 +127,7 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory return new SimpleBufferingClientHttpRequest(connection, this.outputStreaming); } else { - return new SimpleStreamingClientHttpRequest(connection, this.chunkSize, - this.outputStreaming); + return new SimpleStreamingClientHttpRequest(connection, this.chunkSize, this.outputStreaming); } } diff --git a/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpResponse.java b/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpResponse.java index 1fc33f0b69..9ef130d9d7 100644 --- a/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.util.StringUtils; /** - * {@link ClientHttpResponse} implementation that uses standard J2SE facilities. + * {@link ClientHttpResponse} implementation that uses standard JDK facilities. * Obtained via {@link SimpleBufferingClientHttpRequest#execute()} and * {@link SimpleStreamingClientHttpRequest#execute()}. * diff --git a/spring-web/src/main/java/org/springframework/web/util/OpaqueUriComponents.java b/spring-web/src/main/java/org/springframework/web/util/OpaqueUriComponents.java index 706ad83ae3..438ec0b1b7 100644 --- a/spring-web/src/main/java/org/springframework/web/util/OpaqueUriComponents.java +++ b/spring-web/src/main/java/org/springframework/web/util/OpaqueUriComponents.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -95,10 +95,10 @@ final class OpaqueUriComponents extends UriComponents { @Override protected UriComponents expandInternal(UriTemplateVariables uriVariables) { - String expandedScheme = expandUriComponent(this.getScheme(), uriVariables); - String expandedSSp = expandUriComponent(this.ssp, uriVariables); - String expandedFragment = expandUriComponent(this.getFragment(), uriVariables); - return new OpaqueUriComponents(expandedScheme, expandedSSp, expandedFragment); + String expandedScheme = expandUriComponent(getScheme(), uriVariables); + String expandedSsp = expandUriComponent(getSchemeSpecificPart(), uriVariables); + String expandedFragment = expandUriComponent(getFragment(), uriVariables); + return new OpaqueUriComponents(expandedScheme, expandedSsp, expandedFragment); } @Override diff --git a/spring-web/src/main/java/org/springframework/web/util/UriComponents.java b/spring-web/src/main/java/org/springframework/web/util/UriComponents.java index 16b3e29cd8..e6c631d3d8 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriComponents.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriComponents.java @@ -269,8 +269,7 @@ public abstract class UriComponents implements Serializable { public Object getValue(String name) { if (!this.valueIterator.hasNext()) { - throw new IllegalArgumentException( - "Not enough variable values available to expand '" + name + "'"); + throw new IllegalArgumentException("Not enough variable values available to expand '" + name + "'"); } return this.valueIterator.next(); } diff --git a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java index 9708c3fa25..7d8703247a 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java @@ -159,20 +159,20 @@ public class UriComponentsBuilder { */ public static UriComponentsBuilder fromUriString(String uri) { Assert.hasLength(uri, "'uri' must not be empty"); - Matcher m = URI_PATTERN.matcher(uri); - if (m.matches()) { + Matcher matcher = URI_PATTERN.matcher(uri); + if (matcher.matches()) { UriComponentsBuilder builder = new UriComponentsBuilder(); - String scheme = m.group(2); - String userInfo = m.group(5); - String host = m.group(6); - String port = m.group(8); - String path = m.group(9); - String query = m.group(11); - String fragment = m.group(13); + String scheme = matcher.group(2); + String userInfo = matcher.group(5); + String host = matcher.group(6); + String port = matcher.group(8); + String path = matcher.group(9); + String query = matcher.group(11); + String fragment = matcher.group(13); boolean opaque = false; if (StringUtils.hasLength(scheme)) { - String s = uri.substring(scheme.length()); - if (!s.startsWith(":/")) { + String rest = uri.substring(scheme.length()); + if (!rest.startsWith(":/")) { opaque = true; } } @@ -219,21 +219,19 @@ public class UriComponentsBuilder { */ public static UriComponentsBuilder fromHttpUrl(String httpUrl) { Assert.notNull(httpUrl, "'httpUrl' must not be null"); - Matcher m = HTTP_URL_PATTERN.matcher(httpUrl); - if (m.matches()) { + Matcher matcher = HTTP_URL_PATTERN.matcher(httpUrl); + if (matcher.matches()) { UriComponentsBuilder builder = new UriComponentsBuilder(); - - String scheme = m.group(1); - builder.scheme((scheme != null) ? scheme.toLowerCase() : scheme); - builder.userInfo(m.group(4)); - builder.host(m.group(5)); - String port = m.group(7); + String scheme = matcher.group(1); + builder.scheme(scheme != null ? scheme.toLowerCase() : null); + builder.userInfo(matcher.group(4)); + builder.host(matcher.group(5)); + String port = matcher.group(7); if (StringUtils.hasLength(port)) { builder.port(Integer.parseInt(port)); } - builder.path(m.group(8)); - builder.query(m.group(10)); - + builder.path(matcher.group(8)); + builder.query(matcher.group(10)); return builder; } else { @@ -256,7 +254,7 @@ public class UriComponentsBuilder { * Build a {@code UriComponents} instance from the various components * contained in this builder. * @param encoded whether all the components set in this builder are - * encoded ({@code true}) or not ({@code false}). + * encoded ({@code true}) or not ({@code false}) * @return the URI components */ public UriComponents build(boolean encoded) { @@ -457,13 +455,12 @@ public class UriComponentsBuilder { */ public UriComponentsBuilder query(String query) { if (query != null) { - Matcher m = QUERY_PARAM_PATTERN.matcher(query); - while (m.find()) { - String name = m.group(1); - String eq = m.group(2); - String value = m.group(3); - queryParam(name, (value != null ? value : - (StringUtils.hasLength(eq) ? "" : null))); + Matcher matcher = QUERY_PARAM_PATTERN.matcher(query); + while (matcher.find()) { + String name = matcher.group(1); + String eq = matcher.group(2); + String value = matcher.group(3); + queryParam(name, (value != null ? value : (StringUtils.hasLength(eq) ? "" : null))); } } else { @@ -498,7 +495,7 @@ public class UriComponentsBuilder { Assert.notNull(name, "'name' must not be null"); if (!ObjectUtils.isEmpty(values)) { for (Object value : values) { - String valueAsString = value != null ? value.toString() : null; + String valueAsString = (value != null ? value.toString() : null); this.queryParams.add(name, valueAsString); } } diff --git a/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java b/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java index 0f362ddf13..632e2bda2c 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -88,17 +88,17 @@ public class UriTemplate implements Serializable { * UriTemplate template = new UriTemplate("http://example.com/hotels/{hotel}/bookings/{booking}"); * Map<String, String> uriVariables = new HashMap<String, String>(); * uriVariables.put("booking", "42"); - * uriVariables.put("hotel", "1"); + * uriVariables.put("hotel", "Rest & Relax"); * System.out.println(template.expand(uriVariables)); * - * will print:

{@code http://example.com/hotels/1/bookings/42}
+ * will print:
{@code http://example.com/hotels/Rest%20%26%20Relax/bookings/42}
* @param uriVariables the map of URI variables * @return the expanded URI * @throws IllegalArgumentException if {@code uriVariables} is {@code null}; * or if it does not contain values for all the variable names */ public URI expand(Map uriVariables) { - UriComponents expandedComponents = uriComponents.expand(uriVariables); + UriComponents expandedComponents = this.uriComponents.expand(uriVariables); UriComponents encodedComponents = expandedComponents.encode(); return encodedComponents.toUri(); } @@ -109,16 +109,16 @@ public class UriTemplate implements Serializable { *

Example: *

      * UriTemplate template = new UriTemplate("http://example.com/hotels/{hotel}/bookings/{booking}");
-     * System.out.println(template.expand("1", "42));
+     * System.out.println(template.expand("Rest & Relax", "42));
      * 
- * will print:
{@code http://example.com/hotels/1/bookings/42}
+ * will print:
{@code http://example.com/hotels/Rest%20%26%20Relax/bookings/42}
* @param uriVariableValues the array of URI variables * @return the expanded URI * @throws IllegalArgumentException if {@code uriVariables} is {@code null} * or if it does not contain sufficient variables */ public URI expand(Object... uriVariableValues) { - UriComponents expandedComponents = uriComponents.expand(uriVariableValues); + UriComponents expandedComponents = this.uriComponents.expand(uriVariableValues); UriComponents encodedComponents = expandedComponents.encode(); return encodedComponents.toUri(); } @@ -201,11 +201,11 @@ public class UriTemplate implements Serializable { private Parser(String uriTemplate) { Assert.hasText(uriTemplate, "'uriTemplate' must not be null"); - Matcher m = NAMES_PATTERN.matcher(uriTemplate); + Matcher matcher = NAMES_PATTERN.matcher(uriTemplate); int end = 0; - while (m.find()) { - this.patternBuilder.append(quote(uriTemplate, end, m.start())); - String match = m.group(1); + while (matcher.find()) { + this.patternBuilder.append(quote(uriTemplate, end, matcher.start())); + String match = matcher.group(1); int colonIdx = match.indexOf(':'); if (colonIdx == -1) { this.patternBuilder.append(DEFAULT_VARIABLE_PATTERN); @@ -223,7 +223,7 @@ public class UriTemplate implements Serializable { String variableName = match.substring(0, colonIdx); this.variableNames.add(variableName); } - end = m.end(); + end = matcher.end(); } this.patternBuilder.append(quote(uriTemplate, end, uriTemplate.length())); int lastIdx = this.patternBuilder.length() - 1; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java index 1349663447..497e71190c 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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,7 +25,6 @@ import javax.servlet.http.HttpServletRequest; import javax.xml.transform.Source; import org.springframework.beans.BeanUtils; -import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanInitializationException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -134,12 +133,11 @@ import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolv * libraries available on the classpath. * * + * @author Rossen Stoyanchev + * @since 3.1 * @see EnableWebMvc * @see WebMvcConfigurer * @see WebMvcConfigurerAdapter - * - * @author Rossen Stoyanchev - * @since 3.1 */ public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware { @@ -158,10 +156,10 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv ClassUtils.isPresent("org.codehaus.jackson.JsonGenerator", WebMvcConfigurationSupport.class.getClassLoader()); - private ServletContext servletContext; - private ApplicationContext applicationContext; + private ServletContext servletContext; + private List interceptors; private ContentNegotiationManager contentNegotiationManager; @@ -169,6 +167,13 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv private List> messageConverters; + /** + * Set the Spring {@link ApplicationContext}, e.g. for resource loading. + */ + public void setApplicationContext(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + /** * Set the {@link javax.servlet.ServletContext}, e.g. for resource handling, * looking up file extensions, etc. @@ -177,13 +182,6 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv this.servletContext = servletContext; } - /** - * Set the Spring {@link ApplicationContext}, e.g. for resource loading. - */ - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - /** * Return a {@link RequestMappingHandlerMapping} ordered at 0 for mapping * requests to annotated controllers. @@ -203,7 +201,7 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv * use {@link #addInterceptors(InterceptorRegistry)} instead. */ protected final Object[] getInterceptors() { - if (interceptors == null) { + if (this.interceptors == null) { InterceptorRegistry registry = new InterceptorRegistry(); addInterceptors(registry); registry.addInterceptor(new ConversionServiceExposingInterceptor(mvcConversionService())); @@ -233,8 +231,8 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv try { this.contentNegotiationManager = configurer.getContentNegotiationManager(); } - catch (Exception e) { - throw new BeanInitializationException("Could not create ContentNegotiationManager", e); + catch (Exception ex) { + throw new BeanInitializationException("Could not create ContentNegotiationManager", ex); } } return this.contentNegotiationManager; @@ -273,7 +271,7 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv addViewControllers(registry); AbstractHandlerMapping handlerMapping = registry.getHandlerMapping(); - handlerMapping = handlerMapping != null ? handlerMapping : new EmptyHandlerMapping(); + handlerMapping = (handlerMapping != null ? handlerMapping : new EmptyHandlerMapping()); handlerMapping.setInterceptors(getInterceptors()); return handlerMapping; } @@ -304,10 +302,11 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv */ @Bean public HandlerMapping resourceHandlerMapping() { - ResourceHandlerRegistry registry = new ResourceHandlerRegistry(applicationContext, servletContext); + ResourceHandlerRegistry registry = new ResourceHandlerRegistry(this.applicationContext, this.servletContext); addResourceHandlers(registry); + AbstractHandlerMapping handlerMapping = registry.getHandlerMapping(); - handlerMapping = handlerMapping != null ? handlerMapping : new EmptyHandlerMapping(); + handlerMapping = (handlerMapping != null ? handlerMapping : new EmptyHandlerMapping()); return handlerMapping; } @@ -421,22 +420,16 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv String className = "org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"; clazz = ClassUtils.forName(className, WebMvcConfigurationSupport.class.getClassLoader()); } - catch (ClassNotFoundException e) { - throw new BeanInitializationException("Could not find default validator", e); + catch (ClassNotFoundException ex) { + throw new BeanInitializationException("Could not find default validator class", ex); } - catch (LinkageError e) { - throw new BeanInitializationException("Could not find default validator", e); + catch (LinkageError ex) { + throw new BeanInitializationException("Could not load default validator class", ex); } validator = (Validator) BeanUtils.instantiate(clazz); } else { - validator = new Validator() { - public boolean supports(Class clazz) { - return false; - } - public void validate(Object target, Errors errors) { - } - }; + validator = new NoOpValidator(); } } return validator; @@ -494,14 +487,14 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv * used to add default message converters. */ protected final List> getMessageConverters() { - if (messageConverters == null) { - messageConverters = new ArrayList>(); - configureMessageConverters(messageConverters); - if (messageConverters.isEmpty()) { - addDefaultHttpMessageConverters(messageConverters); + if (this.messageConverters == null) { + this.messageConverters = new ArrayList>(); + configureMessageConverters(this.messageConverters); + if (this.messageConverters.isEmpty()) { + addDefaultHttpMessageConverters(this.messageConverters); } } - return messageConverters; + return this.messageConverters; } /** @@ -639,12 +632,26 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv exceptionResolvers.add(new DefaultHandlerExceptionResolver()); } - private final static class EmptyHandlerMapping extends AbstractHandlerMapping { + + private static final class EmptyHandlerMapping extends AbstractHandlerMapping { @Override - protected Object getHandlerInternal(HttpServletRequest request) throws Exception { + protected Object getHandlerInternal(HttpServletRequest request) { return null; } } + + private static final class NoOpValidator implements Validator { + + @Override + public boolean supports(Class clazz) { + return false; + } + + @Override + public void validate(Object target, Errors errors) { + } + } + }