diff options
author | Andrej Shadura <andrew.shadura@collabora.co.uk> | 2019-03-09 12:38:16 +0000 |
---|---|---|
committer | Andrej Shadura <andrew.shadura@collabora.co.uk> | 2019-03-09 12:38:16 +0000 |
commit | 673684ec2c6cac26840588b958de098f0c54dd53 (patch) | |
tree | c59a0c2767a9ccfa80ca84b30e33d7e39ab1cbcc | |
parent | f0e4dab77c149a3dd88691ae95b448a5a7819a32 (diff) | |
parent | 139a199c595da36850738b73ee65310ed0a4a94d (diff) |
Update upstream source from tag 'upstream/4.3.23_git20190308'
Update to upstream version '4.3.23~git20190308'
with Debian dir 6d5a5b12f9bb323cd3b6fb67329b6f998e2ff19a
82 files changed, 1046 insertions, 899 deletions
diff --git a/build.gradle b/build.gradle index 51784558..9af78581 100644 --- a/build.gradle +++ b/build.gradle @@ -62,7 +62,7 @@ configure(allprojects) { project -> ext.jtaVersion = "1.2" ext.junitVersion = "4.12" ext.log4jVersion = "1.2.17" - ext.nettyVersion = "4.1.32.Final" + ext.nettyVersion = "4.1.33.Final" ext.okhttpVersion = "2.7.5" ext.okhttp3Version = "3.8.1" ext.openjpaVersion = "2.4.2" @@ -75,7 +75,7 @@ configure(allprojects) { project -> ext.testngVersion = "6.9.10" ext.tiles2Version = "2.2.2" ext.tiles3Version = "3.0.8" - ext.tomcatVersion = "8.5.37" + ext.tomcatVersion = "8.5.38" ext.tyrusVersion = "1.3.5" // constrained by WebLogic 12.1.3 support ext.undertowVersion = "1.3.33.Final" ext.xmlunitVersion = "1.6" diff --git a/gradle.properties b/gradle.properties index 283aaa12..b2e34644 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -version=4.3.22.RELEASE +version=4.3.23.BUILD-SNAPSHOT diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/ObjenesisCglibAopProxy.java b/spring-aop/src/main/java/org/springframework/aop/framework/ObjenesisCglibAopProxy.java index 0da31db2..ce273cf5 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/ObjenesisCglibAopProxy.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/ObjenesisCglibAopProxy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ import org.springframework.objenesis.SpringObjenesis; /** * Objenesis-based extension of {@link CglibAopProxy} to create proxy instances - * without invoking the constructor of the class. + * without invoking the constructor of the class. Used by default as of Spring 4. * * @author Oliver Gierke * @author Juergen Hoeller @@ -50,7 +50,6 @@ class ObjenesisCglibAopProxy extends CglibAopProxy { @Override - @SuppressWarnings("unchecked") protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) { Class<?> proxyClass = enhancer.createClass(); Object proxyInstance = null; diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAdvisorAutoProxyCreator.java b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAdvisorAutoProxyCreator.java index d7a8d116..1549168d 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAdvisorAutoProxyCreator.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAdvisorAutoProxyCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,8 +29,8 @@ import org.springframework.core.annotation.AnnotationAwareOrderComparator; * Generic auto proxy creator that builds AOP proxies for specific beans * based on detected Advisors for each bean. * - * <p>Subclasses must implement the abstract {@link #findCandidateAdvisors()} - * method to return a list of Advisors applying to any object. Subclasses can + * <p>Subclasses may override the {@link #findCandidateAdvisors()} method to + * return a custom list of Advisors applying to any object. Subclasses can * also override the inherited {@link #shouldSkip} method to exclude certain * objects from auto-proxying. * @@ -153,7 +153,7 @@ public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyC * <p>The default implementation is empty. * <p>Typically used to add Advisors that expose contextual information * required by some of the later advisors. - * @param candidateAdvisors Advisors that have already been identified as + * @param candidateAdvisors the Advisors that have already been identified as * applying to a given bean */ protected void extendAdvisors(List<Advisor> candidateAdvisors) { diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.java b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.java index 904c7650..72717b35 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -130,8 +130,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16)); - private final Set<Object> earlyProxyReferences = - Collections.newSetFromMap(new ConcurrentHashMap<Object, Boolean>(16)); + private final Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap<Object, Object>(16); private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<Object, Class<?>>(16); @@ -231,9 +230,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport @Override public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { Object cacheKey = getCacheKey(bean.getClass(), beanName); - if (!this.earlyProxyReferences.contains(cacheKey)) { - this.earlyProxyReferences.add(cacheKey); - } + this.earlyProxyReferences.put(cacheKey, bean); return wrapIfNecessary(bean, beanName, cacheKey); } @@ -294,7 +291,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); - if (!this.earlyProxyReferences.contains(cacheKey)) { + if (this.earlyProxyReferences.remove(cacheKey) != bean) { return wrapIfNecessary(bean, beanName, cacheKey); } } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactory.java index 83498c33..0ea1dff1 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -132,8 +132,7 @@ public interface BeanFactory { * Will ask the parent factory if the bean cannot be found in this factory instance. * @param name the name of the bean to retrieve * @return an instance of the bean - * @throws NoSuchBeanDefinitionException if there is no bean definition - * with the specified name + * @throws NoSuchBeanDefinitionException if there is no bean with the specified name * @throws BeansException if the bean could not be obtained */ Object getBean(String name) throws BeansException; @@ -180,8 +179,7 @@ public interface BeanFactory { * but may also be translated into a conventional by-name lookup based on the name * of the given type. For more extensive retrieval operations across sets of beans, * use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}. - * @param requiredType type the bean must match; can be an interface or superclass. - * {@code null} is disallowed. + * @param requiredType type the bean must match; can be an interface or superclass * @return an instance of the single bean matching the required type * @throws NoSuchBeanDefinitionException if no bean of the given type was found * @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found @@ -199,8 +197,7 @@ public interface BeanFactory { * but may also be translated into a conventional by-name lookup based on the name * of the given type. For more extensive retrieval operations across sets of beans, * use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}. - * @param requiredType type the bean must match; can be an interface or superclass. - * {@code null} is disallowed. + * @param requiredType type the bean must match; can be an interface or superclass * @param args arguments to use when creating a bean instance using explicit arguments * (only applied when creating a new instance as opposed to retrieving an existing one) * @return an instance of the bean diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/InjectionPoint.java b/spring-beans/src/main/java/org/springframework/beans/factory/InjectionPoint.java index 38ace23f..035dbd27 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/InjectionPoint.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/InjectionPoint.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,8 @@ import org.springframework.util.Assert; /** * A simple descriptor for an injection point, pointing to a method/constructor * parameter or a field. Exposed by {@link UnsatisfiedDependencyException}. + * Also available as an argument for factory methods, reacting to the + * requesting injection point for building a customized bean instance. * * @author Juergen Hoeller * @since 4.3 @@ -101,10 +103,12 @@ public class InjectionPoint { */ public Annotation[] getAnnotations() { if (this.field != null) { - if (this.fieldAnnotations == null) { - this.fieldAnnotations = this.field.getAnnotations(); + Annotation[] fieldAnnotations = this.fieldAnnotations; + if (fieldAnnotations == null) { + fieldAnnotations = this.field.getAnnotations(); + this.fieldAnnotations = fieldAnnotations; } - return this.fieldAnnotations; + return fieldAnnotations; } else { return this.methodParameter.getParameterAnnotations(); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java index b0e8c609..0373e5fd 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java @@ -697,7 +697,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean ReflectionUtils.makeAccessible(method); method.invoke(bean, arguments); } - catch (InvocationTargetException ex){ + catch (InvocationTargetException ex) { throw ex.getTargetException(); } } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/Value.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/Value.java index 88ae5cc0..33d9ba7b 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/Value.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/Value.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2019 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. @@ -30,7 +30,7 @@ import java.lang.annotation.Target; * for dynamic resolution of handler method parameters, e.g. in Spring MVC. * * <p>A common use case is to assign default field values using - * "#{systemProperties.myProp}" style expressions. + * {@code #{systemProperties.myProp}} style expressions. * * <p>Note that actual processing of the {@code @Value} annotation is performed * by a {@link org.springframework.beans.factory.config.BeanPostProcessor @@ -55,7 +55,7 @@ import java.lang.annotation.Target; public @interface Value { /** - * The actual value expression: e.g. "#{systemProperties.myProp}". + * The actual value expression: for example {@code #{systemProperties.myProp}}. */ String value(); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/AutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/AutowireCapableBeanFactory.java index 61b52407..b0e12989 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/AutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/AutowireCapableBeanFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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. @@ -117,7 +117,7 @@ public interface AutowireCapableBeanFactory extends BeanFactory { * {@link BeanPostProcessor BeanPostProcessors}. * <p>Note: This is intended for creating a fresh instance, populating annotated * fields and methods as well as applying all standard bean initialization callbacks. - * It does <i>not</> imply traditional by-name or by-type autowiring of properties; + * It does <i>not</i> imply traditional by-name or by-type autowiring of properties; * use {@link #createBean(Class, int, boolean)} for those purposes. * @param beanClass the class of the bean to create * @return the new bean instance @@ -273,8 +273,9 @@ public interface AutowireCapableBeanFactory extends BeanFactory { * Apply {@link BeanPostProcessor BeanPostProcessors} to the given existing bean * instance, invoking their {@code postProcessBeforeInitialization} methods. * The returned bean instance may be a wrapper around the original. - * @param existingBean the new bean instance - * @param beanName the name of the bean + * @param existingBean the existing bean instance + * @param beanName the name of the bean, to be passed to it if necessary + * (only passed to {@link BeanPostProcessor BeanPostProcessors}) * @return the bean instance to use, either the original or a wrapped one * @throws BeansException if any post-processing failed * @see BeanPostProcessor#postProcessBeforeInitialization @@ -286,8 +287,9 @@ public interface AutowireCapableBeanFactory extends BeanFactory { * Apply {@link BeanPostProcessor BeanPostProcessors} to the given existing bean * instance, invoking their {@code postProcessAfterInitialization} methods. * The returned bean instance may be a wrapper around the original. - * @param existingBean the new bean instance - * @param beanName the name of the bean + * @param existingBean the existing bean instance + * @param beanName the name of the bean, to be passed to it if necessary + * (only passed to {@link BeanPostProcessor BeanPostProcessors}) * @return the bean instance to use, either the original or a wrapped one * @throws BeansException if any post-processing failed * @see BeanPostProcessor#postProcessAfterInitialization @@ -315,8 +317,7 @@ public interface AutowireCapableBeanFactory extends BeanFactory { * including its bean name. * <p>This is effectively a variant of {@link #getBean(Class)} which preserves the * bean name of the matching instance. - * @param requiredType type the bean must match; can be an interface or superclass. - * {@code null} is disallowed. + * @param requiredType type the bean must match; can be an interface or superclass * @return the bean name plus bean instance * @throws NoSuchBeanDefinitionException if no matching bean was found * @throws NoUniqueBeanDefinitionException if more than one matching bean was found diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanExpressionContext.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanExpressionContext.java index 1da52f0e..11329995 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanExpressionContext.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanExpressionContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2018 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,7 +55,7 @@ public class BeanExpressionContext { if (this.beanFactory.containsBean(key)) { return this.beanFactory.getBean(key); } - else if (this.scope != null){ + else if (this.scope != null) { return this.scope.resolveContextualObject(key); } else { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/PreferencesPlaceholderConfigurer.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/PreferencesPlaceholderConfigurer.java index c8de0402..f1a21fbc 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/PreferencesPlaceholderConfigurer.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/PreferencesPlaceholderConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2018 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. @@ -115,7 +115,7 @@ public class PreferencesPlaceholderConfigurer extends PropertyPlaceholderConfigu */ protected String resolvePlaceholder(String path, String key, Preferences preferences) { if (path != null) { - // Do not create the node if it does not exist... + // Do not create the node if it does not exist... try { if (preferences.nodeExists(path)) { return preferences.node(path).get(key, null); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/PropertyOverrideConfigurer.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/PropertyOverrideConfigurer.java index 0acd5139..fcba1644 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/PropertyOverrideConfigurer.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/PropertyOverrideConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2018 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. @@ -64,6 +64,9 @@ import org.springframework.beans.factory.BeanInitializationException; */ public class PropertyOverrideConfigurer extends PropertyResourceConfigurer { + /** + * The default bean name separator. + */ public static final String DEFAULT_BEAN_NAME_SEPARATOR = "."; @@ -72,7 +75,7 @@ public class PropertyOverrideConfigurer extends PropertyResourceConfigurer { private boolean ignoreInvalidKeys = false; /** - * Contains names of beans that have overrides + * Contains names of beans that have overrides. */ private final Set<String> beanNames = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16)); @@ -129,7 +132,7 @@ public class PropertyOverrideConfigurer extends PropertyResourceConfigurer { "': expected 'beanName" + this.beanNameSeparator + "property'"); } String beanName = key.substring(0, separatorIndex); - String beanProperty = key.substring(separatorIndex+1); + String beanProperty = key.substring(separatorIndex + 1); this.beanNames.add(beanName); applyPropertyValue(factory, beanName, beanProperty, value); if (logger.isDebugEnabled()) { @@ -144,12 +147,14 @@ public class PropertyOverrideConfigurer extends PropertyResourceConfigurer { ConfigurableListableBeanFactory factory, String beanName, String property, String value) { BeanDefinition bd = factory.getBeanDefinition(beanName); - while (bd.getOriginatingBeanDefinition() != null) { + BeanDefinition bdToUse = bd; + while (bd != null) { + bdToUse = bd; bd = bd.getOriginatingBeanDefinition(); } PropertyValue pv = new PropertyValue(property, value); pv.setOptional(this.ignoreInvalidKeys); - bd.getPropertyValues().addPropertyValue(pv); + bdToUse.getPropertyValues().addPropertyValue(pv); } @@ -157,8 +162,7 @@ public class PropertyOverrideConfigurer extends PropertyResourceConfigurer { * Were there overrides for this bean? * Only valid after processing has occurred at least once. * @param beanName name of the bean to query status for - * @return whether there were property overrides for - * the named bean + * @return whether there were property overrides for the named bean */ public boolean hasPropertyOverridesFor(String beanName) { return this.beanNames.contains(beanName); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index 55d89dc8..94cb5eb6 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -955,7 +955,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac return null; } - Object instance = null; + Object instance; try { // Mark this bean as currently in creation, even if just partially. beforePrototypeCreation(beanName); @@ -1068,7 +1068,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } - if (mbd.getFactoryMethodName() != null) { + if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } @@ -1092,11 +1092,10 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac } } - // Need to determine the constructor... + // Candidate constructors for autowiring? Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); - if (ctors != null || - mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || - mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { + if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || + mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java index 1ce334fb..593fc663 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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. @@ -433,7 +433,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess */ @Override public boolean isSingleton() { - return SCOPE_SINGLETON.equals(scope) || SCOPE_DEFAULT.equals(scope); + return SCOPE_SINGLETON.equals(this.scope) || SCOPE_DEFAULT.equals(this.scope); } /** @@ -443,7 +443,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess */ @Override public boolean isPrototype() { - return SCOPE_PROTOTYPE.equals(scope); + return SCOPE_PROTOTYPE.equals(this.scope); } /** @@ -625,7 +625,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess * Return whether this bean has the specified qualifier. */ public boolean hasQualifier(String typeName) { - return this.qualifiers.keySet().contains(typeName); + return this.qualifiers.containsKey(typeName); } /** @@ -778,15 +778,15 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess /** * Return information about methods to be overridden by the IoC * container. This will be empty if there are no method overrides. - * Never returns {@code null}. + * <p>Never returns {@code null}. */ public MethodOverrides getMethodOverrides() { return this.methodOverrides; } /** - * Set the name of the initializer method. The default is {@code null} - * in which case there is no initializer method. + * Set the name of the initializer method. + * <p>The default is {@code null} in which case there is no initializer method. */ public void setInitMethodName(String initMethodName) { this.initMethodName = initMethodName; @@ -801,7 +801,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess /** * Specify whether or not the configured init method is the default. - * Default value is {@code false}. + * <p>The default value is {@code false}. * @see #setInitMethodName */ public void setEnforceInitMethod(boolean enforceInitMethod) { @@ -817,8 +817,8 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess } /** - * Set the name of the destroy method. The default is {@code null} - * in which case there is no destroy method. + * Set the name of the destroy method. + * <p>The default is {@code null} in which case there is no destroy method. */ public void setDestroyMethodName(String destroyMethodName) { this.destroyMethodName = destroyMethodName; @@ -833,7 +833,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess /** * Specify whether or not the configured destroy method is the default. - * Default value is {@code false}. + * <p>The default value is {@code false}. * @see #setDestroyMethodName */ public void setEnforceDestroyMethod(boolean enforceDestroyMethod) { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index 074478e0..41464ff0 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -574,7 +574,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto */ @Override public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) - throws NoSuchBeanDefinitionException{ + throws NoSuchBeanDefinitionException { A ann = null; Class<?> beanType = getType(beanName); @@ -586,7 +586,10 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto if (bd instanceof AbstractBeanDefinition) { AbstractBeanDefinition abd = (AbstractBeanDefinition) bd; if (abd.hasBeanClass()) { - ann = AnnotationUtils.findAnnotation(abd.getBeanClass(), annotationType); + Class<?> beanClass = abd.getBeanClass(); + if (beanClass != beanType) { + ann = AnnotationUtils.findAnnotation(beanClass, annotationType); + } } } } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/PropertiesBeanDefinitionReader.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/PropertiesBeanDefinitionReader.java index 454b2c35..6003b5a7 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/PropertiesBeanDefinitionReader.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/PropertiesBeanDefinitionReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -88,7 +88,7 @@ public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader public static final String SEPARATOR = "."; /** - * Special key to distinguish {@code owner.(class)=com.myapp.MyClass}- + * Special key to distinguish {@code owner.(class)=com.myapp.MyClass}. */ public static final String CLASS_KEY = "(class)"; @@ -300,10 +300,10 @@ public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader /** - * Register bean definitions contained in a Map, - * using all property keys (i.e. not filtering by prefix). - * @param map Map: name -> property (String or Object). Property values - * will be strings if coming from a Properties file etc. Property names + * Register bean definitions contained in a Map, using all property keys (i.e. not + * filtering by prefix). + * @param map a map of {@code name} to {@code property} (String or Object). Property + * values will be strings if coming from a Properties file etc. Property names * (keys) <b>must</b> be Strings. Class keys must be Strings. * @return the number of bean definitions found * @throws BeansException in case of loading or parsing errors @@ -316,8 +316,8 @@ public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader /** * Register bean definitions contained in a Map. * Ignore ineligible properties. - * @param map Map name -> property (String or Object). Property values - * will be strings if coming from a Properties file etc. Property names + * @param map a map of {@code name} to {@code property} (String or Object). Property + * values will be strings if coming from a Properties file etc. Property names * (keys) <b>must</b> be Strings. Class keys must be Strings. * @param prefix a filter within the keys in the map: e.g. 'beans.' * (can be empty or {@code null}) @@ -331,9 +331,9 @@ public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader /** * Register bean definitions contained in a Map. * Ignore ineligible properties. - * @param map Map name -> property (String or Object). Property values - * will be strings if coming from a Properties file etc. Property names - * (keys) <b>must</b> be strings. Class keys must be Strings. + * @param map a map of {@code name} to {@code property} (String or Object). Property + * values will be strings if coming from a Properties file etc. Property names + * (keys) <b>must</b> be Strings. Class keys must be Strings. * @param prefix a filter within the keys in the map: e.g. 'beans.' * (can be empty or {@code null}) * @param resourceDescription description of the resource that the @@ -393,9 +393,9 @@ public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader /** * Get all property values, given a prefix (which will be stripped) - * and add the bean they define to the factory with the given name + * and add the bean they define to the factory with the given name. * @param beanName name of the bean to define - * @param map Map containing string pairs + * @param map a Map containing string pairs * @param prefix prefix of each entry, which will be stripped * @param resourceDescription description of the resource that the * Map came from (for logging purposes) @@ -502,7 +502,7 @@ public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader * Reads the value of the entry. Correctly interprets bean references for * values that are prefixed with an asterisk. */ - private Object readValue(Map.Entry<? ,?> entry) { + private Object readValue(Map.Entry<?, ?> entry) { Object val = entry.getValue(); if (val instanceof String) { String strVal = (String) val; 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 f5aee86b..a07ae9e6 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 @@ -351,7 +351,7 @@ public class StaticListableBeanFactory implements ListableBeanFactory { @Override public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) - throws NoSuchBeanDefinitionException{ + throws NoSuchBeanDefinitionException { 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/BeansDtdResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeansDtdResolver.java index fe971fdc..0dc20f67 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeansDtdResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeansDtdResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2019 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,6 +16,7 @@ package org.springframework.beans.factory.xml; +import java.io.FileNotFoundException; import java.io.IOException; import org.apache.commons.logging.Log; @@ -27,7 +28,7 @@ import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; /** - * EntityResolver implementation for the Spring beans DTD, + * {@link EntityResolver} implementation for the Spring beans DTD, * to load the DTD from the Spring class path (or JAR file). * * <p>Fetches "spring-beans-2.0.dtd" from the class path resource @@ -57,6 +58,7 @@ public class BeansDtdResolver implements EntityResolver { logger.trace("Trying to resolve XML entity with public ID [" + publicId + "] and system ID [" + systemId + "]"); } + if (systemId != null && systemId.endsWith(DTD_EXTENSION)) { int lastPathSeparator = systemId.lastIndexOf('/'); int dtdNameStart = systemId.indexOf(DTD_NAME, lastPathSeparator); @@ -75,16 +77,15 @@ public class BeansDtdResolver implements EntityResolver { } return source; } - catch (IOException ex) { + catch (FileNotFoundException ex) { if (logger.isDebugEnabled()) { logger.debug("Could not resolve beans DTD [" + systemId + "]: not found in classpath", ex); } } - } } - // Use the default behavior -> download from website or wherever. + // Fall back to the parser's default behavior. return null; } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/DelegatingEntityResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/DelegatingEntityResolver.java index 019b9c16..00e51ad3 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/DelegatingEntityResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/DelegatingEntityResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2019 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. @@ -86,6 +86,8 @@ public class DelegatingEntityResolver implements EntityResolver { return this.schemaResolver.resolveEntity(publicId, systemId); } } + + // Fall back to the parser's default behavior. return null; } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/PluggableSchemaResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/PluggableSchemaResolver.java index 4798f0a7..e056539d 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/PluggableSchemaResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/PluggableSchemaResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,18 +37,18 @@ import org.springframework.util.CollectionUtils; * {@link EntityResolver} implementation that attempts to resolve schema URLs into * local {@link ClassPathResource classpath resources} using a set of mappings files. * - * <p>By default, this class will look for mapping files in the classpath using the pattern: - * {@code META-INF/spring.schemas} allowing for multiple files to exist on the - * classpath at any one time. + * <p>By default, this class will look for mapping files in the classpath using the + * pattern: {@code META-INF/spring.schemas} allowing for multiple files to exist on + * the classpath at any one time. * - * The format of {@code META-INF/spring.schemas} is a properties - * file where each line should be of the form {@code systemId=schema-location} - * where {@code schema-location} should also be a schema file in the classpath. - * Since systemId is commonly a URL, one must be careful to escape any ':' characters - * which are treated as delimiters in properties files. + * <p>The format of {@code META-INF/spring.schemas} is a properties file where each line + * should be of the form {@code systemId=schema-location} where {@code schema-location} + * should also be a schema file in the classpath. Since {@code systemId} is commonly a + * URL, one must be careful to escape any ':' characters which are treated as delimiters + * in properties files. * - * <p>The pattern for the mapping files can be overidden using the - * {@link #PluggableSchemaResolver(ClassLoader, String)} constructor + * <p>The pattern for the mapping files can be overridden using the + * {@link #PluggableSchemaResolver(ClassLoader, String)} constructor. * * @author Rob Harrop * @author Juergen Hoeller @@ -100,6 +100,7 @@ public class PluggableSchemaResolver implements EntityResolver { this.schemaMappingsLocation = schemaMappingsLocation; } + @Override public InputSource resolveEntity(String publicId, String systemId) throws IOException { if (logger.isTraceEnabled()) { @@ -109,6 +110,10 @@ public class PluggableSchemaResolver implements EntityResolver { if (systemId != null) { String resourceLocation = getSchemaMappings().get(systemId); + if (resourceLocation == null && systemId.startsWith("https:")) { + // Retrieve canonical http schema mapping even for https declaration + resourceLocation = getSchemaMappings().get("http:" + systemId.substring(6)); + } if (resourceLocation != null) { Resource resource = new ClassPathResource(resourceLocation, this.classLoader); try { @@ -127,6 +132,8 @@ public class PluggableSchemaResolver implements EntityResolver { } } } + + // Fall back to the parser's default behavior. return null; } @@ -165,7 +172,7 @@ public class PluggableSchemaResolver implements EntityResolver { @Override public String toString() { - return "EntityResolver using mappings " + getSchemaMappings(); + return "EntityResolver using schema mappings " + getSchemaMappings(); } } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/ResourceEntityResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/ResourceEntityResolver.java index c9108541..109bac6b 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/ResourceEntityResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/ResourceEntityResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2019 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. @@ -30,9 +30,9 @@ import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; /** - * EntityResolver implementation that tries to resolve entity references + * {@code EntityResolver} implementation that tries to resolve entity references * through a {@link org.springframework.core.io.ResourceLoader} (usually, - * relative to the resource base of an ApplicationContext), if applicable. + * relative to the resource base of an {@code ApplicationContext}), if applicable. * Extends {@link DelegatingEntityResolver} to also provide DTD and XSD lookup. * * <p>Allows to use standard XML entities to include XML snippets into an @@ -72,6 +72,7 @@ public class ResourceEntityResolver extends DelegatingEntityResolver { @Override public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { InputSource source = super.resolveEntity(publicId, systemId); + if (source == null && systemId != null) { String resourcePath = null; try { @@ -103,7 +104,27 @@ public class ResourceEntityResolver extends DelegatingEntityResolver { logger.debug("Found XML entity [" + systemId + "]: " + resource); } } + else if (systemId.endsWith(DTD_SUFFIX) || systemId.endsWith(XSD_SUFFIX)) { + // External dtd/xsd lookup via https even for canonical http declaration + String url = systemId; + if (url.startsWith("http:")) { + url = "https:" + url.substring(5); + } + try { + source = new InputSource(new URL(url).openStream()); + source.setPublicId(publicId); + source.setSystemId(systemId); + } + catch (IOException ex) { + if (logger.isDebugEnabled()) { + logger.debug("Could not resolve XML entity [" + systemId + "] through URL [" + url + "]", ex); + } + // Fall back to the parser's default behavior. + source = null; + } + } } + return source; } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/SimpleConstructorNamespaceHandler.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/SimpleConstructorNamespaceHandler.java index 420e10f2..20f4fb39 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/SimpleConstructorNamespaceHandler.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/SimpleConstructorNamespaceHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2018 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. @@ -116,7 +116,7 @@ public class SimpleConstructorNamespaceHandler implements NamespaceHandler { "Constructor argument '" + argName + "' specifies a negative index", attr); } - if (cvs.hasIndexedArgumentValue(index)){ + if (cvs.hasIndexedArgumentValue(index)) { parserContext.getReaderContext().error( "Constructor argument '" + argName + "' with index "+ index+" already defined using <constructor-arg>." + " Only one approach may be used per argument.", attr); @@ -128,7 +128,7 @@ public class SimpleConstructorNamespaceHandler implements NamespaceHandler { // no escaping -> ctr name else { String name = Conventions.attributeNameToPropertyName(argName); - if (containsArgWithName(name, cvs)){ + if (containsArgWithName(name, cvs)) { parserContext.getReaderContext().error( "Constructor argument '" + argName + "' already defined using <constructor-arg>." + " Only one approach may be used per argument.", attr); diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractJCacheOperation.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractJCacheOperation.java index 6db0afb8..98cb6dcb 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractJCacheOperation.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractJCacheOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ package org.springframework.cache.jcache.interceptor; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; @@ -32,8 +33,6 @@ import org.springframework.cache.interceptor.CacheResolver; import org.springframework.util.Assert; import org.springframework.util.ExceptionTypeFilter; -import static java.util.Arrays.*; - /** * A base {@link JCacheOperation} implementation. * @@ -50,24 +49,27 @@ abstract class AbstractJCacheOperation<A extends Annotation> implements JCacheOp /** - * Create a new instance. + * Construct a new {@code AbstractJCacheOperation}. * @param methodDetails the {@link CacheMethodDetails} related to the cached method * @param cacheResolver the cache resolver to resolve regular caches */ protected AbstractJCacheOperation(CacheMethodDetails<A> methodDetails, CacheResolver cacheResolver) { - Assert.notNull(methodDetails, "method details must not be null."); - Assert.notNull(cacheResolver, "cache resolver must not be null."); + Assert.notNull(methodDetails, "CacheMethodDetails must not be null"); + Assert.notNull(cacheResolver, "CacheResolver must not be null"); this.methodDetails = methodDetails; this.cacheResolver = cacheResolver; this.allParameterDetails = initializeAllParameterDetails(methodDetails.getMethod()); } - - /** - * Return the {@link ExceptionTypeFilter} to use to filter exceptions thrown while - * invoking the method. - */ - public abstract ExceptionTypeFilter getExceptionTypeFilter(); + private static List<CacheParameterDetail> initializeAllParameterDetails(Method method) { + int parameterCount = method.getParameterTypes().length; + List<CacheParameterDetail> result = new ArrayList<CacheParameterDetail>(parameterCount); + for (int i = 0; i < parameterCount; i++) { + CacheParameterDetail detail = new CacheParameterDetail(method, i); + result.add(detail); + } + return result; + } @Override @@ -113,12 +115,25 @@ abstract class AbstractJCacheOperation<A extends Annotation> implements JCacheOp return result.toArray(new CacheInvocationParameter[result.size()]); } + + /** + * Return the {@link ExceptionTypeFilter} to use to filter exceptions thrown while + * invoking the method. + * @see #createExceptionTypeFilter + */ + public abstract ExceptionTypeFilter getExceptionTypeFilter(); + + /** + * Convenience method for subclasses to create a specific {@code ExceptionTypeFilter}. + * @see #getExceptionTypeFilter() + */ protected ExceptionTypeFilter createExceptionTypeFilter( Class<? extends Throwable>[] includes, Class<? extends Throwable>[] excludes) { - return new ExceptionTypeFilter(asList(includes), asList(excludes), true); + return new ExceptionTypeFilter(Arrays.asList(includes), Arrays.asList(excludes), true); } + @Override public String toString() { return getOperationDescription().append("]").toString(); @@ -137,16 +152,9 @@ abstract class AbstractJCacheOperation<A extends Annotation> implements JCacheOp } - private static List<CacheParameterDetail> initializeAllParameterDetails(Method method) { - List<CacheParameterDetail> result = new ArrayList<CacheParameterDetail>(); - for (int i = 0; i < method.getParameterTypes().length; i++) { - CacheParameterDetail detail = new CacheParameterDetail(method, i); - result.add(detail); - } - return result; - } - - + /** + * Details for a single cache parameter. + */ protected static class CacheParameterDetail { private final Class<?> rawType; @@ -196,6 +204,9 @@ abstract class AbstractJCacheOperation<A extends Annotation> implements JCacheOp } + /** + * A single cache invocation parameter. + */ protected static class CacheInvocationParameterImpl implements CacheInvocationParameter { private final CacheParameterDetail detail; diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheOperation.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheOperation.java index 94a384dd..7a8a8475 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheOperation.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,9 +24,10 @@ import org.springframework.cache.interceptor.BasicOperation; import org.springframework.cache.interceptor.CacheResolver; /** - * Model the base of JSR-107 cache operation. - * <p>A cache operation can be statically cached as it does not contain - * any runtime operation of a specific cache invocation. + * Model the base of JSR-107 cache operation through an interface contract. + * + * <p>A cache operation can be statically cached as it does not contain any + * runtime operation of a specific cache invocation. * * @author Stephane Nicoll * @since 4.1 @@ -48,4 +49,4 @@ public interface JCacheOperation<A extends Annotation> extends BasicOperation, C */ CacheInvocationParameter[] getAllParameters(Object... values); -}
\ No newline at end of file +} diff --git a/spring-context/src/main/java/org/springframework/context/ResourceLoaderAware.java b/spring-context/src/main/java/org/springframework/context/ResourceLoaderAware.java index cf9edd71..672a2b37 100644 --- a/spring-context/src/main/java/org/springframework/context/ResourceLoaderAware.java +++ b/spring-context/src/main/java/org/springframework/context/ResourceLoaderAware.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2019 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. @@ -20,44 +20,44 @@ import org.springframework.beans.factory.Aware; import org.springframework.core.io.ResourceLoader; /** - * Interface to be implemented by any object that wishes to be notified of - * the <b>ResourceLoader</b> (typically the ApplicationContext) that it runs in. - * This is an alternative to a full ApplicationContext dependency via the - * ApplicationContextAware interface. + * Interface to be implemented by any object that wishes to be notified of the + * {@link ResourceLoader} (typically the ApplicationContext) that it runs in. + * This is an alternative to a full {@link ApplicationContext} dependency via + * the {@link org.springframework.context.ApplicationContextAware} interface. * - * <p>Note that Resource dependencies can also be exposed as bean properties - * of type Resource, populated via Strings with automatic type conversion by - * the bean factory. This removes the need for implementing any callback - * interface just for the purpose of accessing a specific file resource. + * <p>Note that {@link org.springframework.core.io.Resource} dependencies can also + * be exposed as bean properties of type {@code Resource}, populated via Strings + * with automatic type conversion by the bean factory. This removes the need for + * implementing any callback interface just for the purpose of accessing a + * specific file resource. * - * <p>You typically need a ResourceLoader when your application object has - * to access a variety of file resources whose names are calculated. A good - * strategy is to make the object use a DefaultResourceLoader but still - * implement ResourceLoaderAware to allow for overriding when running in an - * ApplicationContext. See ReloadableResourceBundleMessageSource for an example. + * <p>You typically need a {@link ResourceLoader} when your application object has to + * access a variety of file resources whose names are calculated. A good strategy is + * to make the object use a {@link org.springframework.core.io.DefaultResourceLoader} + * but still implement {@code ResourceLoaderAware} to allow for overriding when + * running in an {@code ApplicationContext}. See + * {@link org.springframework.context.support.ReloadableResourceBundleMessageSource} + * for an example. * - * <p>A passed-in ResourceLoader can also be checked for the - * <b>ResourcePatternResolver</b> interface and cast accordingly, to be able - * to resolve resource patterns into arrays of Resource objects. This will always - * work when running in an ApplicationContext (the context interface extends - * ResourcePatternResolver). Use a PathMatchingResourcePatternResolver as default. - * See also the {@code ResourcePatternUtils.getResourcePatternResolver} method. + * <p>A passed-in {@code ResourceLoader} can also be checked for the + * {@link org.springframework.core.io.support.ResourcePatternResolver} interface + * and cast accordingly, in order to resolve resource patterns into arrays of + * {@code Resource} objects. This will always work when running in an ApplicationContext + * (since the context interface extends the ResourcePatternResolver interface). Use a + * {@link org.springframework.core.io.support.PathMatchingResourcePatternResolver} as + * default; see also the {@code ResourcePatternUtils.getResourcePatternResolver} method. * - * <p>As alternative to a ResourcePatternResolver dependency, consider exposing - * bean properties of type Resource array, populated via pattern Strings with - * automatic type conversion by the bean factory. + * <p>As an alternative to a {@code ResourcePatternResolver} dependency, consider + * exposing bean properties of type {@code Resource} array, populated via pattern + * Strings with automatic type conversion by the bean factory at binding time. * * @author Juergen Hoeller * @author Chris Beams * @since 10.03.2004 * @see ApplicationContextAware - * @see org.springframework.beans.factory.InitializingBean * @see org.springframework.core.io.Resource + * @see org.springframework.core.io.ResourceLoader * @see org.springframework.core.io.support.ResourcePatternResolver - * @see org.springframework.core.io.support.ResourcePatternUtils#getResourcePatternResolver - * @see org.springframework.core.io.DefaultResourceLoader - * @see org.springframework.core.io.support.PathMatchingResourcePatternResolver - * @see org.springframework.context.support.ReloadableResourceBundleMessageSource */ public interface ResourceLoaderAware extends Aware { @@ -69,7 +69,7 @@ public interface ResourceLoaderAware extends Aware { * <p>Invoked after population of normal bean properties but before an init callback * like InitializingBean's {@code afterPropertiesSet} or a custom init-method. * Invoked before ApplicationContextAware's {@code setApplicationContext}. - * @param resourceLoader ResourceLoader object to be used by this object + * @param resourceLoader the ResourceLoader object to be used by this object * @see org.springframework.core.io.support.ResourcePatternResolver * @see org.springframework.core.io.support.ResourcePatternUtils#getResourcePatternResolver */ diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java index bf2b838f..98b3d601 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -85,9 +85,9 @@ import org.springframework.util.StringUtils; * another using the {@link Import} annotation). * * <p>This class helps separate the concern of parsing the structure of a Configuration - * class from the concern of registering BeanDefinition objects based on the - * content of that model (with the exception of {@code @ComponentScan} annotations which - * need to be registered immediately). + * class from the concern of registering BeanDefinition objects based on the content of + * that model (with the exception of {@code @ComponentScan} annotations which need to be + * registered immediately). * * <p>This ASM-based implementation avoids reflection and eager class loading in order to * interoperate effectively with lazy class loading in a Spring ApplicationContext. @@ -814,7 +814,7 @@ class ConfigurationClassParser { return new AssignableTypeFilter(clazz).match((MetadataReader) this.source, metadataReaderFactory); } - public ConfigurationClass asConfigClass(ConfigurationClass importedBy) throws IOException { + public ConfigurationClass asConfigClass(ConfigurationClass importedBy) { if (this.source instanceof Class) { return new ConfigurationClass((Class<?>) this.source, importedBy); } @@ -882,7 +882,7 @@ class ConfigurationClassParser { return result; } - public Set<SourceClass> getAnnotations() throws IOException { + public Set<SourceClass> getAnnotations() { Set<SourceClass> result = new LinkedHashSet<SourceClass>(); for (String className : this.metadata.getAnnotationTypes()) { try { diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java index 5ec6846a..abcb5978 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -428,7 +428,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo } @Override - public Object postProcessBeforeInitialization(Object bean, String beanName) { + public Object postProcessBeforeInitialization(Object bean, String beanName) { if (bean instanceof ImportAware) { ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class); AnnotationMetadata importingClass = ir.getImportingClassFor(bean.getClass().getSuperclass().getName()); diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ImportBeanDefinitionRegistrar.java b/spring-context/src/main/java/org/springframework/context/annotation/ImportBeanDefinitionRegistrar.java index 1dce3d41..49af978b 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ImportBeanDefinitionRegistrar.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ImportBeanDefinitionRegistrar.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2019 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. @@ -58,7 +58,6 @@ public interface ImportBeanDefinitionRegistrar { * @param importingClassMetadata annotation metadata of the importing class * @param registry current bean definition registry */ - public void registerBeanDefinitions( - AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry); + void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry); } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ImportSelector.java b/spring-context/src/main/java/org/springframework/context/annotation/ImportSelector.java index c684426f..973fca6f 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ImportSelector.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ImportSelector.java @@ -20,12 +20,12 @@ import org.springframework.core.type.AnnotationMetadata; /** * Interface to be implemented by types that determine which @{@link Configuration} - * class(es) should be imported based on a given selection criteria, usually one or more - * annotation attributes. + * class(es) should be imported based on a given selection criteria, usually one or + * more annotation attributes. * * <p>An {@link ImportSelector} may implement any of the following - * {@link org.springframework.beans.factory.Aware Aware} interfaces, and their respective - * methods will be called prior to {@link #selectImports}: + * {@link org.springframework.beans.factory.Aware Aware} interfaces, + * and their respective methods will be called prior to {@link #selectImports}: * <ul> * <li>{@link org.springframework.context.EnvironmentAware EnvironmentAware}</li> * <li>{@link org.springframework.beans.factory.BeanFactoryAware BeanFactoryAware}</li> @@ -33,10 +33,10 @@ import org.springframework.core.type.AnnotationMetadata; * <li>{@link org.springframework.context.ResourceLoaderAware ResourceLoaderAware}</li> * </ul> * - * <p>ImportSelectors are usually processed in the same way as regular {@code @Import} - * annotations, however, it is also possible to defer selection of imports until all - * {@code @Configuration} classes have been processed (see {@link DeferredImportSelector} - * for details). + * <p>{@code ImportSelector} implementations are usually processed in the same way + * as regular {@code @Import} annotations, however, it is also possible to defer + * selection of imports until all {@code @Configuration} classes have been processed + * (see {@link DeferredImportSelector} for details). * * @author Chris Beams * @since 3.1 diff --git a/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java b/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java index ef92882d..19d3dedf 100644 --- a/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java +++ b/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -257,7 +257,7 @@ public abstract class AbstractApplicationEventMulticaster * type before trying to instantiate it. * <p>If this method returns {@code true} for a given listener as a first pass, * the listener instance will get retrieved and fully evaluated through a - * {@link #supportsEvent(ApplicationListener,ResolvableType, Class)} call afterwards. + * {@link #supportsEvent(ApplicationListener, ResolvableType, Class)} call afterwards. * @param listenerType the listener's type as determined by the BeanFactory * @param eventType the event type to check * @return whether the given listener should be included in the candidates diff --git a/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java b/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java index 9a58e921..1e12aec7 100644 --- a/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java +++ b/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -93,7 +93,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe this.declaredEventTypes = resolveDeclaredEventTypes(method, ann); this.condition = (ann != null ? ann.condition() : null); - this.order = resolveOrder(method); + this.order = resolveOrder(targetMethod); this.methodKey = new AnnotatedElementKey(method, targetClass); } @@ -186,9 +186,9 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe /** * Resolve the method arguments to use for the specified {@link ApplicationEvent}. - * <p>These arguments will be used to invoke the method handled by this instance. Can - * return {@code null} to indicate that no suitable arguments could be resolved and - * therefore the method should not be invoked at all for the specified event. + * <p>These arguments will be used to invoke the method handled by this instance. + * Can return {@code null} to indicate that no suitable arguments could be resolved + * and therefore the method should not be invoked at all for the specified event. */ protected Object[] resolveArguments(ApplicationEvent event) { ResolvableType declaredEventType = getResolvableType(event); @@ -198,13 +198,15 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe if (this.method.getParameterTypes().length == 0) { return new Object[0]; } - if (!ApplicationEvent.class.isAssignableFrom(declaredEventType.getRawClass()) && + Class<?> eventClass = declaredEventType.getRawClass(); + if ((eventClass == null || !ApplicationEvent.class.isAssignableFrom(eventClass)) && event instanceof PayloadApplicationEvent) { - return new Object[] {((PayloadApplicationEvent) event).getPayload()}; - } - else { - return new Object[] {event}; + Object payload = ((PayloadApplicationEvent) event).getPayload(); + if (eventClass == null || eventClass.isInstance(payload)) { + return new Object[] {payload}; + } } + return new Object[] {event}; } protected void handleResult(Object result) { diff --git a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java index 94f0c801..a40f6632 100644 --- a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -91,24 +91,24 @@ import org.springframework.util.StringValueResolver; * to detect special beans defined in its internal bean factory: * Therefore, this class automatically registers * {@link org.springframework.beans.factory.config.BeanFactoryPostProcessor BeanFactoryPostProcessors}, - * {@link org.springframework.beans.factory.config.BeanPostProcessor BeanPostProcessors} + * {@link org.springframework.beans.factory.config.BeanPostProcessor BeanPostProcessors}, * and {@link org.springframework.context.ApplicationListener ApplicationListeners} * which are defined as beans in the context. * * <p>A {@link org.springframework.context.MessageSource} may also be supplied * as a bean in the context, with the name "messageSource"; otherwise, message * resolution is delegated to the parent context. Furthermore, a multicaster - * for application events can be supplied as "applicationEventMulticaster" bean + * for application events can be supplied as an "applicationEventMulticaster" bean * of type {@link org.springframework.context.event.ApplicationEventMulticaster} * in the context; otherwise, a default multicaster of type * {@link org.springframework.context.event.SimpleApplicationEventMulticaster} will be used. * - * <p>Implements resource loading through extending + * <p>Implements resource loading by extending * {@link org.springframework.core.io.DefaultResourceLoader}. * Consequently treats non-URL resource paths as class path resources * (supporting full class path resource names that include the package path, * e.g. "mypackage/myresource.dat"), unless the {@link #getResourceByPath} - * method is overwritten in a subclass. + * method is overridden in a subclass. * * @author Rod Johnson * @author Juergen Hoeller @@ -381,7 +381,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader else { applicationEvent = new PayloadApplicationEvent<Object>(this, event); if (eventType == null) { - eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType(); + eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType(); } } @@ -478,7 +478,6 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader this.beanFactoryPostProcessors.add(postProcessor); } - /** * Return the list of BeanFactoryPostProcessors that will get applied * to the internal BeanFactory. @@ -575,6 +574,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader * active flag as well as performing any initialization of property sources. */ protected void prepareRefresh() { + // Switch to active. this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); @@ -583,10 +583,10 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader logger.info("Refreshing " + this); } - // Initialize any placeholder property sources in the context environment + // Initialize any placeholder property sources in the context environment. initPropertySources(); - // Validate that all properties marked as required are resolvable + // Validate that all properties marked as required are resolvable: // see ConfigurablePropertyResolver#setRequiredProperties getEnvironment().validateRequiredProperties(); @@ -695,7 +695,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader } /** - * Instantiate and invoke all registered BeanPostProcessor beans, + * Instantiate and register all BeanPostProcessor beans, * respecting explicit order if given. * <p>Must be called before any instantiation of application beans. */ @@ -979,6 +979,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader * @see #registerShutdownHook() */ protected void doClose() { + // Check whether an actual close attempt is necessary... if (this.active.get() && this.closed.compareAndSet(false, true)) { if (logger.isInfoEnabled()) { logger.info("Closing " + this); @@ -1013,6 +1014,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader // Let subclasses do some final clean-up if they wish... onClose(); + // Switch to inactive. this.active.set(false); } } @@ -1212,7 +1214,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader @Override public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) - throws NoSuchBeanDefinitionException{ + throws NoSuchBeanDefinitionException { assertBeanFactoryActive(); return getBeanFactory().findAnnotationOnBean(beanName, annotationType); diff --git a/spring-context/src/main/java/org/springframework/context/support/ResourceBundleMessageSource.java b/spring-context/src/main/java/org/springframework/context/support/ResourceBundleMessageSource.java index 48250948..f6710d44 100644 --- a/spring-context/src/main/java/org/springframework/context/support/ResourceBundleMessageSource.java +++ b/spring-context/src/main/java/org/springframework/context/support/ResourceBundleMessageSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -292,7 +292,7 @@ public class ResourceBundleMessageSource extends AbstractResourceBasedMessageSou try { return bundle.getString(key); } - catch (MissingResourceException ex){ + catch (MissingResourceException ex) { // Assume key not found for some other reason // -> do NOT throw the exception to allow for checking parent message source. } diff --git a/spring-context/src/main/java/org/springframework/context/support/SimpleThreadScope.java b/spring-context/src/main/java/org/springframework/context/support/SimpleThreadScope.java index 9dbd8a65..e9989a38 100644 --- a/spring-context/src/main/java/org/springframework/context/support/SimpleThreadScope.java +++ b/spring-context/src/main/java/org/springframework/context/support/SimpleThreadScope.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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,14 +35,13 @@ import org.springframework.core.NamedThreadLocal; * or through a {@link org.springframework.beans.factory.config.CustomScopeConfigurer} bean. * * <p>{@code SimpleThreadScope} <em>does not clean up any objects</em> associated with it. - * As such, it is typically preferable to use - * {@link org.springframework.web.context.request.RequestScope RequestScope} - * in web environments. + * It is therefore typically preferable to use a request-bound scope implementation such + * as {@code org.springframework.web.context.request.RequestScope} in web environments, + * implementing the full lifecycle for scoped attributes (including reliable destruction). * - * <p>For an implementation of a thread-based {@code Scope} with support for - * destruction callbacks, refer to the - * <a href="http://www.springbyexample.org/examples/custom-thread-scope-module.html"> -* Spring by Example Custom Thread Scope Module</a>. + * <p>For an implementation of a thread-based {@code Scope} with support for destruction + * callbacks, refer to + * <a href="http://www.springbyexample.org/examples/custom-thread-scope-module.html">Spring by Example</a>. * * <p>Thanks to Eugene Kuleshov for submitting the original prototype for a thread scope! * diff --git a/spring-context/src/test/java/org/springframework/beans/factory/xml/XmlBeanFactoryTests.java b/spring-context/src/test/java/org/springframework/beans/factory/xml/XmlBeanFactoryTests.java index 6543e365..25c3ab13 100644 --- a/spring-context/src/test/java/org/springframework/beans/factory/xml/XmlBeanFactoryTests.java +++ b/spring-context/src/test/java/org/springframework/beans/factory/xml/XmlBeanFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -129,16 +129,16 @@ public class XmlBeanFactoryTests { return new ClassPathResource(CLASSNAME + suffix, CLASS); } - /* SPR-2368 */ - @Test - public void testCollectionsReferredToAsRefLocals() throws Exception { + + @Test // SPR-2368 + public void testCollectionsReferredToAsRefLocals() { DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(factory).loadBeanDefinitions(COLLECTIONS_XSD_CONTEXT); factory.preInstantiateSingletons(); } @Test - public void testRefToSeparatePrototypeInstances() throws Exception { + public void testRefToSeparatePrototypeInstances() { DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf); reader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_NONE); @@ -157,7 +157,7 @@ public class XmlBeanFactoryTests { } @Test - public void testRefToSingleton() throws Exception { + public void testRefToSingleton() { DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf); reader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_NONE); @@ -313,7 +313,7 @@ public class XmlBeanFactoryTests { } @Test - public void testInheritanceFromParentFactoryPrototype() throws Exception { + public void testInheritanceFromParentFactoryPrototype() { DefaultListableBeanFactory parent = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(parent).loadBeanDefinitions(PARENT_CONTEXT); DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent); @@ -329,7 +329,7 @@ public class XmlBeanFactoryTests { } @Test - public void testInheritanceWithDifferentClass() throws Exception { + public void testInheritanceWithDifferentClass() { DefaultListableBeanFactory parent = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(parent).loadBeanDefinitions(PARENT_CONTEXT); DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent); @@ -344,7 +344,7 @@ public class XmlBeanFactoryTests { } @Test - public void testInheritanceWithClass() throws Exception { + public void testInheritanceWithClass() { DefaultListableBeanFactory parent = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(parent).loadBeanDefinitions(PARENT_CONTEXT); DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent); @@ -359,7 +359,7 @@ public class XmlBeanFactoryTests { } @Test - public void testPrototypeInheritanceFromParentFactoryPrototype() throws Exception { + public void testPrototypeInheritanceFromParentFactoryPrototype() { DefaultListableBeanFactory parent = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(parent).loadBeanDefinitions(PARENT_CONTEXT); DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent); @@ -379,7 +379,7 @@ public class XmlBeanFactoryTests { } @Test - public void testPrototypeInheritanceFromParentFactorySingleton() throws Exception { + public void testPrototypeInheritanceFromParentFactorySingleton() { DefaultListableBeanFactory parent = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(parent).loadBeanDefinitions(PARENT_CONTEXT); DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent); @@ -439,7 +439,7 @@ public class XmlBeanFactoryTests { } @Test - public void testDependenciesMaterializeThis() throws Exception { + public void testDependenciesMaterializeThis() { DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(DEP_MATERIALIZE_CONTEXT); @@ -458,7 +458,7 @@ public class XmlBeanFactoryTests { } @Test - public void testChildOverridesParentBean() throws Exception { + public void testChildOverridesParentBean() { DefaultListableBeanFactory parent = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(parent).loadBeanDefinitions(PARENT_CONTEXT); DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent); @@ -477,7 +477,7 @@ public class XmlBeanFactoryTests { * If a singleton does this the factory will fail to load. */ @Test - public void testBogusParentageFromParentFactory() throws Exception { + public void testBogusParentageFromParentFactory() { DefaultListableBeanFactory parent = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(parent).loadBeanDefinitions(PARENT_CONTEXT); DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent); @@ -488,7 +488,7 @@ public class XmlBeanFactoryTests { } catch (BeanDefinitionStoreException ex) { // check exception message contains the name - assertTrue(ex.getMessage().indexOf("bogusParent") != -1); + assertTrue(ex.getMessage().contains("bogusParent")); assertTrue(ex.getCause() instanceof NoSuchBeanDefinitionException); } } @@ -499,7 +499,7 @@ public class XmlBeanFactoryTests { * instances even if derived from a prototype */ @Test - public void testSingletonInheritsFromParentFactoryPrototype() throws Exception { + public void testSingletonInheritsFromParentFactoryPrototype() { DefaultListableBeanFactory parent = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(parent).loadBeanDefinitions(PARENT_CONTEXT); DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent); @@ -664,7 +664,7 @@ public class XmlBeanFactoryTests { } @Test - public void testInitMethodIsInvoked() throws Exception { + public void testInitMethodIsInvoked() { DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(INITIALIZERS_CONTEXT); DoubleInitializer in = (DoubleInitializer) xbf.getBean("init-method1"); @@ -684,14 +684,14 @@ public class XmlBeanFactoryTests { fail(); } catch (BeanCreationException ex) { - assertTrue(ex.getResourceDescription().indexOf("initializers.xml") != -1); + assertTrue(ex.getResourceDescription().contains("initializers.xml")); assertEquals("init-method2", ex.getBeanName()); assertTrue(ex.getCause() instanceof IOException); } } @Test - public void testNoSuchInitMethod() throws Exception { + public void testNoSuchInitMethod() { DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(INITIALIZERS_CONTEXT); try { @@ -700,9 +700,9 @@ public class XmlBeanFactoryTests { } catch (FatalBeanException ex) { // check message is helpful - assertTrue(ex.getMessage().indexOf("initializers.xml") != -1); - assertTrue(ex.getMessage().indexOf("init-method3") != -1); - assertTrue(ex.getMessage().indexOf("init") != -1); + assertTrue(ex.getMessage().contains("initializers.xml")); + assertTrue(ex.getMessage().contains("init-method3")); + assertTrue(ex.getMessage().contains("init")); } } @@ -710,7 +710,7 @@ public class XmlBeanFactoryTests { * Check that InitializingBean method is called first. */ @Test - public void testInitializingBeanAndInitMethod() throws Exception { + public void testInitializingBeanAndInitMethod() { InitAndIB.constructed = false; DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(INITIALIZERS_CONTEXT); @@ -731,7 +731,7 @@ public class XmlBeanFactoryTests { * Check that InitializingBean method is not called twice. */ @Test - public void testInitializingBeanAndSameInitMethod() throws Exception { + public void testInitializingBeanAndSameInitMethod() { InitAndIB.constructed = false; DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(INITIALIZERS_CONTEXT); @@ -749,7 +749,7 @@ public class XmlBeanFactoryTests { } @Test - public void testDefaultLazyInit() throws Exception { + public void testDefaultLazyInit() { InitAndIB.constructed = false; DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(DEFAULT_LAZY_CONTEXT); @@ -765,13 +765,13 @@ public class XmlBeanFactoryTests { } @Test(expected = BeanDefinitionStoreException.class) - public void noSuchXmlFile() throws Exception { + public void noSuchXmlFile() { DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(MISSING_CONTEXT); } @Test(expected = BeanDefinitionStoreException.class) - public void invalidXmlFile() throws Exception { + public void invalidXmlFile() { DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(INVALID_CONTEXT); } @@ -825,7 +825,7 @@ public class XmlBeanFactoryTests { } @Test - public void testAutowire() throws Exception { + public void testAutowire() { DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(AUTOWIRE_CONTEXT); TestBean spouse = new TestBean("kerry", 0); @@ -834,7 +834,7 @@ public class XmlBeanFactoryTests { } @Test - public void testAutowireWithParent() throws Exception { + public void testAutowireWithParent() { DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(AUTOWIRE_CONTEXT); DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(); @@ -847,7 +847,7 @@ public class XmlBeanFactoryTests { doTestAutowire(xbf); } - private void doTestAutowire(DefaultListableBeanFactory xbf) throws Exception { + private void doTestAutowire(DefaultListableBeanFactory xbf) { DependenciesBean rod1 = (DependenciesBean) xbf.getBean("rod1"); TestBean kerry = (TestBean) xbf.getBean("spouse"); // should have been autowired @@ -896,7 +896,7 @@ public class XmlBeanFactoryTests { } @Test - public void testAutowireWithDefault() throws Exception { + public void testAutowireWithDefault() { DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(DEFAULT_AUTOWIRE_CONTEXT); @@ -919,7 +919,7 @@ public class XmlBeanFactoryTests { } @Test - public void testAutowireByConstructor() throws Exception { + public void testAutowireByConstructor() { DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT); ConstructorDependenciesBean rod1 = (ConstructorDependenciesBean) xbf.getBean("rod1"); @@ -957,7 +957,7 @@ public class XmlBeanFactoryTests { } @Test - public void testAutowireByConstructorWithSimpleValues() throws Exception { + public void testAutowireByConstructorWithSimpleValues() { DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT); @@ -995,7 +995,7 @@ public class XmlBeanFactoryTests { xbf.getBean("rod2Accessor"); } catch (BeanCreationException ex) { - assertTrue(ex.toString().indexOf("touchy") != -1); + assertTrue(ex.toString().contains("touchy")); ex.printStackTrace(); assertNull(ex.getRelatedCauses()); } @@ -1075,14 +1075,14 @@ public class XmlBeanFactoryTests { } @Test(expected = BeanCreationException.class) - public void throwsExceptionOnTooManyArguments() throws Exception { + public void throwsExceptionOnTooManyArguments() { DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT); xbf.getBean("rod7", ConstructorDependenciesBean.class); } @Test(expected = UnsatisfiedDependencyException.class) - public void throwsExceptionOnAmbiguousResolution() throws Exception { + public void throwsExceptionOnAmbiguousResolution() { DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT); xbf.getBean("rod8", ConstructorDependenciesBean.class); @@ -1176,7 +1176,7 @@ public class XmlBeanFactoryTests { fail("Must have thrown a CannotLoadBeanClassException"); } catch (CannotLoadBeanClassException ex) { - assertTrue(ex.getResourceDescription().indexOf("classNotFound.xml") != -1); + assertTrue(ex.getResourceDescription().contains("classNotFound.xml")); assertTrue(ex.getCause() instanceof ClassNotFoundException); } } @@ -1428,12 +1428,12 @@ public class XmlBeanFactoryTests { } catch (BeanDefinitionStoreException ex) { // Check that the bogus method name was included in the error message - assertTrue("Bogus method name correctly reported", ex.getMessage().indexOf("bogusMethod") != -1); + assertTrue("Bogus method name correctly reported", ex.getMessage().contains("bogusMethod")); } } @Test - public void serializableMethodReplacerAndSuperclass() throws Exception { + public void serializableMethodReplacerAndSuperclass() throws IOException { DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf); reader.loadBeanDefinitions(DELEGATION_OVERRIDES_CONTEXT); @@ -1632,7 +1632,7 @@ public class XmlBeanFactoryTests { } @Test - public void testWithDuplicateName() throws Exception { + public void testWithDuplicateName() { DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); try { new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(TEST_WITH_DUP_NAMES_CONTEXT); @@ -1644,7 +1644,7 @@ public class XmlBeanFactoryTests { } @Test - public void testWithDuplicateNameInAlias() throws Exception { + public void testWithDuplicateNameInAlias() { DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); try { new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(TEST_WITH_DUP_NAME_IN_ALIAS_CONTEXT); diff --git a/spring-context/src/test/java/org/springframework/context/config/ContextNamespaceHandlerTests.java b/spring-context/src/test/java/org/springframework/context/config/ContextNamespaceHandlerTests.java index bf106be7..abfb143f 100644 --- a/spring-context/src/test/java/org/springframework/context/config/ContextNamespaceHandlerTests.java +++ b/spring-context/src/test/java/org/springframework/context/config/ContextNamespaceHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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,7 +48,7 @@ public class ContextNamespaceHandlerTests { @Test - public void propertyPlaceholder() throws Exception { + public void propertyPlaceholder() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext( "contextNamespaceHandlerTests-replace.xml", getClass()); assertEquals("bar", applicationContext.getBean("string")); @@ -56,7 +56,7 @@ public class ContextNamespaceHandlerTests { } @Test - public void propertyPlaceholderSystemProperties() throws Exception { + public void propertyPlaceholderSystemProperties() { String value = System.setProperty("foo", "spam"); try { ApplicationContext applicationContext = new ClassPathXmlApplicationContext( @@ -72,7 +72,7 @@ public class ContextNamespaceHandlerTests { } @Test - public void propertyPlaceholderEnvironmentProperties() throws Exception { + public void propertyPlaceholderEnvironmentProperties() { MockEnvironment env = new MockEnvironment().withProperty("foo", "spam"); GenericXmlApplicationContext applicationContext = new GenericXmlApplicationContext(); applicationContext.setEnvironment(env); @@ -83,7 +83,7 @@ public class ContextNamespaceHandlerTests { } @Test - public void propertyPlaceholderLocation() throws Exception { + public void propertyPlaceholderLocation() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext( "contextNamespaceHandlerTests-location.xml", getClass()); assertEquals("bar", applicationContext.getBean("foo")); @@ -92,7 +92,7 @@ public class ContextNamespaceHandlerTests { } @Test - public void propertyPlaceholderLocationWithSystemPropertyForOneLocation() throws Exception { + public void propertyPlaceholderLocationWithSystemPropertyForOneLocation() { System.setProperty("properties", "classpath*:/org/springframework/context/config/test-*.properties"); try { @@ -108,7 +108,7 @@ public class ContextNamespaceHandlerTests { } @Test - public void propertyPlaceholderLocationWithSystemPropertyForMultipleLocations() throws Exception { + public void propertyPlaceholderLocationWithSystemPropertyForMultipleLocations() { System.setProperty("properties", "classpath*:/org/springframework/context/config/test-*.properties," + "classpath*:/org/springframework/context/config/empty-*.properties," + @@ -126,7 +126,7 @@ public class ContextNamespaceHandlerTests { } @Test - public void propertyPlaceholderLocationWithSystemPropertyMissing() throws Exception { + public void propertyPlaceholderLocationWithSystemPropertyMissing() { try { ApplicationContext applicationContext = new ClassPathXmlApplicationContext( "contextNamespaceHandlerTests-location-placeholder.xml", getClass()); @@ -140,7 +140,7 @@ public class ContextNamespaceHandlerTests { } @Test - public void propertyPlaceholderIgnored() throws Exception { + public void propertyPlaceholderIgnored() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext( "contextNamespaceHandlerTests-replace-ignore.xml", getClass()); assertEquals("${bar}", applicationContext.getBean("string")); @@ -148,7 +148,7 @@ public class ContextNamespaceHandlerTests { } @Test - public void propertyOverride() throws Exception { + public void propertyOverride() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext( "contextNamespaceHandlerTests-override.xml", getClass()); Date date = (Date) applicationContext.getBean("date"); diff --git a/spring-context/src/test/java/org/springframework/context/event/EventPublicationInterceptorTests.java b/spring-context/src/test/java/org/springframework/context/event/EventPublicationInterceptorTests.java index 6437ac57..dc298c22 100644 --- a/spring-context/src/test/java/org/springframework/context/event/EventPublicationInterceptorTests.java +++ b/spring-context/src/test/java/org/springframework/context/event/EventPublicationInterceptorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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. @@ -49,14 +49,14 @@ public class EventPublicationInterceptorTests { this.publisher = mock(ApplicationEventPublisher.class); } - @Test(expected=IllegalArgumentException.class) + @Test(expected = IllegalArgumentException.class) public void testWithNoApplicationEventClassSupplied() throws Exception { EventPublicationInterceptor interceptor = new EventPublicationInterceptor(); interceptor.setApplicationEventPublisher(this.publisher); interceptor.afterPropertiesSet(); } - @Test(expected=IllegalArgumentException.class) + @Test(expected = IllegalArgumentException.class) public void testWithNonApplicationEventClassSupplied() throws Exception { EventPublicationInterceptor interceptor = new EventPublicationInterceptor(); interceptor.setApplicationEventPublisher(this.publisher); @@ -64,7 +64,7 @@ public class EventPublicationInterceptorTests { interceptor.afterPropertiesSet(); } - @Test(expected=IllegalArgumentException.class) + @Test(expected = IllegalArgumentException.class) public void testWithAbstractStraightApplicationEventClassSupplied() throws Exception { EventPublicationInterceptor interceptor = new EventPublicationInterceptor(); interceptor.setApplicationEventPublisher(this.publisher); @@ -72,7 +72,7 @@ public class EventPublicationInterceptorTests { interceptor.afterPropertiesSet(); } - @Test(expected=IllegalArgumentException.class) + @Test(expected = IllegalArgumentException.class) public void testWithApplicationEventClassThatDoesntExposeAValidCtor() throws Exception { EventPublicationInterceptor interceptor = new EventPublicationInterceptor(); interceptor.setApplicationEventPublisher(this.publisher); @@ -129,7 +129,7 @@ public class EventPublicationInterceptorTests { public static class FactoryBeanTestListener extends TestListener implements FactoryBean<Object> { @Override - public Object getObject() throws Exception { + public Object getObject() { return "test"; } diff --git a/spring-context/src/test/java/org/springframework/context/event/PayloadApplicationEventTests.java b/spring-context/src/test/java/org/springframework/context/event/PayloadApplicationEventTests.java new file mode 100644 index 00000000..1b1100ba --- /dev/null +++ b/spring-context/src/test/java/org/springframework/context/event/PayloadApplicationEventTests.java @@ -0,0 +1,69 @@ +/* + * Copyright 2002-2019 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.context.event; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.PayloadApplicationEvent; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.stereotype.Component; + +import static org.junit.Assert.*; + +/** + * @author Juergen Hoeller + */ +public class PayloadApplicationEventTests { + + @Test + public void testEventClassWithInterface() { + ApplicationContext ac = new AnnotationConfigApplicationContext(AuditableListener.class); + AuditablePayloadEvent event = new AuditablePayloadEvent<>(this, "xyz"); + ac.publishEvent(event); + assertTrue(ac.getBean(AuditableListener.class).events.contains(event)); + } + + + public interface Auditable { + } + + + @SuppressWarnings("serial") + public static class AuditablePayloadEvent<T> extends PayloadApplicationEvent<T> implements Auditable { + + public AuditablePayloadEvent(Object source, T payload) { + super(source, payload); + } + } + + + @Component + public static class AuditableListener { + + public final List<Auditable> events = new ArrayList<>(); + + @EventListener + public void onEvent(Auditable event) { + events.add(event); + } + } + +} diff --git a/spring-context/src/test/resources/org/springframework/beans/factory/xml/XmlBeanFactoryTests-resource.xml b/spring-context/src/test/resources/org/springframework/beans/factory/xml/XmlBeanFactoryTests-resource.xml index a48a3267..d03cdec6 100644 --- a/spring-context/src/test/resources/org/springframework/beans/factory/xml/XmlBeanFactoryTests-resource.xml +++ b/spring-context/src/test/resources/org/springframework/beans/factory/xml/XmlBeanFactoryTests-resource.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> +<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "https://www.springframework.org/dtd/spring-beans-2.0.dtd"> <beans> diff --git a/spring-context/src/test/resources/org/springframework/context/config/contextNamespaceHandlerTests-simple.xml b/spring-context/src/test/resources/org/springframework/context/config/contextNamespaceHandlerTests-simple.xml index 42bd4335..b8f2aa88 100644 --- a/spring-context/src/test/resources/org/springframework/context/config/contextNamespaceHandlerTests-simple.xml +++ b/spring-context/src/test/resources/org/springframework/context/config/contextNamespaceHandlerTests-simple.xml @@ -2,8 +2,8 @@ <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" - xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd - http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> + xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-2.5.xsd + http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context-3.1.xsd"> <context:property-placeholder/> diff --git a/spring-core/src/main/java/org/springframework/core/AttributeAccessor.java b/spring-core/src/main/java/org/springframework/core/AttributeAccessor.java index 27130bce..af621349 100644 --- a/spring-core/src/main/java/org/springframework/core/AttributeAccessor.java +++ b/spring-core/src/main/java/org/springframework/core/AttributeAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ package org.springframework.core; public interface AttributeAccessor { /** - * Set the attribute defined by {@code name} to the supplied {@code value}. + * Set the attribute defined by {@code name} to the supplied {@code value}. * If {@code value} is {@code null}, the attribute is {@link #removeAttribute removed}. * <p>In general, users should take care to prevent overlaps with other * metadata attributes by using fully-qualified names, perhaps using diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/ConversionUtils.java b/spring-core/src/main/java/org/springframework/core/convert/support/ConversionUtils.java index 3475f76e..27a92c5a 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/ConversionUtils.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/ConversionUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -20,6 +20,7 @@ import org.springframework.core.convert.ConversionFailedException; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.GenericConverter; +import org.springframework.util.ClassUtils; /** * Internal utilities for the conversion package. @@ -59,7 +60,7 @@ abstract class ConversionUtils { // yes return true; } - if (sourceElementType.getType().isAssignableFrom(targetElementType.getType())) { + if (ClassUtils.isAssignable(sourceElementType.getType(), targetElementType.getType())) { // maybe return true; } diff --git a/spring-core/src/main/java/org/springframework/core/io/support/ResourcePatternUtils.java b/spring-core/src/main/java/org/springframework/core/io/support/ResourcePatternUtils.java index e9721a95..eb6f98f2 100644 --- a/spring-core/src/main/java/org/springframework/core/io/support/ResourcePatternUtils.java +++ b/spring-core/src/main/java/org/springframework/core/io/support/ResourcePatternUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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,10 +48,10 @@ public abstract class ResourcePatternUtils { } /** - * Return a default ResourcePatternResolver for the given ResourceLoader. - * <p>This might be the ResourceLoader itself, if it implements the - * ResourcePatternResolver extension, or a PathMatchingResourcePatternResolver - * built on the given ResourceLoader. + * Return a default {@link ResourcePatternResolver} for the given {@link ResourceLoader}. + * <p>This might be the {@code ResourceLoader} itself, if it implements the + * {@code ResourcePatternResolver} extension, or a default + * {@link PathMatchingResourcePatternResolver} built on the given {@code ResourceLoader}. * @param resourceLoader the ResourceLoader to build a pattern resolver for * (may be {@code null} to indicate a default ResourceLoader) * @return the ResourcePatternResolver 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 0b161158..f09925d5 100644 --- a/spring-core/src/main/java/org/springframework/util/ClassUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ClassUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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 @@ import java.util.Map; import java.util.Set; /** - * Miscellaneous class utility methods. + * Miscellaneous {@code java.lang.Class} utility methods. * Mainly for internal use within the framework. * * @author Juergen Hoeller @@ -709,10 +709,12 @@ public abstract class ClassUtils { * @param interfaces the interfaces to merge * @param classLoader the ClassLoader to create the composite Class in * @return the merged interface as Class + * @throws IllegalArgumentException if the specified interfaces expose + * conflicting method signatures (or a similar constraint is violated) * @see java.lang.reflect.Proxy#getProxyClass */ public static Class<?> createCompositeInterface(Class<?>[] interfaces, ClassLoader classLoader) { - Assert.notEmpty(interfaces, "Interfaces must not be empty"); + Assert.notEmpty(interfaces, "Interface array must not be empty"); return Proxy.getProxyClass(classLoader, interfaces); } diff --git a/spring-core/src/main/java/org/springframework/util/CollectionUtils.java b/spring-core/src/main/java/org/springframework/util/CollectionUtils.java index 8edb77e9..f8ad1814 100644 --- a/spring-core/src/main/java/org/springframework/util/CollectionUtils.java +++ b/spring-core/src/main/java/org/springframework/util/CollectionUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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. @@ -125,7 +125,7 @@ public abstract class CollectionUtils { * Check whether the given Iterator contains the given element. * @param iterator the Iterator to check * @param element the element to look for - * @return {@code true} if found, {@code false} else + * @return {@code true} if found, {@code false} otherwise */ public static boolean contains(Iterator<?> iterator, Object element) { if (iterator != null) { @@ -143,7 +143,7 @@ public abstract class CollectionUtils { * Check whether the given Enumeration contains the given element. * @param enumeration the Enumeration to check * @param element the element to look for - * @return {@code true} if found, {@code false} else + * @return {@code true} if found, {@code false} otherwise */ public static boolean contains(Enumeration<?> enumeration, Object element) { if (enumeration != null) { @@ -163,7 +163,7 @@ public abstract class CollectionUtils { * {@code true} for an equal element as well. * @param collection the Collection to check * @param element the element to look for - * @return {@code true} if found, {@code false} else + * @return {@code true} if found, {@code false} otherwise */ public static boolean containsInstance(Collection<?> collection, Object element) { if (collection != null) { @@ -268,7 +268,7 @@ public abstract class CollectionUtils { * Determine whether the given Collection only contains a single unique object. * @param collection the Collection to check * @return {@code true} if the collection contains a single reference or - * multiple references to the same instance, {@code false} else + * multiple references to the same instance, {@code false} otherwise */ public static boolean hasUniqueObject(Collection<?> collection) { if (isEmpty(collection)) { @@ -326,12 +326,13 @@ public abstract class CollectionUtils { } /** - * Adapt an enumeration to an iterator. - * @param enumeration the enumeration - * @return the iterator + * Adapt an {@link Enumeration} to an {@link Iterator}. + * @param enumeration the original {@code Enumeration} + * @return the adapted {@code Iterator} */ + @SuppressWarnings("unchecked") public static <E> Iterator<E> toIterator(Enumeration<E> enumeration) { - return new EnumerationIterator<E>(enumeration); + return (enumeration != null ? new EnumerationIterator<E>(enumeration) : Collections.EMPTY_SET.iterator()); } /** @@ -508,7 +509,7 @@ public abstract class CollectionUtils { if (this == other) { return true; } - return map.equals(other); + return this.map.equals(other); } @Override diff --git a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java index 05a46229..39e608d4 100644 --- a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -606,7 +606,7 @@ public abstract class ObjectUtils { /** * Determine the class name for the given object. - * <p>Returns {@code "null"} if {@code obj} is {@code null}. + * <p>Returns a {@code "null"} String if {@code obj} is {@code null}. * @param obj the object to introspect (may be {@code null}) * @return the corresponding class name */ @@ -617,7 +617,7 @@ public abstract class ObjectUtils { /** * Return a String representation of the specified Object. * <p>Builds a String representation of the contents in case of an array. - * Returns {@code "null"} if {@code obj} is {@code null}. + * Returns a {@code "null"} String if {@code obj} is {@code null}. * @param obj the object to build a String representation for * @return a String representation of {@code obj} */ @@ -663,8 +663,8 @@ public abstract class ObjectUtils { * Return a String representation of the contents of the specified array. * <p>The String representation consists of a list of the array's elements, * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated - * by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. + * by the characters {@code ", "} (a comma followed by a space). + * Returns a {@code "null"} String if {@code array} is {@code null}. * @param array the array to build a String representation for * @return a String representation of {@code array} */ @@ -694,8 +694,8 @@ public abstract class ObjectUtils { * Return a String representation of the contents of the specified array. * <p>The String representation consists of a list of the array's elements, * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated - * by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. + * by the characters {@code ", "} (a comma followed by a space). + * Returns a {@code "null"} String if {@code array} is {@code null}. * @param array the array to build a String representation for * @return a String representation of {@code array} */ @@ -726,8 +726,8 @@ public abstract class ObjectUtils { * Return a String representation of the contents of the specified array. * <p>The String representation consists of a list of the array's elements, * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated - * by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. + * by the characters {@code ", "} (a comma followed by a space). + * Returns a {@code "null"} String if {@code array} is {@code null}. * @param array the array to build a String representation for * @return a String representation of {@code array} */ @@ -757,8 +757,8 @@ public abstract class ObjectUtils { * Return a String representation of the contents of the specified array. * <p>The String representation consists of a list of the array's elements, * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated - * by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. + * by the characters {@code ", "} (a comma followed by a space). + * Returns a {@code "null"} String if {@code array} is {@code null}. * @param array the array to build a String representation for * @return a String representation of {@code array} */ @@ -788,8 +788,8 @@ public abstract class ObjectUtils { * Return a String representation of the contents of the specified array. * <p>The String representation consists of a list of the array's elements, * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated - * by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. + * by the characters {@code ", "} (a comma followed by a space). + * Returns a {@code "null"} String if {@code array} is {@code null}. * @param array the array to build a String representation for * @return a String representation of {@code array} */ @@ -820,8 +820,8 @@ public abstract class ObjectUtils { * Return a String representation of the contents of the specified array. * <p>The String representation consists of a list of the array's elements, * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated - * by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. + * by the characters {@code ", "} (a comma followed by a space). + * Returns a {@code "null"} String if {@code array} is {@code null}. * @param array the array to build a String representation for * @return a String representation of {@code array} */ @@ -852,8 +852,8 @@ public abstract class ObjectUtils { * Return a String representation of the contents of the specified array. * <p>The String representation consists of a list of the array's elements, * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated - * by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. + * by the characters {@code ", "} (a comma followed by a space). + * Returns a {@code "null"} String if {@code array} is {@code null}. * @param array the array to build a String representation for * @return a String representation of {@code array} */ @@ -883,8 +883,8 @@ public abstract class ObjectUtils { * Return a String representation of the contents of the specified array. * <p>The String representation consists of a list of the array's elements, * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated - * by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. + * by the characters {@code ", "} (a comma followed by a space). + * Returns a {@code "null"} String if {@code array} is {@code null}. * @param array the array to build a String representation for * @return a String representation of {@code array} */ @@ -914,8 +914,8 @@ public abstract class ObjectUtils { * Return a String representation of the contents of the specified array. * <p>The String representation consists of a list of the array's elements, * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated - * by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. + * by the characters {@code ", "} (a comma followed by a space). + * Returns a {@code "null"} String if {@code array} is {@code null}. * @param array the array to build a String representation for * @return a String representation of {@code array} */ 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 50827aa0..2ecab2dc 100644 --- a/spring-core/src/main/java/org/springframework/util/StringUtils.java +++ b/spring-core/src/main/java/org/springframework/util/StringUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -766,6 +766,32 @@ public abstract class StringUtils { //--------------------------------------------------------------------- /** + * Copy the given {@link Collection} into a {@code String} array. + * <p>The {@code Collection} must contain {@code String} elements only. + * @param collection the {@code Collection} to copy + * @return the resulting {@code String} array + */ + public static String[] toStringArray(Collection<String> collection) { + if (collection == null) { + return null; + } + return collection.toArray(new String[collection.size()]); + } + + /** + * Copy the given {@link Enumeration} into a {@code String} array. + * <p>The {@code Enumeration} must contain {@code String} elements only. + * @param enumeration the {@code Enumeration} to copy + * @return the resulting {@code String} array + */ + public static String[] toStringArray(Enumeration<String> enumeration) { + if (enumeration == null) { + return null; + } + return toStringArray(Collections.list(enumeration)); + } + + /** * Append the given {@code String} to the given {@code String} array, * returning a new array consisting of the input array contents plus * the given {@code String}. @@ -838,8 +864,8 @@ public abstract class StringUtils { } /** - * Turn given source {@code String} array into sorted array. - * @param array the source array + * Sort the given {@code String} array if necessary. + * @param array the original array * @return the sorted array (never {@code null}) */ public static String[] sortStringArray(String[] array) { @@ -852,32 +878,6 @@ public abstract class StringUtils { } /** - * Copy the given {@code Collection} into a {@code String} array. - * <p>The {@code Collection} must contain {@code String} elements only. - * @param collection the {@code Collection} to copy - * @return the {@code String} array - */ - public static String[] toStringArray(Collection<String> collection) { - if (collection == null) { - return null; - } - return collection.toArray(new String[collection.size()]); - } - - /** - * 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 - */ - public static String[] toStringArray(Enumeration<String> enumeration) { - if (enumeration == null) { - return null; - } - return toStringArray(Collections.list(enumeration)); - } - - /** * Trim the elements of the given {@code String} array, * calling {@code String.trim()} on each of them. * @param array the original {@code String} array diff --git a/spring-core/src/main/java/org/springframework/util/UpdateMessageDigestInputStream.java b/spring-core/src/main/java/org/springframework/util/UpdateMessageDigestInputStream.java index 90bfa4a7..875e51bf 100644 --- a/spring-core/src/main/java/org/springframework/util/UpdateMessageDigestInputStream.java +++ b/spring-core/src/main/java/org/springframework/util/UpdateMessageDigestInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2018 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,7 +38,7 @@ abstract class UpdateMessageDigestInputStream extends InputStream { */ public void updateMessageDigest(MessageDigest messageDigest) throws IOException { int data; - while ((data = read()) != -1){ + while ((data = read()) != -1) { messageDigest.update((byte) data); } } @@ -54,7 +54,7 @@ abstract class UpdateMessageDigestInputStream extends InputStream { public void updateMessageDigest(MessageDigest messageDigest, int len) throws IOException { int data; int bytesRead = 0; - while (bytesRead < len && (data = read()) != -1){ + while (bytesRead < len && (data = read()) != -1) { messageDigest.update((byte) data); bytesRead++; } diff --git a/spring-core/src/test/java/org/springframework/core/convert/converter/DefaultConversionServiceTests.java b/spring-core/src/test/java/org/springframework/core/convert/converter/DefaultConversionServiceTests.java index 19880892..46ee27c1 100644 --- a/spring-core/src/test/java/org/springframework/core/convert/converter/DefaultConversionServiceTests.java +++ b/spring-core/src/test/java/org/springframework/core/convert/converter/DefaultConversionServiceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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. @@ -133,7 +133,7 @@ public class DefaultConversionServiceTests { } @Test - public void testStringToByte() throws Exception { + public void testStringToByte() { assertEquals(Byte.valueOf("1"), conversionService.convert("1", Byte.class)); } @@ -155,7 +155,7 @@ public class DefaultConversionServiceTests { @Test public void testStringToInteger() { - assertEquals(Integer.valueOf("1"), conversionService.convert("1", Integer.class)); + assertEquals(Integer.valueOf(1), conversionService.convert("1", Integer.class)); } @Test @@ -165,7 +165,7 @@ public class DefaultConversionServiceTests { @Test public void testStringToLong() { - assertEquals(Long.valueOf("1"), conversionService.convert("1", Long.class)); + assertEquals(Long.valueOf(1), conversionService.convert("1", Long.class)); } @Test @@ -180,7 +180,7 @@ public class DefaultConversionServiceTests { @Test public void testFloatToString() { - assertEquals("1.0", conversionService.convert(new Float("1.0"), String.class)); + assertEquals("1.0", conversionService.convert(Float.valueOf("1.0"), String.class)); } @Test @@ -190,7 +190,7 @@ public class DefaultConversionServiceTests { @Test public void testDoubleToString() { - assertEquals("1.0", conversionService.convert(new Double("1.0"), String.class)); + assertEquals("1.0", conversionService.convert(Double.valueOf("1.0"), String.class)); } @Test @@ -224,12 +224,12 @@ public class DefaultConversionServiceTests { } @Test - public void testStringToEnum() throws Exception { + public void testStringToEnum() { assertEquals(Foo.BAR, conversionService.convert("BAR", Foo.class)); } @Test - public void testStringToEnumWithSubclass() throws Exception { + public void testStringToEnumWithSubclass() { assertEquals(SubFoo.BAZ, conversionService.convert("BAZ", SubFoo.BAR.getClass())); } @@ -244,12 +244,12 @@ public class DefaultConversionServiceTests { } @Test - public void testIntegerToEnum() throws Exception { + public void testIntegerToEnum() { assertEquals(Foo.BAR, conversionService.convert(0, Foo.class)); } @Test - public void testIntegerToEnumWithSubclass() throws Exception { + public void testIntegerToEnumWithSubclass() { assertEquals(SubFoo.BAZ, conversionService.convert(1, SubFoo.BAR.getClass())); } @@ -325,7 +325,7 @@ public class DefaultConversionServiceTests { @Test public void testCharacterToNumber() { - assertEquals(new Integer(65), conversionService.convert('A', Integer.class)); + assertEquals(Integer.valueOf(65), conversionService.convert('A', Integer.class)); } // collection conversion @@ -343,9 +343,9 @@ public class DefaultConversionServiceTests { @SuppressWarnings("unchecked") List<Integer> result = (List<Integer>) conversionService.convert(new String[] {"1", "2", "3"}, TypeDescriptor .valueOf(String[].class), new TypeDescriptor(getClass().getDeclaredField("genericList"))); - assertEquals(new Integer("1"), result.get(0)); - assertEquals(new Integer("2"), result.get(1)); - assertEquals(new Integer("3"), result.get(2)); + assertEquals(Integer.valueOf(1), result.get(0)); + assertEquals(Integer.valueOf(2), result.get(1)); + assertEquals(Integer.valueOf(3), result.get(2)); } @Test @@ -384,10 +384,6 @@ public class DefaultConversionServiceTests { conversionService.convert(new String[]{"1", "2", "3"}, AbstractList.class); } - public static enum FooEnum { - BAR, BAZ - } - @Test public void convertArrayToString() { String result = conversionService.convert(new String[] {"1", "2", "3"}, String.class); @@ -419,9 +415,9 @@ public class DefaultConversionServiceTests { public void convertStringToArrayWithElementConversion() { Integer[] result = conversionService.convert("1,2,3", Integer[].class); assertEquals(3, result.length); - assertEquals(new Integer(1), result[0]); - assertEquals(new Integer(2), result[1]); - assertEquals(new Integer(3), result[2]); + assertEquals(Integer.valueOf(1), result[0]); + assertEquals(Integer.valueOf(2), result[1]); + assertEquals(Integer.valueOf(3), result[2]); } @Test @@ -450,7 +446,7 @@ public class DefaultConversionServiceTests { public void convertArrayToObjectWithElementConversion() { String[] array = new String[] {"3"}; Integer result = conversionService.convert(array, Integer.class); - assertEquals(new Integer(3), result); + assertEquals(Integer.valueOf(3), result); } @Test @@ -471,12 +467,12 @@ public class DefaultConversionServiceTests { public void convertObjectToArrayWithElementConversion() { Integer[] result = conversionService.convert(3L, Integer[].class); assertEquals(1, result.length); - assertEquals(new Integer(3), result[0]); + assertEquals(Integer.valueOf(3), result[0]); } @Test public void convertCollectionToArray() { - List<String> list = new ArrayList<String>(); + List<String> list = new ArrayList<>(); list.add("1"); list.add("2"); list.add("3"); @@ -488,14 +484,14 @@ public class DefaultConversionServiceTests { @Test public void convertCollectionToArrayWithElementConversion() { - List<String> list = new ArrayList<String>(); + List<String> list = new ArrayList<>(); list.add("1"); list.add("2"); list.add("3"); Integer[] result = conversionService.convert(list, Integer[].class); - assertEquals(new Integer(1), result[0]); - assertEquals(new Integer(2), result[1]); - assertEquals(new Integer(3), result[2]); + assertEquals(Integer.valueOf(1), result[0]); + assertEquals(Integer.valueOf(2), result[1]); + assertEquals(Integer.valueOf(3), result[2]); } @Test @@ -514,9 +510,8 @@ public class DefaultConversionServiceTests { } @Test - @SuppressWarnings("rawtypes") public void convertStringToCollection() { - List result = conversionService.convert("1,2,3", List.class); + List<?> result = conversionService.convert("1,2,3", List.class); assertEquals(3, result.size()); assertEquals("1", result.get(0)); assertEquals("2", result.get(1)); @@ -524,9 +519,8 @@ public class DefaultConversionServiceTests { } @Test - @SuppressWarnings("rawtypes") public void convertStringToCollectionWithElementConversion() throws Exception { - List result = (List) conversionService.convert("1,2,3", TypeDescriptor.valueOf(String.class), + List<?> result = (List) conversionService.convert("1,2,3", TypeDescriptor.valueOf(String.class), new TypeDescriptor(getClass().getField("genericList"))); assertEquals(3, result.size()); assertEquals(1, result.get(0)); @@ -535,9 +529,8 @@ public class DefaultConversionServiceTests { } @Test - @SuppressWarnings("rawtypes") public void convertEmptyStringToCollection() { - Collection result = conversionService.convert("", Collection.class); + Collection<?> result = conversionService.convert("", Collection.class); assertEquals(0, result.size()); } @@ -545,44 +538,37 @@ public class DefaultConversionServiceTests { public void convertCollectionToObject() { List<Long> list = Collections.singletonList(3L); Long result = conversionService.convert(list, Long.class); - assertEquals(new Long(3), result); + assertEquals(Long.valueOf(3), result); } @Test public void convertCollectionToObjectWithElementConversion() { List<String> list = Collections.singletonList("3"); Integer result = conversionService.convert(list, Integer.class); - assertEquals(new Integer(3), result); + assertEquals(Integer.valueOf(3), result); } @Test public void convertCollectionToObjectAssignableTarget() throws Exception { - Collection<String> source = new ArrayList<String>(); + Collection<String> source = new ArrayList<>(); source.add("foo"); Object result = conversionService.convert(source, new TypeDescriptor(getClass().getField("assignableTarget"))); assertEquals(source, result); } @Test - @SuppressWarnings("rawtypes") - public void convertCollectionToObjectWithCustomConverter() throws Exception { - List<String> source = new ArrayList<String>(); + public void convertCollectionToObjectWithCustomConverter() { + List<String> source = new ArrayList<>(); source.add("A"); source.add("B"); - conversionService.addConverter(new Converter<List, ListWrapper>() { - @Override - public ListWrapper convert(List source) { - return new ListWrapper(source); - } - }); + conversionService.addConverter(List.class, ListWrapper.class, ListWrapper::new); ListWrapper result = conversionService.convert(source, ListWrapper.class); assertSame(source, result.getList()); } @Test - @SuppressWarnings("rawtypes") public void convertObjectToCollection() { - List result = conversionService.convert(3L, List.class); + List<?> result = conversionService.convert(3L, List.class); assertEquals(1, result.size()); assertEquals(3L, result.get(0)); } @@ -593,19 +579,19 @@ public class DefaultConversionServiceTests { List<Integer> result = (List<Integer>) conversionService.convert(3L, TypeDescriptor.valueOf(Long.class), new TypeDescriptor(getClass().getField("genericList"))); assertEquals(1, result.size()); - assertEquals(new Integer(3), result.get(0)); + assertEquals(Integer.valueOf(3), result.get(0)); } @Test - public void convertArrayToArray() { + public void convertStringArrayToIntegerArray() { Integer[] result = conversionService.convert(new String[] {"1", "2", "3"}, Integer[].class); - assertEquals(new Integer(1), result[0]); - assertEquals(new Integer(2), result[1]); - assertEquals(new Integer(3), result[2]); + assertEquals(Integer.valueOf(1), result[0]); + assertEquals(Integer.valueOf(2), result[1]); + assertEquals(Integer.valueOf(3), result[2]); } @Test - public void convertArrayToPrimitiveArray() { + public void convertStringArrayToIntArray() { int[] result = conversionService.convert(new String[] {"1", "2", "3"}, int[].class); assertEquals(1, result[0]); assertEquals(2, result[1]); @@ -613,7 +599,39 @@ public class DefaultConversionServiceTests { } @Test - public void convertArrayToWrapperArray() { + public void convertIntegerArrayToIntegerArray() { + Integer[] result = conversionService.convert(new Integer[] {1, 2, 3}, Integer[].class); + assertEquals(Integer.valueOf(1), result[0]); + assertEquals(Integer.valueOf(2), result[1]); + assertEquals(Integer.valueOf(3), result[2]); + } + + @Test + public void convertIntegerArrayToIntArray() { + int[] result = conversionService.convert(new Integer[] {1, 2, 3}, int[].class); + assertEquals(1, result[0]); + assertEquals(2, result[1]); + assertEquals(3, result[2]); + } + + @Test + public void convertObjectArrayToIntegerArray() { + Integer[] result = conversionService.convert(new Object[] {1, 2, 3}, Integer[].class); + assertEquals(Integer.valueOf(1), result[0]); + assertEquals(Integer.valueOf(2), result[1]); + assertEquals(Integer.valueOf(3), result[2]); + } + + @Test + public void convertObjectArrayToIntArray() { + int[] result = conversionService.convert(new Object[] {1, 2, 3}, int[].class); + assertEquals(1, result[0]); + assertEquals(2, result[1]); + assertEquals(3, result[2]); + } + + @Test + public void convertByteArrayToWrapperArray() { byte[] byteArray = new byte[] {1, 2, 3}; Byte[] converted = conversionService.convert(byteArray, Byte[].class); assertThat(converted, equalTo(new Byte[]{1, 2, 3})); @@ -661,16 +679,16 @@ public class DefaultConversionServiceTests { @Test public void convertCollectionToCollection() throws Exception { - Set<String> foo = new LinkedHashSet<String>(); + Set<String> foo = new LinkedHashSet<>(); foo.add("1"); foo.add("2"); foo.add("3"); @SuppressWarnings("unchecked") List<Integer> bar = (List<Integer>) conversionService.convert(foo, TypeDescriptor.forObject(foo), new TypeDescriptor(getClass().getField("genericList"))); - assertEquals(new Integer(1), bar.get(0)); - assertEquals(new Integer(2), bar.get(1)); - assertEquals(new Integer(3), bar.get(2)); + assertEquals(Integer.valueOf(1), bar.get(0)); + assertEquals(Integer.valueOf(2), bar.get(1)); + assertEquals(Integer.valueOf(3), bar.get(2)); } @Test @@ -683,8 +701,8 @@ public class DefaultConversionServiceTests { @Test @SuppressWarnings("rawtypes") - public void convertCollectionToCollectionNotGeneric() throws Exception { - Set<String> foo = new LinkedHashSet<String>(); + public void convertCollectionToCollectionNotGeneric() { + Set<String> foo = new LinkedHashSet<>(); foo.add("1"); foo.add("2"); foo.add("3"); @@ -706,39 +724,39 @@ public class DefaultConversionServiceTests { List<Integer> bar = (List<Integer>) conversionService.convert(values, TypeDescriptor.forObject(values), new TypeDescriptor(getClass().getField("genericList"))); assertEquals(3, bar.size()); - assertEquals(new Integer(1), bar.get(0)); - assertEquals(new Integer(2), bar.get(1)); - assertEquals(new Integer(3), bar.get(2)); + assertEquals(Integer.valueOf(1), bar.get(0)); + assertEquals(Integer.valueOf(2), bar.get(1)); + assertEquals(Integer.valueOf(3), bar.get(2)); } @Test public void collection() { - List<String> strings = new ArrayList<String>(); + List<String> strings = new ArrayList<>(); strings.add("3"); strings.add("9"); @SuppressWarnings("unchecked") List<Integer> integers = (List<Integer>) conversionService.convert(strings, TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(Integer.class))); - assertEquals(new Integer(3), integers.get(0)); - assertEquals(new Integer(9), integers.get(1)); + assertEquals(Integer.valueOf(3), integers.get(0)); + assertEquals(Integer.valueOf(9), integers.get(1)); } @Test public void convertMapToMap() throws Exception { - Map<String, String> foo = new HashMap<String, String>(); + Map<String, String> foo = new HashMap<>(); foo.put("1", "BAR"); foo.put("2", "BAZ"); @SuppressWarnings("unchecked") - Map<Integer, FooEnum> map = (Map<Integer, FooEnum>) conversionService.convert(foo, + Map<Integer, Foo> map = (Map<Integer, Foo>) conversionService.convert(foo, TypeDescriptor.forObject(foo), new TypeDescriptor(getClass().getField("genericMap"))); - assertEquals(FooEnum.BAR, map.get(1)); - assertEquals(FooEnum.BAZ, map.get(2)); + assertEquals(Foo.BAR, map.get(1)); + assertEquals(Foo.BAZ, map.get(2)); } @Test @SuppressWarnings("rawtypes") public void convertHashMapValuesToList() { - Map<String, Integer> hashMap = new LinkedHashMap<String, Integer>(); + Map<String, Integer> hashMap = new LinkedHashMap<>(); hashMap.put("1", 1); hashMap.put("2", 2); List converted = conversionService.convert(hashMap.values(), List.class); @@ -747,14 +765,14 @@ public class DefaultConversionServiceTests { @Test public void map() { - Map<String, String> strings = new HashMap<String, String>(); + Map<String, String> strings = new HashMap<>(); strings.put("3", "9"); strings.put("6", "31"); @SuppressWarnings("unchecked") Map<Integer, Integer> integers = (Map<Integer, Integer>) conversionService.convert(strings, TypeDescriptor.map(Map.class, TypeDescriptor.valueOf(Integer.class), TypeDescriptor.valueOf(Integer.class))); - assertEquals(new Integer(9), integers.get(3)); - assertEquals(new Integer(31), integers.get(6)); + assertEquals(Integer.valueOf(9), integers.get(3)); + assertEquals(Integer.valueOf(31), integers.get(6)); } @Test @@ -847,13 +865,13 @@ public class DefaultConversionServiceTests { @Test(expected = ConverterNotFoundException.class) public void convertObjectToObjectNoValueOfMethodOrConstructor() { - conversionService.convert(new Long(3), SSN.class); + conversionService.convert(Long.valueOf(3), SSN.class); } @Test public void convertObjectToObjectFinderMethod() { TestEntity e = conversionService.convert(1L, TestEntity.class); - assertEquals(new Long(1), e.getId()); + assertEquals(Long.valueOf(1), e.getId()); } @Test @@ -866,29 +884,24 @@ public class DefaultConversionServiceTests { @Test public void convertObjectToObjectFinderMethodWithIdConversion() { TestEntity entity = conversionService.convert("1", TestEntity.class); - assertEquals(new Long(1), entity.getId()); + assertEquals(Long.valueOf(1), entity.getId()); } @Test - public void convertCharArrayToString() throws Exception { + public void convertCharArrayToString() { String converted = conversionService.convert(new char[] {'a', 'b', 'c'}, String.class); assertThat(converted, equalTo("a,b,c")); } @Test - public void convertStringToCharArray() throws Exception { + public void convertStringToCharArray() { char[] converted = conversionService.convert("a,b,c", char[].class); assertThat(converted, equalTo(new char[]{'a', 'b', 'c'})); } @Test - public void convertStringToCustomCharArray() throws Exception { - conversionService.addConverter(new Converter<String, char[]>() { - @Override - public char[] convert(String source) { - return source.toCharArray(); - } - }); + public void convertStringToCustomCharArray() { + conversionService.addConverter(String.class, char[].class, String::toCharArray); char[] converted = conversionService.convert("abc", char[].class); assertThat(converted, equalTo(new char[] {'a', 'b', 'c'})); } @@ -905,16 +918,11 @@ public class DefaultConversionServiceTests { @Test public void convertCannotOptimizeArray() { - conversionService.addConverter(new Converter<Byte, Byte>() { - @Override - public Byte convert(Byte source) { - return (byte) (source + 1); - } - }); + conversionService.addConverter(Byte.class, Byte.class, source -> (byte) (source + 1)); byte[] byteArray = new byte[] {1, 2, 3}; byte[] converted = conversionService.convert(byteArray, byte[].class); assertNotSame(byteArray, converted); - assertTrue(Arrays.equals(new byte[] {2, 3, 4}, converted)); + assertArrayEquals(new byte[]{2, 3, 4}, converted); } @Test @@ -953,7 +961,7 @@ public class DefaultConversionServiceTests { watch.stop(); watch.start("convert 4,000,000 manually"); for (int i = 0; i < 4000000; i++) { - new Integer(3).toString(); + Integer.valueOf(3).toString(); } watch.stop(); // System.out.println(watch.prettyPrint()); @@ -962,11 +970,11 @@ public class DefaultConversionServiceTests { // test fields and helpers - public List<Integer> genericList = new ArrayList<Integer>(); + public List<Integer> genericList = new ArrayList<>(); public Stream<Integer> genericStream; - public Map<Integer, FooEnum> genericMap = new HashMap<Integer, FooEnum>(); + public Map<Integer, Foo> genericMap = new HashMap<>(); public EnumSet<Foo> enumSet; diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/CompoundExpression.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/CompoundExpression.java index 26c17fb0..841d325d 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/CompoundExpression.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/CompoundExpression.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,8 @@ import org.springframework.expression.spel.ExpressionState; import org.springframework.expression.spel.SpelEvaluationException; /** - * Represents a DOT separated expression sequence, such as 'property1.property2.methodOne()' + * Represents a DOT separated expression sequence, such as + * {@code 'property1.property2.methodOne()'}. * * @author Andy Clement * @since 3.0 @@ -111,7 +112,7 @@ public class CompoundExpression extends SpelNodeImpl { } return sb.toString(); } - + @Override public boolean isCompilable() { for (SpelNodeImpl child: this.children) { @@ -121,11 +122,11 @@ public class CompoundExpression extends SpelNodeImpl { } return true; } - + @Override public void generateCode(MethodVisitor mv, CodeFlow cf) { - for (int i = 0; i < this.children.length;i++) { - this.children[i].generateCode(mv, cf); + for (SpelNodeImpl child : this.children) { + child.generateCode(mv, cf); } cf.pushDescriptor(this.exitTypeDescriptor); } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/InlineMap.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/InlineMap.java index aa1233b5..35729c17 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/InlineMap.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/InlineMap.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2019 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 @@ import org.springframework.expression.spel.SpelNode; public class InlineMap extends SpelNodeImpl { // If the map is purely literals, it is a constant value and can be computed and cached - private TypedValue constant = null; + private TypedValue constant; public InlineMap(int pos, SpelNodeImpl... args) { @@ -44,7 +44,7 @@ public class InlineMap extends SpelNodeImpl { /** - * If all the components of the list are constants, or lists/maps that themselves + * If all the components of the map are constants, or lists/maps that themselves * contain constants, then a constant list can be built to represent this node. * This will speed up later getValue calls and reduce the amount of garbage created. */ @@ -67,14 +67,14 @@ public class InlineMap extends SpelNodeImpl { break; } } - else if (!((c%2)==0 && (child instanceof PropertyOrFieldReference))) { + else if (!(c % 2 == 0 && child instanceof PropertyOrFieldReference)) { isConstant = false; break; } } } if (isConstant) { - Map<Object,Object> constantMap = new LinkedHashMap<Object,Object>(); + Map<Object, Object> constantMap = new LinkedHashMap<Object, Object>(); int childCount = getChildCount(); for (int c = 0; c < childCount; c++) { SpelNode keyChild = getChild(c++); @@ -148,15 +148,15 @@ public class InlineMap extends SpelNodeImpl { } /** - * @return whether this list is a constant value + * Return whether this list is a constant value. */ public boolean isConstant() { return this.constant != null; } @SuppressWarnings("unchecked") - public Map<Object,Object> getConstantValue() { - return (Map<Object,Object>) this.constant.getValue(); + public Map<Object, Object> getConstantValue() { + return (Map<Object, Object>) this.constant.getValue(); } } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/ValueRef.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/ValueRef.java index 8e9b8a87..14046c39 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/ValueRef.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/ValueRef.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,8 +23,8 @@ import org.springframework.expression.spel.SpelMessage; /** * Represents a reference to a value. With a reference it is possible to get or set the * value. Passing around value references rather than the values themselves can avoid - * incorrect duplication of operand evaluation. For example in 'list[index++]++' without a - * value reference for 'list[index++]' it would be necessary to evaluate list[index++] + * incorrect duplication of operand evaluation. For example in 'list[index++]++' without + * a value reference for 'list[index++]' it would be necessary to evaluate list[index++] * twice (once to get the value, once to determine where the value goes) and that would * double increment index. * @@ -102,7 +102,8 @@ public interface ValueRef { @Override public void setValue(Object newValue) { - throw new SpelEvaluationException(this.node.pos, SpelMessage.NOT_ASSIGNABLE, this.node.toStringAST()); + throw new SpelEvaluationException( + this.node.getStartPosition(), SpelMessage.NOT_ASSIGNABLE, this.node.toStringAST()); } @Override diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcOperations.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcOperations.java index 64aa2a82..cba33bac 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcOperations.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -53,10 +53,10 @@ public interface JdbcOperations { * data access operations, within Spring's managed JDBC environment: * that is, participating in Spring-managed transactions and converting * JDBC SQLExceptions into Spring's DataAccessException hierarchy. - * <p>The callback action can return a result object, for example a - * domain object or a collection of domain objects. - * @param action the callback object that specifies the action - * @return a result object returned by the action, or {@code null} + * <p>The callback action can return a result object, for example a domain + * object or a collection of domain objects. + * @param action a callback object that specifies the action + * @return a result object returned by the action, or {@code null} if none * @throws DataAccessException if there is any problem */ <T> T execute(ConnectionCallback<T> action) throws DataAccessException; @@ -72,10 +72,10 @@ public interface JdbcOperations { * access operations on a single Statement, within Spring's managed JDBC * environment: that is, participating in Spring-managed transactions and * converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. - * <p>The callback action can return a result object, for example a - * domain object or a collection of domain objects. - * @param action callback object that specifies the action - * @return a result object returned by the action, or {@code null} + * <p>The callback action can return a result object, for example a domain + * object or a collection of domain objects. + * @param action a callback that specifies the action + * @return a result object returned by the action, or {@code null} if none * @throws DataAccessException if there is any problem */ <T> T execute(StatementCallback<T> action) throws DataAccessException; @@ -93,8 +93,8 @@ public interface JdbcOperations { * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to * execute a static query with a PreparedStatement, use the overloaded * {@code query} method with {@code null} as argument array. - * @param sql SQL query to execute - * @param rse object that will extract all rows of results + * @param sql the SQL query to execute + * @param rse a callback that will extract all rows of results * @return an arbitrary result object, as returned by the ResultSetExtractor * @throws DataAccessException if there is any problem executing the query * @see #query(String, Object[], ResultSetExtractor) @@ -107,21 +107,21 @@ public interface JdbcOperations { * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to * execute a static query with a PreparedStatement, use the overloaded * {@code query} method with {@code null} as argument array. - * @param sql SQL query to execute - * @param rch object that will extract results, one row at a time + * @param sql the SQL query to execute + * @param rch a callback that will extract results, one row at a time * @throws DataAccessException if there is any problem executing the query * @see #query(String, Object[], RowCallbackHandler) */ void query(String sql, RowCallbackHandler rch) throws DataAccessException; /** - * Execute a query given static SQL, mapping each row to a Java object + * Execute a query given static SQL, mapping each row to a result object * via a RowMapper. * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to * execute a static query with a PreparedStatement, use the overloaded * {@code query} method with {@code null} as argument array. - * @param sql SQL query to execute - * @param rowMapper object that will map one object per row + * @param sql the SQL query to execute + * @param rowMapper a callback that will map one object per row * @return the result List, containing mapped objects * @throws DataAccessException if there is any problem executing the query * @see #query(String, Object[], RowMapper) @@ -129,14 +129,14 @@ public interface JdbcOperations { <T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException; /** - * Execute a query given static SQL, mapping a single result row to a Java - * object via a RowMapper. + * Execute a query given static SQL, mapping a single result row to a + * result object via a RowMapper. * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to * execute a static query with a PreparedStatement, use the overloaded * {@link #queryForObject(String, RowMapper, Object...)} method with * {@code null} as argument array. - * @param sql SQL query to execute - * @param rowMapper object that will map one object per row + * @param sql the SQL query to execute + * @param rowMapper a callback that will map one object per row * @return the single mapped object (may be {@code null} if the given * {@link RowMapper} returned {@code} null) * @throws IncorrectResultSizeDataAccessException if the query does not @@ -155,7 +155,7 @@ public interface JdbcOperations { * <p>This method is useful for running static SQL with a known outcome. * The query is expected to be a single row/single column query; the returned * result will be directly mapped to the corresponding object type. - * @param sql SQL query to execute + * @param sql the SQL query to execute * @param requiredType the type that the result object is expected to match * @return the result object of the required type, or {@code null} in case of SQL NULL * @throws IncorrectResultSizeDataAccessException if the query does not return @@ -166,16 +166,15 @@ public interface JdbcOperations { <T> T queryForObject(String sql, Class<T> requiredType) throws DataAccessException; /** - * Execute a query for a result Map, given static SQL. + * Execute a query for a result map, given static SQL. * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to * execute a static query with a PreparedStatement, use the overloaded * {@link #queryForMap(String, Object...)} method with {@code null} * as argument array. * <p>The query is expected to be a single row query; the result row will be * mapped to a Map (one entry for each column, using the column name as the key). - * @param sql SQL query to execute - * @return the result Map (one entry for each column, using the - * column name as the key) + * @param sql the SQL query to execute + * @return the result Map (one entry per column, with column name as key) * @throws IncorrectResultSizeDataAccessException if the query does not * return exactly one row * @throws DataAccessException if there is any problem executing the query @@ -191,7 +190,7 @@ public interface JdbcOperations { * {@code queryForList} method with {@code null} as argument array. * <p>The results will be mapped to a List (one entry for each row) of * result objects, each of them matching the specified element type. - * @param sql SQL query to execute + * @param sql the SQL query to execute * @param elementType the required type of element in the result list * (for example, {@code Integer.class}) * @return a List of objects that match the specified element type @@ -209,8 +208,8 @@ public interface JdbcOperations { * <p>The results will be mapped to a List (one entry for each row) of * Maps (one entry for each column using the column name as the key). * Each element in the list will be of the form returned by this interface's - * queryForMap() methods. - * @param sql SQL query to execute + * {@code queryForMap} methods. + * @param sql the SQL query to execute * @return an List that contains a Map per row * @throws DataAccessException if there is any problem executing the query * @see #queryForList(String, Object[]) @@ -228,7 +227,7 @@ public interface JdbcOperations { * be available at runtime: by default, Sun's {@code com.sun.rowset.CachedRowSetImpl} * class is used, which is part of JDK 1.5+ and also available separately as part of * Sun's JDBC RowSet Implementations download (rowset.jar). - * @param sql SQL query to execute + * @param sql the SQL query to execute * @return a SqlRowSet representation (possibly a wrapper around a * {@code javax.sql.rowset.CachedRowSet}) * @throws DataAccessException if there is any problem executing the query @@ -264,14 +263,14 @@ public interface JdbcOperations { /** * Execute a JDBC data access operation, implemented as callback action * working on a JDBC PreparedStatement. This allows for implementing arbitrary - * data access operations on a single Statement, within Spring's managed - * JDBC environment: that is, participating in Spring-managed transactions - * and converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. - * <p>The callback action can return a result object, for example a - * domain object or a collection of domain objects. - * @param psc object that can create a PreparedStatement given a Connection - * @param action callback object that specifies the action - * @return a result object returned by the action, or {@code null} + * data access operations on a single Statement, within Spring's managed JDBC + * environment: that is, participating in Spring-managed transactions and + * converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. + * <p>The callback action can return a result object, for example a domain + * object or a collection of domain objects. + * @param psc a callback that creates a PreparedStatement given a Connection + * @param action a callback that specifies the action + * @return a result object returned by the action, or {@code null} if none * @throws DataAccessException if there is any problem */ <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action) throws DataAccessException; @@ -279,25 +278,24 @@ public interface JdbcOperations { /** * Execute a JDBC data access operation, implemented as callback action * working on a JDBC PreparedStatement. This allows for implementing arbitrary - * data access operations on a single Statement, within Spring's managed - * JDBC environment: that is, participating in Spring-managed transactions - * and converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. - * <p>The callback action can return a result object, for example a - * domain object or a collection of domain objects. - * @param sql SQL to execute - * @param action callback object that specifies the action - * @return a result object returned by the action, or {@code null} + * data access operations on a single Statement, within Spring's managed JDBC + * environment: that is, participating in Spring-managed transactions and + * converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. + * <p>The callback action can return a result object, for example a domain + * object or a collection of domain objects. + * @param sql the SQL to execute + * @param action a callback that specifies the action + * @return a result object returned by the action, or {@code null} if none * @throws DataAccessException if there is any problem */ <T> T execute(String sql, PreparedStatementCallback<T> action) throws DataAccessException; /** - * Query using a prepared statement, reading the ResultSet with a - * ResultSetExtractor. + * Query using a prepared statement, reading the ResultSet with a ResultSetExtractor. * <p>A PreparedStatementCreator can either be implemented directly or * configured through a PreparedStatementCreatorFactory. - * @param psc object that can create a PreparedStatement given a Connection - * @param rse object that will extract results + * @param psc a callback that creates a PreparedStatement given a Connection + * @param rse a callback that will extract results * @return an arbitrary result object, as returned by the ResultSetExtractor * @throws DataAccessException if there is any problem * @see PreparedStatementCreatorFactory @@ -305,28 +303,26 @@ public interface JdbcOperations { <T> T query(PreparedStatementCreator psc, ResultSetExtractor<T> rse) throws DataAccessException; /** - * Query using a prepared statement, reading the ResultSet with a - * ResultSetExtractor. - * @param sql SQL query to execute - * @param pss object that knows how to set values on the prepared statement. + * Query using a prepared statement, reading the ResultSet with a ResultSetExtractor. + * @param sql the SQL query to execute + * @param pss a callback that knows how to set values on the prepared statement. * If this is {@code null}, the SQL will be assumed to contain no bind parameters. - * Even if there are no bind parameters, this object may be used to - * set fetch size and other performance options. - * @param rse object that will extract results + * Even if there are no bind parameters, this callback may be used to set the + * fetch size and other performance options. + * @param rse a callback that will extract results * @return an arbitrary result object, as returned by the ResultSetExtractor * @throws DataAccessException if there is any problem */ <T> T query(String sql, PreparedStatementSetter pss, ResultSetExtractor<T> rse) throws DataAccessException; /** - * Query given SQL to create a prepared statement from SQL and a list - * of arguments to bind to the query, reading the ResultSet with a - * ResultSetExtractor. - * @param sql SQL query to execute + * Query given SQL to create a prepared statement from SQL and a list of arguments + * to bind to the query, reading the ResultSet with a ResultSetExtractor. + * @param sql the SQL query to execute * @param args arguments to bind to the query - * @param argTypes SQL types of the arguments + * @param argTypes the SQL types of the arguments * (constants from {@code java.sql.Types}) - * @param rse object that will extract results + * @param rse a callback that will extract results * @return an arbitrary result object, as returned by the ResultSetExtractor * @throws DataAccessException if the query fails * @see java.sql.Types @@ -334,26 +330,24 @@ public interface JdbcOperations { <T> T query(String sql, Object[] args, int[] argTypes, ResultSetExtractor<T> rse) throws DataAccessException; /** - * Query given SQL to create a prepared statement from SQL and a list - * of arguments to bind to the query, reading the ResultSet with a - * ResultSetExtractor. - * @param sql SQL query to execute + * Query given SQL to create a prepared statement from SQL and a list of arguments + * to bind to the query, reading the ResultSet with a ResultSetExtractor. + * @param sql the SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale - * @param rse object that will extract results + * @param rse a callback that will extract results * @return an arbitrary result object, as returned by the ResultSetExtractor * @throws DataAccessException if the query fails */ <T> T query(String sql, Object[] args, ResultSetExtractor<T> rse) throws DataAccessException; /** - * Query given SQL to create a prepared statement from SQL and a list - * of arguments to bind to the query, reading the ResultSet with a - * ResultSetExtractor. - * @param sql SQL query to execute - * @param rse object that will extract results + * Query given SQL to create a prepared statement from SQL and a list of arguments + * to bind to the query, reading the ResultSet with a ResultSetExtractor. + * @param sql the SQL query to execute + * @param rse a callback that will extract results * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not @@ -365,12 +359,12 @@ public interface JdbcOperations { <T> T query(String sql, ResultSetExtractor<T> rse, Object... args) throws DataAccessException; /** - * Query using a prepared statement, reading the ResultSet on a per-row - * basis with a RowCallbackHandler. + * Query using a prepared statement, reading the ResultSet on a per-row basis + * with a RowCallbackHandler. * <p>A PreparedStatementCreator can either be implemented directly or * configured through a PreparedStatementCreatorFactory. - * @param psc object that can create a PreparedStatement given a Connection - * @param rch object that will extract results, one row at a time + * @param psc a callback that creates a PreparedStatement given a Connection + * @param rch a callback that will extract results, one row at a time * @throws DataAccessException if there is any problem * @see PreparedStatementCreatorFactory */ @@ -378,15 +372,14 @@ public interface JdbcOperations { /** * Query given SQL to create a prepared statement from SQL and a - * PreparedStatementSetter implementation that knows how to bind values - * to the query, reading the ResultSet on a per-row basis with a - * RowCallbackHandler. - * @param sql SQL query to execute - * @param pss object that knows how to set values on the prepared statement. + * PreparedStatementSetter implementation that knows how to bind values to the + * query, reading the ResultSet on a per-row basis with a RowCallbackHandler. + * @param sql the SQL query to execute + * @param pss a callback that knows how to set values on the prepared statement. * If this is {@code null}, the SQL will be assumed to contain no bind parameters. - * Even if there are no bind parameters, this object may be used to - * set fetch size and other performance options. - * @param rch object that will extract results, one row at a time + * Even if there are no bind parameters, this callback may be used to set the + * fetch size and other performance options. + * @param rch a callback that will extract results, one row at a time * @throws DataAccessException if the query fails */ void query(String sql, PreparedStatementSetter pss, RowCallbackHandler rch) throws DataAccessException; @@ -395,11 +388,11 @@ public interface JdbcOperations { * Query given SQL to create a prepared statement from SQL and a list of * arguments to bind to the query, reading the ResultSet on a per-row basis * with a RowCallbackHandler. - * @param sql SQL query to execute + * @param sql the SQL query to execute * @param args arguments to bind to the query - * @param argTypes SQL types of the arguments + * @param argTypes the SQL types of the arguments * (constants from {@code java.sql.Types}) - * @param rch object that will extract results, one row at a time + * @param rch a callback that will extract results, one row at a time * @throws DataAccessException if the query fails * @see java.sql.Types */ @@ -409,12 +402,12 @@ public interface JdbcOperations { * Query given SQL to create a prepared statement from SQL and a list of * arguments to bind to the query, reading the ResultSet on a per-row basis * with a RowCallbackHandler. - * @param sql SQL query to execute + * @param sql the SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale - * @param rch object that will extract results, one row at a time + * @param rch a callback that will extract results, one row at a time * @throws DataAccessException if the query fails */ void query(String sql, Object[] args, RowCallbackHandler rch) throws DataAccessException; @@ -423,8 +416,8 @@ public interface JdbcOperations { * Query given SQL to create a prepared statement from SQL and a list of * arguments to bind to the query, reading the ResultSet on a per-row basis * with a RowCallbackHandler. - * @param sql SQL query to execute - * @param rch object that will extract results, one row at a time + * @param sql the SQL query to execute + * @param rch a callback that will extract results, one row at a time * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not @@ -435,12 +428,12 @@ public interface JdbcOperations { void query(String sql, RowCallbackHandler rch, Object... args) throws DataAccessException; /** - * Query using a prepared statement, mapping each row to a Java object + * Query using a prepared statement, mapping each row to a result object * via a RowMapper. * <p>A PreparedStatementCreator can either be implemented directly or * configured through a PreparedStatementCreatorFactory. - * @param psc object that can create a PreparedStatement given a Connection - * @param rowMapper object that will map one object per row + * @param psc a callback that creates a PreparedStatement given a Connection + * @param rowMapper a callback that will map one object per row * @return the result List, containing mapped objects * @throws DataAccessException if there is any problem * @see PreparedStatementCreatorFactory @@ -450,27 +443,27 @@ public interface JdbcOperations { /** * Query given SQL to create a prepared statement from SQL and a * PreparedStatementSetter implementation that knows how to bind values - * to the query, mapping each row to a Java object via a RowMapper. - * @param sql SQL query to execute - * @param pss object that knows how to set values on the prepared statement. + * to the query, mapping each row to a result object via a RowMapper. + * @param sql the SQL query to execute + * @param pss a callback that knows how to set values on the prepared statement. * If this is {@code null}, the SQL will be assumed to contain no bind parameters. - * Even if there are no bind parameters, this object may be used to - * set fetch size and other performance options. - * @param rowMapper object that will map one object per row + * Even if there are no bind parameters, this callback may be used to set the + * fetch size and other performance options. + * @param rowMapper a callback that will map one object per row * @return the result List, containing mapped objects * @throws DataAccessException if the query fails */ <T> List<T> query(String sql, PreparedStatementSetter pss, RowMapper<T> rowMapper) throws DataAccessException; /** - * Query given SQL to create a prepared statement from SQL and a list - * of arguments to bind to the query, mapping each row to a Java object + * Query given SQL to create a prepared statement from SQL and a list of + * arguments to bind to the query, mapping each row to a result object * via a RowMapper. - * @param sql SQL query to execute + * @param sql the SQL query to execute * @param args arguments to bind to the query - * @param argTypes SQL types of the arguments + * @param argTypes the SQL types of the arguments * (constants from {@code java.sql.Types}) - * @param rowMapper object that will map one object per row + * @param rowMapper a callback that will map one object per row * @return the result List, containing mapped objects * @throws DataAccessException if the query fails * @see java.sql.Types @@ -478,26 +471,26 @@ public interface JdbcOperations { <T> List<T> query(String sql, Object[] args, int[] argTypes, RowMapper<T> rowMapper) throws DataAccessException; /** - * Query given SQL to create a prepared statement from SQL and a list - * of arguments to bind to the query, mapping each row to a Java object + * Query given SQL to create a prepared statement from SQL and a list of + * arguments to bind to the query, mapping each row to a result object * via a RowMapper. - * @param sql SQL query to execute + * @param sql the SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale - * @param rowMapper object that will map one object per row + * @param rowMapper a callback that will map one object per row * @return the result List, containing mapped objects * @throws DataAccessException if the query fails */ <T> List<T> query(String sql, Object[] args, RowMapper<T> rowMapper) throws DataAccessException; /** - * Query given SQL to create a prepared statement from SQL and a list - * of arguments to bind to the query, mapping each row to a Java object + * Query given SQL to create a prepared statement from SQL and a list of + * arguments to bind to the query, mapping each row to a result object * via a RowMapper. - * @param sql SQL query to execute - * @param rowMapper object that will map one object per row + * @param sql the SQL query to execute + * @param rowMapper a callback that will map one object per row * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not @@ -511,13 +504,13 @@ public interface JdbcOperations { /** * Query given SQL to create a prepared statement from SQL and a list * of arguments to bind to the query, mapping a single result row to a - * Java object via a RowMapper. - * @param sql SQL query to execute + * result object via a RowMapper. + * @param sql the SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type) - * @param argTypes SQL types of the arguments + * @param argTypes the SQL types of the arguments * (constants from {@code java.sql.Types}) - * @param rowMapper object that will map one object per row + * @param rowMapper a callback that will map one object per row * @return the single mapped object (may be {@code null} if the given * {@link RowMapper} returned {@code} null) * @throws IncorrectResultSizeDataAccessException if the query does not @@ -530,13 +523,13 @@ public interface JdbcOperations { /** * Query given SQL to create a prepared statement from SQL and a list * of arguments to bind to the query, mapping a single result row to a - * Java object via a RowMapper. - * @param sql SQL query to execute + * result object via a RowMapper. + * @param sql the SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale - * @param rowMapper object that will map one object per row + * @param rowMapper a callback that will map one object per row * @return the single mapped object (may be {@code null} if the given * {@link RowMapper} returned {@code} null) * @throws IncorrectResultSizeDataAccessException if the query does not @@ -548,9 +541,9 @@ public interface JdbcOperations { /** * Query given SQL to create a prepared statement from SQL and a list * of arguments to bind to the query, mapping a single result row to a - * Java object via a RowMapper. - * @param sql SQL query to execute - * @param rowMapper object that will map one object per row + * result object via a RowMapper. + * @param sql the SQL query to execute + * @param rowMapper a callback that will map one object per row * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not @@ -565,13 +558,13 @@ public interface JdbcOperations { <T> T queryForObject(String sql, RowMapper<T> rowMapper, Object... args) throws DataAccessException; /** - * Query given SQL to create a prepared statement from SQL and a - * list of arguments to bind to the query, expecting a result object. + * Query given SQL to create a prepared statement from SQL and a list of + * arguments to bind to the query, expecting a result object. * <p>The query is expected to be a single row/single column query; the returned * result will be directly mapped to the corresponding object type. - * @param sql SQL query to execute + * @param sql the SQL query to execute * @param args arguments to bind to the query - * @param argTypes SQL types of the arguments + * @param argTypes the SQL types of the arguments * (constants from {@code java.sql.Types}) * @param requiredType the type that the result object is expected to match * @return the result object of the required type, or {@code null} in case of SQL NULL @@ -585,11 +578,11 @@ public interface JdbcOperations { throws DataAccessException; /** - * Query given SQL to create a prepared statement from SQL and a - * list of arguments to bind to the query, expecting a result object. + * Query given SQL to create a prepared statement from SQL and a list of + * arguments to bind to the query, expecting a result object. * <p>The query is expected to be a single row/single column query; the returned * result will be directly mapped to the corresponding object type. - * @param sql SQL query to execute + * @param sql the SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not @@ -604,11 +597,11 @@ public interface JdbcOperations { <T> T queryForObject(String sql, Object[] args, Class<T> requiredType) throws DataAccessException; /** - * Query given SQL to create a prepared statement from SQL and a - * list of arguments to bind to the query, expecting a result object. + * Query given SQL to create a prepared statement from SQL and a list of + * arguments to bind to the query, expecting a result object. * <p>The query is expected to be a single row/single column query; the returned * result will be directly mapped to the corresponding object type. - * @param sql SQL query to execute + * @param sql the SQL query to execute * @param requiredType the type that the result object is expected to match * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); @@ -624,16 +617,15 @@ public interface JdbcOperations { <T> T queryForObject(String sql, Class<T> requiredType, Object... args) throws DataAccessException; /** - * Query given SQL to create a prepared statement from SQL and a - * list of arguments to bind to the query, expecting a result Map. + * Query given SQL to create a prepared statement from SQL and a list of + * arguments to bind to the query, expecting a result map. * <p>The query is expected to be a single row query; the result row will be * mapped to a Map (one entry for each column, using the column name as the key). - * @param sql SQL query to execute + * @param sql the SQL query to execute * @param args arguments to bind to the query - * @param argTypes SQL types of the arguments + * @param argTypes the SQL types of the arguments * (constants from {@code java.sql.Types}) - * @return the result Map (one entry for each column, using the - * column name as the key) + * @return the result Map (one entry per column, with column name as key) * @throws IncorrectResultSizeDataAccessException if the query does not * return exactly one row * @throws DataAccessException if the query fails @@ -644,14 +636,14 @@ public interface JdbcOperations { Map<String, Object> queryForMap(String sql, Object[] args, int[] argTypes) throws DataAccessException; /** - * Query given SQL to create a prepared statement from SQL and a - * list of arguments to bind to the query, expecting a result Map. - * The queryForMap() methods defined by this interface are appropriate - * when you don't have a domain model. Otherwise, consider using - * one of the queryForObject() methods. + * Query given SQL to create a prepared statement from SQL and a list of + * arguments to bind to the query, expecting a result map. + * <p>The {@code queryForMap} methods defined by this interface are appropriate + * when you don't have a domain model. Otherwise, consider using one of the + * {@code queryForObject} methods. * <p>The query is expected to be a single row query; the result row will be * mapped to a Map (one entry for each column, using the column name as the key). - * @param sql SQL query to execute + * @param sql the SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not @@ -667,13 +659,13 @@ public interface JdbcOperations { Map<String, Object> queryForMap(String sql, Object... args) throws DataAccessException; /** - * Query given SQL to create a prepared statement from SQL and a - * list of arguments to bind to the query, expecting a result list. + * Query given SQL to create a prepared statement from SQL and a list of + * arguments to bind to the query, expecting a result list. * <p>The results will be mapped to a List (one entry for each row) of * result objects, each of them matching the specified element type. - * @param sql SQL query to execute + * @param sql the SQL query to execute * @param args arguments to bind to the query - * @param argTypes SQL types of the arguments + * @param argTypes the SQL types of the arguments * (constants from {@code java.sql.Types}) * @param elementType the required type of element in the result list * (for example, {@code Integer.class}) @@ -682,15 +674,15 @@ public interface JdbcOperations { * @see #queryForList(String, Class) * @see SingleColumnRowMapper */ - <T>List<T> queryForList(String sql, Object[] args, int[] argTypes, Class<T> elementType) + <T> List<T> queryForList(String sql, Object[] args, int[] argTypes, Class<T> elementType) throws DataAccessException; /** - * Query given SQL to create a prepared statement from SQL and a - * list of arguments to bind to the query, expecting a result list. + * Query given SQL to create a prepared statement from SQL and a list of + * arguments to bind to the query, expecting a result list. * <p>The results will be mapped to a List (one entry for each row) of * result objects, each of them matching the specified element type. - * @param sql SQL query to execute + * @param sql the SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not @@ -705,11 +697,11 @@ public interface JdbcOperations { <T> List<T> queryForList(String sql, Object[] args, Class<T> elementType) throws DataAccessException; /** - * Query given SQL to create a prepared statement from SQL and a - * list of arguments to bind to the query, expecting a result list. + * Query given SQL to create a prepared statement from SQL and a list of + * arguments to bind to the query, expecting a result list. * <p>The results will be mapped to a List (one entry for each row) of * result objects, each of them matching the specified element type. - * @param sql SQL query to execute + * @param sql the SQL query to execute * @param elementType the required type of element in the result list * (for example, {@code Integer.class}) * @param args arguments to bind to the query @@ -725,15 +717,15 @@ public interface JdbcOperations { <T> List<T> queryForList(String sql, Class<T> elementType, Object... args) throws DataAccessException; /** - * Query given SQL to create a prepared statement from SQL and a - * list of arguments to bind to the query, expecting a result list. + * Query given SQL to create a prepared statement from SQL and a list of + * arguments to bind to the query, expecting a result list. * <p>The results will be mapped to a List (one entry for each row) of * Maps (one entry for each column, using the column name as the key). - * Thus Each element in the list will be of the form returned by this interface's - * queryForMap() methods. - * @param sql SQL query to execute + * Each element in the list will be of the form returned by this interface's + * {@code queryForMap} methods. + * @param sql the SQL query to execute * @param args arguments to bind to the query - * @param argTypes SQL types of the arguments + * @param argTypes the SQL types of the arguments * (constants from {@code java.sql.Types}) * @return a List that contains a Map per row * @throws DataAccessException if the query fails @@ -743,13 +735,13 @@ public interface JdbcOperations { List<Map<String, Object>> queryForList(String sql, Object[] args, int[] argTypes) throws DataAccessException; /** - * Query given SQL to create a prepared statement from SQL and a - * list of arguments to bind to the query, expecting a result list. + * Query given SQL to create a prepared statement from SQL and a list of + * arguments to bind to the query, expecting a result list. * <p>The results will be mapped to a List (one entry for each row) of * Maps (one entry for each column, using the column name as the key). * Each element in the list will be of the form returned by this interface's - * queryForMap() methods. - * @param sql SQL query to execute + * {@code queryForMap} methods. + * @param sql the SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not @@ -761,17 +753,17 @@ public interface JdbcOperations { List<Map<String, Object>> queryForList(String sql, Object... args) throws DataAccessException; /** - * Query given SQL to create a prepared statement from SQL and a - * list of arguments to bind to the query, expecting a SqlRowSet. + * Query given SQL to create a prepared statement from SQL and a list of + * arguments to bind to the query, expecting a SqlRowSet. * <p>The results will be mapped to an SqlRowSet which holds the data in a * disconnected fashion. This wrapper will translate any SQLExceptions thrown. * <p>Note that, for the default implementation, JDBC RowSet support needs to * be available at runtime: by default, Sun's {@code com.sun.rowset.CachedRowSetImpl} * class is used, which is part of JDK 1.5+ and also available separately as part of * Sun's JDBC RowSet Implementations download (rowset.jar). - * @param sql SQL query to execute + * @param sql the SQL query to execute * @param args arguments to bind to the query - * @param argTypes SQL types of the arguments + * @param argTypes the SQL types of the arguments * (constants from {@code java.sql.Types}) * @return a SqlRowSet representation (possibly a wrapper around a * {@code javax.sql.rowset.CachedRowSet}) @@ -784,15 +776,15 @@ public interface JdbcOperations { SqlRowSet queryForRowSet(String sql, Object[] args, int[] argTypes) throws DataAccessException; /** - * Query given SQL to create a prepared statement from SQL and a - * list of arguments to bind to the query, expecting a SqlRowSet. + * Query given SQL to create a prepared statement from SQL and a list of + * arguments to bind to the query, expecting a SqlRowSet. * <p>The results will be mapped to an SqlRowSet which holds the data in a * disconnected fashion. This wrapper will translate any SQLExceptions thrown. * <p>Note that, for the default implementation, JDBC RowSet support needs to * be available at runtime: by default, Sun's {@code com.sun.rowset.CachedRowSetImpl} * class is used, which is part of JDK 1.5+ and also available separately as part of * Sun's JDBC RowSet Implementations download (rowset.jar). - * @param sql SQL query to execute + * @param sql the SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not @@ -807,11 +799,12 @@ public interface JdbcOperations { SqlRowSet queryForRowSet(String sql, Object... args) throws DataAccessException; /** - * Issue a single SQL update operation (such as an insert, update or delete statement) - * using a PreparedStatementCreator to provide SQL and any required parameters. + * Issue a single SQL update operation (such as an insert, update or delete + * statement) using a PreparedStatementCreator to provide SQL and any + * required parameters. * <p>A PreparedStatementCreator can either be implemented directly or * configured through a PreparedStatementCreatorFactory. - * @param psc object that provides SQL and any necessary parameters + * @param psc a callback that provides SQL and any necessary parameters * @return the number of rows affected * @throws DataAccessException if there is any problem issuing the update * @see PreparedStatementCreatorFactory @@ -824,8 +817,8 @@ public interface JdbcOperations { * <p>Note that the given PreparedStatementCreator has to create a statement * with activated extraction of generated keys (a JDBC 3.0 feature). This can * either be done directly or through using a PreparedStatementCreatorFactory. - * @param psc object that provides SQL and any necessary parameters - * @param generatedKeyHolder KeyHolder that will hold the generated keys + * @param psc a callback that provides SQL and any necessary parameters + * @param generatedKeyHolder a KeyHolder that will hold the generated keys * @return the number of rows affected * @throws DataAccessException if there is any problem issuing the update * @see PreparedStatementCreatorFactory @@ -838,7 +831,7 @@ public interface JdbcOperations { * with given SQL. Simpler than using a PreparedStatementCreator as this method * will create the PreparedStatement: The PreparedStatementSetter just needs to * set parameters. - * @param sql SQL containing bind parameters + * @param sql the SQL containing bind parameters * @param pss helper that sets bind parameters. If this is {@code null} * we run an update with static SQL. * @return the number of rows affected @@ -849,9 +842,9 @@ public interface JdbcOperations { /** * Issue a single SQL update operation (such as an insert, update or delete statement) * via a prepared statement, binding the given arguments. - * @param sql SQL containing bind parameters + * @param sql the SQL containing bind parameters * @param args arguments to bind to the query - * @param argTypes SQL types of the arguments + * @param argTypes the SQL types of the arguments * (constants from {@code java.sql.Types}) * @return the number of rows affected * @throws DataAccessException if there is any problem issuing the update @@ -862,7 +855,7 @@ public interface JdbcOperations { /** * Issue a single SQL update operation (such as an insert, update or delete statement) * via a prepared statement, binding the given arguments. - * @param sql SQL containing bind parameters + * @param sql the SQL containing bind parameters * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not @@ -898,7 +891,7 @@ public interface JdbcOperations { * Execute a batch using the supplied SQL statement with the batch of supplied arguments. * @param sql the SQL statement to execute. * @param batchArgs the List of Object arrays containing the batch of arguments for the query - * @param argTypes SQL types of the arguments + * @param argTypes the SQL types of the arguments * (constants from {@code java.sql.Types}) * @return an array containing the numbers of rows affected by each update in the batch */ @@ -911,7 +904,7 @@ public interface JdbcOperations { * @param sql the SQL statement to execute. * @param batchArgs the List of Object arrays containing the batch of arguments for the query * @param batchSize batch size - * @param pss ParameterizedPreparedStatementSetter to use + * @param pss the ParameterizedPreparedStatementSetter to use * @return an array containing for each batch another array containing the numbers of rows affected * by each update in the batch * @since 3.1 @@ -927,14 +920,14 @@ public interface JdbcOperations { /** * Execute a JDBC data access operation, implemented as callback action * working on a JDBC CallableStatement. This allows for implementing arbitrary - * data access operations on a single Statement, within Spring's managed - * JDBC environment: that is, participating in Spring-managed transactions - * and converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. - * <p>The callback action can return a result object, for example a - * domain object or a collection of domain objects. - * @param csc object that can create a CallableStatement given a Connection - * @param action callback object that specifies the action - * @return a result object returned by the action, or {@code null} + * data access operations on a single Statement, within Spring's managed JDBC + * environment: that is, participating in Spring-managed transactions and + * converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. + * <p>The callback action can return a result object, for example a domain + * object or a collection of domain objects. + * @param csc a callback that creates a CallableStatement given a Connection + * @param action a callback that specifies the action + * @return a result object returned by the action, or {@code null} if none * @throws DataAccessException if there is any problem */ <T> T execute(CallableStatementCreator csc, CallableStatementCallback<T> action) throws DataAccessException; @@ -942,24 +935,24 @@ public interface JdbcOperations { /** * Execute a JDBC data access operation, implemented as callback action * working on a JDBC CallableStatement. This allows for implementing arbitrary - * data access operations on a single Statement, within Spring's managed - * JDBC environment: that is, participating in Spring-managed transactions - * and converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. - * <p>The callback action can return a result object, for example a - * domain object or a collection of domain objects. + * data access operations on a single Statement, within Spring's managed JDBC + * environment: that is, participating in Spring-managed transactions and + * converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. + * <p>The callback action can return a result object, for example a domain + * object or a collection of domain objects. * @param callString the SQL call string to execute - * @param action callback object that specifies the action - * @return a result object returned by the action, or {@code null} + * @param action a callback that specifies the action + * @return a result object returned by the action, or {@code null} if none * @throws DataAccessException if there is any problem */ <T> T execute(String callString, CallableStatementCallback<T> action) throws DataAccessException; /** - * Execute a SQL call using a CallableStatementCreator to provide SQL and any - * required parameters. - * @param csc object that provides SQL and any necessary parameters + * Execute a SQL call using a CallableStatementCreator to provide SQL and + * any required parameters. + * @param csc a callback that provides SQL and any necessary parameters * @param declaredParameters list of declared SqlParameter objects - * @return Map of extracted out parameters + * @return a Map of extracted out parameters * @throws DataAccessException if there is any problem issuing the update */ Map<String, Object> call(CallableStatementCreator csc, List<SqlParameter> declaredParameters) 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 6f97a196..951e9441 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-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,6 @@ import java.sql.Statement; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -672,11 +671,10 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { * Query using a prepared statement, allowing for a PreparedStatementCreator * and a PreparedStatementSetter. Most other query methods use this method, * but application code will always work with either a creator or a setter. - * @param psc Callback handler that can create a PreparedStatement given a - * Connection - * @param pss object that knows how to set values on the prepared statement. - * If this is null, the SQL will be assumed to contain no bind parameters. - * @param rse object that will extract results. + * @param psc a callback that creates a PreparedStatement given a Connection + * @param pss a callback that knows how to set values on the prepared statement. + * If this is {@code null}, the SQL will be assumed to contain no bind parameters. + * @param rse a callback that will extract results * @return an arbitrary result object, as returned by the ResultSetExtractor * @throws DataAccessException if there is any problem */ @@ -873,6 +871,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { throws DataAccessException { logger.debug("Executing prepared SQL update"); + return execute(psc, new PreparedStatementCallback<Integer>() { @Override public Integer doInPreparedStatement(PreparedStatement ps) throws SQLException { @@ -1054,6 +1053,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { }); } + //------------------------------------------------------------------------- // Methods dealing with callable statements //------------------------------------------------------------------------- @@ -1121,6 +1121,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { final List<SqlParameter> updateCountParameters = new ArrayList<SqlParameter>(); final List<SqlParameter> resultSetParameters = new ArrayList<SqlParameter>(); final List<SqlParameter> callParameters = new ArrayList<SqlParameter>(); + for (SqlParameter parameter : declaredParameters) { if (parameter.isResultsParameter()) { if (parameter instanceof SqlReturnResultSet) { @@ -1134,6 +1135,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { callParameters.add(parameter); } } + return execute(csc, new CallableStatementCallback<Map<String, Object>>() { @Override public Map<String, Object> doInCallableStatement(CallableStatement cs) throws SQLException { @@ -1143,28 +1145,28 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { logger.debug("CallableStatement.execute() returned '" + retVal + "'"); logger.debug("CallableStatement.getUpdateCount() returned " + updateCount); } - Map<String, Object> returnedResults = createResultsMap(); + Map<String, Object> resultsMap = createResultsMap(); if (retVal || updateCount != -1) { - returnedResults.putAll(extractReturnedResults(cs, updateCountParameters, resultSetParameters, updateCount)); + resultsMap.putAll(extractReturnedResults(cs, updateCountParameters, resultSetParameters, updateCount)); } - returnedResults.putAll(extractOutputParameters(cs, callParameters)); - return returnedResults; + resultsMap.putAll(extractOutputParameters(cs, callParameters)); + return resultsMap; } }); } /** * Extract returned ResultSets from the completed stored procedure. - * @param cs JDBC wrapper for the stored procedure - * @param updateCountParameters Parameter list of declared update count parameters for the stored procedure - * @param resultSetParameters Parameter list of declared resultSet parameters for the stored procedure - * @return Map that contains returned results + * @param cs a JDBC wrapper for the stored procedure + * @param updateCountParameters the parameter list of declared update count parameters for the stored procedure + * @param resultSetParameters the parameter list of declared resultSet parameters for the stored procedure + * @return a Map that contains returned results */ protected Map<String, Object> extractReturnedResults(CallableStatement cs, List<SqlParameter> updateCountParameters, List<SqlParameter> resultSetParameters, int updateCount) throws SQLException { - Map<String, Object> returnedResults = new HashMap<String, Object>(); + Map<String, Object> results = new LinkedHashMap<String, Object>(4); int rsIndex = 0; int updateIndex = 0; boolean moreResults; @@ -1173,7 +1175,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { if (updateCount == -1) { if (resultSetParameters != null && resultSetParameters.size() > rsIndex) { SqlReturnResultSet declaredRsParam = (SqlReturnResultSet) resultSetParameters.get(rsIndex); - returnedResults.putAll(processResultSet(cs.getResultSet(), declaredRsParam)); + results.putAll(processResultSet(cs.getResultSet(), declaredRsParam)); rsIndex++; } else { @@ -1183,7 +1185,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { if (logger.isDebugEnabled()) { logger.debug("Added default SqlReturnResultSet parameter named '" + rsName + "'"); } - returnedResults.putAll(processResultSet(cs.getResultSet(), undeclaredRsParam)); + results.putAll(processResultSet(cs.getResultSet(), undeclaredRsParam)); rsIndex++; } } @@ -1192,7 +1194,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { if (updateCountParameters != null && updateCountParameters.size() > updateIndex) { SqlReturnUpdateCount ucParam = (SqlReturnUpdateCount) updateCountParameters.get(updateIndex); String declaredUcName = ucParam.getName(); - returnedResults.put(declaredUcName, updateCount); + results.put(declaredUcName, updateCount); updateIndex++; } else { @@ -1201,7 +1203,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { if (logger.isDebugEnabled()) { logger.debug("Added default SqlReturnUpdateCount parameter named '" + undeclaredName + "'"); } - returnedResults.put(undeclaredName, updateCount); + results.put(undeclaredName, updateCount); updateIndex++; } } @@ -1214,19 +1216,19 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { } while (moreResults || updateCount != -1); } - return returnedResults; + return results; } /** * Extract output parameters from the completed stored procedure. - * @param cs JDBC wrapper for the stored procedure + * @param cs the JDBC wrapper for the stored procedure * @param parameters parameter list for the stored procedure - * @return Map that contains returned results + * @return a Map that contains returned results */ protected Map<String, Object> extractOutputParameters(CallableStatement cs, List<SqlParameter> parameters) throws SQLException { - Map<String, Object> returnedResults = new HashMap<String, Object>(); + Map<String, Object> results = new LinkedHashMap<String, Object>(parameters.size()); int sqlColIndex = 1; for (SqlParameter param : parameters) { if (param instanceof SqlOutParameter) { @@ -1234,25 +1236,25 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { if (outParam.isReturnTypeSupported()) { Object out = outParam.getSqlReturnType().getTypeValue( cs, sqlColIndex, outParam.getSqlType(), outParam.getTypeName()); - returnedResults.put(outParam.getName(), out); + results.put(outParam.getName(), out); } else { Object out = cs.getObject(sqlColIndex); if (out instanceof ResultSet) { if (outParam.isResultSetSupported()) { - returnedResults.putAll(processResultSet((ResultSet) out, outParam)); + results.putAll(processResultSet((ResultSet) out, outParam)); } else { String rsName = outParam.getName(); SqlReturnResultSet rsParam = new SqlReturnResultSet(rsName, getColumnMapRowMapper()); - returnedResults.putAll(processResultSet((ResultSet) out, rsParam)); + results.putAll(processResultSet((ResultSet) out, rsParam)); if (logger.isDebugEnabled()) { logger.debug("Added default SqlReturnResultSet parameter named '" + rsName + "'"); } } } else { - returnedResults.put(outParam.getName(), out); + results.put(outParam.getName(), out); } } } @@ -1260,48 +1262,46 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { sqlColIndex++; } } - return returnedResults; + return results; } /** * Process the given ResultSet from a stored procedure. * @param rs the ResultSet to process * @param param the corresponding stored procedure parameter - * @return Map that contains returned results + * @return a Map that contains returned results */ @SuppressWarnings({"unchecked", "rawtypes"}) protected Map<String, Object> processResultSet(ResultSet rs, ResultSetSupportingSqlParameter param) throws SQLException { - if (rs == null) { - return Collections.emptyMap(); - } - - Map<String, Object> returnedResults = new HashMap<String, Object>(); - try { - ResultSet rsToUse = rs; - if (this.nativeJdbcExtractor != null) { - rsToUse = this.nativeJdbcExtractor.getNativeResultSet(rs); - } - if (param.getRowMapper() != null) { - RowMapper rowMapper = param.getRowMapper(); - Object result = (new RowMapperResultSetExtractor(rowMapper)).extractData(rsToUse); - returnedResults.put(param.getName(), result); - } - else if (param.getRowCallbackHandler() != null) { - RowCallbackHandler rch = param.getRowCallbackHandler(); - (new RowCallbackHandlerResultSetExtractor(rch)).extractData(rsToUse); - returnedResults.put(param.getName(), "ResultSet returned from stored procedure was processed"); + if (rs != null) { + try { + ResultSet rsToUse = rs; + if (this.nativeJdbcExtractor != null) { + rsToUse = this.nativeJdbcExtractor.getNativeResultSet(rs); + } + if (param.getRowMapper() != null) { + RowMapper rowMapper = param.getRowMapper(); + Object data = (new RowMapperResultSetExtractor(rowMapper)).extractData(rsToUse); + return Collections.singletonMap(param.getName(), data); + } + else if (param.getRowCallbackHandler() != null) { + RowCallbackHandler rch = param.getRowCallbackHandler(); + (new RowCallbackHandlerResultSetExtractor(rch)).extractData(rsToUse); + return Collections.singletonMap(param.getName(), + (Object) "ResultSet returned from stored procedure was processed"); + } + else if (param.getResultSetExtractor() != null) { + Object data = param.getResultSetExtractor().extractData(rsToUse); + return Collections.singletonMap(param.getName(), data); + } } - else if (param.getResultSetExtractor() != null) { - Object result = param.getResultSetExtractor().extractData(rsToUse); - returnedResults.put(param.getName(), result); + finally { + JdbcUtils.closeResultSet(rs); } } - finally { - JdbcUtils.closeResultSet(rs); - } - return returnedResults; + return Collections.emptyMap(); } @@ -1392,8 +1392,8 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { } /** - * Throw an SQLWarningException if we're not ignoring warnings, - * else log the warnings (at debug level). + * Throw a SQLWarningException if we're not ignoring warnings, + * otherwise log the warnings at debug level. * @param stmt the current JDBC statement * @throws SQLWarningException if not ignoring warnings * @see org.springframework.jdbc.SQLWarningException @@ -1415,7 +1415,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { } /** - * Throw an SQLWarningException if encountering an actual warning. + * Throw a SQLWarningException if encountering an actual warning. * @param warning the warnings object from the current statement. * May be {@code null}, in which case this method does nothing. * @throws SQLWarningException in case of an actual warning to be raised @@ -1428,8 +1428,8 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { /** * Determine SQL from potential provider object. - * @param sqlProvider object that's potentially a SqlProvider - * @return the SQL string, or {@code null} + * @param sqlProvider object which is potentially a SqlProvider + * @return the SQL string, or {@code null} if not known * @see SqlProvider */ private static String getSql(Object sqlProvider) { @@ -1456,7 +1456,6 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { } @Override - @SuppressWarnings("rawtypes") public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // Invocation on ConnectionProxy interface coming in... diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractMessageBrokerConfiguration.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractMessageBrokerConfiguration.java index b81c1823..9ef7a78e 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractMessageBrokerConfiguration.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractMessageBrokerConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -65,18 +65,20 @@ import org.springframework.validation.Validator; * protocols such as STOMP. * * <p>{@link #clientInboundChannel()} and {@link #clientOutboundChannel()} deliver - * messages to and from remote clients to several message handlers such as + * messages to and from remote clients to several message handlers such as the + * following. * <ul> * <li>{@link #simpAnnotationMethodMessageHandler()}</li> * <li>{@link #simpleBrokerMessageHandler()}</li> * <li>{@link #stompBrokerRelayMessageHandler()}</li> * <li>{@link #userDestinationMessageHandler()}</li> * </ul> - * while {@link #brokerChannel()} delivers messages from within the application to the + * + * <p>{@link #brokerChannel()} delivers messages from within the application to the * the respective message handlers. {@link #brokerMessagingTemplate()} can be injected * into any application component to send messages. * - * <p>Subclasses are responsible for the part of the configuration that feed messages + * <p>Subclasses are responsible for the parts of the configuration that feed messages * to and from the client inbound/outbound channels (e.g. STOMP over WebSocket). * * @author Rossen Stoyanchev @@ -387,7 +389,7 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC * Override this method to add custom message converters. * @param messageConverters the list to add converters to, initially empty * @return {@code true} if default message converters should be added to list, - * {@code false} if no more converters should be added. + * {@code false} if no more converters should be added */ protected boolean configureMessageConverters(List<MessageConverter> messageConverters) { return true; @@ -410,7 +412,7 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC } /** - * Create the user registry that provides access to the local users. + * Create the user registry that provides access to local users. */ protected abstract SimpUserRegistry createLocalUserRegistry(); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java index d4700498..bdd0e14f 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -258,7 +258,7 @@ public class StompDecoder { if (index + 1 >= inString.length()) { throw new StompConversionException("Illegal escape sequence at index " + index + ": " + inString); } - Character c = inString.charAt(index + 1); + char c = inString.charAt(index + 1); if (c == 'r') { sb.append('\r'); } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompSession.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompSession.java index bc358a92..8851a394 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompSession.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompSession.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,8 +17,8 @@ package org.springframework.messaging.simp.stomp; /** - * Represents a STOMP session with operations to send messages, create - * subscriptions and receive messages on those subscriptions. + * Represents a STOMP session with operations to send messages, + * create subscriptions and receive messages on those subscriptions. * * @author Rossen Stoyanchev * @since 4.2 @@ -37,10 +37,10 @@ public interface StompSession { /** * When enabled, a receipt header is automatically added to future - * {@code send} and {@code subscribe} operations on this session, which causes - * the server to return a RECEIPT. An application can then use the - * {@link StompSession.Receiptable - * Receiptable} returned from the operation to track the receipt. + * {@code send} and {@code subscribe} operations on this session, which + * causes the server to return a RECEIPT. An application can then use + * the {@link StompSession.Receiptable Receiptable} returned from the + * operation to track the receipt. * <p>A receipt header can also be added manually through the overloaded * methods that accept {@code StompHeaders}. */ @@ -57,11 +57,11 @@ public interface StompSession { Receiptable send(String destination, Object payload); /** - * An overloaded version of {@link #send(String, Object)} that accepts - * full {@link StompHeaders} instead of a destination. The headers must + * An overloaded version of {@link #send(String, Object)} with full + * {@link StompHeaders} instead of just a destination. The headers must * contain a destination and may also have other headers such as - * "content-type" or custom headers for the broker to propagate to subscribers, - * or broker-specific, non-standard headers.. + * "content-type" or custom headers for the broker to propagate to + * subscribers, or broker-specific, non-standard headers. * @param headers the message headers * @param payload the message payload * @return a Receiptable for tracking receipts @@ -79,7 +79,7 @@ public interface StompSession { /** * An overloaded version of {@link #subscribe(String, StompFrameHandler)} - * that accepts full {@link StompHeaders} rather instead of a destination. + * with full {@link StompHeaders} instead of just a destination. * @param headers the headers for the subscribe message frame * @param handler the handler for received messages * @return a handle to use to unsubscribe and/or track receipts diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/MultiServerUserRegistry.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/MultiServerUserRegistry.java index f155ec70..efe489fc 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/MultiServerUserRegistry.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/MultiServerUserRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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. @@ -63,7 +63,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati * Create an instance wrapping the local user registry. */ public MultiServerUserRegistry(SimpUserRegistry localRegistry) { - Assert.notNull(localRegistry, "'localRegistry' is required."); + Assert.notNull(localRegistry, "'localRegistry' is required"); this.id = generateId(); this.localRegistry = localRegistry; this.delegateApplicationEvents = this.localRegistry instanceof SmartApplicationListener; @@ -274,10 +274,10 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati private String name; - /* User sessions from "this" registry only (i.e. one server) */ + // User sessions from "this" registry only (i.e. one server) private Set<TransferSimpSession> sessions; - /* Cross-server session lookup (e.g. user connected to multiple servers) */ + // Cross-server session lookup (e.g. user connected to multiple servers) private SessionLookup sessionLookup; /** @@ -518,13 +518,13 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati return false; } SimpSubscription otherSubscription = (SimpSubscription) other; - return (ObjectUtils.nullSafeEquals(getSession(), otherSubscription.getSession()) && - this.id.equals(otherSubscription.getId())); + return (getId().equals(otherSubscription.getId()) && + ObjectUtils.nullSafeEquals(getSession(), otherSubscription.getSession())); } @Override public int hashCode() { - return this.id.hashCode() * 31 + ObjectUtils.nullSafeHashCode(getSession()); + return getId().hashCode() * 31 + ObjectUtils.nullSafeHashCode(getSession()); } @Override diff --git a/spring-test/src/main/java/org/springframework/test/context/TestContext.java b/spring-test/src/main/java/org/springframework/test/context/TestContext.java index cd8df7ab..385b3241 100644 --- a/spring-test/src/main/java/org/springframework/test/context/TestContext.java +++ b/spring-test/src/main/java/org/springframework/test/context/TestContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,8 @@ import org.springframework.test.annotation.DirtiesContext.HierarchyMode; * * @author Sam Brannen * @since 2.5 + * @see TestContextManager + * @see TestExecutionListener */ public interface TestContext extends AttributeAccessor, Serializable { @@ -38,7 +40,7 @@ public interface TestContext extends AttributeAccessor, Serializable { * <p>Implementations of this method are responsible for loading the * application context if the corresponding context has not already been * loaded, potentially caching the context as well. - * @return the application context + * @return the application context (never {@code null}) * @throws IllegalStateException if an error occurs while retrieving the * application context */ @@ -70,8 +72,7 @@ public interface TestContext extends AttributeAccessor, Serializable { * Get the {@linkplain Throwable exception} that was thrown during execution * of the {@linkplain #getTestMethod() test method}. * <p>Note: this is a mutable property. - * @return the exception that was thrown, or {@code null} if no - * exception was thrown + * @return the exception that was thrown, or {@code null} if no exception was thrown * @see #updateState(Object, Method, Throwable) */ Throwable getTestException(); @@ -89,14 +90,13 @@ public interface TestContext extends AttributeAccessor, Serializable { void markApplicationContextDirty(HierarchyMode hierarchyMode); /** - * Update this test context to reflect the state of the currently executing - * test. + * Update this test context to reflect the state of the currently executing test. * <p>Caution: concurrent invocations of this method might not be thread-safe, * depending on the underlying implementation. * @param testInstance the current test instance (may be {@code null}) * @param testMethod the current test method (may be {@code null}) - * @param testException the exception that was thrown in the test method, or - * {@code null} if no exception was thrown + * @param testException the exception that was thrown in the test method, + * or {@code null} if no exception was thrown */ void updateState(Object testInstance, Method testMethod, Throwable testException); diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttribute.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttribute.java index debf7a95..79991f12 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttribute.java +++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2019 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. @@ -20,8 +20,8 @@ import org.springframework.transaction.TransactionDefinition; /** * This interface adds a {@code rollbackOn} specification to {@link TransactionDefinition}. - * As custom {@code rollbackOn} is only possible with AOP, this class resides - * in the AOP transaction package. + * As custom {@code rollbackOn} is only possible with AOP, it resides in the AOP-related + * transaction subpackage. * * @author Rod Johnson * @author Juergen Hoeller @@ -35,6 +35,7 @@ public interface TransactionAttribute extends TransactionDefinition { * Return a qualifier value associated with this transaction attribute. * <p>This may be used for choosing a corresponding transaction manager * to process this specific transaction. + * @since 3.0 */ String getQualifier(); diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttributeEditor.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttributeEditor.java index a7d2abdf..ed284719 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttributeEditor.java +++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttributeEditor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,7 +45,6 @@ public class TransactionAttributeEditor extends PropertyEditorSupport { /** * Format is PROPAGATION_NAME,ISOLATION_NAME,readOnly,timeout_NNNN,+Exception1,-Exception2. * Null or the empty string means that the method is non transactional. - * @see java.beans.PropertyEditor#setAsText(java.lang.String) */ @Override public void setAsText(String text) throws IllegalArgumentException { @@ -53,36 +52,36 @@ public class TransactionAttributeEditor extends PropertyEditorSupport { // tokenize it with "," String[] tokens = StringUtils.commaDelimitedListToStringArray(text); RuleBasedTransactionAttribute attr = new RuleBasedTransactionAttribute(); - for (int i = 0; i < tokens.length; i++) { + for (String token : tokens) { // Trim leading and trailing whitespace. - String token = StringUtils.trimWhitespace(tokens[i].trim()); + String trimmedToken = StringUtils.trimWhitespace(token.trim()); // Check whether token contains illegal whitespace within text. - if (StringUtils.containsWhitespace(token)) { + if (StringUtils.containsWhitespace(trimmedToken)) { throw new IllegalArgumentException( - "Transaction attribute token contains illegal whitespace: [" + token + "]"); + "Transaction attribute token contains illegal whitespace: [" + trimmedToken + "]"); } // Check token type. - if (token.startsWith(RuleBasedTransactionAttribute.PREFIX_PROPAGATION)) { - attr.setPropagationBehaviorName(token); + if (trimmedToken.startsWith(RuleBasedTransactionAttribute.PREFIX_PROPAGATION)) { + attr.setPropagationBehaviorName(trimmedToken); } - else if (token.startsWith(RuleBasedTransactionAttribute.PREFIX_ISOLATION)) { - attr.setIsolationLevelName(token); + else if (trimmedToken.startsWith(RuleBasedTransactionAttribute.PREFIX_ISOLATION)) { + attr.setIsolationLevelName(trimmedToken); } - else if (token.startsWith(RuleBasedTransactionAttribute.PREFIX_TIMEOUT)) { - String value = token.substring(DefaultTransactionAttribute.PREFIX_TIMEOUT.length()); + else if (trimmedToken.startsWith(RuleBasedTransactionAttribute.PREFIX_TIMEOUT)) { + String value = trimmedToken.substring(DefaultTransactionAttribute.PREFIX_TIMEOUT.length()); attr.setTimeout(Integer.parseInt(value)); } - else if (token.equals(RuleBasedTransactionAttribute.READ_ONLY_MARKER)) { + else if (trimmedToken.equals(RuleBasedTransactionAttribute.READ_ONLY_MARKER)) { attr.setReadOnly(true); } - else if (token.startsWith(RuleBasedTransactionAttribute.PREFIX_COMMIT_RULE)) { - attr.getRollbackRules().add(new NoRollbackRuleAttribute(token.substring(1))); + else if (trimmedToken.startsWith(RuleBasedTransactionAttribute.PREFIX_COMMIT_RULE)) { + attr.getRollbackRules().add(new NoRollbackRuleAttribute(trimmedToken.substring(1))); } - else if (token.startsWith(RuleBasedTransactionAttribute.PREFIX_ROLLBACK_RULE)) { - attr.getRollbackRules().add(new RollbackRuleAttribute(token.substring(1))); + else if (trimmedToken.startsWith(RuleBasedTransactionAttribute.PREFIX_ROLLBACK_RULE)) { + attr.getRollbackRules().add(new RollbackRuleAttribute(trimmedToken.substring(1))); } else { - throw new IllegalArgumentException("Invalid transaction attribute token: [" + token + "]"); + throw new IllegalArgumentException("Invalid transaction attribute token: [" + trimmedToken + "]"); } } setValue(attr); 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 690b2763..2507b218 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-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -1315,7 +1315,7 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable /** - * Return a {@code HttpHeaders} object that can only be read, not written to. + * Return an {@code HttpHeaders} object that can only be read, not written to. */ public static HttpHeaders readOnlyHttpHeaders(HttpHeaders headers) { Assert.notNull(headers, "HttpHeaders must not be null"); diff --git a/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java b/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java index d439b7cc..4e717f0a 100644 --- a/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java +++ b/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -20,6 +20,7 @@ import java.io.IOException; import java.lang.reflect.Type; import java.net.URI; import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -767,7 +768,7 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat if (this.responseType instanceof Class) { responseClass = (Class<?>) this.responseType; } - List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>(); + Set<MediaType> allSupportedMediaTypes = new LinkedHashSet<MediaType>(); for (HttpMessageConverter<?> converter : getMessageConverters()) { if (responseClass != null) { if (converter.canRead(responseClass, null)) { @@ -782,11 +783,12 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat } } if (!allSupportedMediaTypes.isEmpty()) { - MediaType.sortBySpecificity(allSupportedMediaTypes); + List<MediaType> result = new ArrayList<MediaType>(allSupportedMediaTypes); + MediaType.sortBySpecificity(result); if (logger.isDebugEnabled()) { logger.debug("Setting request Accept header to " + allSupportedMediaTypes); } - request.getHeaders().setAccept(allSupportedMediaTypes); + request.getHeaders().setAccept(result); } } } diff --git a/spring-web/src/test/java/org/springframework/web/client/RestTemplateTests.java b/spring-web/src/test/java/org/springframework/web/client/RestTemplateTests.java index 6f4798af..c1a8bdfb 100644 --- a/spring-web/src/test/java/org/springframework/web/client/RestTemplateTests.java +++ b/spring-web/src/test/java/org/springframework/web/client/RestTemplateTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,8 @@ package org.springframework.web.client; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; @@ -43,6 +45,8 @@ import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.converter.GenericHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.util.StringUtils; import org.springframework.web.util.DefaultUriTemplateHandler; import static org.hamcrest.MatcherAssert.assertThat; @@ -878,4 +882,24 @@ public class RestTemplateTests { verify(response).close(); } + @Test + public void acceptHeaderValueShouldBeNotDuplicated() throws Exception { + final StringHttpMessageConverter utf8HttpMessageConverter = new StringHttpMessageConverter(StandardCharsets.UTF_8); + final StringHttpMessageConverter iso88591HttpMessageConverter = new StringHttpMessageConverter(StandardCharsets.ISO_8859_1); + + final RestTemplate multipleEncodingTemplate = new RestTemplate(Arrays.asList(utf8HttpMessageConverter, iso88591HttpMessageConverter)); + multipleEncodingTemplate.setRequestFactory(requestFactory); + given(requestFactory.createRequest(new URI("http://example.com"), GET)).willReturn(request); + + final HttpHeaders requestHeaders = new HttpHeaders(); + given(request.getHeaders()).willReturn(requestHeaders); + given(request.execute()).willReturn(response); + + final HttpHeaders responseHeaders = new HttpHeaders(); + given(response.getHeaders()).willReturn(responseHeaders); + + multipleEncodingTemplate.getForObject("http://example.com", String.class); + assertEquals("text/plain, */*", StringUtils.collectionToDelimitedString(request.getHeaders().get("accept"), ",")); + } + } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java index da047ed0..9aa9ff5a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -1095,8 +1095,8 @@ public class DispatcherServlet extends FrameworkServlet { logger.debug("Request is already a MultipartHttpServletRequest - if not in a forward, " + "this typically results from an additional MultipartFilter in web.xml"); } - else if (hasMultipartException(request) ) { - logger.debug("Multipart resolution failed for current request before - " + + else if (hasMultipartException(request)) { + logger.debug("Multipart resolution previously failed for current request - " + "skipping re-resolution for undisturbed error rendering"); } else { @@ -1345,7 +1345,7 @@ public class DispatcherServlet extends FrameworkServlet { * @param attributesSnapshot the snapshot of the request attributes before the include */ @SuppressWarnings("unchecked") - private void restoreAttributesAfterInclude(HttpServletRequest request, Map<?,?> attributesSnapshot) { + private void restoreAttributesAfterInclude(HttpServletRequest request, Map<?, ?> attributesSnapshot) { // Need to copy into separate Collection here, to avoid side effects // on the Enumeration when removing attributes. Set<String> attrsToCheck = new HashSet<String>(); @@ -1364,7 +1364,7 @@ public class DispatcherServlet extends FrameworkServlet { // or removing the attribute, respectively, if appropriate. for (String attrName : attrsToCheck) { Object attrValue = attributesSnapshot.get(attrName); - if (attrValue == null){ + if (attrValue == null) { request.removeAttribute(attrName); } else if (attrValue != request.getAttribute(attrName)) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java index 627994d3..7f27b8c0 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -206,7 +206,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { } configurePathMatchingProperties(handlerMappingDef, element, context); - readerContext.getRegistry().registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME , handlerMappingDef); + readerContext.getRegistry().registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME, handlerMappingDef); RuntimeBeanReference corsRef = MvcNamespaceUtils.registerCorsConfigurations(null, context, source); handlerMappingDef.getPropertyValues().add("corsConfigurations", corsRef); @@ -264,7 +264,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { handlerAdapterDef.getPropertyValues().add("callableInterceptors", callableInterceptors); handlerAdapterDef.getPropertyValues().add("deferredResultInterceptors", deferredResultInterceptors); - readerContext.getRegistry().registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME , handlerAdapterDef); + readerContext.getRegistry().registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME, handlerAdapterDef); RootBeanDefinition uriContributorDef = new RootBeanDefinition(CompositeUriComponentsContributorFactoryBean.class); @@ -387,7 +387,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { factoryBeanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); factoryBeanDef.getPropertyValues().add("mediaTypes", getDefaultMediaTypes()); String name = CONTENT_NEGOTIATION_MANAGER_BEAN_NAME; - context.getReaderContext().getRegistry().registerBeanDefinition(name , factoryBeanDef); + context.getReaderContext().getRegistry().registerBeanDefinition(name, factoryBeanDef); context.registerComponent(new BeanComponentDefinition(factoryBeanDef, name)); beanRef = new RuntimeBeanReference(name); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceUtils.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceUtils.java index ed3ea853..4945be22 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceUtils.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -81,8 +81,8 @@ public abstract class MvcNamespaceUtils { } parserContext.getRegistry().registerAlias(urlPathHelperRef.getBeanName(), URL_PATH_HELPER_BEAN_NAME); } - else if (!parserContext.getRegistry().isAlias(URL_PATH_HELPER_BEAN_NAME) - && !parserContext.getRegistry().containsBeanDefinition(URL_PATH_HELPER_BEAN_NAME)) { + else if (!parserContext.getRegistry().isAlias(URL_PATH_HELPER_BEAN_NAME) && + !parserContext.getRegistry().containsBeanDefinition(URL_PATH_HELPER_BEAN_NAME)) { RootBeanDefinition urlPathHelperDef = new RootBeanDefinition(UrlPathHelper.class); urlPathHelperDef.setSource(source); urlPathHelperDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); @@ -106,8 +106,8 @@ public abstract class MvcNamespaceUtils { } parserContext.getRegistry().registerAlias(pathMatcherRef.getBeanName(), PATH_MATCHER_BEAN_NAME); } - else if (!parserContext.getRegistry().isAlias(PATH_MATCHER_BEAN_NAME) - && !parserContext.getRegistry().containsBeanDefinition(PATH_MATCHER_BEAN_NAME)) { + else if (!parserContext.getRegistry().isAlias(PATH_MATCHER_BEAN_NAME) && + !parserContext.getRegistry().containsBeanDefinition(PATH_MATCHER_BEAN_NAME)) { RootBeanDefinition pathMatcherDef = new RootBeanDefinition(AntPathMatcher.class); pathMatcherDef.setSource(source); pathMatcherDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); @@ -122,7 +122,7 @@ public abstract class MvcNamespaceUtils { * name unless already registered. */ private static void registerBeanNameUrlHandlerMapping(ParserContext context, Object source) { - if (!context.getRegistry().containsBeanDefinition(BEAN_NAME_URL_HANDLER_MAPPING_BEAN_NAME)){ + if (!context.getRegistry().containsBeanDefinition(BEAN_NAME_URL_HANDLER_MAPPING_BEAN_NAME)) { RootBeanDefinition mappingDef = new RootBeanDefinition(BeanNameUrlHandlerMapping.class); mappingDef.setSource(source); mappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); @@ -193,7 +193,7 @@ public abstract class MvcNamespaceUtils { * unless already registered. */ private static void registerHandlerMappingIntrospector(ParserContext parserContext, Object source) { - if (!parserContext.getRegistry().containsBeanDefinition(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)){ + if (!parserContext.getRegistry().containsBeanDefinition(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)) { RootBeanDefinition beanDef = new RootBeanDefinition(HandlerMappingIntrospector.class); beanDef.setSource(source); beanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java index 48571d6b..dccb28d0 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -152,7 +152,7 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping i * both "/test" and "/team". For details, see the AntPathMatcher class. * <p>Looks for the most exact pattern, where most exact is defined as * the longest path pattern. - * @param urlPath URL the bean is mapped to + * @param urlPath the URL the bean is mapped to * @param request current HTTP request (to expose the path within the mapping to) * @return the associated handler instance, or {@code null} if not found * @see #exposePathWithinMapping @@ -179,7 +179,7 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping i } else if (useTrailingSlashMatch()) { if (!registeredPattern.endsWith("/") && getPathMatcher().match(registeredPattern + "/", urlPath)) { - matchingPatterns.add(registeredPattern +"/"); + matchingPatterns.add(registeredPattern + "/"); } } } @@ -271,7 +271,9 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping i * @param request the request to expose the path to * @see #PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE */ - protected void exposePathWithinMapping(String bestMatchingPattern, String pathWithinMapping, HttpServletRequest request) { + protected void exposePathWithinMapping(String bestMatchingPattern, String pathWithinMapping, + HttpServletRequest request) { + request.setAttribute(BEST_MATCHING_PATTERN_ATTRIBUTE, bestMatchingPattern); request.setAttribute(PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, pathWithinMapping); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerExceptionResolverComposite.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerExceptionResolverComposite.java index 238ad765..dcf1125e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerExceptionResolverComposite.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerExceptionResolverComposite.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -65,11 +65,11 @@ public class HandlerExceptionResolverComposite implements HandlerExceptionResolv /** * Resolve the exception by iterating over the list of configured exception resolvers. - * The first one to return a ModelAndView instance wins. Otherwise {@code null} is returned. + * <p>The first one to return a {@link ModelAndView} wins. Otherwise {@code null} is returned. */ @Override - public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, - Object handler,Exception ex) { + public ModelAndView resolveException( + HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { if (this.resolvers != null) { for (HandlerExceptionResolver handlerExceptionResolver : this.resolvers) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/AbstractRequestCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/AbstractRequestCondition.java index 26fb5641..1c1ba726 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/AbstractRequestCondition.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/AbstractRequestCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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. @@ -28,16 +28,39 @@ import java.util.Iterator; */ public abstract class AbstractRequestCondition<T extends AbstractRequestCondition<T>> implements RequestCondition<T> { + /** + * Indicates whether this condition is empty, i.e. whether or not it + * contains any discrete items. + * @return {@code true} if empty; {@code false} otherwise + */ + public boolean isEmpty() { + return getContent().isEmpty(); + } + + /** + * Return the discrete items a request condition is composed of. + * <p>For example URL patterns, HTTP request methods, param expressions, etc. + * @return a collection of objects (never {@code null}) + */ + protected abstract Collection<?> getContent(); + + /** + * The notation to use when printing discrete items of content. + * <p>For example {@code " || "} for URL patterns or {@code " && "} + * for param expressions. + */ + protected abstract String getToStringInfix(); + + @Override - public boolean equals(Object obj) { - if (this == obj) { + public boolean equals(Object other) { + if (this == other) { return true; } - if (obj != null && getClass() == obj.getClass()) { - AbstractRequestCondition<?> other = (AbstractRequestCondition<?>) obj; - return getContent().equals(other.getContent()); + if (other == null || getClass() != other.getClass()) { + return false; } - return false; + return getContent().equals(((AbstractRequestCondition<?>) other).getContent()); } @Override @@ -59,28 +82,4 @@ public abstract class AbstractRequestCondition<T extends AbstractRequestConditio return builder.toString(); } - /** - * Indicates whether this condition is empty, i.e. whether or not it - * contains any discrete items. - * @return {@code true} if empty; {@code false} otherwise - */ - public boolean isEmpty() { - return getContent().isEmpty(); - } - - - /** - * Return the discrete items a request condition is composed of. - * <p>For example URL patterns, HTTP request methods, param expressions, etc. - * @return a collection of objects, never {@code null} - */ - protected abstract Collection<?> getContent(); - - /** - * The notation to use when printing discrete items of content. - * <p>For example {@code " || "} for URL patterns or {@code " && "} - * for param expressions. - */ - protected abstract String getToStringInfix(); - } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PatternsRequestCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PatternsRequestCondition.java index 43f5b496..d800d0c9 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PatternsRequestCondition.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PatternsRequestCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2019 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. @@ -179,8 +179,8 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat else { result.add(""); } - return new PatternsRequestCondition(result, this.pathHelper, this.pathMatcher, this.useSuffixPatternMatch, - this.useTrailingSlashMatch, this.fileExtensions); + return new PatternsRequestCondition(result, this.pathHelper, this.pathMatcher, + this.useSuffixPatternMatch, this.useTrailingSlashMatch, this.fileExtensions); } /** @@ -201,17 +201,14 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat */ @Override public PatternsRequestCondition getMatchingCondition(HttpServletRequest request) { - if (this.patterns.isEmpty()) { return this; } - String lookupPath = this.pathHelper.getLookupPathForRequest(request); List<String> matches = getMatchingPatterns(lookupPath); - - return matches.isEmpty() ? null : - new PatternsRequestCondition(matches, this.pathHelper, this.pathMatcher, this.useSuffixPatternMatch, - this.useTrailingSlashMatch, this.fileExtensions); + return (!matches.isEmpty() ? + new PatternsRequestCondition(matches, this.pathHelper, this.pathMatcher, + this.useSuffixPatternMatch, this.useTrailingSlashMatch, this.fileExtensions) : null); } /** @@ -259,7 +256,7 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat } if (this.useTrailingSlashMatch) { if (!pattern.endsWith("/") && this.pathMatcher.match(pattern + "/", lookupPath)) { - return pattern +"/"; + return pattern + "/"; } } return null; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMethodMappingNamingStrategy.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMethodMappingNamingStrategy.java index 4fe3ea65..982bebbc 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMethodMappingNamingStrategy.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMethodMappingNamingStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,7 +46,7 @@ public class RequestMappingInfoHandlerMethodMappingNamingStrategy } StringBuilder sb = new StringBuilder(); String simpleTypeName = handlerMethod.getBeanType().getSimpleName(); - for (int i = 0 ; i < simpleTypeName.length(); i++) { + for (int i = 0; i < simpleTypeName.length(); i++) { if (Character.isUpperCase(simpleTypeName.charAt(i))) { sb.append(simpleTypeName.charAt(i)); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java index 57be99d1..e1c2cef2 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -117,7 +117,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce * resolution use {@link #setArgumentResolvers} instead. */ public void setCustomArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { - this.customArgumentResolvers= argumentResolvers; + this.customArgumentResolvers = argumentResolvers; } /** diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SessionAttributeMethodArgumentResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SessionAttributeMethodArgumentResolver.java index 7c7d0811..38a1bd27 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SessionAttributeMethodArgumentResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SessionAttributeMethodArgumentResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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. @@ -53,7 +53,7 @@ public class SessionAttributeMethodArgumentResolver extends AbstractNamedValueMe @Override protected void handleMissingValue(String name, MethodParameter parameter) throws ServletException { throw new ServletRequestBindingException("Missing session attribute '" + name + - "' of type " + parameter.getNestedParameterType().getSimpleName()); + "' of type " + parameter.getNestedParameterType().getSimpleName()); } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ViewMethodReturnValueHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ViewMethodReturnValueHandler.java index d9d8abd2..2d8b4fce 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ViewMethodReturnValueHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ViewMethodReturnValueHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,7 +52,7 @@ public class ViewMethodReturnValueHandler implements HandlerMethodReturnValueHan if (returnValue == null) { return; } - else if (returnValue instanceof View){ + else if (returnValue instanceof View) { View view = (View) returnValue; mavContainer.setView(view); if (view instanceof SmartView) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ViewNameMethodReturnValueHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ViewNameMethodReturnValueHandler.java index 9601ce60..ca846f90 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ViewNameMethodReturnValueHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ViewNameMethodReturnValueHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2019 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,10 +32,10 @@ import org.springframework.web.servlet.RequestToViewNameTranslator; * as the actual return value is left as-is allowing the configured * {@link RequestToViewNameTranslator} to select a view name by convention. * - * <p>A String return value can be interpreted in more than one ways depending - * on the presence of annotations like {@code @ModelAttribute} or - * {@code @ResponseBody}. Therefore this handler should be configured after - * the handlers that support these annotations. + * <p>A String return value can be interpreted in more than one ways depending on + * the presence of annotations like {@code @ModelAttribute} or {@code @ResponseBody}. + * Therefore this handler should be configured after the handlers that support these + * annotations. * * @author Rossen Stoyanchev * @author Juergen Hoeller @@ -47,12 +47,10 @@ public class ViewNameMethodReturnValueHandler implements HandlerMethodReturnValu /** - * Configure one more simple patterns (as described in - * {@link PatternMatchUtils#simpleMatch}) to use in order to recognize - * custom redirect prefixes in addition to "redirect:". - * <p>Note that simply configuring this property will not make a custom - * redirect prefix work. There must be a custom View that recognizes the - * prefix as well. + * Configure one more simple patterns (as described in {@link PatternMatchUtils#simpleMatch}) + * to use in order to recognize custom redirect prefixes in addition to "redirect:". + * <p>Note that simply configuring this property will not make a custom redirect prefix work. + * There must be a custom View that recognizes the prefix as well. * @since 4.1 */ public void setRedirectPatterns(String... redirectPatterns) { @@ -84,7 +82,7 @@ public class ViewNameMethodReturnValueHandler implements HandlerMethodReturnValu mavContainer.setRedirectModelScenario(true); } } - else if (returnValue != null){ + else if (returnValue != null) { // should not happen throw new UnsupportedOperationException("Unexpected return type: " + returnType.getParameterType().getName() + " in method: " + returnType.getMethod()); diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/EnableWebSocket.java b/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/EnableWebSocket.java index af8d056d..170fc18f 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/EnableWebSocket.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/EnableWebSocket.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ import org.springframework.context.annotation.Import; /** * Add this annotation to an {@code @Configuration} class to configure - * processing WebSocket requests: + * processing WebSocket requests. A typical configuration would look like this: * * <pre class="code"> * @Configuration @@ -49,7 +49,7 @@ import org.springframework.context.annotation.Import; * registry.addHandler(echoWebSocketHandler(), "/echo").withSockJS(); * } * - * @Bean + * @Override * public WebSocketHandler echoWebSocketHandler() { * return new EchoWebSocketHandler(); * } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/EnableWebSocketMessageBroker.java b/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/EnableWebSocketMessageBroker.java index e9d4d85e..bcd2a4b7 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/EnableWebSocketMessageBroker.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/EnableWebSocketMessageBroker.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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. @@ -50,7 +50,7 @@ import org.springframework.context.annotation.Import; * registry.addEndpoint("/portfolio").withSockJS(); * } * - * @Bean + * @Override * public void configureMessageBroker(MessageBrokerRegistry registry) { * registry.enableStompBrokerRelay("/queue/", "/topic/"); * registry.setApplicationDestinationPrefixes("/app/"); diff --git a/src/asciidoc/core-beans.adoc b/src/asciidoc/core-beans.adoc index f899f2c7..249bb87a 100644 --- a/src/asciidoc/core-beans.adoc +++ b/src/asciidoc/core-beans.adoc @@ -3560,11 +3560,11 @@ init-method. [[aware-list]] === Other Aware interfaces -Besides `ApplicationContextAware` and `BeanNameAware` discussed above, Spring offers a -range of `Aware` interfaces that allow beans to indicate to the container that they -require a certain __infrastructure__ dependency. The most important `Aware` interfaces -are summarized below - as a general rule, the name is a good indication of the -dependency type: +Besides `ApplicationContextAware` and `BeanNameAware` discussed above, Spring offers +a range of `Aware` callback interfaces that allow beans to indicate to the container +that they require a certain __infrastructure__ dependency. The most important `Aware` +interfaces are summarized below - as a general rule, the name is a good indication of +the dependency type: [[beans-factory-nature-aware-list]] .Aware interfaces diff --git a/src/asciidoc/core-resources.adoc b/src/asciidoc/core-resources.adoc index 4ba4ce1b..699e5a48 100644 --- a/src/asciidoc/core-resources.adoc +++ b/src/asciidoc/core-resources.adoc @@ -289,8 +289,8 @@ The following table summarizes the strategy for converting ``String``s to ``Reso [[resources-resourceloaderaware]] == The ResourceLoaderAware interface -The `ResourceLoaderAware` interface is a special marker interface, identifying objects -that expect to be provided with a `ResourceLoader` reference. +The `ResourceLoaderAware` interface is a special callback interface which identifies +components that expect to be provided with a `ResourceLoader` reference: [source,java,indent=0] [subs="verbatim,quotes"] diff --git a/src/asciidoc/integration.adoc b/src/asciidoc/integration.adoc index 825c58e3..1b8442ea 100644 --- a/src/asciidoc/integration.adoc +++ b/src/asciidoc/integration.adoc @@ -1932,10 +1932,9 @@ operations that do not refer to a specific destination. One of the most common uses of JMS messages in the EJB world is to drive message-driven beans (MDBs). Spring offers a solution to create message-driven POJOs (MDPs) in a way -that does not tie a user to an EJB container. (See <<jms-asynchronousMessageReception>> -for detailed coverage of Spring's MDP support.) As from Spring Framework 4.1, endpoint -methods can be simply annotated using `@JmsListener` see <<jms-annotated>> for more -details. +that does not tie a user to an EJB container. (See <<jms-receiving-async>> for detailed +coverage of Spring's MDP support.) As from Spring Framework 4.1, endpoint methods can +be simply annotated using `@JmsListener` see <<jms-annotated>> for more details. A message listener container is used to receive messages from a JMS message queue and drive the `MessageListener` that is injected into it. The listener container is @@ -2209,7 +2208,7 @@ potentially be blocked indefinitely. The property `receiveTimeout` specifies how the receiver should wait before giving up waiting for a message. -[[jms-asynchronousMessageReception]] +[[jms-receiving-async]] ==== Asynchronous reception: Message-Driven POJOs [NOTE] |