Browse Source

Polishing

(cherry picked from commit b5127dc)
pull/1260/head
Juergen Hoeller 10 years ago
parent
commit
74b4dd0a40
  1. 21
      spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java
  2. 6
      spring-context/src/main/java/org/springframework/jmx/export/assembler/MethodNameBasedMBeanInfoAssembler.java
  3. 20
      spring-context/src/test/java/org/springframework/jmx/export/assembler/MethodNameBasedMBeanInfoAssemblerMappedTests.java
  4. 19
      spring-context/src/test/java/org/springframework/jmx/export/assembler/MethodNameBasedMBeanInfoAssemblerTests.java
  5. 22
      spring-core/src/main/java/org/springframework/core/ConfigurableObjectInputStream.java
  6. 4
      spring-core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java
  7. 5
      spring-core/src/main/java/org/springframework/core/io/FileSystemResource.java
  8. 21
      spring-core/src/main/java/org/springframework/core/io/Resource.java
  9. 23
      spring-core/src/main/java/org/springframework/core/io/UrlResource.java
  10. 33
      spring-core/src/main/java/org/springframework/util/ClassUtils.java
  11. 13
      spring-core/src/main/java/org/springframework/util/ResourceUtils.java
  12. 16
      spring-core/src/test/java/org/springframework/core/convert/support/CollectionToCollectionConverterTests.java
  13. 142
      spring-jdbc/src/main/java/org/springframework/jdbc/core/BeanPropertyRowMapper.java
  14. 20
      spring-web/src/main/java/org/springframework/http/HttpStatus.java
  15. 10
      spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java
  16. 10
      spring-web/src/test/resources/org/springframework/web/util/HtmlCharacterEntityReferences.dtd
  17. 20
      spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/ServletWrappingController.java

