From cc70fdcbebfeeb4eaa14979b59eee8cddf9336b8 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 27 Sep 2017 15:20:17 +0200 Subject: [PATCH] Backport further refinements from the nullability efforts Issue: SPR-15656 --- .../AbstractNestablePropertyAccessor.java | 10 +- .../factory/CannotLoadBeanClassException.java | 11 +- .../factory/config/DependencyDescriptor.java | 8 +- .../support/StaticListableBeanFactory.java | 28 ++- .../xml/AbstractBeanDefinitionParser.java | 4 +- .../xml/BeanDefinitionParserDelegate.java | 3 +- .../context/annotation/ConditionContext.java | 22 +- .../org/springframework/jmx/IJmxTestBean.java | 16 +- .../org/springframework/util/ClassUtils.java | 4 +- .../util/ConcurrentReferenceHashMap.java | 21 +- .../org/springframework/util/StringUtils.java | 37 ++- .../jdbc/core/BatchUpdateUtils.java | 13 +- .../jdbc/core/JdbcTemplate.java | 9 +- .../jdbc/core/StatementCreatorUtils.java | 4 +- .../core/metadata/CallMetaDataContext.java | 18 +- .../core/metadata/CallMetaDataProvider.java | 7 +- .../metadata/DerbyTableMetaDataProvider.java | 22 +- .../metadata/OracleCallMetaDataProvider.java | 8 +- .../PostgresCallMetaDataProvider.java | 10 +- .../namedparam/SqlParameterSourceUtils.java | 5 +- .../DataSourceTransactionManager.java | 4 +- .../jdbc/datasource/DataSourceUtils.java | 8 +- .../init/DataSourceInitializer.java | 11 +- .../init/DatabasePopulatorUtils.java | 6 +- .../jdbc/object/RdbmsOperation.java | 28 +-- ...bstractFallbackSQLExceptionTranslator.java | 20 +- .../jdbc/support/JdbcUtils.java | 4 +- .../jdbc/support/SQLErrorCodesFactory.java | 6 +- .../jdbc/support/lob/TemporaryLobCreator.java | 91 ++++--- .../AbstractListenerContainerParser.java | 7 +- .../jms/connection/JmsResourceHolder.java | 7 +- .../jms/connection/JmsTransactionManager.java | 6 +- .../AbstractMessageListenerContainer.java | 10 +- .../AbstractAdaptableMessageListener.java | 10 +- .../StandardJmsActivationSpecFactory.java | 4 +- .../simp/stomp/StompClientSupportTests.java | 16 +- ...jectOptimisticLockingFailureException.java | 4 +- .../orm/ObjectRetrievalFailureException.java | 4 +- .../oxm/jaxb/Jaxb2Marshaller.java | 4 +- .../CciLocalTransactionManager.java | 12 +- ...onnectionSpecConnectionFactoryAdapter.java | 16 +- .../interceptor/TransactionAspectSupport.java | 4 +- .../TransactionAttributeSourcePointcut.java | 4 +- .../transaction/TransactionSupportTests.java | 6 +- .../org/springframework/http/HttpHeaders.java | 14 +- .../springframework/web/util/WebUtils.java | 17 +- .../BeanTypeNotPresentCondition.java | 67 ----- .../web/servlet/tags/UrlTag.java | 2 +- .../web/servlet/tags/UrlTagTests.java | 234 ++++++------------ .../foo/ComponentBeanDefinitionParser.java | 28 +-- 50 files changed, 382 insertions(+), 532 deletions(-) delete mode 100644 spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/BeanTypeNotPresentCondition.java diff --git a/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java b/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java index 8d6cf7e97ab2..6496e3d6f3ec 100644 --- a/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -55,10 +55,10 @@ * as String arrays are converted in such a format if the array itself is not * assignable. * - * @author Rod Johnson * @author Juergen Hoeller - * @author Rob Harrop * @author Stephane Nicoll + * @author Rod Johnson + * @author Rob Harrop * @since 4.2 * @see #registerCustomEditor * @see #setPropertyValues @@ -96,9 +96,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA Object rootObject; - /** - * Map with cached nested Accessors: nested path -> Accessor instance. - */ + /** Map with cached nested Accessors: nested path -> Accessor instance */ private Map nestedPropertyAccessors; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/CannotLoadBeanClassException.java b/spring-beans/src/main/java/org/springframework/beans/factory/CannotLoadBeanClassException.java index 772da666e2d7..26de990a68e6 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/CannotLoadBeanClassException.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/CannotLoadBeanClassException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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,8 +46,8 @@ public class CannotLoadBeanClassException extends FatalBeanException { public CannotLoadBeanClassException( String resourceDescription, String beanName, String beanClassName, ClassNotFoundException cause) { - super("Cannot find class [" + beanClassName + "] for bean with name '" + beanName + - "' defined in " + resourceDescription, cause); + super("Cannot find class [" + String.valueOf(beanClassName) + "] for bean with name '" + beanName + "'" + + (resourceDescription != null ? " defined in " + resourceDescription : ""), cause); this.resourceDescription = resourceDescription; this.beanName = beanName; this.beanClassName = beanClassName; @@ -64,8 +64,9 @@ public CannotLoadBeanClassException( public CannotLoadBeanClassException( String resourceDescription, String beanName, String beanClassName, LinkageError cause) { - super("Error loading class [" + beanClassName + "] for bean with name '" + beanName + - "' defined in " + resourceDescription + ": problem with class file or dependent class", cause); + super("Error loading class [" + String.valueOf(beanClassName) + "] for bean with name '" + beanName + "'" + + (resourceDescription != null ? " defined in " + resourceDescription : "") + + ": problem with class file or dependent class", cause); this.resourceDescription = resourceDescription; this.beanName = beanName; this.beanClassName = beanClassName; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java index 36db05b19e66..03097d126b8d 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java @@ -240,12 +240,14 @@ public void setContainingClass(Class containingClass) { * @since 4.0 */ public ResolvableType getResolvableType() { - if (this.resolvableType == null) { - this.resolvableType = (this.field != null ? + ResolvableType resolvableType = this.resolvableType; + if (resolvableType == null) { + resolvableType = (this.field != null ? ResolvableType.forField(this.field, this.nestingLevel, this.containingClass) : ResolvableType.forMethodParameter(this.methodParameter)); + this.resolvableType = resolvableType; } - return this.resolvableType; + return resolvableType; } /** diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java index d1aa847fe0c9..12eaf2d54fc7 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,6 +35,7 @@ import org.springframework.core.ResolvableType; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.util.Assert; +import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; /** @@ -134,12 +135,21 @@ public Object getBean(String name) throws BeansException { @SuppressWarnings("unchecked") public T getBean(String name, Class requiredType) throws BeansException { Object bean = getBean(name); - if (requiredType != null && !requiredType.isAssignableFrom(bean.getClass())) { + if (requiredType != null && !requiredType.isInstance(bean)) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return (T) bean; } + @Override + public Object getBean(String name, Object... args) throws BeansException { + if (!ObjectUtils.isEmpty(args)) { + throw new UnsupportedOperationException( + "StaticListableBeanFactory does not support explicit bean creation arguments"); + } + return getBean(name); + } + @Override public T getBean(Class requiredType) throws BeansException { String[] beanNames = getBeanNamesForType(requiredType); @@ -154,18 +164,9 @@ else if (beanNames.length > 1) { } } - @Override - public Object getBean(String name, Object... args) throws BeansException { - if (args != null) { - throw new UnsupportedOperationException( - "StaticListableBeanFactory does not support explicit bean creation arguments"); - } - return getBean(name); - } - @Override public T getBean(Class requiredType, Object... args) throws BeansException { - if (args != null) { + if (!ObjectUtils.isEmpty(args)) { throw new UnsupportedOperationException( "StaticListableBeanFactory does not support explicit bean creation arguments"); } @@ -352,7 +353,8 @@ public Map getBeansWithAnnotation(Class an public A findAnnotationOnBean(String beanName, Class annotationType) throws NoSuchBeanDefinitionException{ - return AnnotationUtils.findAnnotation(getType(beanName), annotationType); + Class beanType = getType(beanName); + return (beanType != null ? AnnotationUtils.findAnnotation(beanType, annotationType) : null); } } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/AbstractBeanDefinitionParser.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/AbstractBeanDefinitionParser.java index ad6c6e2f2edd..fc2b3280cc96 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/AbstractBeanDefinitionParser.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/AbstractBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -140,7 +140,7 @@ protected void registerBeanDefinition(BeanDefinitionHolder definition, BeanDefin /** * Central template method to actually parse the supplied {@link Element} * into one or more {@link BeanDefinition BeanDefinitions}. - * @param element the element that is to be parsed into one or more {@link BeanDefinition BeanDefinitions} + * @param element the element that is to be parsed into one or more {@link BeanDefinition BeanDefinitions} * @param parserContext the object encapsulating the current state of the parsing process; * provides access to a {@link org.springframework.beans.factory.support.BeanDefinitionRegistry} * @return the primary {@link BeanDefinition} resulting from the parsing of the supplied {@link Element} diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java index aec5bc5ddb07..89b1726d32ad 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java @@ -389,8 +389,7 @@ else if (parentDefaults != null) { } /** - * Return the defaults definition object, or {@code null} if the - * defaults have been initialized yet. + * Return the defaults definition object. */ public DocumentDefaultsDefinition getDefaults() { return this.defaults; diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConditionContext.java b/spring-context/src/main/java/org/springframework/context/annotation/ConditionContext.java index 8be2dad82967..8c11ac72e627 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConditionContext.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConditionContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2017 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,43 +25,39 @@ * Context information for use by {@link Condition}s. * * @author Phillip Webb + * @author Juergen Hoeller * @since 4.0 */ public interface ConditionContext { /** * Return the {@link BeanDefinitionRegistry} that will hold the bean definition - * should the condition match or {@code null} if the registry is not available. - * @return the registry or {@code null} + * should the condition match, or {@code null} if the registry is not available. */ BeanDefinitionRegistry getRegistry(); /** * Return the {@link ConfigurableListableBeanFactory} that will hold the bean - * definition should the condition match or {@code null} if the bean factory + * definition should the condition match, or {@code null} if the bean factory * is not available. - * @return the bean factory or {@code null} */ ConfigurableListableBeanFactory getBeanFactory(); /** - * Return the {@link Environment} for which the current application is running + * Return the {@link Environment} for which the current application is running, * or {@code null} if no environment is available. - * @return the environment or {@code null} */ Environment getEnvironment(); /** - * Return the {@link ResourceLoader} currently being used or {@code null} - * if the resource loader cannot be obtained. - * @return a resource loader or {@code null} + * Return the {@link ResourceLoader} currently being used, or {@code null} if + * the resource loader cannot be obtained. */ ResourceLoader getResourceLoader(); /** - * Return the {@link ClassLoader} that should be used to load additional - * classes or {@code null} if the default classloader should be used. - * @return the class loader or {@code null} + * Return the {@link ClassLoader} that should be used to load additional classes, + * or {@code null} if the default classloader should be used. */ ClassLoader getClassLoader(); diff --git a/spring-context/src/test/java/org/springframework/jmx/IJmxTestBean.java b/spring-context/src/test/java/org/springframework/jmx/IJmxTestBean.java index ca6a1cd7966f..185d5fcd7a7a 100644 --- a/spring-context/src/test/java/org/springframework/jmx/IJmxTestBean.java +++ b/spring-context/src/test/java/org/springframework/jmx/IJmxTestBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,19 +22,19 @@ */ public interface IJmxTestBean { - public int add(int x, int y); + int add(int x, int y); - public long myOperation(); + long myOperation(); - public int getAge(); + int getAge(); - public void setAge(int age); + void setAge(int age); - public void setName(String name) throws Exception; + void setName(String name) throws Exception; - public String getName(); + String getName(); // used to test invalid methods that exist in the proxy interface - public void dontExposeMe(); + void dontExposeMe(); } diff --git a/spring-core/src/main/java/org/springframework/util/ClassUtils.java b/spring-core/src/main/java/org/springframework/util/ClassUtils.java index 5e98f9b723cc..5a99de2ea30f 100644 --- a/spring-core/src/main/java/org/springframework/util/ClassUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ClassUtils.java @@ -1030,7 +1030,7 @@ public static String classPackageAsResourcePath(Class clazz) { * in the given array. *

