Commit ef9a891c authored by Emmanuel Bourg's avatar Emmanuel Bourg

New upstream version 4.3.18

parent 9a51aaff
......@@ -62,7 +62,7 @@ configure(allprojects) { project ->
ext.jtaVersion = "1.2"
ext.junitVersion = "4.12"
ext.log4jVersion = "1.2.17"
ext.nettyVersion = "4.1.24.Final"
ext.nettyVersion = "4.1.25.Final"
ext.okhttpVersion = "2.7.5"
ext.okhttp3Version = "3.8.1"
ext.openjpaVersion = "2.4.2"
......
version=4.3.17.RELEASE
version=4.3.18.RELEASE
/*
* Copyright 2002-2016 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.
......@@ -34,6 +34,7 @@ import org.springframework.context.annotation.Role;
* @see org.springframework.cache.annotation.CachingConfigurationSelector
*/
@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class AspectJCachingConfiguration extends AbstractCachingConfiguration {
@Bean(name = CacheManagementConfigUtils.CACHE_ASPECT_BEAN_NAME)
......
/*
* 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.
......@@ -34,6 +34,7 @@ import org.springframework.context.annotation.Role;
* @see org.springframework.cache.annotation.CachingConfigurationSelector
*/
@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class AspectJJCacheConfiguration extends AbstractJCacheConfiguration {
@Bean(name = CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME)
......
......@@ -76,15 +76,16 @@ public abstract class YamlProcessor {
* name: My Cool App
* </pre>
* when mapped with
* <code>documentMatchers = YamlProcessor.mapMatcher({"environment": "prod"})</code>
* <pre class="code">
* setDocumentMatchers(properties ->
* ("prod".equals(properties.getProperty("environment")) ? MatchStatus.FOUND : MatchStatus.NOT_FOUND));
* </pre>
* would end up as
* <pre class="code">
* environment=prod
* url=http://foo.bar.com
* name=My Cool App
* url=http://dev.bar.com
* </pre>
* @param matchers a map of keys to value patterns (regular expressions)
*/
public void setDocumentMatchers(DocumentMatcher... matchers) {
this.documentMatchers = Arrays.asList(matchers);
......@@ -93,8 +94,7 @@ public abstract class YamlProcessor {
/**
* Flag indicating that a document for which all the
* {@link #setDocumentMatchers(DocumentMatcher...) document matchers} abstain will
* nevertheless match.
* @param matchDefault the flag to set (default true)
* nevertheless match. Default is {@code true}.
*/
public void setMatchDefault(boolean matchDefault) {
this.matchDefault = matchDefault;
......@@ -103,9 +103,7 @@ public abstract class YamlProcessor {
/**
* Method to use for resolving resources. Each resource will be converted to a Map,
* so this property is used to decide which map entries to keep in the final output
* from this factory.
* @param resolutionMethod the resolution method to set (defaults to
* {@link ResolutionMethod#OVERRIDE}).
* from this factory. Default is {@link ResolutionMethod#OVERRIDE}.
*/
public void setResolutionMethod(ResolutionMethod resolutionMethod) {
Assert.notNull(resolutionMethod, "ResolutionMethod must not be null");
......
/*
* Copyright 2002-2016 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.
......@@ -47,17 +47,16 @@ public class YamlPropertiesFactoryBeanTests {
@Test
public void testLoadResource() throws Exception {
public void testLoadResource() {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(new ByteArrayResource(
"foo: bar\nspam:\n foo: baz".getBytes()));
factory.setResources(new ByteArrayResource("foo: bar\nspam:\n foo: baz".getBytes()));
Properties properties = factory.getObject();
assertThat(properties.getProperty("foo"), equalTo("bar"));
assertThat(properties.getProperty("spam.foo"), equalTo("baz"));
}
@Test
public void testBadResource() throws Exception {
public void testBadResource() {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(new ByteArrayResource(
"foo: bar\ncd\nspam:\n foo: baz".getBytes()));
......@@ -67,7 +66,7 @@ public class YamlPropertiesFactoryBeanTests {
}
@Test
public void testLoadResourcesWithOverride() throws Exception {
public void testLoadResourcesWithOverride() {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(
new ByteArrayResource("foo: bar\nspam:\n foo: baz".getBytes()),
......@@ -79,7 +78,7 @@ public class YamlPropertiesFactoryBeanTests {
}
@Test
public void testLoadResourcesWithInternalOverride() throws Exception {
public void testLoadResourcesWithInternalOverride() {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(new ByteArrayResource(
"foo: bar\nspam:\n foo: baz\nfoo: bucket".getBytes()));
......@@ -89,7 +88,7 @@ public class YamlPropertiesFactoryBeanTests {
@Test
@Ignore("We can't fail on duplicate keys because the Map is created by the YAML library")
public void testLoadResourcesWithNestedInternalOverride() throws Exception {
public void testLoadResourcesWithNestedInternalOverride() {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(new ByteArrayResource(
"foo:\n bar: spam\n foo: baz\nbreak: it\nfoo: bucket".getBytes()));
......@@ -98,7 +97,7 @@ public class YamlPropertiesFactoryBeanTests {
}
@Test
public void testLoadResourceWithMultipleDocuments() throws Exception {
public void testLoadResourceWithMultipleDocuments() {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(new ByteArrayResource(
"foo: bar\nspam: baz\n---\nfoo: bag".getBytes()));
......@@ -108,37 +107,29 @@ public class YamlPropertiesFactoryBeanTests {
}
@Test
public void testLoadResourceWithSelectedDocuments() throws Exception {
public void testLoadResourceWithSelectedDocuments() {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(new ByteArrayResource(
"foo: bar\nspam: baz\n---\nfoo: bag\nspam: bad".getBytes()));
factory.setDocumentMatchers(new DocumentMatcher() {
@Override
public MatchStatus matches(Properties properties) {
return ("bag".equals(properties.getProperty("foo")) ?
MatchStatus.FOUND : MatchStatus.NOT_FOUND);
}
});
factory.setDocumentMatchers(properties -> ("bag".equals(properties.getProperty("foo")) ?
MatchStatus.FOUND : MatchStatus.NOT_FOUND));
Properties properties = factory.getObject();
assertThat(properties.getProperty("foo"), equalTo("bag"));
assertThat(properties.getProperty("spam"), equalTo("bad"));
}
@Test
public void testLoadResourceWithDefaultMatch() throws Exception {
public void testLoadResourceWithDefaultMatch() {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setMatchDefault(true);
factory.setResources(new ByteArrayResource(
"one: two\n---\nfoo: bar\nspam: baz\n---\nfoo: bag\nspam: bad".getBytes()));
factory.setDocumentMatchers(new DocumentMatcher() {
@Override
public MatchStatus matches(Properties properties) {
if (!properties.containsKey("foo")) {
return MatchStatus.ABSTAIN;
}
return ("bag".equals(properties.getProperty("foo")) ?
MatchStatus.FOUND : MatchStatus.NOT_FOUND);
factory.setDocumentMatchers(properties -> {
if (!properties.containsKey("foo")) {
return MatchStatus.ABSTAIN;
}
return ("bag".equals(properties.getProperty("foo")) ?
MatchStatus.FOUND : MatchStatus.NOT_FOUND);
});
Properties properties = factory.getObject();
assertThat(properties.getProperty("foo"), equalTo("bag"));
......@@ -147,7 +138,7 @@ public class YamlPropertiesFactoryBeanTests {
}
@Test
public void testLoadResourceWithoutDefaultMatch() throws Exception {
public void testLoadResourceWithoutDefaultMatch() {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setMatchDefault(false);
factory.setResources(new ByteArrayResource(
......@@ -169,20 +160,17 @@ public class YamlPropertiesFactoryBeanTests {
}
@Test
public void testLoadResourceWithDefaultMatchSkippingMissedMatch() throws Exception {
public void testLoadResourceWithDefaultMatchSkippingMissedMatch() {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setMatchDefault(true);
factory.setResources(new ByteArrayResource(
"one: two\n---\nfoo: bag\nspam: bad\n---\nfoo: bar\nspam: baz".getBytes()));
factory.setDocumentMatchers(new DocumentMatcher() {
@Override
public MatchStatus matches(Properties properties) {
if (!properties.containsKey("foo")) {
return MatchStatus.ABSTAIN;
}
return ("bag".equals(properties.getProperty("foo")) ?
MatchStatus.FOUND : MatchStatus.NOT_FOUND);
factory.setDocumentMatchers(properties -> {
if (!properties.containsKey("foo")) {
return MatchStatus.ABSTAIN;
}
return ("bag".equals(properties.getProperty("foo")) ?
MatchStatus.FOUND : MatchStatus.NOT_FOUND);
});
Properties properties = factory.getObject();
assertThat(properties.getProperty("foo"), equalTo("bag"));
......@@ -191,7 +179,7 @@ public class YamlPropertiesFactoryBeanTests {
}
@Test
public void testLoadNonExistentResource() throws Exception {
public void testLoadNonExistentResource() {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResolutionMethod(ResolutionMethod.OVERRIDE_AND_IGNORE);
factory.setResources(new ClassPathResource("no-such-file.yml"));
......@@ -200,7 +188,7 @@ public class YamlPropertiesFactoryBeanTests {
}
@Test
public void testLoadNull() throws Exception {
public void testLoadNull() {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(new ByteArrayResource("foo: bar\nspam:".getBytes()));
Properties properties = factory.getObject();
......@@ -209,7 +197,7 @@ public class YamlPropertiesFactoryBeanTests {
}
@Test
public void testLoadArrayOfString() throws Exception {
public void testLoadArrayOfString() {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(new ByteArrayResource("foo:\n- bar\n- baz".getBytes()));
Properties properties = factory.getObject();
......@@ -219,7 +207,7 @@ public class YamlPropertiesFactoryBeanTests {
}
@Test
public void testLoadArrayOfInteger() throws Exception {
public void testLoadArrayOfInteger() {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(new ByteArrayResource("foo:\n- 1\n- 2".getBytes()));
Properties properties = factory.getObject();
......@@ -229,7 +217,7 @@ public class YamlPropertiesFactoryBeanTests {
}
@Test
public void testLoadArrayOfObject() throws Exception {
public void testLoadArrayOfObject() {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(new ByteArrayResource(
"foo:\n- bar:\n spam: crap\n- baz\n- one: two\n three: four".getBytes()
......@@ -247,8 +235,8 @@ public class YamlPropertiesFactoryBeanTests {
public void testYaml() {
Yaml yaml = new Yaml();
Map<String, ?> map = yaml.loadAs("foo: bar\nspam:\n foo: baz", Map.class);
assertThat(map.get("foo"), equalTo((Object) "bar"));
assertThat(((Map<String, Object>) map.get("spam")).get("foo"), equalTo((Object) "baz"));
assertThat(map.get("foo"), equalTo("bar"));
assertThat(((Map<String, Object>) map.get("spam")).get("foo"), equalTo("baz"));
}
}
/*
* 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.
......@@ -36,6 +36,7 @@ import org.springframework.context.annotation.Role;
* @see org.springframework.cache.annotation.CachingConfigurationSelector
*/
@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyJCacheConfiguration extends AbstractJCacheConfiguration {
@Bean(name = CacheManagementConfigUtils.JCACHE_ADVISOR_BEAN_NAME)
......
......@@ -470,61 +470,21 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
this.resourceLoader = this.applicationContext;
}
// Initialize the SchedulerFactory instance...
SchedulerFactory schedulerFactory = prepareSchedulerFactory();
if (this.resourceLoader != null) {
// Make given ResourceLoader available for SchedulerFactory configuration.
configTimeResourceLoaderHolder.set(this.resourceLoader);
}
if (this.taskExecutor != null) {
// Make given TaskExecutor available for SchedulerFactory configuration.
configTimeTaskExecutorHolder.set(this.taskExecutor);
}
if (this.dataSource != null) {
// Make given DataSource available for SchedulerFactory configuration.
configTimeDataSourceHolder.set(this.dataSource);
}
if (this.nonTransactionalDataSource != null) {
// Make given non-transactional DataSource available for SchedulerFactory configuration.
configTimeNonTransactionalDataSourceHolder.set(this.nonTransactionalDataSource);
}
// Get Scheduler instance from SchedulerFactory.
// Initialize the Scheduler instance...
this.scheduler = prepareScheduler(prepareSchedulerFactory());
try {
this.scheduler = createScheduler(schedulerFactory, this.schedulerName);
populateSchedulerContext();
if (!this.jobFactorySet && !(this.scheduler instanceof RemoteScheduler)) {
// Use AdaptableJobFactory as default for a local Scheduler, unless when
// explicitly given a null value through the "jobFactory" bean property.
this.jobFactory = new AdaptableJobFactory();
}
if (this.jobFactory != null) {
if (this.jobFactory instanceof SchedulerContextAware) {
((SchedulerContextAware) this.jobFactory).setSchedulerContext(this.scheduler.getContext());
}
this.scheduler.setJobFactory(this.jobFactory);
}
registerListeners();
registerJobsAndTriggers();
}
finally {
if (this.resourceLoader != null) {
configTimeResourceLoaderHolder.remove();
}
if (this.taskExecutor != null) {
configTimeTaskExecutorHolder.remove();
catch (Exception ex) {
try {
this.scheduler.shutdown(true);
}
if (this.dataSource != null) {
configTimeDataSourceHolder.remove();
}
if (this.nonTransactionalDataSource != null) {
configTimeNonTransactionalDataSourceHolder.remove();
catch (Exception ex2) {
logger.debug("Scheduler shutdown exception after registration failure", ex2);
}
throw ex;
}
registerListeners();
registerJobsAndTriggers();
}
......@@ -591,6 +551,59 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
schedulerFactory.initialize(mergedProps);
}
private Scheduler prepareScheduler(SchedulerFactory schedulerFactory) throws SchedulerException {
if (this.resourceLoader != null) {
// Make given ResourceLoader available for SchedulerFactory configuration.
configTimeResourceLoaderHolder.set(this.resourceLoader);
}
if (this.taskExecutor != null) {
// Make given TaskExecutor available for SchedulerFactory configuration.
configTimeTaskExecutorHolder.set(this.taskExecutor);
}
if (this.dataSource != null) {
// Make given DataSource available for SchedulerFactory configuration.
configTimeDataSourceHolder.set(this.dataSource);
}
if (this.nonTransactionalDataSource != null) {
// Make given non-transactional DataSource available for SchedulerFactory configuration.
configTimeNonTransactionalDataSourceHolder.set(this.nonTransactionalDataSource);
}
// Get Scheduler instance from SchedulerFactory.
try {
Scheduler scheduler = createScheduler(schedulerFactory, this.schedulerName);
populateSchedulerContext(scheduler);
if (!this.jobFactorySet && !(scheduler instanceof RemoteScheduler)) {
// Use AdaptableJobFactory as default for a local Scheduler, unless when
// explicitly given a null value through the "jobFactory" bean property.
this.jobFactory = new AdaptableJobFactory();
}
if (this.jobFactory != null) {
if (this.jobFactory instanceof SchedulerContextAware) {
((SchedulerContextAware) this.jobFactory).setSchedulerContext(scheduler.getContext());
}
scheduler.setJobFactory(this.jobFactory);
}
return scheduler;
}
finally {
if (this.resourceLoader != null) {
configTimeResourceLoaderHolder.remove();
}
if (this.taskExecutor != null) {
configTimeTaskExecutorHolder.remove();
}
if (this.dataSource != null) {
configTimeDataSourceHolder.remove();
}
if (this.nonTransactionalDataSource != null) {
configTimeNonTransactionalDataSourceHolder.remove();
}
}
}
/**
* Create the Scheduler instance for the given factory and scheduler name.
* Called by {@link #afterPropertiesSet}.
......@@ -610,7 +623,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
Thread currentThread = Thread.currentThread();
ClassLoader threadContextClassLoader = currentThread.getContextClassLoader();
boolean overrideClassLoader = (this.resourceLoader != null &&
!this.resourceLoader.getClassLoader().equals(threadContextClassLoader));
this.resourceLoader.getClassLoader() != threadContextClassLoader);
if (overrideClassLoader) {
currentThread.setContextClassLoader(this.resourceLoader.getClassLoader());
}
......@@ -642,10 +655,10 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
* Expose the specified context attributes and/or the current
* ApplicationContext in the Quartz SchedulerContext.
*/
private void populateSchedulerContext() throws SchedulerException {
private void populateSchedulerContext(Scheduler scheduler) throws SchedulerException {
// Put specified objects into Scheduler context.
if (this.schedulerContextMap != null) {
getScheduler().getContext().putAll(this.schedulerContextMap);
scheduler.getContext().putAll(this.schedulerContextMap);
}
// Register ApplicationContext in Scheduler context.
......@@ -655,7 +668,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
"SchedulerFactoryBean needs to be set up in an ApplicationContext " +
"to be able to handle an 'applicationContextSchedulerContextKey'");
}
getScheduler().getContext().put(this.applicationContextSchedulerContextKey, this.applicationContext);
scheduler.getContext().put(this.applicationContextSchedulerContextKey, this.applicationContext);
}
}
......
/*
* 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.
......@@ -35,6 +35,7 @@ import org.springframework.context.annotation.Role;
* @see CachingConfigurationSelector
*/
@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyCachingConfiguration extends AbstractCachingConfiguration {
@Bean(name = CacheManagementConfigUtils.CACHE_ADVISOR_BEAN_NAME)
......
......@@ -18,7 +18,6 @@ package org.springframework.context.annotation.configuration;
import org.junit.Test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.FactoryBean;
......@@ -67,7 +66,7 @@ public class DuplicatePostProcessingTests {
private final ExampleBean exampleBean = new ExampleBean();
@Override
public ExampleBean getObject() throws Exception {
public ExampleBean getObject() {
return this.exampleBean;
}
......@@ -87,14 +86,13 @@ public class DuplicatePostProcessingTests {
private ApplicationContext applicationContext;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof ExampleBean) {
this.applicationContext.publishEvent(new ExampleApplicationEvent(this));
}
......@@ -102,12 +100,13 @@ public class DuplicatePostProcessingTests {
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
}
@SuppressWarnings("serial")
static class ExampleApplicationEvent extends ApplicationEvent {
public ExampleApplicationEvent(Object source) {
......@@ -126,7 +125,7 @@ public class DuplicatePostProcessingTests {
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
}
......
......@@ -36,13 +36,10 @@ import org.springframework.util.ReflectionUtils;
/**
* A function reference is of the form "#someFunction(a,b,c)". Functions may be defined
* in the context prior to the expression being evaluated or within the expression itself
* using a lambda function definition. For example: Lambda function definition in an
* expression: "(#max = {|x,y|$x>$y?$x:$y};max(2,3))" Calling context defined function:
* "#isEven(37)". Functions may also be static java methods, registered in the context
* prior to invocation of the expression.
* in the context prior to the expression being evaluated. Functions may also be static
* Java methods, registered in the context prior to invocation of the expression.
*
* <p>Functions are very simplistic, the arguments are not part of the definition
* <p>Functions are very simplistic. The arguments are not part of the definition
* (right now), so the names must be unique.
*
* @author Andy Clement
......@@ -71,7 +68,7 @@ public class FunctionReference extends SpelNodeImpl {
throw new SpelEvaluationException(getStartPosition(), SpelMessage.FUNCTION_NOT_DEFINED, this.name);
}
if (!(value.getValue() instanceof Method)) {
// Two possibilities: a lambda function or a Java static method registered as a function
// Possibly a static Java method registered as a function
throw new SpelEvaluationException(
SpelMessage.FUNCTION_REFERENCE_CANNOT_BE_INVOKED, this.name, value.getClass());
}
......
......@@ -83,7 +83,10 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
private final Map<PropertyCacheKey, TypeDescriptor> typeDescriptorCache =
new ConcurrentHashMap<PropertyCacheKey, TypeDescriptor>(64);
private InvokerPair lastReadInvokerPair;
private final Map<Class<?>, Method[]> sortedMethodsCache =
new ConcurrentHashMap<Class<?>, Method[]>(64);
private volatile InvokerPair lastReadInvokerPair;
/**
......@@ -277,6 +280,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
throw new AccessException("Type conversion failure", evaluationException);
}
}
PropertyCacheKey cacheKey = new PropertyCacheKey(type, name, target instanceof Class);
Member cachedMember = this.writerCache.get(cacheKey);
......@@ -400,7 +404,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
private Method findMethodForProperty(String[] methodSuffixes, String prefix, Class<?> clazz,
boolean mustBeStatic, int numberOfParams, Set<Class<?>> requiredReturnTypes) {
Method[] methods = getSortedClassMethods(clazz);
Method[] methods = getSortedMethods(clazz);
for (String methodSuffix : methodSuffixes) {
for (Method method : methods) {
if (isCandidateForProperty(method, clazz) && method.getName().equals(prefix + methodSuffix) &&
......@@ -428,16 +432,20 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
}
/**
* Return class methods ordered with non bridge methods appearing higher.
* Return class methods ordered with non-bridge methods appearing higher.
*/
private Method[] getSortedClassMethods(Class<?> clazz) {
Method[] methods = clazz.getMethods();
Arrays.sort(methods, new Comparator<Method>() {
@Override
public int compare(Method o1, Method o2) {
return (o1.isBridge() == o2.isBridge()) ? 0 : (o1.isBridge() ? 1 : -1);
}
});
private Method[] getSortedMethods(Class<?> clazz) {
Method[] methods = this.sortedMethodsCache.get(clazz);
if (methods == null) {
methods = clazz.getMethods();
Arrays.sort(methods, new Comparator<Method>() {
@Override
public int compare(Method o1, Method o2) {
return (o1.isBridge() == o2.isBridge()) ? 0 : (o1.isBridge() ? 1 : -1);
}
});
this.sortedMethodsCache.put(clazz, methods);
}
return methods;
}
......
/*
* 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.
......@@ -51,13 +51,12 @@ public class ColumnMapRowMapper implements RowMapper<Map<String, Object>> {
public Map<String, Object> mapRow(ResultSet rs, int rowNum) throws SQLException {
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
Map<String, Object> mapOfColValues = createColumnMap(columnCount);
Map<String, Object> mapOfColumnValues = createColumnMap(columnCount);
for (int i = 1; i <= columnCount; i++) {
String key = getColumnKey(JdbcUtils.lookupColumnName(rsmd, i));
Object obj = getColumnValue(rs, i);
mapOfColValues.put(key, obj);
String column = JdbcUtils.lookupColumnName(rsmd, i);
mapOfColumnValues.put(getColumnKey(column), getColumnValue(rs, i));
}
return mapOfColValues;
return mapOfColumnValues;
}
/**
......
......@@ -38,6 +38,7 @@ import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.lang.UsesJava7;
import org.springframework.util.ClassUtils;
import org.springframework.util.NumberUtils;
import org.springframework.util.StringUtils;
/**
* Generic utility methods for working with JDBC. Mainly for internal use
......@@ -335,7 +336,7 @@ public abstract class JdbcUtils {
return action.processMetaData(metaData);
}
catch (CannotGetJdbcConnectionException ex) {
throw new MetaDataAccessException("Could not get Connection for extracting meta data", ex);
throw new MetaDataAccessException("Could not get Connection for extracting meta-data", ex);
}
catch (SQLException ex) {
throw new MetaDataAccessException("Error while extracting DatabaseMetaData", ex);
......@@ -458,13 +459,13 @@ public abstract class JdbcUtils {