21
spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -156,7 +156,7 @@ class ConstructorResolver {
catch (Throwable ex) { catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() + "Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex); "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
} }
} }
AutowireUtils.sortConstructors(candidates); AutowireUtils.sortConstructors(candidates);
@ -613,8 +613,8 @@ class ConstructorResolver {
String beanName, RootBeanDefinition mbd, BeanWrapper bw, String beanName, RootBeanDefinition mbd, BeanWrapper bw,
ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) { ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {
TypeConverter converter = (this.beanFactory.getCustomTypeConverter() != null ? TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
this.beanFactory.getCustomTypeConverter() : bw); TypeConverter converter = (customConverter != null ? customConverter : bw);
BeanDefinitionValueResolver valueResolver = BeanDefinitionValueResolver valueResolver =
new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter); new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
@ -670,8 +670,8 @@ class ConstructorResolver {
boolean autowiring) throws UnsatisfiedDependencyException { boolean autowiring) throws UnsatisfiedDependencyException {
String methodType = (methodOrCtor instanceof Constructor ? "constructor" : "factory method"); String methodType = (methodOrCtor instanceof Constructor ? "constructor" : "factory method");
TypeConverter converter = (this.beanFactory.getCustomTypeConverter() != null ? TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
this.beanFactory.getCustomTypeConverter() : bw); TypeConverter converter = (customConverter != null ? customConverter : bw);
ArgumentsHolder args = new ArgumentsHolder(paramTypes.length); ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = Set<ConstructorArgumentValues.ValueHolder> usedValueHolders =
@ -772,12 +772,13 @@ class ConstructorResolver {
private Object[] resolvePreparedArguments( private Object[] resolvePreparedArguments(
String beanName, RootBeanDefinition mbd, BeanWrapper bw, Member methodOrCtor, Object[] argsToResolve) { String beanName, RootBeanDefinition mbd, BeanWrapper bw, Member methodOrCtor, Object[] argsToResolve) {
Class<?>[] paramTypes = (methodOrCtor instanceof Method ? TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
((Method) methodOrCtor).getParameterTypes() : ((Constructor<?>) methodOrCtor).getParameterTypes()); TypeConverter converter = (customConverter != null ? customConverter : bw);
TypeConverter converter = (this.beanFactory.getCustomTypeConverter() != null ?
this.beanFactory.getCustomTypeConverter() : bw);
BeanDefinitionValueResolver valueResolver = BeanDefinitionValueResolver valueResolver =
new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter); new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
Class<?>[] paramTypes = (methodOrCtor instanceof Method ?
((Method) methodOrCtor).getParameterTypes() : ((Constructor<?>) methodOrCtor).getParameterTypes());
Object[] resolvedArgs = new Object[argsToResolve.length]; Object[] resolvedArgs = new Object[argsToResolve.length];
for (int argIndex = 0; argIndex < argsToResolve.length; argIndex++) { for (int argIndex = 0; argIndex < argsToResolve.length; argIndex++) {
Object argValue = argsToResolve[argIndex]; Object argValue = argsToResolve[argIndex];

6
spring-context/src/main/java/org/springframework/jmx/export/assembler/MethodNameBasedMBeanInfoAssembler.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -72,7 +72,7 @@ public class MethodNameBasedMBeanInfoAssembler extends AbstractConfigurableMBean
* @param methodNames an array of method names indicating the methods to use * @param methodNames an array of method names indicating the methods to use
* @see #setMethodMappings * @see #setMethodMappings
*/ */
public void setManagedMethods(String[] methodNames) { public void setManagedMethods(String... methodNames) {
this.managedMethods = new HashSet<String>(Arrays.asList(methodNames)); this.managedMethods = new HashSet<String>(Arrays.asList(methodNames));
} }
@ -85,7 +85,7 @@ public class MethodNameBasedMBeanInfoAssembler extends AbstractConfigurableMBean
*/ */
public void setMethodMappings(Properties mappings) { public void setMethodMappings(Properties mappings) {
this.methodMappings = new HashMap<String, Set<String>>(); this.methodMappings = new HashMap<String, Set<String>>();
for (Enumeration en = mappings.keys(); en.hasMoreElements();) { for (Enumeration<?> en = mappings.keys(); en.hasMoreElements();) {
String beanKey = (String) en.nextElement(); String beanKey = (String) en.nextElement();
String[] methodNames = StringUtils.commaDelimitedListToStringArray(mappings.getProperty(beanKey)); String[] methodNames = StringUtils.commaDelimitedListToStringArray(mappings.getProperty(beanKey));
this.methodMappings.put(beanKey, new HashSet<String>(Arrays.asList(methodNames))); this.methodMappings.put(beanKey, new HashSet<String>(Arrays.asList(methodNames)));

20
spring-context/src/test/java/org/springframework/jmx/export/assembler/MethodNameBasedMBeanInfoAssemblerMappedTests.java

@ -1,23 +1,22 @@
/* /*
* Copyright 2002-2013 the original author or authors. * Copyright 2002-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not * Licensed under the Apache License, Version 2.0 (the "License");
* use this file except in compliance with the License. You may obtain a copy of * you may not use this file except in compliance with the License.
* the License at * 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 * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS,
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* License for the specific language governing permissions and limitations under * See the License for the specific language governing permissions and
* the License. * limitations under the License.
*/ */
package org.springframework.jmx.export.assembler; package org.springframework.jmx.export.assembler;
import java.util.Properties; import java.util.Properties;
import javax.management.MBeanAttributeInfo; import javax.management.MBeanAttributeInfo;
import javax.management.modelmbean.ModelMBeanAttributeInfo; import javax.management.modelmbean.ModelMBeanAttributeInfo;
import javax.management.modelmbean.ModelMBeanInfo; import javax.management.modelmbean.ModelMBeanInfo;
@ -34,6 +33,7 @@ public class MethodNameBasedMBeanInfoAssemblerMappedTests extends AbstractJmxAss
protected static final String OBJECT_NAME = "bean:name=testBean4"; protected static final String OBJECT_NAME = "bean:name=testBean4";
@Test @Test
public void testGetAgeIsReadOnly() throws Exception { public void testGetAgeIsReadOnly() throws Exception {
ModelMBeanInfo info = getMBeanInfoFromAssembler(); ModelMBeanInfo info = getMBeanInfoFromAssembler();
@ -47,7 +47,7 @@ public class MethodNameBasedMBeanInfoAssemblerMappedTests extends AbstractJmxAss
public void testWithFallThrough() throws Exception { public void testWithFallThrough() throws Exception {
MethodNameBasedMBeanInfoAssembler assembler = MethodNameBasedMBeanInfoAssembler assembler =
getWithMapping("foobar", "add,myOperation,getName,setName,getAge"); getWithMapping("foobar", "add,myOperation,getName,setName,getAge");
assembler.setManagedMethods(new String[]{"getNickName", "setNickName"}); assembler.setManagedMethods("getNickName", "setNickName");
ModelMBeanInfo inf = assembler.getMBeanInfo(getBean(), getObjectName()); ModelMBeanInfo inf = assembler.getMBeanInfo(getBean(), getObjectName());
MBeanAttributeInfo attr = inf.getAttribute("NickName"); MBeanAttributeInfo attr = inf.getAttribute("NickName");

19
spring-context/src/test/java/org/springframework/jmx/export/assembler/MethodNameBasedMBeanInfoAssemblerTests.java

@ -1,17 +1,17 @@
/* /*
* Copyright 2002-2013 the original author or authors. * Copyright 2002-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not * Licensed under the Apache License, Version 2.0 (the "License");
* use this file except in compliance with the License. You may obtain a copy of * you may not use this file except in compliance with the License.
* the License at * 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 * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS,
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* License for the specific language governing permissions and limitations under * See the License for the specific language governing permissions and
* the License. * limitations under the License.
*/ */
package org.springframework.jmx.export.assembler; package org.springframework.jmx.export.assembler;
@ -33,6 +33,7 @@ public class MethodNameBasedMBeanInfoAssemblerTests extends AbstractJmxAssembler
protected static final String OBJECT_NAME = "bean:name=testBean5"; protected static final String OBJECT_NAME = "bean:name=testBean5";
@Override @Override
protected String getObjectName() { protected String getObjectName() {
return OBJECT_NAME; return OBJECT_NAME;
@ -51,7 +52,7 @@ public class MethodNameBasedMBeanInfoAssemblerTests extends AbstractJmxAssembler
@Override @Override
protected MBeanInfoAssembler getAssembler() { protected MBeanInfoAssembler getAssembler() {
MethodNameBasedMBeanInfoAssembler assembler = new MethodNameBasedMBeanInfoAssembler(); MethodNameBasedMBeanInfoAssembler assembler = new MethodNameBasedMBeanInfoAssembler();
assembler.setManagedMethods(new String[] {"add", "myOperation", "getName", "setName", "getAge"}); assembler.setManagedMethods("add", "myOperation", "getName", "setName", "getAge");
return assembler; return assembler;
} }

22
spring-core/src/main/java/org/springframework/core/ConfigurableObjectInputStream.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,7 +21,6 @@ import java.io.InputStream;
import java.io.NotSerializableException; import java.io.NotSerializableException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectStreamClass; import java.io.ObjectStreamClass;
import java.lang.reflect.Proxy;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
@ -68,7 +67,7 @@ public class ConfigurableObjectInputStream extends ObjectInputStream {
@Override @Override
protected Class resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException { protected Class<?> resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException {
try { try {
if (this.classLoader != null) { if (this.classLoader != null) {
// Use the specified ClassLoader to resolve local classes. // Use the specified ClassLoader to resolve local classes.
@ -85,13 +84,13 @@ public class ConfigurableObjectInputStream extends ObjectInputStream {
} }
@Override @Override
protected Class resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException { protected Class<?> resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException {
if (!this.acceptProxyClasses) { if (!this.acceptProxyClasses) {
throw new NotSerializableException("Not allowed to accept serialized proxy classes"); throw new NotSerializableException("Not allowed to accept serialized proxy classes");
} }
if (this.classLoader != null) { if (this.classLoader != null) {
// Use the specified ClassLoader to resolve local proxy classes. // Use the specified ClassLoader to resolve local proxy classes.
Class[] resolvedInterfaces = new Class[interfaces.length]; Class<?>[] resolvedInterfaces = new Class<?>[interfaces.length];
for (int i = 0; i < interfaces.length; i++) { for (int i = 0; i < interfaces.length; i++) {
try { try {
resolvedInterfaces[i] = ClassUtils.forName(interfaces[i], this.classLoader); resolvedInterfaces[i] = ClassUtils.forName(interfaces[i], this.classLoader);
@ -101,7 +100,7 @@ public class ConfigurableObjectInputStream extends ObjectInputStream {
} }
} }
try { try {
return Proxy.getProxyClass(this.classLoader, resolvedInterfaces); return ClassUtils.createCompositeInterface(resolvedInterfaces, this.classLoader);
} }
catch (IllegalArgumentException ex) { catch (IllegalArgumentException ex) {
throw new ClassNotFoundException(null, ex); throw new ClassNotFoundException(null, ex);
@ -113,11 +112,11 @@ public class ConfigurableObjectInputStream extends ObjectInputStream {
return super.resolveProxyClass(interfaces); return super.resolveProxyClass(interfaces);
} }
catch (ClassNotFoundException ex) { catch (ClassNotFoundException ex) {
Class[] resolvedInterfaces = new Class[interfaces.length]; Class<?>[] resolvedInterfaces = new Class<?>[interfaces.length];
for (int i = 0; i < interfaces.length; i++) { for (int i = 0; i < interfaces.length; i++) {
resolvedInterfaces[i] = resolveFallbackIfPossible(interfaces[i], ex); resolvedInterfaces[i] = resolveFallbackIfPossible(interfaces[i], ex);
} }
return Proxy.getProxyClass(getFallbackClassLoader(), resolvedInterfaces); return ClassUtils.createCompositeInterface(resolvedInterfaces, getFallbackClassLoader());
} }
} }
} }
@ -131,7 +130,7 @@ public class ConfigurableObjectInputStream extends ObjectInputStream {
* @param ex the original exception thrown when attempting to load the class * @param ex the original exception thrown when attempting to load the class
* @return the newly resolved class (never {@code null}) * @return the newly resolved class (never {@code null})
*/ */
protected Class resolveFallbackIfPossible(String className, ClassNotFoundException ex) protected Class<?> resolveFallbackIfPossible(String className, ClassNotFoundException ex)
throws IOException, ClassNotFoundException{ throws IOException, ClassNotFoundException{
throw ex; throw ex;
@ -139,8 +138,9 @@ public class ConfigurableObjectInputStream extends ObjectInputStream {
/** /**
* Return the fallback ClassLoader to use when no ClassLoader was specified * Return the fallback ClassLoader to use when no ClassLoader was specified
* and ObjectInputStream's own default ClassLoader failed. * and ObjectInputStream's own default class loader failed.
* <p>The default implementation simply returns {@code null}. * <p>The default implementation simply returns {@code null}, indicating
* that no specific fallback is available.
*/ */
protected ClassLoader getFallbackClassLoader() throws IOException { protected ClassLoader getFallbackClassLoader() throws IOException {
return null; return null;

4
spring-core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2013 the original author or authors. * Copyright 2002-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -72,7 +72,7 @@ public abstract class AbstractFileResolvingResource extends AbstractResource {
} }
/** /**
* This implementation returns a File reference for the underlying class path * This implementation returns a File reference for the given URI-identified
* resource, provided that it refers to a file in the file system. * resource, provided that it refers to a file in the file system.
* @see org.springframework.util.ResourceUtils#getFile(java.net.URI, String) * @see org.springframework.util.ResourceUtils#getFile(java.net.URI, String)
*/ */

5
spring-core/src/main/java/org/springframework/core/io/FileSystemResource.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -30,7 +30,7 @@ import org.springframework.util.StringUtils;
/** /**
* {@link Resource} implementation for {@code java.io.File} handles. * {@link Resource} implementation for {@code java.io.File} handles.
* Obviously supports resolution as File, and also as URL. * Supports resolution as a {@code File} and also as a {@code URL}.
* Implements the extended {@link WritableResource} interface. * Implements the extended {@link WritableResource} interface.
* *
* @author Juergen Hoeller * @author Juergen Hoeller
@ -85,7 +85,6 @@ public class FileSystemResource extends AbstractResource implements WritableReso
return this.path; return this.path;
} }
/** /**
* This implementation returns whether the underlying file exists. * This implementation returns whether the underlying file exists.
* @see java.io.File#exists() * @see java.io.File#exists()

21
spring-core/src/main/java/org/springframework/core/io/Resource.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -37,25 +37,25 @@ import java.net.URL;
* @see #getFile() * @see #getFile()
* @see WritableResource * @see WritableResource
* @see ContextResource * @see ContextResource
* @see FileSystemResource
* @see ClassPathResource
* @see UrlResource * @see UrlResource
* @see ClassPathResource
* @see FileSystemResource
* @see ByteArrayResource * @see ByteArrayResource
* @see InputStreamResource * @see InputStreamResource
*/ */
public interface Resource extends InputStreamSource { public interface Resource extends InputStreamSource {
/** /**
* Return whether this resource actually exists in physical form. * Determine whether this resource actually exists in physical form.
* <p>This method performs a definitive existence check, whereas the * <p>This method performs a definitive existence check, whereas the
* existence of a {@code Resource} handle only guarantees a * existence of a {@code Resource} handle only guarantees a valid
* valid descriptor handle. * descriptor handle.
*/ */
boolean exists(); boolean exists();
/** /**
* Return whether the contents of this resource can be read, * Indicate whether the contents of this resource can be read via
* e.g. via {@link #getInputStream()} or {@link #getFile()}. * {@link #getInputStream()}.
* <p>Will be {@code true} for typical resource descriptors; * <p>Will be {@code true} for typical resource descriptors;
* note that actual content reading may still fail when attempted. * note that actual content reading may still fail when attempted.
* However, a value of {@code false} is a definitive indication * However, a value of {@code false} is a definitive indication
@ -65,8 +65,8 @@ public interface Resource extends InputStreamSource {
boolean isReadable(); boolean isReadable();
/** /**
* Return whether this resource represents a handle with an open * Indicate whether this resource represents a handle with an open stream.
* stream. If true, the InputStream cannot be read multiple times, * If {@code true}, the InputStream cannot be read multiple times,
* and must be read and closed to avoid resource leaks. * and must be read and closed to avoid resource leaks.
* <p>Will be {@code false} for typical resource descriptors. * <p>Will be {@code false} for typical resource descriptors.
*/ */
@ -83,6 +83,7 @@ public interface Resource extends InputStreamSource {
* Return a URI handle for this resource. * Return a URI handle for this resource.
* @throws IOException if the resource cannot be resolved as URI, * @throws IOException if the resource cannot be resolved as URI,
* i.e. if the resource is not available as descriptor * i.e. if the resource is not available as descriptor
* @since 2.5
*/ */
URI getURI() throws IOException; URI getURI() throws IOException;

23
spring-core/src/main/java/org/springframework/core/io/UrlResource.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2013 the original author or authors. * Copyright 2002-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -32,8 +32,8 @@ import org.springframework.util.StringUtils;
/** /**
* {@link Resource} implementation for {@code java.net.URL} locators. * {@link Resource} implementation for {@code java.net.URL} locators.
* Obviously supports resolution as URL, and also as File in case of * Supports resolution as a {@code URL} and also as a {@code File} in
* the "file:" protocol. * case of the {@code "file:"} protocol.
* *
* @author Juergen Hoeller * @author Juergen Hoeller
* @since 28.12.2003 * @since 28.12.2003
@ -58,9 +58,10 @@ public class UrlResource extends AbstractFileResolvingResource {
/** /**
* Create a new UrlResource based on the given URI object. * Create a new {@code UrlResource} based on the given URI object.
* @param uri a URI * @param uri a URI
* @throws MalformedURLException if the given URL path is not valid * @throws MalformedURLException if the given URL path is not valid
* @since 2.5
*/ */
public UrlResource(URI uri) throws MalformedURLException { public UrlResource(URI uri) throws MalformedURLException {
Assert.notNull(uri, "URI must not be null"); Assert.notNull(uri, "URI must not be null");
@ -70,7 +71,7 @@ public class UrlResource extends AbstractFileResolvingResource {
} }
/** /**
* Create a new UrlResource based on the given URL object. * Create a new {@code UrlResource} based on the given URL object.
* @param url a URL * @param url a URL
*/ */
public UrlResource(URL url) { public UrlResource(URL url) {
@ -81,7 +82,7 @@ public class UrlResource extends AbstractFileResolvingResource {
} }
/** /**
* Create a new UrlResource based on a URL path. * Create a new {@code UrlResource} based on a URL path.
* <p>Note: The given path needs to be pre-encoded if necessary. * <p>Note: The given path needs to be pre-encoded if necessary.
* @param path a URL path * @param path a URL path
* @throws MalformedURLException if the given URL path is not valid * @throws MalformedURLException if the given URL path is not valid
@ -95,7 +96,7 @@ public class UrlResource extends AbstractFileResolvingResource {
} }
/** /**
* Create a new UrlResource based on a URI specification. * Create a new {@code UrlResource} based on a URI specification.
* <p>The given parts will automatically get encoded if necessary. * <p>The given parts will automatically get encoded if necessary.
* @param protocol the URL protocol to use (e.g. "jar" or "file" - without colon); * @param protocol the URL protocol to use (e.g. "jar" or "file" - without colon);
* also known as "scheme" * also known as "scheme"
@ -109,7 +110,7 @@ public class UrlResource extends AbstractFileResolvingResource {
} }
/** /**
* Create a new UrlResource based on a URI specification. * Create a new {@code UrlResource} based on a URI specification.
* <p>The given parts will automatically get encoded if necessary. * <p>The given parts will automatically get encoded if necessary.
* @param protocol the URL protocol to use (e.g. "jar" or "file" - without colon); * @param protocol the URL protocol to use (e.g. "jar" or "file" - without colon);
* also known as "scheme" * also known as "scheme"
@ -133,6 +134,7 @@ public class UrlResource extends AbstractFileResolvingResource {
} }
} }
/** /**
* Determine a cleaned URL for the given original URL. * Determine a cleaned URL for the given original URL.
* @param originalUrl the original URL * @param originalUrl the original URL
@ -151,10 +153,9 @@ public class UrlResource extends AbstractFileResolvingResource {
} }
} }
/** /**
* This implementation opens an InputStream for the given URL. * This implementation opens an InputStream for the given URL.
* It sets the "UseCaches" flag to {@code false}, * <p>It sets the {@code useCaches} flag to {@code false},
* mainly to avoid jar file locking on Windows. * mainly to avoid jar file locking on Windows.
* @see java.net.URL#openConnection() * @see java.net.URL#openConnection()
* @see java.net.URLConnection#setUseCaches(boolean) * @see java.net.URLConnection#setUseCaches(boolean)
@ -213,7 +214,7 @@ public class UrlResource extends AbstractFileResolvingResource {
} }
/** /**
* This implementation creates a UrlResource, applying the given path * This implementation creates a {@code UrlResource}, applying the given path
* relative to the path of the underlying URL of this resource descriptor. * relative to the path of the underlying URL of this resource descriptor.
* @see java.net.URL#URL(java.net.URL, String) * @see java.net.URL#URL(java.net.URL, String)
*/ */

33
spring-core/src/main/java/org/springframework/util/ClassUtils.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2015 the original author or authors. * Copyright 2002-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -55,13 +55,16 @@ public abstract class ClassUtils {
/** Prefix for internal non-primitive array class names: "[L" */ /** Prefix for internal non-primitive array class names: "[L" */
private static final String NON_PRIMITIVE_ARRAY_PREFIX = "[L"; private static final String NON_PRIMITIVE_ARRAY_PREFIX = "[L";
/** The package separator character '.' */ /** The package separator character: '.' */
private static final char PACKAGE_SEPARATOR = '.'; private static final char PACKAGE_SEPARATOR = '.';
/** The inner class separator character '$' */ /** The path separator character: '/' */
private static final char PATH_SEPARATOR = '/';
/** The inner class separator character: '$' */
private static final char INNER_CLASS_SEPARATOR = '$'; private static final char INNER_CLASS_SEPARATOR = '$';
/** The CGLIB class separator character "$$" */ /** The CGLIB class separator: "$$" */
public static final String CGLIB_CLASS_SEPARATOR = "$$"; public static final String CGLIB_CLASS_SEPARATOR = "$$";
/** The ".class" file suffix */ /** The ".class" file suffix */
@ -265,9 +268,10 @@ public abstract class ClassUtils {
return (clToUse != null ? clToUse.loadClass(name) : Class.forName(name)); return (clToUse != null ? clToUse.loadClass(name) : Class.forName(name));
} }
catch (ClassNotFoundException ex) { catch (ClassNotFoundException ex) {
int lastDotIndex = name.lastIndexOf('.'); int lastDotIndex = name.lastIndexOf(PACKAGE_SEPARATOR);
if (lastDotIndex != -1) { if (lastDotIndex != -1) {
String innerClassName = name.substring(0, lastDotIndex) + '$' + name.substring(lastDotIndex + 1); String innerClassName =
name.substring(0, lastDotIndex) + INNER_CLASS_SEPARATOR + name.substring(lastDotIndex + 1);
try { try {
return (clToUse != null ? clToUse.loadClass(innerClassName) : Class.forName(innerClassName)); return (clToUse != null ? clToUse.loadClass(innerClassName) : Class.forName(innerClassName));
} }
@ -455,8 +459,8 @@ public abstract class ClassUtils {
* @see java.beans.Introspector#decapitalize(String) * @see java.beans.Introspector#decapitalize(String)
*/ */
public static String getShortNameAsProperty(Class<?> clazz) { public static String getShortNameAsProperty(Class<?> clazz) {
String shortName = ClassUtils.getShortName(clazz); String shortName = getShortName(clazz);
int dotIndex = shortName.lastIndexOf('.'); int dotIndex = shortName.lastIndexOf(PACKAGE_SEPARATOR);
shortName = (dotIndex != -1 ? shortName.substring(dotIndex + 1) : shortName); shortName = (dotIndex != -1 ? shortName.substring(dotIndex + 1) : shortName);
return Introspector.decapitalize(shortName); return Introspector.decapitalize(shortName);
} }
@ -525,7 +529,7 @@ public abstract class ClassUtils {
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
while (clazz.isArray()) { while (clazz.isArray()) {
clazz = clazz.getComponentType(); clazz = clazz.getComponentType();
result.append(ClassUtils.ARRAY_SUFFIX); result.append(ARRAY_SUFFIX);
} }
result.insert(0, clazz.getName()); result.insert(0, clazz.getName());
return result.toString(); return result.toString();
@ -955,7 +959,7 @@ public abstract class ClassUtils {
*/ */
public static String convertResourcePathToClassName(String resourcePath) { public static String convertResourcePathToClassName(String resourcePath) {
Assert.notNull(resourcePath, "Resource path must not be null"); Assert.notNull(resourcePath, "Resource path must not be null");
return resourcePath.replace('/', '.'); return resourcePath.replace(PATH_SEPARATOR, PACKAGE_SEPARATOR);
} }
/** /**
@ -965,7 +969,7 @@ public abstract class ClassUtils {
*/ */
public static String convertClassNameToResourcePath(String className) { public static String convertClassNameToResourcePath(String className) {
Assert.notNull(className, "Class name must not be null"); Assert.notNull(className, "Class name must not be null");
return className.replace('.', '/'); return className.replace(PACKAGE_SEPARATOR, PATH_SEPARATOR);
} }
/** /**
@ -1011,12 +1015,12 @@ public abstract class ClassUtils {
return ""; return "";
} }
String className = clazz.getName(); String className = clazz.getName();
int packageEndIndex = className.lastIndexOf('.'); int packageEndIndex = className.lastIndexOf(PACKAGE_SEPARATOR);
if (packageEndIndex == -1) { if (packageEndIndex == -1) {
return ""; return "";
} }
String packageName = className.substring(0, packageEndIndex); String packageName = className.substring(0, packageEndIndex);
return packageName.replace('.', '/'); return packageName.replace(PACKAGE_SEPARATOR, PATH_SEPARATOR);
} }
/** /**
@ -1165,7 +1169,6 @@ public abstract class ClassUtils {
*/ */
public static Class<?> createCompositeInterface(Class<?>[] interfaces, ClassLoader classLoader) { public static Class<?> createCompositeInterface(Class<?>[] interfaces, ClassLoader classLoader) {
Assert.notEmpty(interfaces, "Interfaces must not be empty"); Assert.notEmpty(interfaces, "Interfaces must not be empty");
Assert.notNull(classLoader, "ClassLoader must not be null");
return Proxy.getProxyClass(classLoader, interfaces); return Proxy.getProxyClass(classLoader, interfaces);
} }
@ -1229,7 +1232,7 @@ public abstract class ClassUtils {
* @see org.springframework.aop.support.AopUtils#isCglibProxy(Object) * @see org.springframework.aop.support.AopUtils#isCglibProxy(Object)
*/ */
public static boolean isCglibProxy(Object object) { public static boolean isCglibProxy(Object object) {
return ClassUtils.isCglibProxyClass(object.getClass()); return isCglibProxyClass(object.getClass());
} }
/** /**

13
spring-core/src/main/java/org/springframework/util/ResourceUtils.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -126,8 +126,8 @@ public abstract class ResourceUtils {
URL url = (cl != null ? cl.getResource(path) : ClassLoader.getSystemResource(path)); URL url = (cl != null ? cl.getResource(path) : ClassLoader.getSystemResource(path));
if (url == null) { if (url == null) {
String description = "class path resource [" + path + "]"; String description = "class path resource [" + path + "]";
throw new FileNotFoundException( throw new FileNotFoundException(description +
description + " cannot be resolved to URL because it does not exist"); " cannot be resolved to URL because it does not exist");
} }
return url; return url;
} }
@ -166,9 +166,8 @@ public abstract class ResourceUtils {
ClassLoader cl = ClassUtils.getDefaultClassLoader(); ClassLoader cl = ClassUtils.getDefaultClassLoader();
URL url = (cl != null ? cl.getResource(path) : ClassLoader.getSystemResource(path)); URL url = (cl != null ? cl.getResource(path) : ClassLoader.getSystemResource(path));
if (url == null) { if (url == null) {
throw new FileNotFoundException( throw new FileNotFoundException(description +
description + " cannot be resolved to absolute file path " + " cannot be resolved to absolute file path because it does not exist");
"because it does not reside in the file system");
} }
return getFile(url, description); return getFile(url, description);
} }
@ -227,6 +226,7 @@ public abstract class ResourceUtils {
* @return a corresponding File object * @return a corresponding File object
* @throws FileNotFoundException if the URL cannot be resolved to * @throws FileNotFoundException if the URL cannot be resolved to
* a file in the file system * a file in the file system
* @since 2.5
*/ */
public static File getFile(URI resourceUri) throws FileNotFoundException { public static File getFile(URI resourceUri) throws FileNotFoundException {
return getFile(resourceUri, "URI"); return getFile(resourceUri, "URI");
@ -241,6 +241,7 @@ public abstract class ResourceUtils {
* @return a corresponding File object * @return a corresponding File object
* @throws FileNotFoundException if the URL cannot be resolved to * @throws FileNotFoundException if the URL cannot be resolved to
* a file in the file system * a file in the file system
* @since 2.5
*/ */
public static File getFile(URI resourceUri, String description) throws FileNotFoundException { public static File getFile(URI resourceUri, String description) throws FileNotFoundException {
Assert.notNull(resourceUri, "Resource URI must not be null"); Assert.notNull(resourceUri, "Resource URI must not be null");

16
spring-core/src/test/java/org/springframework/core/convert/support/CollectionToCollectionConverterTests.java

@ -74,10 +74,10 @@ public class CollectionToCollectionConverterTests {
conversionService.addConverterFactory(new StringToNumberConverterFactory()); conversionService.addConverterFactory(new StringToNumberConverterFactory());
assertTrue(conversionService.canConvert(sourceType, targetType)); assertTrue(conversionService.canConvert(sourceType, targetType));
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<String> result = (List<String>) conversionService.convert(list, sourceType, targetType); List<Integer> result = (List<Integer>) conversionService.convert(list, sourceType, targetType);
assertFalse(list.equals(result)); assertFalse(list.equals(result));
assertEquals(9, result.get(0)); assertEquals(9, result.get(0).intValue());
assertEquals(37, result.get(1)); assertEquals(37, result.get(1).intValue());
} }
@Test @Test
@ -199,7 +199,7 @@ public class CollectionToCollectionConverterTests {
public void listToCollectionNoCopyRequired() throws NoSuchFieldException { public void listToCollectionNoCopyRequired() throws NoSuchFieldException {
List<?> input = new ArrayList<String>(Arrays.asList("foo", "bar")); List<?> input = new ArrayList<String>(Arrays.asList("foo", "bar"));
assertSame(input, conversionService.convert(input, TypeDescriptor.forObject(input), assertSame(input, conversionService.convert(input, TypeDescriptor.forObject(input),
new TypeDescriptor(getClass().getField("wildCardCollection")))); new TypeDescriptor(getClass().getField("wildcardCollection"))));
} }
@Test @Test
@ -232,7 +232,7 @@ public class CollectionToCollectionConverterTests {
assertSame(resources, conversionService.convert(resources, sourceType, new TypeDescriptor(getClass().getField("resources")))); assertSame(resources, conversionService.convert(resources, sourceType, new TypeDescriptor(getClass().getField("resources"))));
} }
@Test(expected=ConverterNotFoundException.class) @Test(expected = ConverterNotFoundException.class)
public void elementTypesNotConvertible() throws Exception { public void elementTypesNotConvertible() throws Exception {
List<String> resources = new ArrayList<String>(); List<String> resources = new ArrayList<String>();
resources.add(null); resources.add(null);
@ -241,7 +241,7 @@ public class CollectionToCollectionConverterTests {
assertEquals(resources, conversionService.convert(resources, sourceType, new TypeDescriptor(getClass().getField("resources")))); assertEquals(resources, conversionService.convert(resources, sourceType, new TypeDescriptor(getClass().getField("resources"))));
} }
@Test(expected=ConversionFailedException.class) @Test(expected = ConversionFailedException.class)
public void nothingInCommon() throws Exception { public void nothingInCommon() throws Exception {
List<Object> resources = new ArrayList<Object>(); List<Object> resources = new ArrayList<Object>();
resources.add(new ClassPathResource("test")); resources.add(new ClassPathResource("test"));
@ -261,9 +261,9 @@ public class CollectionToCollectionConverterTests {
public List<String> strings; public List<String> strings;
public List list = Collections.emptyList(); public List<?> list = Collections.emptyList();
public Collection<?> wildCardCollection = Collections.emptyList(); public Collection<?> wildcardCollection = Collections.emptyList();
public List<Resource> resources; public List<Resource> resources;

142
spring-jdbc/src/main/java/org/springframework/jdbc/core/BeanPropertyRowMapper.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2013 the original author or authors. * Copyright 2002-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -37,6 +37,7 @@ import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.jdbc.support.JdbcUtils; import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
@ -56,14 +57,14 @@ import org.springframework.util.StringUtils;
* <p>To facilitate mapping between columns and fields that don't have matching names, * <p>To facilitate mapping between columns and fields that don't have matching names,
* try using column aliases in the SQL statement like "select fname as first_name from customer". * try using column aliases in the SQL statement like "select fname as first_name from customer".
* *
* <p>For 'null' values read from the databasem, we will attempt to call the setter, but in the case of * <p>For 'null' values read from the database, we will attempt to call the setter, but in the case of
* Java primitives, this causes a TypeMismatchException. This class can be configured (using the * Java primitives, this causes a TypeMismatchException. This class can be configured (using the
* primitivesDefaultedForNullValue property) to trap this exception and use the primitives default value. * primitivesDefaultedForNullValue property) to trap this exception and use the primitives default value.
* Be aware that if you use the values from the generated bean to update the database the primitive value * Be aware that if you use the values from the generated bean to update the database the primitive value
* will have been set to the primitive's default value instead of null. * will have been set to the primitive's default value instead of null.
* *
* <p>Please note that this class is designed to provide convenience rather than high performance. * <p>Please note that this class is designed to provide convenience rather than high performance.
* For best performance consider using a custom RowMapper. * For best performance, consider using a custom {@link RowMapper} implementation.
* *
* @author Thomas Risberg * @author Thomas Risberg
* @author Juergen Hoeller * @author Juergen Hoeller
@ -91,7 +92,7 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
/** /**
* Create a new BeanPropertyRowMapper for bean-style configuration. * Create a new {@code BeanPropertyRowMapper} for bean-style configuration.
* @see #setMappedClass * @see #setMappedClass
* @see #setCheckFullyPopulated * @see #setCheckFullyPopulated
*/ */
@ -99,8 +100,8 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
} }
/** /**
* Create a new BeanPropertyRowMapper, accepting unpopulated properties * Create a new {@code BeanPropertyRowMapper}, accepting unpopulated
* in the target bean. * properties in the target bean.
* <p>Consider using the {@link #newInstance} factory method instead, * <p>Consider using the {@link #newInstance} factory method instead,
* which allows for specifying the mapped type once only. * which allows for specifying the mapped type once only.
* @param mappedClass the class that each row should be mapped to * @param mappedClass the class that each row should be mapped to
@ -110,7 +111,7 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
} }
/** /**
* Create a new BeanPropertyRowMapper. * Create a new {@code BeanPropertyRowMapper}.
* @param mappedClass the class that each row should be mapped to * @param mappedClass the class that each row should be mapped to
* @param checkFullyPopulated whether we're strictly validating that * @param checkFullyPopulated whether we're strictly validating that
* all bean properties have been mapped from corresponding database fields * all bean properties have been mapped from corresponding database fields
@ -136,9 +137,51 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
} }
} }
/**
* Get the class that we are mapping to.
*/
public final Class<T> getMappedClass() {
return this.mappedClass;
}
/**
* Set whether we're strictly validating that all bean properties have been mapped
* from corresponding database fields.
* <p>Default is {@code false}, accepting unpopulated properties in the target bean.
*/
public void setCheckFullyPopulated(boolean checkFullyPopulated) {
this.checkFullyPopulated = checkFullyPopulated;
}
/**
* Return whether we're strictly validating that all bean properties have been
* mapped from corresponding database fields.
*/
public boolean isCheckFullyPopulated() {
return this.checkFullyPopulated;
}
/**
* Set whether we're defaulting Java primitives in the case of mapping a null value
* from corresponding database fields.
* <p>Default is {@code false}, throwing an exception when nulls are mapped to Java primitives.
*/
public void setPrimitivesDefaultedForNullValue(boolean primitivesDefaultedForNullValue) {
this.primitivesDefaultedForNullValue = primitivesDefaultedForNullValue;
}
/**
* Return whether we're defaulting Java primitives in the case of mapping a null value
* from corresponding database fields.
*/
public boolean isPrimitivesDefaultedForNullValue() {
return this.primitivesDefaultedForNullValue;
}
/** /**
* Initialize the mapping metadata for the given class. * Initialize the mapping metadata for the given class.
* @param mappedClass the mapped class. * @param mappedClass the mapped class
*/ */
protected void initialize(Class<T> mappedClass) { protected void initialize(Class<T> mappedClass) {
this.mappedClass = mappedClass; this.mappedClass = mappedClass;
@ -160,7 +203,7 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
/** /**
* Convert a name in camelCase to an underscored name in lower case. * Convert a name in camelCase to an underscored name in lower case.
* Any upper case letters are converted to lower case with a preceding underscore. * Any upper case letters are converted to lower case with a preceding underscore.
* @param name the string containing original name * @param name the original name
* @return the converted name * @return the converted name
*/ */
private String underscoreName(String name) { private String underscoreName(String name) {
@ -182,48 +225,6 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
return result.toString(); return result.toString();
} }
/**
* Get the class that we are mapping to.
*/
public final Class<T> getMappedClass() {
return this.mappedClass;
}
/**
* Set whether we're strictly validating that all bean properties have been
* mapped from corresponding database fields.
* <p>Default is {@code false}, accepting unpopulated properties in the
* target bean.
*/
public void setCheckFullyPopulated(boolean checkFullyPopulated) {
this.checkFullyPopulated = checkFullyPopulated;
}
/**
* Return whether we're strictly validating that all bean properties have been
* mapped from corresponding database fields.
*/
public boolean isCheckFullyPopulated() {
return this.checkFullyPopulated;
}
/**
* Set whether we're defaulting Java primitives in the case of mapping a null value
* from corresponding database fields.
* <p>Default is {@code false}, throwing an exception when nulls are mapped to Java primitives.
*/
public void setPrimitivesDefaultedForNullValue(boolean primitivesDefaultedForNullValue) {
this.primitivesDefaultedForNullValue = primitivesDefaultedForNullValue;
}
/**
* Return whether we're defaulting Java primitives in the case of mapping a null value
* from corresponding database fields.
*/
public boolean isPrimitivesDefaultedForNullValue() {
return primitivesDefaultedForNullValue;
}
/** /**
* Extract the values for all columns in the current row. * Extract the values for all columns in the current row.
@ -242,26 +243,30 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
for (int index = 1; index <= columnCount; index++) { for (int index = 1; index <= columnCount; index++) {
String column = JdbcUtils.lookupColumnName(rsmd, index); String column = JdbcUtils.lookupColumnName(rsmd, index);
PropertyDescriptor pd = this.mappedFields.get(column.replaceAll(" ", "").toLowerCase()); String field = column.replaceAll(" ", "").toLowerCase();
PropertyDescriptor pd = this.mappedFields.get(field);
if (pd != null) { if (pd != null) {
try { try {
Object value = getColumnValue(rs, index, pd); Object value = getColumnValue(rs, index, pd);
if (logger.isDebugEnabled() && rowNumber == 0) { if (rowNumber == 0 && logger.isDebugEnabled()) {
logger.debug("Mapping column '" + column + "' to property '" + logger.debug("Mapping column '" + column + "' to property '" + pd.getName() +
pd.getName() + "' of type " + pd.getPropertyType()); "' of type [" + ClassUtils.getQualifiedName(pd.getPropertyType()) + "]");
} }
try { try {
bw.setPropertyValue(pd.getName(), value); bw.setPropertyValue(pd.getName(), value);
} }
catch (TypeMismatchException e) { catch (TypeMismatchException ex) {
if (value == null && primitivesDefaultedForNullValue) { if (value == null && this.primitivesDefaultedForNullValue) {
logger.debug("Intercepted TypeMismatchException for row " + rowNumber + if (logger.isDebugEnabled()) {
" and column '" + column + "' with value " + value + logger.debug("Intercepted TypeMismatchException for row " + rowNumber +
" when setting property '" + pd.getName() + "' of type " + pd.getPropertyType() + " and column '" + column + "' with null value when setting property '" +
" on object: " + mappedObject); pd.getName() + "' of type [" +
ClassUtils.getQualifiedName(pd.getPropertyType()) +
"] on object: " + mappedObject, ex);
}
} }
else { else {
throw e; throw ex;
} }
} }
if (populatedProperties != null) { if (populatedProperties != null) {
@ -270,14 +275,21 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
} }
catch (NotWritablePropertyException ex) { catch (NotWritablePropertyException ex) {
throw new DataRetrievalFailureException( throw new DataRetrievalFailureException(
"Unable to map column " + column + " to property " + pd.getName(), ex); "Unable to map column '" + column + "' to property '" + pd.getName() + "'", ex);
}
}
else {
// No PropertyDescriptor found
if (rowNumber == 0 && logger.isDebugEnabled()) {
logger.debug("No property found for column '" + column + "' mapped to field '" + field + "'");
} }
} }
} }
if (populatedProperties != null && !populatedProperties.equals(this.mappedProperties)) { if (populatedProperties != null && !populatedProperties.equals(this.mappedProperties)) {
throw new InvalidDataAccessApiUsageException("Given ResultSet does not contain all fields " + throw new InvalidDataAccessApiUsageException("Given ResultSet does not contain all fields " +
"necessary to populate object of class [" + this.mappedClass + "]: " + this.mappedProperties); "necessary to populate object of class [" + this.mappedClass.getName() + "]: " +
this.mappedProperties);
} }
return mappedObject; return mappedObject;
@ -312,7 +324,7 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
/** /**
* Static factory method to create a new BeanPropertyRowMapper * Static factory method to create a new {@code BeanPropertyRowMapper}
* (with the mapped class specified only once). * (with the mapped class specified only once).
* @param mappedClass the class that each row should be mapped to * @param mappedClass the class that each row should be mapped to
*/ */

20
spring-web/src/main/java/org/springframework/http/HttpStatus.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2013 the original author or authors. * Copyright 2002-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,11 +17,12 @@
package org.springframework.http; package org.springframework.http;
/** /**
* Java 5 enumeration of HTTP status codes. * Enumeration of HTTP status codes.
* *
* <p>The HTTP status code series can be retrieved via {@link #series()}. * <p>The HTTP status code series can be retrieved via {@link #series()}.
* *
* @author Arjen Poutsma * @author Arjen Poutsma
* @since 3.0
* @see HttpStatus.Series * @see HttpStatus.Series
* @see <a href="http://www.iana.org/assignments/http-status-codes">HTTP Status Code Registry</a> * @see <a href="http://www.iana.org/assignments/http-status-codes">HTTP Status Code Registry</a>
* @see <a href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes">List of HTTP status codes - Wikipedia</a> * @see <a href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes">List of HTTP status codes - Wikipedia</a>
@ -364,17 +365,17 @@ public enum HttpStatus {
NETWORK_AUTHENTICATION_REQUIRED(511, "Network Authentication Required"); NETWORK_AUTHENTICATION_REQUIRED(511, "Network Authentication Required");
private final int value; private final int value;
private final String reasonPhrase; private final String reasonPhrase;
private HttpStatus(int value, String reasonPhrase) { HttpStatus(int value, String reasonPhrase) {
this.value = value; this.value = value;
this.reasonPhrase = reasonPhrase; this.reasonPhrase = reasonPhrase;
} }
/** /**
* Return the integer value of this status code. * Return the integer value of this status code.
*/ */
@ -386,7 +387,7 @@ public enum HttpStatus {
* Return the reason phrase of this status code. * Return the reason phrase of this status code.
*/ */
public String getReasonPhrase() { public String getReasonPhrase() {
return reasonPhrase; return this.reasonPhrase;
} }
/** /**
@ -402,7 +403,7 @@ public enum HttpStatus {
*/ */
@Override @Override
public String toString() { public String toString() {
return Integer.toString(value); return Integer.toString(this.value);
} }
@ -423,10 +424,10 @@ public enum HttpStatus {
/** /**
* Java 5 enumeration of HTTP status series. * Enumeration of HTTP status series.
* <p>Retrievable via {@link HttpStatus#series()}. * <p>Retrievable via {@link HttpStatus#series()}.
*/ */
public static enum Series { public enum Series {
INFORMATIONAL(1), INFORMATIONAL(1),
SUCCESSFUL(2), SUCCESSFUL(2),
@ -436,7 +437,7 @@ public enum HttpStatus {
private final int value; private final int value;
private Series(int value) { Series(int value) {
this.value = value; this.value = value;
} }
@ -460,7 +461,6 @@ public enum HttpStatus {
public static Series valueOf(HttpStatus status) { public static Series valueOf(HttpStatus status) {
return valueOf(status.value); return valueOf(status.value);
} }
} }
} }

10
spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -243,7 +243,7 @@ public class UrlPathHelper {
if (c1 == c2) { if (c1 == c2) {
continue; continue;
} }
if (ignoreCase && (Character.toLowerCase(c1) == Character.toLowerCase(c2))) { else if (ignoreCase && (Character.toLowerCase(c1) == Character.toLowerCase(c2))) {
continue; continue;
} }
return null; return null;
@ -251,7 +251,7 @@ public class UrlPathHelper {
if (index2 != mapping.length()) { if (index2 != mapping.length()) {
return null; return null;
} }
if (index1 == requestUri.length()) { else if (index1 == requestUri.length()) {
return ""; return "";
} }
else if (requestUri.charAt(index1) == ';') { else if (requestUri.charAt(index1) == ';') {
@ -452,8 +452,8 @@ public class UrlPathHelper {
* @return the updated URI string * @return the updated URI string
*/ */
public String removeSemicolonContent(String requestUri) { public String removeSemicolonContent(String requestUri) {
return this.removeSemicolonContent ? return (this.removeSemicolonContent ?
removeSemicolonContentInternal(requestUri) : removeJsessionid(requestUri); removeSemicolonContentInternal(requestUri) : removeJsessionid(requestUri));
} }
private String removeSemicolonContentInternal(String requestUri) { private String removeSemicolonContentInternal(String requestUri) {

10
spring-web/src/test/resources/org/springframework/web/util/HtmlCharacterEntityReferences.dtd

@ -1,11 +1,9 @@
<!-- File containing all charcter entity references definied <!-- File containing all character entity references defined
by the HTML 4.0 standard. --> by the HTML 4.0 standard. -->
<!-- Valuable informations and a complete description of the <!-- Valuable information and a complete description of the
HTML 4.0 character set can be found at HTML 4.0 character set can be found at
http://www.w3.org/TR/html4/charset.html. http://www.w3.org/TR/html4/charset.html. -->
-->
<!-- Portions © International Organization for Standardization 1986 <!-- Portions © International Organization for Standardization 1986
Permission to copy in any form is granted for use with Permission to copy in any form is granted for use with
conforming SGML systems and applications as defined in conforming SGML systems and applications as defined in

20
spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/ServletWrappingController.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -78,13 +78,11 @@ import org.springframework.web.servlet.ModelAndView;
* @author Juergen Hoeller * @author Juergen Hoeller
* @since 1.1.1 * @since 1.1.1
* @see ServletForwardingController * @see ServletForwardingController
* @see org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor
* @see org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
*/ */
public class ServletWrappingController extends AbstractController public class ServletWrappingController extends AbstractController
implements BeanNameAware, InitializingBean, DisposableBean { implements BeanNameAware, InitializingBean, DisposableBean {
private Class<?> servletClass; private Class<? extends Servlet> servletClass;
private String servletName; private String servletName;
@ -100,7 +98,7 @@ public class ServletWrappingController extends AbstractController
* Needs to implement {@code javax.servlet.Servlet}. * Needs to implement {@code javax.servlet.Servlet}.
* @see javax.servlet.Servlet * @see javax.servlet.Servlet
*/ */
public void setServletClass(Class<?> servletClass) { public void setServletClass(Class<? extends Servlet> servletClass) {
this.servletClass = servletClass; this.servletClass = servletClass;
} }
@ -131,27 +129,23 @@ public class ServletWrappingController extends AbstractController
*/ */
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
if (this.servletClass == null) { if (this.servletClass == null) {
throw new IllegalArgumentException("servletClass is required"); throw new IllegalArgumentException("'servletClass' is required");
}
if (!Servlet.class.isAssignableFrom(this.servletClass)) {
throw new IllegalArgumentException("servletClass [" + this.servletClass.getName() +
"] needs to implement interface [javax.servlet.Servlet]");
} }
if (this.servletName == null) { if (this.servletName == null) {
this.servletName = this.beanName; this.servletName = this.beanName;
} }
this.servletInstance = (Servlet) this.servletClass.newInstance(); this.servletInstance = this.servletClass.newInstance();
this.servletInstance.init(new DelegatingServletConfig()); this.servletInstance.init(new DelegatingServletConfig());
} }
/** /**
* Invoke the the wrapped Servlet instance. * Invoke the wrapped Servlet instance.
* @see javax.servlet.Servlet#service(javax.servlet.ServletRequest, javax.servlet.ServletResponse) * @see javax.servlet.Servlet#service(javax.servlet.ServletRequest, javax.servlet.ServletResponse)
*/ */
@Override @Override
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
throws Exception { throws Exception {
this.servletInstance.service(request, response); this.servletInstance.service(request, response);
return null; return null;

Loading…
Cancel
Save