Basically like {@code AbstractCollection.toString()}, but stripping * the "class "/"interface " prefix before every class name. - * @param classes a Collection of Class objects (may be {@code null}) + * @param classes an array of Class objects * @return a String of form "[com.foo.Bar, com.foo.Baz]" * @see java.util.AbstractCollection#toString() */ @@ -1231,6 +1231,7 @@ public static boolean isVisible(Class clazz, ClassLoader classLoader) { /** * Check whether the given object is a CGLIB proxy. * @param object the object to check + * @see #isCglibProxyClass(Class) * @see org.springframework.aop.support.AopUtils#isCglibProxy(Object) */ public static boolean isCglibProxy(Object object) { @@ -1240,6 +1241,7 @@ public static boolean isCglibProxy(Object object) { /** * Check whether the specified class is a CGLIB-generated class. * @param clazz the class to check + * @see #isCglibProxyClassName(String) */ public static boolean isCglibProxyClass(Class clazz) { return (clazz != null && isCglibProxyClassName(clazz.getName())); diff --git a/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java b/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java index ff2c36717a01..17127f2eeb58 100644 --- a/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java +++ b/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java @@ -419,9 +419,8 @@ protected final class Segment extends ReentrantLock { private final int initialSize; /** - * Array of references indexed using the low order bits from the hash. This - * property should only be set via {@link #setReferences} to ensure that the - * {@code resizeThreshold} is maintained. + * Array of references indexed using the low order bits from the hash. + * This property should only be set along with {@code resizeThreshold}. */ private volatile Reference[] references; @@ -617,14 +616,14 @@ private void setReferences(Reference[] references) { } /** - * @return the size of the current references array + * Return the size of the current references array. */ public final int getSize() { return this.references.length; } /** - * @return the total number of references in this segment + * Return the total number of references in this segment. */ public final int getCount() { return this.count; @@ -639,21 +638,17 @@ public final int getCount() { protected interface Reference { /** - * Returns the referenced entry or {@code null} if the entry is no longer - * available. - * @return the entry or {@code null} + * Return the referenced entry, or {@code null} if the entry is no longer available. */ Entry get(); /** - * Returns the hash for the reference. - * @return the hash + * Return the hash for the reference. */ int getHash(); /** - * Returns the next reference in the chain or {@code null} - * @return the next reference of {@code null} + * Return the next reference in the chain, or {@code null} if none. */ Reference getNext(); @@ -930,7 +925,7 @@ protected class ReferenceManager { * Factory method used to create a new {@link Reference}. * @param entry the entry contained in the reference * @param hash the hash - * @param next the next reference in the chain or {@code null} + * @param next the next reference in the chain, or {@code null} if none * @return a new {@link Reference} */ public Reference createReference(Entry entry, int hash, Reference next) { diff --git a/spring-core/src/main/java/org/springframework/util/StringUtils.java b/spring-core/src/main/java/org/springframework/util/StringUtils.java index 1367d9ef4d10..be81cd84b3de 100644 --- a/spring-core/src/main/java/org/springframework/util/StringUtils.java +++ b/spring-core/src/main/java/org/springframework/util/StringUtils.java @@ -114,7 +114,7 @@ public static boolean hasLength(CharSequence str) { * @see #hasText(String) */ public static boolean hasLength(String str) { - return hasLength((CharSequence) str); + return (str != null && !str.isEmpty()); } /** @@ -159,7 +159,7 @@ public static boolean hasText(CharSequence str) { * @see #hasText(CharSequence) */ public static boolean hasText(String str) { - return hasText((CharSequence) str); + return (str != null && !str.isEmpty() && hasText((CharSequence) str)); } /** @@ -376,8 +376,8 @@ public static boolean substringMatch(CharSequence str, int index, CharSequence s /** * Count the occurrences of the substring {@code sub} in string {@code str}. - * @param str string to search in. Return 0 if this is {@code null}. - * @param sub string to search for. Return 0 if this is {@code null}. + * @param str string to search in + * @param sub string to search for */ public static int countOccurrencesOf(String str, String sub) { if (!hasLength(str) || !hasLength(sub)) { @@ -395,8 +395,7 @@ public static int countOccurrencesOf(String str, String sub) { } /** - * Replace all occurrences of a substring within a string with - * another string. + * Replace all occurrences of a substring within a string with another string. * @param inString {@code String} to examine * @param oldPattern {@code String} to replace * @param newPattern {@code String} to insert @@ -513,9 +512,8 @@ public static String unqualify(String qualifiedName, char separator) { * Capitalize a {@code String}, changing the first letter to * upper case as per {@link Character#toUpperCase(char)}. * No other letters are changed. - * @param str the {@code String} to capitalize, may be {@code null} - * @return the capitalized {@code String}, or {@code null} if the supplied - * string is {@code null} + * @param str the {@code String} to capitalize + * @return the capitalized {@code String} */ public static String capitalize(String str) { return changeFirstCharacterCase(str, true); @@ -525,9 +523,8 @@ public static String capitalize(String str) { * Uncapitalize a {@code String}, changing the first letter to * lower case as per {@link Character#toLowerCase(char)}. * No other letters are changed. - * @param str the {@code String} to uncapitalize, may be {@code null} - * @return the uncapitalized {@code String}, or {@code null} if the supplied - * string is {@code null} + * @param str the {@code String} to uncapitalize + * @return the uncapitalized {@code String} */ public static String uncapitalize(String str) { return changeFirstCharacterCase(str, false); @@ -597,9 +594,8 @@ public static String getFilenameExtension(String path) { /** * Strip the filename extension from the given Java resource path, * e.g. "mypath/myfile.txt" -> "mypath/myfile". - * @param path the file path (may be {@code null}) - * @return the path with stripped filename extension, - * or {@code null} if none + * @param path the file path + * @return the path with stripped filename extension */ public static String stripFilenameExtension(String path) { if (path == null) { @@ -724,7 +720,7 @@ public static boolean pathEquals(String path1, String path2) { * @param localeString the locale {@code String}, following {@code Locale's} * {@code toString()} format ("en", "en_UK", etc); * also accepts spaces as separators, as an alternative to underscores - * @return a corresponding {@code Locale} instance + * @return a corresponding {@code Locale} instance, or {@code null} if none * @throws IllegalArgumentException in case of an invalid locale specification */ public static Locale parseLocaleString(String localeString) { @@ -877,8 +873,7 @@ public static String[] sortStringArray(String[] array) { * Copy the given {@code Collection} into a {@code String} array. *

The {@code Collection} must contain {@code String} elements only. * @param collection the {@code Collection} to copy - * @return the {@code String} array ({@code null} if the supplied - * {@code Collection} was {@code null}) + * @return the {@code String} array */ public static String[] toStringArray(Collection collection) { if (collection == null) { @@ -892,8 +887,7 @@ public static String[] toStringArray(Collection collection) { * Copy the given Enumeration into a {@code String} array. * The Enumeration must contain {@code String} elements only. * @param enumeration the Enumeration to copy - * @return the {@code String} array ({@code null} if the passed-in - * Enumeration was {@code null}) + * @return the {@code String} array */ public static String[] toStringArray(Enumeration enumeration) { if (enumeration == null) { @@ -1048,8 +1042,7 @@ public static String[] tokenizeToStringArray(String str, String delimiters) { * @param ignoreEmptyTokens omit empty tokens from the result array * (only applies to tokens that are empty after trimming; StringTokenizer * will not consider subsequent delimiters as token in the first place). - * @return an array of the tokens ({@code null} if the input {@code String} - * was {@code null}) + * @return an array of the tokens * @see java.util.StringTokenizer * @see String#trim() * @see #delimitedListToStringArray diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/BatchUpdateUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/BatchUpdateUtils.java index eec11f6f4d56..c0dfbc1ba4b0 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/BatchUpdateUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/BatchUpdateUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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,20 +25,21 @@ * within the framework. * * @author Thomas Risberg + * @since 3.0 */ public abstract class BatchUpdateUtils { - public static int[] executeBatchUpdate(String sql, final List batchValues, final int[] columnTypes, JdbcOperations jdbcOperations) { + public static int[] executeBatchUpdate( + String sql, final List batchValues, final int[] columnTypes, JdbcOperations jdbcOperations) { + return jdbcOperations.batchUpdate( sql, new BatchPreparedStatementSetter() { - @Override public void setValues(PreparedStatement ps, int i) throws SQLException { Object[] values = batchValues.get(i); setStatementParameters(values, ps, columnTypes); } - @Override public int getBatchSize() { return batchValues.size(); @@ -46,7 +47,9 @@ public int getBatchSize() { }); } - protected static void setStatementParameters(Object[] values, PreparedStatement ps, int[] columnTypes) throws SQLException { + protected static void setStatementParameters(Object[] values, PreparedStatement ps, int[] columnTypes) + throws SQLException { + int colIndex = 0; for (Object value : values) { colIndex++; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java index f8dc3b355d90..79e8b9b0c22e 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -1267,11 +1267,14 @@ protected Map extractOutputParameters(CallableStatement cs, List * @param param the corresponding stored procedure parameter * @return Map that contains returned results */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected Map processResultSet(ResultSet rs, ResultSetSupportingSqlParameter param) throws SQLException { + @SuppressWarnings({"unchecked", "rawtypes"}) + protected Map processResultSet(ResultSet rs, ResultSetSupportingSqlParameter param) + throws SQLException { + if (rs == null) { return Collections.emptyMap(); } + Map returnedResults = new HashMap(); try { ResultSet rsToUse = rs; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/StatementCreatorUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/StatementCreatorUtils.java index 71a6c433fbe3..a1092a5f6a4f 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/StatementCreatorUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/StatementCreatorUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -119,7 +119,7 @@ public abstract class StatementCreatorUtils { /** * Derive a default SQL type from the given Java type. * @param javaType the Java type to translate - * @return the corresponding SQL type, or {@code null} if none found + * @return the corresponding SQL type, or {@link SqlTypeValue#TYPE_UNKNOWN} if none found */ public static int javaTypeToSqlParameterType(Class javaType) { Integer sqlType = javaTypeToSqlTypeMap.get(javaType); diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java index effb5b8bbe39..a30c9186a0c0 100755 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -234,6 +234,14 @@ public boolean isNamedBinding() { } + /** + * Initialize this class with metadata from the database. + * @param dataSource the DataSource used to retrieve metadata + */ + public void initializeMetaData(DataSource dataSource) { + this.metaDataProvider = CallMetaDataProviderFactory.createMetaDataProvider(dataSource, this); + } + /** * Create a ReturnResultSetParameter/SqlOutParameter depending on the support provided * by the JDBC driver used for the database in use. @@ -278,14 +286,6 @@ public List getCallParameters() { return this.callParameters; } - /** - * Initialize this class with metadata from the database. - * @param dataSource the DataSource used to retrieve metadata - */ - public void initializeMetaData(DataSource dataSource) { - this.metaDataProvider = CallMetaDataProviderFactory.createMetaDataProvider(dataSource, this); - } - /** * Process the list of parameters provided, and if procedure column metadata is used, * the parameters will be matched against the metadata information and any missing diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataProvider.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataProvider.java index 2991c6d55cd5..a888190dc60a 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataProvider.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2017 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. @@ -51,9 +51,8 @@ public interface CallMetaDataProvider { * @throws SQLException in case of initialization failure * @see org.springframework.jdbc.core.simple.SimpleJdbcCall#withoutProcedureColumnMetaDataAccess() */ - void initializeWithProcedureColumnMetaData( - DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String procedureName) - throws SQLException; + void initializeWithProcedureColumnMetaData(DatabaseMetaData databaseMetaData, String catalogName, + String schemaName, String procedureName) throws SQLException; /** * Provide any modification of the procedure name passed in to match the meta data currently used. diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/DerbyTableMetaDataProvider.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/DerbyTableMetaDataProvider.java index afabd9bcf984..53702005522c 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/DerbyTableMetaDataProvider.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/DerbyTableMetaDataProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,8 +21,8 @@ /** * The Derby specific implementation of the {@link org.springframework.jdbc.core.metadata.TableMetaDataProvider}. - * Overrides the Derby metadata info regarding retreiving generated keys. It seems to work OK so not sure why they - * claim it's not supported. + * Overrides the Derby metadata info regarding retrieving generated keys. It seems to work OK so not sure why + * they claim it's not supported. * * @author Thomas Risberg * @since 3.0 @@ -31,26 +31,26 @@ public class DerbyTableMetaDataProvider extends GenericTableMetaDataProvider { private boolean supportsGeneratedKeysOverride = false; + public DerbyTableMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException { super(databaseMetaData); } + @Override public void initializeWithMetaData(DatabaseMetaData databaseMetaData) throws SQLException { super.initializeWithMetaData(databaseMetaData); if (!databaseMetaData.supportsGetGeneratedKeys()) { - logger.warn("Overriding supportsGetGeneratedKeys from DatabaseMetaData to 'true'; it was reported as " + - "'false' by " + databaseMetaData.getDriverName() + " " + databaseMetaData.getDriverVersion()); - supportsGeneratedKeysOverride = true; + if (logger.isWarnEnabled()) { + logger.warn("Overriding supportsGetGeneratedKeys from DatabaseMetaData to 'true'; it was reported as " + + "'false' by " + databaseMetaData.getDriverName() + " " + databaseMetaData.getDriverVersion()); + } + this.supportsGeneratedKeysOverride = true; } } @Override public boolean isGetGeneratedKeysSupported() { - boolean derbysAnswer = super.isGetGeneratedKeysSupported(); - if (!derbysAnswer) { - return supportsGeneratedKeysOverride; - } - return derbysAnswer; + return (super.isGetGeneratedKeysSupported() || this.supportsGeneratedKeysOverride); } } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/OracleCallMetaDataProvider.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/OracleCallMetaDataProvider.java index 119ed0eb1ed9..d0d0744f8e0e 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/OracleCallMetaDataProvider.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/OracleCallMetaDataProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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,7 @@ import org.springframework.jdbc.core.SqlParameter; /** - * Oracle specific implementation for the {@link CallMetaDataProvider} interface. + * Oracle-specific implementation for the {@link CallMetaDataProvider} interface. * This class is intended for internal use by the Simple JDBC classes. * * @author Thomas Risberg @@ -59,13 +59,13 @@ public int getRefCursorSqlType() { @Override public String metaDataCatalogNameToUse(String catalogName) { // Oracle uses catalog name for package name or an empty string if no package - return catalogName == null ? "" : catalogNameToUse(catalogName); + return (catalogName == null ? "" : catalogNameToUse(catalogName)); } @Override public String metaDataSchemaNameToUse(String schemaName) { // Use current user schema if no schema specified - return schemaName == null ? getUserName() : super.metaDataSchemaNameToUse(schemaName); + return (schemaName == null ? getUserName() : super.metaDataSchemaNameToUse(schemaName)); } @Override diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/PostgresCallMetaDataProvider.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/PostgresCallMetaDataProvider.java index 33c25c20e691..81aa6e680249 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/PostgresCallMetaDataProvider.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/PostgresCallMetaDataProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2017 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,7 @@ import org.springframework.jdbc.core.SqlParameter; /** - * Oracle specific implementation for the {@link org.springframework.jdbc.core.metadata.CallMetaDataProvider} interface. + * Postgres-specific implementation for the {@link CallMetaDataProvider} interface. * This class is intended for internal use by the Simple JDBC classes. * * @author Thomas Risberg @@ -59,7 +59,7 @@ public int getRefCursorSqlType() { @Override public String metaDataSchemaNameToUse(String schemaName) { // Use public schema if no schema specified - return schemaName == null ? "public" : super.metaDataSchemaNameToUse(schemaName); + return (schemaName == null ? "public" : super.metaDataSchemaNameToUse(schemaName)); } @Override @@ -74,7 +74,7 @@ public SqlParameter createDefaultOutParameter(String parameterName, CallParamete @Override public boolean byPassReturnParameter(String parameterName) { - return (RETURN_VALUE_NAME.equals(parameterName) || - super.byPassReturnParameter(parameterName)); + return RETURN_VALUE_NAME.equals(parameterName); } + } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/SqlParameterSourceUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/SqlParameterSourceUtils.java index 89ebde23da48..7aeb335e835c 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/SqlParameterSourceUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/SqlParameterSourceUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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. @@ -90,8 +90,7 @@ public static Map extractCaseInsensitiveParameterNames(SqlParame Map caseInsensitiveParameterNames = new HashMap(); if (parameterSource instanceof BeanPropertySqlParameterSource) { String[] propertyNames = ((BeanPropertySqlParameterSource)parameterSource).getReadablePropertyNames(); - for (int i = 0; i < propertyNames.length; i++) { - String name = propertyNames[i]; + for (String name : propertyNames) { caseInsensitiveParameterNames.put(name.toLowerCase(), name); } } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceTransactionManager.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceTransactionManager.java index 6119b47ca51e..bd4496a4c877 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceTransactionManager.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceTransactionManager.java @@ -229,7 +229,7 @@ protected Object doGetTransaction() { @Override protected boolean isExistingTransaction(Object transaction) { DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction; - return (txObject.getConnectionHolder() != null && txObject.getConnectionHolder().isTransactionActive()); + return (txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive()); } /** @@ -241,7 +241,7 @@ protected void doBegin(Object transaction, TransactionDefinition definition) { Connection con = null; try { - if (txObject.getConnectionHolder() == null || + if (!txObject.hasConnectionHolder() || txObject.getConnectionHolder().isSynchronizedWithTransaction()) { Connection newCon = this.dataSource.getConnection(); if (logger.isDebugEnabled()) { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceUtils.java index 5cad3aa6f0a1..3da36f7535f7 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2017 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. @@ -268,8 +268,10 @@ public static void applyTransactionTimeout(Statement stmt, DataSource dataSource */ public static void applyTimeout(Statement stmt, DataSource dataSource, int timeout) throws SQLException { Assert.notNull(stmt, "No Statement specified"); - Assert.notNull(dataSource, "No DataSource specified"); - ConnectionHolder holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); + ConnectionHolder holder = null; + if (dataSource != null) { + holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); + } if (holder != null && holder.hasTimeout()) { // Remaining transaction timeout overrides specified value. stmt.setQueryTimeout(holder.getTimeToLiveInSeconds()); diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DataSourceInitializer.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DataSourceInitializer.java index 574c1ae5a6c2..3f650da03695 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DataSourceInitializer.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DataSourceInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2017 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. @@ -54,10 +54,8 @@ public void setDataSource(DataSource dataSource) { } /** - * Set the {@link DatabasePopulator} to execute during the bean initialization - * phase. - * @param databasePopulator the {@code DatabasePopulator} to use during - * initialization + * Set the {@link DatabasePopulator} to execute during the bean initialization phase. + * @param databasePopulator the {@code DatabasePopulator} to use during initialization * @see #setDatabaseCleaner */ public void setDatabasePopulator(DatabasePopulator databasePopulator) { @@ -84,6 +82,7 @@ public void setEnabled(boolean enabled) { this.enabled = enabled; } + /** * Use the {@linkplain #setDatabasePopulator database populator} to set up * the database. @@ -103,7 +102,7 @@ public void destroy() { } private void execute(DatabasePopulator populator) { - Assert.state(dataSource != null, "DataSource must be set"); + Assert.state(this.dataSource != null, "DataSource must be set"); if (this.enabled && populator != null) { DatabasePopulatorUtils.execute(populator, this.dataSource); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulatorUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulatorUtils.java index e153f3790dcd..ad645a7c2982 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulatorUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulatorUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -48,9 +48,7 @@ public static void execute(DatabasePopulator populator, DataSource dataSource) t populator.populate(connection); } finally { - if (connection != null) { - DataSourceUtils.releaseConnection(connection, dataSource); - } + DataSourceUtils.releaseConnection(connection, dataSource); } } catch (Throwable ex) { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/object/RdbmsOperation.java b/spring-jdbc/src/main/java/org/springframework/jdbc/object/RdbmsOperation.java index 7392219062d6..b6ad500ca436 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/object/RdbmsOperation.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/object/RdbmsOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -32,6 +32,7 @@ import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.SqlParameter; +import org.springframework.util.Assert; /** * An "RDBMS operation" is a multi-threaded, reusable object representing a query, @@ -85,27 +86,25 @@ public abstract class RdbmsOperation implements InitializingBean { /** - * An alternative to the more commonly used setDataSource() when you want to - * use the same JdbcTemplate in multiple RdbmsOperations. This is appropriate if the - * JdbcTemplate has special configuration such as a SQLExceptionTranslator that should - * apply to multiple RdbmsOperation objects. + * An alternative to the more commonly used {@link #setDataSource} when you want to + * use the same {@link JdbcTemplate} in multiple {@code RdbmsOperations}. This is + * appropriate if the {@code JdbcTemplate} has special configuration such as a + * {@link org.springframework.jdbc.support.SQLExceptionTranslator} to be reused. */ public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { - if (jdbcTemplate == null) { - throw new IllegalArgumentException("jdbcTemplate must not be null"); - } + Assert.notNull(jdbcTemplate, "JdbcTemplate must not be null"); this.jdbcTemplate = jdbcTemplate; } /** - * Return the JdbcTemplate object used by this object. + * Return the {@link JdbcTemplate} used by this operation object. */ public JdbcTemplate getJdbcTemplate() { return this.jdbcTemplate; } /** - * Set the JDBC DataSource to obtain connections from. + * Set the JDBC {@link DataSource} to obtain connections from. * @see org.springframework.jdbc.core.JdbcTemplate#setDataSource */ public void setDataSource(DataSource dataSource) { @@ -233,9 +232,8 @@ public void setSql(String sql) { } /** - * Subclasses can override this to supply dynamic SQL if they wish, - * but SQL is normally set by calling the setSql() method - * or in a subclass constructor. + * Subclasses can override this to supply dynamic SQL if they wish, but SQL is + * normally set by calling the {@link #setSql} method or in a subclass constructor. */ public String getSql() { return this.sql; @@ -287,7 +285,7 @@ public void declareParameter(SqlParameter param) throws InvalidDataAccessApiUsag * @param parameters Array containing the declared {@link SqlParameter} objects * @see #declaredParameters */ - public void setParameters(SqlParameter[] parameters) { + public void setParameters(SqlParameter... parameters) { if (isCompiled()) { throw new InvalidDataAccessApiUsageException("Cannot add parameters once the query is compiled"); } @@ -396,7 +394,7 @@ protected void validateParameters(Object[] parameters) throws InvalidDataAccessA * Validate the named parameters passed to an execute method based on declared parameters. * Subclasses should invoke this method before every {@code executeQuery()} or * {@code update()} method. - * @param parameters parameter Map supplied. May be {@code null}. + * @param parameters parameter Map supplied (may be {@code null}) * @throws InvalidDataAccessApiUsageException if the parameters are invalid */ protected void validateNamedParameters(Map parameters) throws InvalidDataAccessApiUsageException { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/AbstractFallbackSQLExceptionTranslator.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/AbstractFallbackSQLExceptionTranslator.java index 6e4c548eab2a..2e46da56d3b7 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/AbstractFallbackSQLExceptionTranslator.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/AbstractFallbackSQLExceptionTranslator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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. @@ -70,16 +70,22 @@ public DataAccessException translate(String task, String sql, SQLException ex) { sql = ""; } - DataAccessException dex = doTranslate(task, sql, ex); - if (dex != null) { + DataAccessException dae = doTranslate(task, sql, ex); + if (dae != null) { // Specific exception match found. - return dex; + return dae; } + // Looking for a fallback... SQLExceptionTranslator fallback = getFallbackTranslator(); if (fallback != null) { - return fallback.translate(task, sql, ex); + dae = fallback.translate(task, sql, ex); + if (dae != null) { + // Fallback exception match found. + return dae; + } } + // We couldn't identify it more precisely. return new UncategorizedSQLException(task, sql, ex); } @@ -90,7 +96,7 @@ public DataAccessException translate(String task, String sql, SQLException ex) { * is allowed to return {@code null} to indicate that no exception match has * been found and that fallback translation should kick in. * @param task readable text describing the task being attempted - * @param sql SQL query or update that caused the problem (may be {@code null}) + * @param sql SQL query or update that caused the problem (if known) * @param ex the offending {@code SQLException} * @return the DataAccessException, wrapping the {@code SQLException}; * or {@code null} if no exception match found @@ -103,7 +109,7 @@ public DataAccessException translate(String task, String sql, SQLException ex) { *

To be called by translator subclasses when creating an instance of a generic * {@link org.springframework.dao.DataAccessException} class. * @param task readable text describing the task being attempted - * @param sql the SQL statement that caused the problem (may be {@code null}) + * @param sql the SQL statement that caused the problem * @param ex the offending {@code SQLException} * @return the message {@code String} to use */ diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcUtils.java index f5a4c69622f0..061d36c16d1e 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcUtils.java @@ -472,8 +472,8 @@ public static String lookupColumnName(ResultSetMetaData resultSetMetaData, int c } /** - * Convert a column name with underscores to the corresponding property name using "camel case". A name - * like "customer_number" would match a "customerNumber" property name. + * Convert a column name with underscores to the corresponding property name using "camel case". + * A name like "customer_number" would match a "customerNumber" property name. * @param name the column name to be converted * @return the name using "camel case" */ diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLErrorCodesFactory.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLErrorCodesFactory.java index 49148fda93bb..3d6569a5fb44 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLErrorCodesFactory.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLErrorCodesFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -216,9 +216,9 @@ public SQLErrorCodes getErrorCodes(DataSource dataSource) { } catch (MetaDataAccessException ex) { logger.warn("Error while extracting database name - falling back to empty error codes", ex); - // Fallback is to return an empty SQLErrorCodes instance. - return new SQLErrorCodes(); } + // Fallback is to return an empty SQLErrorCodes instance. + return new SQLErrorCodes(); } } } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/TemporaryLobCreator.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/TemporaryLobCreator.java index fbe1b55744a7..43938efffc0b 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/TemporaryLobCreator.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/TemporaryLobCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2017 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. @@ -59,11 +59,15 @@ public class TemporaryLobCreator implements LobCreator { public void setBlobAsBytes(PreparedStatement ps, int paramIndex, byte[] content) throws SQLException { - Blob blob = ps.getConnection().createBlob(); - blob.setBytes(1, content); - - this.temporaryBlobs.add(blob); - ps.setBlob(paramIndex, blob); + if (content != null) { + Blob blob = ps.getConnection().createBlob(); + blob.setBytes(1, content); + this.temporaryBlobs.add(blob); + ps.setBlob(paramIndex, blob); + } + else { + ps.setBlob(paramIndex, (Blob) null); + } if (logger.isDebugEnabled()) { logger.debug(content != null ? "Copied bytes into temporary BLOB with length " + content.length : @@ -76,17 +80,21 @@ public void setBlobAsBinaryStream( PreparedStatement ps, int paramIndex, InputStream binaryStream, int contentLength) throws SQLException { - Blob blob = ps.getConnection().createBlob(); - try { - FileCopyUtils.copy(binaryStream, blob.setBinaryStream(1)); + if (binaryStream != null) { + Blob blob = ps.getConnection().createBlob(); + try { + FileCopyUtils.copy(binaryStream, blob.setBinaryStream(1)); + } + catch (IOException ex) { + throw new DataAccessResourceFailureException("Could not copy into LOB stream", ex); + } + this.temporaryBlobs.add(blob); + ps.setBlob(paramIndex, blob); } - catch (IOException ex) { - throw new DataAccessResourceFailureException("Could not copy into LOB stream", ex); + else { + ps.setBlob(paramIndex, (Blob) null); } - this.temporaryBlobs.add(blob); - ps.setBlob(paramIndex, blob); - if (logger.isDebugEnabled()) { logger.debug(binaryStream != null ? "Copied binary stream into temporary BLOB with length " + contentLength : @@ -98,11 +106,15 @@ public void setBlobAsBinaryStream( public void setClobAsString(PreparedStatement ps, int paramIndex, String content) throws SQLException { - Clob clob = ps.getConnection().createClob(); - clob.setString(1, content); - - this.temporaryClobs.add(clob); - ps.setClob(paramIndex, clob); + if (content != null) { + Clob clob = ps.getConnection().createClob(); + clob.setString(1, content); + this.temporaryClobs.add(clob); + ps.setClob(paramIndex, clob); + } + else { + ps.setClob(paramIndex, (Clob) null); + } if (logger.isDebugEnabled()) { logger.debug(content != null ? "Copied string into temporary CLOB with length " + content.length() : @@ -115,17 +127,21 @@ public void setClobAsAsciiStream( PreparedStatement ps, int paramIndex, InputStream asciiStream, int contentLength) throws SQLException { - Clob clob = ps.getConnection().createClob(); - try { - FileCopyUtils.copy(asciiStream, clob.setAsciiStream(1)); + if (asciiStream != null) { + Clob clob = ps.getConnection().createClob(); + try { + FileCopyUtils.copy(asciiStream, clob.setAsciiStream(1)); + } + catch (IOException ex) { + throw new DataAccessResourceFailureException("Could not copy into LOB stream", ex); + } + this.temporaryClobs.add(clob); + ps.setClob(paramIndex, clob); } - catch (IOException ex) { - throw new DataAccessResourceFailureException("Could not copy into LOB stream", ex); + else { + ps.setClob(paramIndex, (Clob) null); } - this.temporaryClobs.add(clob); - ps.setClob(paramIndex, clob); - if (logger.isDebugEnabled()) { logger.debug(asciiStream != null ? "Copied ASCII stream into temporary CLOB with length " + contentLength : @@ -138,17 +154,21 @@ public void setClobAsCharacterStream( PreparedStatement ps, int paramIndex, Reader characterStream, int contentLength) throws SQLException { - Clob clob = ps.getConnection().createClob(); - try { - FileCopyUtils.copy(characterStream, clob.setCharacterStream(1)); + if (characterStream != null) { + Clob clob = ps.getConnection().createClob(); + try { + FileCopyUtils.copy(characterStream, clob.setCharacterStream(1)); + } + catch (IOException ex) { + throw new DataAccessResourceFailureException("Could not copy into LOB stream", ex); + } + this.temporaryClobs.add(clob); + ps.setClob(paramIndex, clob); } - catch (IOException ex) { - throw new DataAccessResourceFailureException("Could not copy into LOB stream", ex); + else { + ps.setClob(paramIndex, (Clob) null); } - this.temporaryClobs.add(clob); - ps.setClob(paramIndex, clob); - if (logger.isDebugEnabled()) { logger.debug(characterStream != null ? "Copied character stream into temporary CLOB with length " + contentLength : @@ -170,4 +190,5 @@ public void close() { logger.error("Could not free LOB", ex); } } + } diff --git a/spring-jms/src/main/java/org/springframework/jms/config/AbstractListenerContainerParser.java b/spring-jms/src/main/java/org/springframework/jms/config/AbstractListenerContainerParser.java index f2d33d302356..2bc28bc07384 100644 --- a/spring-jms/src/main/java/org/springframework/jms/config/AbstractListenerContainerParser.java +++ b/spring-jms/src/main/java/org/springframework/jms/config/AbstractListenerContainerParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -151,15 +151,14 @@ private void parseListener(Element containerEle, Element listenerEle, ParserCont listenerDef.getPropertyValues().add("delegate", new RuntimeBeanReference(ref)); } - String method = null; if (listenerEle.hasAttribute(METHOD_ATTRIBUTE)) { - method = listenerEle.getAttribute(METHOD_ATTRIBUTE); + String method = listenerEle.getAttribute(METHOD_ATTRIBUTE); if (!StringUtils.hasText(method)) { parserContext.getReaderContext().error( "Listener 'method' attribute contains empty value.", listenerEle); } + listenerDef.getPropertyValues().add("defaultListenerMethod", method); } - listenerDef.getPropertyValues().add("defaultListenerMethod", method); PropertyValue messageConverterPv = commonContainerProperties.getPropertyValue("messageConverter"); if (messageConverterPv != null) { diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/JmsResourceHolder.java b/spring-jms/src/main/java/org/springframework/jms/connection/JmsResourceHolder.java index 98c4b60a5e95..62fe3928d86c 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/JmsResourceHolder.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/JmsResourceHolder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2017 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. @@ -170,10 +170,7 @@ public Session getSession(Class sessionType) { } public Session getSession(Class sessionType, Connection connection) { - List sessions = this.sessions; - if (connection != null) { - sessions = this.sessionsPerConnection.get(connection); - } + List sessions = (connection != null ? this.sessionsPerConnection.get(connection) : this.sessions); return CollectionUtils.findValueOfType(sessions, sessionType); } diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/JmsTransactionManager.java b/spring-jms/src/main/java/org/springframework/jms/connection/JmsTransactionManager.java index bf44f8fa01a1..f5cae1f5beee 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/JmsTransactionManager.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/JmsTransactionManager.java @@ -170,7 +170,7 @@ protected Object doGetTransaction() { @Override protected boolean isExistingTransaction(Object transaction) { JmsTransactionObject txObject = (JmsTransactionObject) transaction; - return (txObject.getResourceHolder() != null); + return txObject.hasResourceHolder(); } @Override @@ -316,6 +316,10 @@ public JmsResourceHolder getResourceHolder() { return this.resourceHolder; } + public boolean hasResourceHolder() { + return (this.resourceHolder != null); + } + @Override public boolean isRollbackOnly() { return this.resourceHolder.isRollbackOnly(); diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/AbstractMessageListenerContainer.java b/spring-jms/src/main/java/org/springframework/jms/listener/AbstractMessageListenerContainer.java index ec36bcc06f2e..d39a0701db03 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/AbstractMessageListenerContainer.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/AbstractMessageListenerContainer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -197,7 +197,6 @@ public abstract class AbstractMessageListenerContainer extends AbstractJmsListen * @see #setDestinationName(String) */ public void setDestination(Destination destination) { - Assert.notNull(destination, "'destination' must not be null"); this.destination = destination; if (destination instanceof Topic && !(destination instanceof Queue)) { // Clearly a Topic: let's set the "pubSubDomain" flag accordingly. @@ -223,11 +222,9 @@ public Destination getDestination() { * container picking up the new destination immediately (works e.g. with * DefaultMessageListenerContainer, as long as the cache level is less than * CACHE_CONSUMER). However, this is considered advanced usage; use it with care! - * @param destinationName the desired destination (can be {@code null}) * @see #setDestination(javax.jms.Destination) */ public void setDestinationName(String destinationName) { - Assert.notNull(destinationName, "'destinationName' must not be null"); this.destination = destinationName; } @@ -246,7 +243,8 @@ public String getDestinationName() { * (never {@code null}). */ protected String getDestinationDescription() { - return this.destination.toString(); + Object destination = this.destination; + return (destination != null ? destination.toString() : ""); } /** @@ -432,7 +430,7 @@ public String getSubscriptionName() { */ public void setDurableSubscriptionName(String durableSubscriptionName) { this.subscriptionName = durableSubscriptionName; - this.subscriptionDurable = true; + this.subscriptionDurable = (durableSubscriptionName != null); } /** diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java index 2f53f57e95f6..a896dc61ab4a 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -191,6 +191,9 @@ public void onMessage(Message message) { } } + @Override + public abstract void onMessage(Message message, Session session) throws JMSException; + /** * Handle the given exception that arose during listener execution. * The default implementation logs the exception at error level. @@ -204,6 +207,7 @@ protected void handleListenerException(Throwable ex) { logger.error("Listener execution failed", ex); } + /** * Extract the message body from the given JMS message. * @param message the JMS {@code Message} @@ -453,6 +457,7 @@ protected Object extractPayload(Message message) throws JMSException { @Override protected Message createMessageForPayload(Object payload, Session session, Object conversionHint) throws JMSException { + MessageConverter converter = getMessageConverter(); if (converter == null) { throw new IllegalStateException("No message converter, cannot handle '" + payload + "'"); @@ -464,6 +469,7 @@ protected Message createMessageForPayload(Object payload, Session session, Objec return converter.toMessage(payload, session); } + protected class LazyResolutionMessage implements org.springframework.messaging.Message { private final javax.jms.Message message; @@ -487,7 +493,6 @@ public Object getPayload() { "Failed to extract payload from [" + this.message + "]", ex); } } - // return this.payload; } @@ -513,7 +518,6 @@ public MessageHeaders getHeaders() { return this.headers; } } - } diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/StandardJmsActivationSpecFactory.java b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/StandardJmsActivationSpecFactory.java index 4cc2bd97d704..f607d4803c90 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/StandardJmsActivationSpecFactory.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/StandardJmsActivationSpecFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -94,7 +94,7 @@ public void setDestinationResolver(DestinationResolver destinationResolver) { * Return the {@link DestinationResolver} to use for resolving destinations names. */ public DestinationResolver getDestinationResolver() { - return destinationResolver; + return this.destinationResolver; } @Override diff --git a/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompClientSupportTests.java b/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompClientSupportTests.java index cceb2764b635..559767bd90f3 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompClientSupportTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompClientSupportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,29 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.messaging.simp.stomp; -import org.junit.Before; import org.junit.Test; import static org.junit.Assert.*; /** - * Unit tests for {@@link StompClientSupport}. + * Unit tests for {@link StompClientSupport}. + * * @author Rossen Stoyanchev */ public class StompClientSupportTests { - private StompClientSupport stompClient; + private final StompClientSupport stompClient = new StompClientSupport() {}; - @Before - public void setUp() throws Exception { - this.stompClient = new StompClientSupport() {}; - } - @Test - public void defaultHearbeatValidation() throws Exception { + public void defaultHeartbeatValidation() throws Exception { trySetDefaultHeartbeat(null); trySetDefaultHeartbeat(new long[] {-1, 0}); trySetDefaultHeartbeat(new long[] {0, -1}); diff --git a/spring-orm/src/main/java/org/springframework/orm/ObjectOptimisticLockingFailureException.java b/spring-orm/src/main/java/org/springframework/orm/ObjectOptimisticLockingFailureException.java index 2fd001c34223..7db4eb74ad64 100644 --- a/spring-orm/src/main/java/org/springframework/orm/ObjectOptimisticLockingFailureException.java +++ b/spring-orm/src/main/java/org/springframework/orm/ObjectOptimisticLockingFailureException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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. @@ -149,7 +149,7 @@ public String getPersistentClassName() { * Return the identifier of the object for which the locking failed. */ public Object getIdentifier() { - return identifier; + return this.identifier; } } diff --git a/spring-orm/src/main/java/org/springframework/orm/ObjectRetrievalFailureException.java b/spring-orm/src/main/java/org/springframework/orm/ObjectRetrievalFailureException.java index 0603e7469725..196260c1b2a9 100644 --- a/spring-orm/src/main/java/org/springframework/orm/ObjectRetrievalFailureException.java +++ b/spring-orm/src/main/java/org/springframework/orm/ObjectRetrievalFailureException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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. @@ -123,7 +123,7 @@ public String getPersistentClassName() { * Return the identifier of the object that was not found. */ public Object getIdentifier() { - return identifier; + return this.identifier; } } diff --git a/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java b/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java index 436734427bb3..17e7ae1d5619 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -196,7 +196,6 @@ public void setContextPaths(String... contextPaths) { * or {@link #setPackagesToScan "packagesToScan"} is required. */ public void setContextPath(String contextPath) { - Assert.hasText(contextPath, "'contextPath' must not be null"); this.contextPath = contextPath; } @@ -213,7 +212,6 @@ public String getContextPath() { * or {@link #setPackagesToScan "packagesToScan"} is required. */ public void setClassesToBeBound(Class... classesToBeBound) { - Assert.notEmpty(classesToBeBound, "'classesToBeBound' must not be empty"); this.classesToBeBound = classesToBeBound; } diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/connection/CciLocalTransactionManager.java b/spring-tx/src/main/java/org/springframework/jca/cci/connection/CciLocalTransactionManager.java index f2dc5e9e2001..47f3a84c9b55 100644 --- a/spring-tx/src/main/java/org/springframework/jca/cci/connection/CciLocalTransactionManager.java +++ b/spring-tx/src/main/java/org/springframework/jca/cci/connection/CciLocalTransactionManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,14 +40,14 @@ * *

Application code is required to retrieve the CCI Connection via * {@link ConnectionFactoryUtils#getConnection(ConnectionFactory)} instead of a standard - * J2EE-style {@link ConnectionFactory#getConnection()} call. Spring classes such as + * Java EE-style {@link ConnectionFactory#getConnection()} call. Spring classes such as * {@link org.springframework.jca.cci.core.CciTemplate} use this strategy implicitly. * If not used in combination with this transaction manager, the * {@link ConnectionFactoryUtils} lookup strategy behaves exactly like the native * DataSource lookup; it can thus be used in a portable fashion. * *

Alternatively, you can allow application code to work with the standard - * J2EE lookup pattern {@link ConnectionFactory#getConnection()}, for example + * Java EE lookup pattern {@link ConnectionFactory#getConnection()}, for example * for legacy code that is not aware of Spring at all. In that case, define a * {@link TransactionAwareConnectionFactoryProxy} for your target ConnectionFactory, * which will automatically participate in Spring-managed transactions. @@ -135,7 +135,7 @@ protected Object doGetTransaction() { protected boolean isExistingTransaction(Object transaction) { CciLocalTransactionObject txObject = (CciLocalTransactionObject) transaction; // Consider a pre-bound connection as transaction. - return (txObject.getConnectionHolder() != null); + return txObject.hasConnectionHolder(); } @Override @@ -269,6 +269,10 @@ public void setConnectionHolder(ConnectionHolder connectionHolder) { public ConnectionHolder getConnectionHolder() { return this.connectionHolder; } + + public boolean hasConnectionHolder() { + return (this.connectionHolder != null); + } } } diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionSpecConnectionFactoryAdapter.java b/spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionSpecConnectionFactoryAdapter.java index 78f3b29a7167..04112c501bcb 100644 --- a/spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionSpecConnectionFactoryAdapter.java +++ b/spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionSpecConnectionFactoryAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,11 @@ import javax.resource.ResourceException; import javax.resource.cci.Connection; +import javax.resource.cci.ConnectionFactory; import javax.resource.cci.ConnectionSpec; import org.springframework.core.NamedThreadLocal; +import org.springframework.util.Assert; /** * An adapter for a target CCI {@link javax.resource.cci.ConnectionFactory}, @@ -129,15 +131,9 @@ public final Connection getConnection() throws ResourceException { * @see javax.resource.cci.ConnectionFactory#getConnection() */ protected Connection doGetConnection(ConnectionSpec spec) throws ResourceException { - if (getTargetConnectionFactory() == null) { - throw new IllegalStateException("targetConnectionFactory is required"); - } - if (spec != null) { - return getTargetConnectionFactory().getConnection(spec); - } - else { - return getTargetConnectionFactory().getConnection(); - } + ConnectionFactory connectionFactory = getTargetConnectionFactory(); + Assert.state(connectionFactory != null, "No 'targetConnectionFactory' set"); + return (spec != null ? connectionFactory.getConnection(spec) : connectionFactory.getConnection()); } } diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAspectSupport.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAspectSupport.java index cfe0f803cc3e..78b4340d24f7 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAspectSupport.java +++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAspectSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -197,7 +197,7 @@ public void setTransactionAttributes(Properties transactionAttributes) { * @see NameMatchTransactionAttributeSource * @see org.springframework.transaction.annotation.AnnotationTransactionAttributeSource */ - public void setTransactionAttributeSources(TransactionAttributeSource[] transactionAttributeSources) { + public void setTransactionAttributeSources(TransactionAttributeSource... transactionAttributeSources) { this.transactionAttributeSource = new CompositeTransactionAttributeSource(transactionAttributeSources); } diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttributeSourcePointcut.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttributeSourcePointcut.java index fa6d9e1ac645..dc9696889e02 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttributeSourcePointcut.java +++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttributeSourcePointcut.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -34,7 +34,7 @@ abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPoi @Override public boolean matches(Method method, Class targetClass) { - if (TransactionalProxy.class.isAssignableFrom(targetClass)) { + if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) { return false; } TransactionAttributeSource tas = getTransactionAttributeSource(); diff --git a/spring-tx/src/test/java/org/springframework/transaction/TransactionSupportTests.java b/spring-tx/src/test/java/org/springframework/transaction/TransactionSupportTests.java index 871e6b1b6e9f..5c3b1616b1ff 100644 --- a/spring-tx/src/test/java/org/springframework/transaction/TransactionSupportTests.java +++ b/spring-tx/src/test/java/org/springframework/transaction/TransactionSupportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -38,11 +38,11 @@ public void noExistingTransaction() { PlatformTransactionManager tm = new TestTransactionManager(false, true); DefaultTransactionStatus status1 = (DefaultTransactionStatus) tm.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_SUPPORTS)); - assertTrue("Must not have transaction", status1.getTransaction() == null); + assertFalse("Must not have transaction", status1.hasTransaction()); DefaultTransactionStatus status2 = (DefaultTransactionStatus) tm.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED)); - assertTrue("Must have transaction", status2.getTransaction() != null); + assertTrue("Must have transaction", status2.hasTransaction()); assertTrue("Must be new transaction", status2.isNewTransaction()); try { diff --git a/spring-web/src/main/java/org/springframework/http/HttpHeaders.java b/spring-web/src/main/java/org/springframework/http/HttpHeaders.java index 7ea19ab8d6dd..ed5b5e59bc80 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpHeaders.java +++ b/spring-web/src/main/java/org/springframework/http/HttpHeaders.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -784,13 +784,13 @@ public long getDate() { /** * Set the (new) entity tag of the body, as specified by the {@code ETag} header. */ - public void setETag(String eTag) { - if (eTag != null) { - Assert.isTrue(eTag.startsWith("\"") || eTag.startsWith("W/"), - "Invalid eTag, does not start with W/ or \""); - Assert.isTrue(eTag.endsWith("\""), "Invalid eTag, does not end with \""); + public void setETag(String etag) { + if (etag != null) { + Assert.isTrue(etag.startsWith("\"") || etag.startsWith("W/"), + "Invalid ETag: does not start with W/ or \""); + Assert.isTrue(etag.endsWith("\""), "Invalid ETag: does not end with \""); } - set(ETAG, eTag); + set(ETAG, etag); } /** diff --git a/spring-web/src/main/java/org/springframework/web/util/WebUtils.java b/spring-web/src/main/java/org/springframework/web/util/WebUtils.java index 13195a76a794..f7d0b295d18d 100644 --- a/spring-web/src/main/java/org/springframework/web/util/WebUtils.java +++ b/spring-web/src/main/java/org/springframework/web/util/WebUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -39,6 +39,7 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; /** @@ -153,16 +154,15 @@ public static void setWebAppRootSystemProperty(ServletContext servletContext) th String root = servletContext.getRealPath("/"); if (root == null) { throw new IllegalStateException( - "Cannot set web app root system property when WAR file is not expanded"); + "Cannot set web app root system property when WAR file is not expanded"); } String param = servletContext.getInitParameter(WEB_APP_ROOT_KEY_PARAM); String key = (param != null ? param : DEFAULT_WEB_APP_ROOT_KEY); String oldValue = System.getProperty(key); if (oldValue != null && !StringUtils.pathEquals(oldValue, root)) { - throw new IllegalStateException( - "Web app root system property already set to different value: '" + - key + "' = [" + oldValue + "] instead of [" + root + "] - " + - "Choose unique values for the 'webAppRootKey' context-param in your web.xml files!"); + throw new IllegalStateException("Web app root system property already set to different value: '" + + key + "' = [" + oldValue + "] instead of [" + root + "] - " + + "Choose unique values for the 'webAppRootKey' context-param in your web.xml files!"); } System.setProperty(key, root); servletContext.log("Set web app root system property: '" + key + "' = [" + root + "]"); @@ -814,7 +814,7 @@ else if (CollectionUtils.isEmpty(allowedOrigins)) { * Check if the request is a same-origin one, based on {@code Origin}, {@code Host}, * {@code Forwarded} and {@code X-Forwarded-Host} headers. * @return {@code true} if the request is a same-origin one, {@code false} in case - * of cross-origin request. + * of cross-origin request * @since 4.2 */ public static boolean isSameOrigin(HttpRequest request) { @@ -837,7 +837,8 @@ public static boolean isSameOrigin(HttpRequest request) { } UriComponents actualUrl = urlBuilder.build(); UriComponents originUrl = UriComponentsBuilder.fromOriginHeader(origin).build(); - return (actualUrl.getHost().equals(originUrl.getHost()) && getPort(actualUrl) == getPort(originUrl)); + return (ObjectUtils.nullSafeEquals(actualUrl.getHost(), originUrl.getHost()) && + getPort(actualUrl) == getPort(originUrl)); } private static int getPort(UriComponents uri) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/BeanTypeNotPresentCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/BeanTypeNotPresentCondition.java deleted file mode 100644 index 90a90226ee57..000000000000 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/BeanTypeNotPresentCondition.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.servlet.config.annotation; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.BeanFactoryUtils; -import org.springframework.beans.factory.ListableBeanFactory; -import org.springframework.context.annotation.ConditionContext; -import org.springframework.context.annotation.ConfigurationCondition; -import org.springframework.core.type.AnnotatedTypeMetadata; -import org.springframework.util.ObjectUtils; - -/** - * A simple configuration condition that checks for the absence of any beans - * of a given type. - * - * @author Rossen Stoyanchev - * @since 4.1 - */ -class BeanTypeNotPresentCondition implements ConfigurationCondition { - - private static final Log logger = - LogFactory.getLog("org.springframework.web.servlet.config.annotation.ViewResolution"); - - private final Class beanType; - - - BeanTypeNotPresentCondition(Class beanType) { - this.beanType = beanType; - } - - - @Override - public ConfigurationPhase getConfigurationPhase() { - return ConfigurationPhase.PARSE_CONFIGURATION; - } - - public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { - ListableBeanFactory factory = context.getBeanFactory(); - String[] names = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(factory, this.beanType, false, false); - if (ObjectUtils.isEmpty(names)) { - logger.debug("No bean of type [" + this.beanType + "]. Conditional configuration applies."); - return true; - } - else { - logger.debug("Found bean of type [" + this.beanType + "]. Conditional configuration does not apply."); - return false; - } - } - -} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/UrlTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/UrlTag.java index 6566cd831e1f..9672aed0d96a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/UrlTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/UrlTag.java @@ -197,7 +197,7 @@ public int doEndTag() throws JspException { * Build the URL for the tag from the tag attributes and parameters. * @return the URL value as a String */ - private String createUrl() throws JspException { + String createUrl() throws JspException { HttpServletRequest request = (HttpServletRequest) pageContext.getRequest(); HttpServletResponse response = (HttpServletResponse) pageContext.getResponse(); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/UrlTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/UrlTagTests.java index 1647d4a40b4f..f78243d6be8b 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/UrlTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/UrlTagTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package org.springframework.web.servlet.tags; -import java.lang.reflect.Method; import java.util.HashSet; import java.util.LinkedList; import java.util.List; @@ -30,7 +29,6 @@ import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.mock.web.test.MockPageContext; -import org.springframework.util.ReflectionUtils; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; @@ -44,13 +42,15 @@ public class UrlTagTests extends AbstractTagTests { private MockPageContext context; + @Before - public void setUp() throws Exception { + public void setup() throws Exception { context = createPageContext(); tag = new UrlTag(); tag.setPageContext(context); } + @Test public void paramSupport() { assertThat(tag, instanceOf(ParamAware.class)); @@ -66,7 +66,6 @@ public void doStartTag() throws JspException { @Test public void doEndTag() throws JspException { tag.setValue("url/path"); - tag.doStartTag(); int action = tag.doEndTag(); @@ -77,12 +76,10 @@ public void doEndTag() throws JspException { public void varDefaultScope() throws JspException { tag.setValue("url/path"); tag.setVar("var"); - tag.doStartTag(); tag.doEndTag(); - assertEquals("url/path", context.getAttribute("var", - PageContext.PAGE_SCOPE)); + assertEquals("url/path", context.getAttribute("var", PageContext.PAGE_SCOPE)); } @Test @@ -90,19 +87,16 @@ public void varExplicitScope() throws JspException { tag.setValue("url/path"); tag.setVar("var"); tag.setScope("request"); - tag.doStartTag(); tag.doEndTag(); - assertEquals("url/path", context.getAttribute("var", - PageContext.REQUEST_SCOPE)); + assertEquals("url/path", context.getAttribute("var", PageContext.REQUEST_SCOPE)); } @Test public void setHtmlEscapeDefault() throws JspException { tag.setValue("url/path"); tag.setVar("var"); - tag.doStartTag(); Param param = new Param(); @@ -116,9 +110,7 @@ public void setHtmlEscapeDefault() throws JspException { tag.addParam(param); tag.doEndTag(); - - assertEquals("url/path?n%20me=v%26l%3De&name=value2", context - .getAttribute("var")); + assertEquals("url/path?n%20me=v%26l%3De&name=value2", context.getAttribute("var")); } @Test @@ -140,9 +132,7 @@ public void setHtmlEscapeFalse() throws JspException { tag.addParam(param); tag.doEndTag(); - - assertEquals("url/path?n%20me=v%26l%3De&name=value2", context - .getAttribute("var")); + assertEquals("url/path?n%20me=v%26l%3De&name=value2", context.getAttribute("var")); } @Test @@ -150,7 +140,6 @@ public void setHtmlEscapeTrue() throws JspException { tag.setValue("url/path"); tag.setVar("var"); tag.setHtmlEscape(true); - tag.doStartTag(); Param param = new Param(); @@ -164,9 +153,7 @@ public void setHtmlEscapeTrue() throws JspException { tag.addParam(param); tag.doEndTag(); - - assertEquals("url/path?n%20me=v%26l%3De&name=value2", context - .getAttribute("var")); + assertEquals("url/path?n%20me=v%26l%3De&name=value2", context.getAttribute("var")); } @Test @@ -174,7 +161,6 @@ public void setJavaScriptEscapeTrue() throws JspException { tag.setValue("url/path"); tag.setVar("var"); tag.setJavaScriptEscape(true); - tag.doStartTag(); Param param = new Param(); @@ -188,9 +174,7 @@ public void setJavaScriptEscapeTrue() throws JspException { tag.addParam(param); tag.doEndTag(); - - assertEquals("url\\/path?n%20me=v%26l%3De&name=value2", context - .getAttribute("var")); + assertEquals("url\\/path?n%20me=v%26l%3De&name=value2", context.getAttribute("var")); } @Test @@ -199,7 +183,6 @@ public void setHtmlAndJavaScriptEscapeTrue() throws JspException { tag.setVar("var"); tag.setHtmlEscape(true); tag.setJavaScriptEscape(true); - tag.doStartTag(); Param param = new Param(); @@ -213,25 +196,22 @@ public void setHtmlAndJavaScriptEscapeTrue() throws JspException { tag.addParam(param); tag.doEndTag(); - - assertEquals("url\\/path?n%20me=v%26l%3De&name=value2", context - .getAttribute("var")); + assertEquals("url\\/path?n%20me=v%26l%3De&name=value2", context.getAttribute("var")); } @Test public void createQueryStringNoParams() throws JspException { - List params = new LinkedList(); - Set usedParams = new HashSet(); + List params = new LinkedList<>(); + Set usedParams = new HashSet<>(); String queryString = tag.createQueryString(params, usedParams, true); - assertEquals("", queryString); } @Test public void createQueryStringOneParam() throws JspException { - List params = new LinkedList(); - Set usedParams = new HashSet(); + List params = new LinkedList<>(); + Set usedParams = new HashSet<>(); Param param = new Param(); param.setName("name"); @@ -239,15 +219,13 @@ public void createQueryStringOneParam() throws JspException { params.add(param); String queryString = tag.createQueryString(params, usedParams, true); - assertEquals("?name=value", queryString); } @Test - public void createQueryStringOneParamForExsistingQueryString() - throws JspException { - List params = new LinkedList(); - Set usedParams = new HashSet(); + public void createQueryStringOneParamForExsistingQueryString() throws JspException { + List params = new LinkedList<>(); + Set usedParams = new HashSet<>(); Param param = new Param(); param.setName("name"); @@ -255,14 +233,13 @@ public void createQueryStringOneParamForExsistingQueryString() params.add(param); String queryString = tag.createQueryString(params, usedParams, false); - assertEquals("&name=value", queryString); } @Test public void createQueryStringOneParamEmptyValue() throws JspException { - List params = new LinkedList(); - Set usedParams = new HashSet(); + List params = new LinkedList<>(); + Set usedParams = new HashSet<>(); Param param = new Param(); param.setName("name"); @@ -270,14 +247,13 @@ public void createQueryStringOneParamEmptyValue() throws JspException { params.add(param); String queryString = tag.createQueryString(params, usedParams, true); - assertEquals("?name=", queryString); } @Test public void createQueryStringOneParamNullValue() throws JspException { - List params = new LinkedList(); - Set usedParams = new HashSet(); + List params = new LinkedList<>(); + Set usedParams = new HashSet<>(); Param param = new Param(); param.setName("name"); @@ -285,31 +261,28 @@ public void createQueryStringOneParamNullValue() throws JspException { params.add(param); String queryString = tag.createQueryString(params, usedParams, true); - assertEquals("?name", queryString); } @Test public void createQueryStringOneParamAlreadyUsed() throws JspException { - List params = new LinkedList(); - Set usedParams = new HashSet(); + List params = new LinkedList<>(); + Set usedParams = new HashSet<>(); Param param = new Param(); param.setName("name"); param.setValue("value"); params.add(param); - usedParams.add("name"); String queryString = tag.createQueryString(params, usedParams, true); - assertEquals("", queryString); } @Test public void createQueryStringTwoParams() throws JspException { - List params = new LinkedList(); - Set usedParams = new HashSet(); + List params = new LinkedList<>(); + Set usedParams = new HashSet<>(); Param param = new Param(); param.setName("name"); @@ -322,14 +295,13 @@ public void createQueryStringTwoParams() throws JspException { params.add(param); String queryString = tag.createQueryString(params, usedParams, true); - assertEquals("?name=value&name=value2", queryString); } @Test public void createQueryStringUrlEncoding() throws JspException { - List params = new LinkedList(); - Set usedParams = new HashSet(); + List params = new LinkedList<>(); + Set usedParams = new HashSet<>(); Param param = new Param(); param.setName("n me"); @@ -342,14 +314,13 @@ public void createQueryStringUrlEncoding() throws JspException { params.add(param); String queryString = tag.createQueryString(params, usedParams, true); - assertEquals("?n%20me=v%26l%3De&name=value2", queryString); } @Test public void createQueryStringParamNullName() throws JspException { - List params = new LinkedList(); - Set usedParams = new HashSet(); + List params = new LinkedList<>(); + Set usedParams = new HashSet<>(); Param param = new Param(); param.setName(null); @@ -357,14 +328,13 @@ public void createQueryStringParamNullName() throws JspException { params.add(param); String queryString = tag.createQueryString(params, usedParams, true); - assertEquals("", queryString); } @Test public void createQueryStringParamEmptyName() throws JspException { - List params = new LinkedList(); - Set usedParams = new HashSet(); + List params = new LinkedList<>(); + Set usedParams = new HashSet<>(); Param param = new Param(); param.setName(""); @@ -372,78 +342,65 @@ public void createQueryStringParamEmptyName() throws JspException { params.add(param); String queryString = tag.createQueryString(params, usedParams, true); - assertEquals("", queryString); } @Test public void replaceUriTemplateParamsNoParams() throws JspException { - List params = new LinkedList(); - Set usedParams = new HashSet(); - - String uri = tag.replaceUriTemplateParams("url/path", params, - usedParams); + List params = new LinkedList<>(); + Set usedParams = new HashSet<>(); + String uri = tag.replaceUriTemplateParams("url/path", params, usedParams); assertEquals("url/path", uri); assertEquals(0, usedParams.size()); } @Test - public void replaceUriTemplateParamsTemplateWithoutParamMatch() - throws JspException { - List params = new LinkedList(); - Set usedParams = new HashSet(); - - String uri = tag.replaceUriTemplateParams("url/{path}", params, - usedParams); + public void replaceUriTemplateParamsTemplateWithoutParamMatch() throws JspException { + List params = new LinkedList<>(); + Set usedParams = new HashSet<>(); + String uri = tag.replaceUriTemplateParams("url/{path}", params, usedParams); assertEquals("url/{path}", uri); assertEquals(0, usedParams.size()); } @Test - public void replaceUriTemplateParamsTemplateWithParamMatch() - throws JspException { - List params = new LinkedList(); - Set usedParams = new HashSet(); + public void replaceUriTemplateParamsTemplateWithParamMatch() throws JspException { + List params = new LinkedList<>(); + Set usedParams = new HashSet<>(); Param param = new Param(); param.setName("name"); param.setValue("value"); params.add(param); - String uri = tag.replaceUriTemplateParams("url/{name}", params, - usedParams); - + String uri = tag.replaceUriTemplateParams("url/{name}", params, usedParams); assertEquals("url/value", uri); assertEquals(1, usedParams.size()); assertTrue(usedParams.contains("name")); } @Test - public void replaceUriTemplateParamsTemplateWithParamMatchNamePreEncoding() - throws JspException { - List params = new LinkedList(); - Set usedParams = new HashSet(); + public void replaceUriTemplateParamsTemplateWithParamMatchNamePreEncoding() throws JspException { + List params = new LinkedList<>(); + Set usedParams = new HashSet<>(); Param param = new Param(); param.setName("n me"); param.setValue("value"); params.add(param); - String uri = tag.replaceUriTemplateParams("url/{n me}", params, - usedParams); - + String uri = tag.replaceUriTemplateParams("url/{n me}", params, usedParams); assertEquals("url/value", uri); assertEquals(1, usedParams.size()); assertTrue(usedParams.contains("n me")); } @Test - public void replaceUriTemplateParamsTemplateWithParamMatchValueEncoded() - throws JspException { - List params = new LinkedList(); - Set usedParams = new HashSet(); + public void replaceUriTemplateParamsTemplateWithParamMatchValueEncoded() throws JspException { + List params = new LinkedList<>(); + Set usedParams = new HashSet<>(); Param param = new Param(); param.setName("name"); @@ -458,13 +415,10 @@ public void replaceUriTemplateParamsTemplateWithParamMatchValueEncoded() assertTrue(usedParams.contains("name")); } - // SPR-11401 - - @Test - public void replaceUriTemplateParamsTemplateWithPathSegment() - throws JspException { - List params = new LinkedList(); - Set usedParams = new HashSet(); + @Test // SPR-11401 + public void replaceUriTemplateParamsTemplateWithPathSegment() throws JspException { + List params = new LinkedList<>(); + Set usedParams = new HashSet<>(); Param param = new Param(); param.setName("name"); @@ -479,10 +433,9 @@ public void replaceUriTemplateParamsTemplateWithPathSegment() } @Test - public void replaceUriTemplateParamsTemplateWithPath() - throws JspException { - List params = new LinkedList(); - Set usedParams = new HashSet(); + public void replaceUriTemplateParamsTemplateWithPath() throws JspException { + List params = new LinkedList<>(); + Set usedParams = new HashSet<>(); Param param = new Param(); param.setName("name"); @@ -490,7 +443,6 @@ public void replaceUriTemplateParamsTemplateWithPath() params.add(param); String uri = tag.replaceUriTemplateParams("url/{name}", params, usedParams); - assertEquals("url/my/Id", uri); assertEquals(1, usedParams.size()); assertTrue(usedParams.contains("name")); @@ -499,89 +451,71 @@ public void replaceUriTemplateParamsTemplateWithPath() @Test public void createUrlRemoteServer() throws JspException { tag.setValue("http://www.springframework.org/"); - tag.doStartTag(); - // String uri = tag.createUrl(); - String uri = invokeCreateUrl(tag); - + String uri = tag.createUrl(); assertEquals("http://www.springframework.org/", uri); } @Test public void createUrlRelative() throws JspException { tag.setValue("url/path"); - tag.doStartTag(); - String uri = invokeCreateUrl(tag); - + String uri = tag.createUrl(); assertEquals("url/path", uri); } @Test public void createUrlLocalContext() throws JspException { - ((MockHttpServletRequest) context.getRequest()) - .setContextPath("/app-context"); + ((MockHttpServletRequest) context.getRequest()).setContextPath("/app-context"); tag.setValue("/url/path"); - tag.doStartTag(); - String uri = invokeCreateUrl(tag); - + String uri = tag.createUrl(); assertEquals("/app-context/url/path", uri); } @Test public void createUrlRemoteContext() throws JspException { - ((MockHttpServletRequest) context.getRequest()) - .setContextPath("/app-context"); + ((MockHttpServletRequest) context.getRequest()).setContextPath("/app-context"); tag.setValue("/url/path"); tag.setContext("some-other-context"); - tag.doStartTag(); - String uri = invokeCreateUrl(tag); - + String uri = tag.createUrl(); assertEquals("/some-other-context/url/path", uri); } @Test public void createUrlRemoteContextWithSlash() throws JspException { - ((MockHttpServletRequest) context.getRequest()) - .setContextPath("/app-context"); + ((MockHttpServletRequest) context.getRequest()).setContextPath("/app-context"); tag.setValue("/url/path"); tag.setContext("/some-other-context"); - tag.doStartTag(); - String uri = invokeCreateUrl(tag); - + String uri = tag.createUrl(); assertEquals("/some-other-context/url/path", uri); } @Test public void createUrlRemoteContextSingleSlash() throws JspException { - ((MockHttpServletRequest) context.getRequest()) - .setContextPath("/app-context"); + ((MockHttpServletRequest) context.getRequest()).setContextPath("/app-context"); tag.setValue("/url/path"); tag.setContext("/"); - tag.doStartTag(); - String uri = invokeCreateUrl(tag); - + String uri = tag.createUrl(); assertEquals("/url/path", uri); } @Test public void createUrlWithParams() throws JspException { tag.setValue("url/path"); - tag.doStartTag(); Param param = new Param(); @@ -594,15 +528,13 @@ public void createUrlWithParams() throws JspException { param.setValue("v lue"); tag.addParam(param); - String uri = invokeCreateUrl(tag); - + String uri = tag.createUrl(); assertEquals("url/path?name=value&n%20me=v%20lue", uri); } @Test public void createUrlWithTemplateParams() throws JspException { tag.setValue("url/{name}"); - tag.doStartTag(); Param param = new Param(); @@ -615,16 +547,13 @@ public void createUrlWithTemplateParams() throws JspException { param.setValue("v lue"); tag.addParam(param); - String uri = invokeCreateUrl(tag); - + String uri = tag.createUrl(); assertEquals("url/value?n%20me=v%20lue", uri); } @Test - public void createUrlWithParamAndExsistingQueryString() - throws JspException { + public void createUrlWithParamAndExistingQueryString() throws JspException { tag.setValue("url/path?foo=bar"); - tag.doStartTag(); Param param = new Param(); @@ -632,29 +561,8 @@ public void createUrlWithParamAndExsistingQueryString() param.setValue("value"); tag.addParam(param); - String uri = invokeCreateUrl(tag); - + String uri = tag.createUrl(); assertEquals("url/path?foo=bar&name=value", uri); } - @Test - public void jspWriterOutput() { - // TODO assert that the output to the JspWriter is the expected output - } - - @Test - public void servletRepsonseEncodeUrl() { - // TODO assert that HttpServletResponse.encodeURL(String) is invoked for - // non absolute urls - } - - // support methods - - private String invokeCreateUrl(UrlTag tag) { - Method createUrl = ReflectionUtils.findMethod(tag.getClass(), - "createUrl"); - ReflectionUtils.makeAccessible(createUrl); - return (String) ReflectionUtils.invokeMethod(createUrl, tag); - } - } diff --git a/src/test/java/com/foo/ComponentBeanDefinitionParser.java b/src/test/java/com/foo/ComponentBeanDefinitionParser.java index 9fb2213c2bb7..792842dbac1e 100644 --- a/src/test/java/com/foo/ComponentBeanDefinitionParser.java +++ b/src/test/java/com/foo/ComponentBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,32 +18,30 @@ import java.util.List; +import org.w3c.dom.Element; + import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.ManagedList; import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.CollectionUtils; import org.springframework.util.xml.DomUtils; -import org.w3c.dom.Element; public class ComponentBeanDefinitionParser extends AbstractBeanDefinitionParser { @Override - protected AbstractBeanDefinition parseInternal(Element element, - ParserContext parserContext) { + protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { return parseComponentElement(element); } private static AbstractBeanDefinition parseComponentElement(Element element) { - BeanDefinitionBuilder factory = BeanDefinitionBuilder - .rootBeanDefinition(ComponentFactoryBean.class); - + BeanDefinitionBuilder factory = BeanDefinitionBuilder.rootBeanDefinition(ComponentFactoryBean.class); factory.addPropertyValue("parent", parseComponent(element)); - List childElements = DomUtils.getChildElementsByTagName( - element, "component"); - if (childElements != null && childElements.size() > 0) { + List childElements = DomUtils.getChildElementsByTagName(element, "component"); + if (!CollectionUtils.isEmpty(childElements)) { parseChildComponents(childElements, factory); } @@ -51,19 +49,17 @@ private static AbstractBeanDefinition parseComponentElement(Element element) { } private static BeanDefinition parseComponent(Element element) { - BeanDefinitionBuilder component = BeanDefinitionBuilder - .rootBeanDefinition(Component.class); + BeanDefinitionBuilder component = BeanDefinitionBuilder.rootBeanDefinition(Component.class); component.addPropertyValue("name", element.getAttribute("name")); return component.getBeanDefinition(); } - private static void parseChildComponents(List childElements, - BeanDefinitionBuilder factory) { - ManagedList children = new ManagedList( - childElements.size()); + private static void parseChildComponents(List childElements, BeanDefinitionBuilder factory) { + ManagedList children = new ManagedList(childElements.size()); for (Element element : childElements) { children.add(parseComponentElement(element)); } factory.addPropertyValue("children", children); } + }