diff --git a/eclipse/org.eclipse.jdt.ui.prefs b/eclipse/org.eclipse.jdt.ui.prefs index 43281c1a5c..45d41ec935 100644 --- a/eclipse/org.eclipse.jdt.ui.prefs +++ b/eclipse/org.eclipse.jdt.ui.prefs @@ -87,7 +87,7 @@ sp_cleanup.always_use_this_for_non_static_method_access=false sp_cleanup.convert_to_enhanced_for_loop=false sp_cleanup.correct_indentation=false sp_cleanup.format_source_code=true -sp_cleanup.format_source_code_changes_only=true +sp_cleanup.format_source_code_changes_only=false sp_cleanup.make_local_variable_final=false sp_cleanup.make_parameters_final=false sp_cleanup.make_private_fields_final=false diff --git a/spring-boot-deployment-tests/pom.xml b/spring-boot-deployment-tests/pom.xml index f1af1b523f..4051933721 100644 --- a/spring-boot-deployment-tests/pom.xml +++ b/spring-boot-deployment-tests/pom.xml @@ -20,7 +20,7 @@ ${basedir}/.. 1.7 300000 - ${user.home}/.cargo/installs + ${java.io.tmpdir}/cargo/installs spring-boot-deployment-test-tomee diff --git a/spring-boot/src/main/java/org/springframework/boot/bind/PropertySourcesPropertyValues.java b/spring-boot/src/main/java/org/springframework/boot/bind/PropertySourcesPropertyValues.java index 705326a731..2d14b3359e 100644 --- a/spring-boot/src/main/java/org/springframework/boot/bind/PropertySourcesPropertyValues.java +++ b/spring-boot/src/main/java/org/springframework/boot/bind/PropertySourcesPropertyValues.java @@ -19,6 +19,8 @@ package org.springframework.boot.bind; import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.regex.Pattern; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.PropertyValue; @@ -37,17 +39,22 @@ import org.springframework.validation.DataBinder; * used with the latter. * * @author Dave Syer + * @author Phillip Webb */ public class PropertySourcesPropertyValues implements PropertyValues { - private final PropertySources propertySources; + private static final Pattern COLLECTION_PROPERTY = Pattern.compile("\\[(\\d+)\\]"); - private final Map propertyValues = new LinkedHashMap(); + private final PropertySources propertySources; private final Collection nonEnumerableFallbackNames; private final PropertyNamePatternsMatcher includes; + private final Map propertyValues = new LinkedHashMap(); + + private final ConcurrentHashMap> collectionOwners = new ConcurrentHashMap>(); + /** * Create a new PropertyValues from the given PropertySources. * @param propertySources a PropertySources instance @@ -187,10 +194,15 @@ public class PropertySourcesPropertyValues implements PropertyValues { private PropertyValue putIfAbsent(String propertyName, Object value, PropertySource source) { if (value != null && !this.propertyValues.containsKey(propertyName)) { - PropertyValue propertyValue = new OriginCapablePropertyValue(propertyName, - value, propertyName, source); - this.propertyValues.put(propertyName, propertyValue); - return propertyValue; + PropertySource collectionOwner = this.collectionOwners.putIfAbsent( + COLLECTION_PROPERTY.matcher(propertyName).replaceAll("[]"), source); + if (collectionOwner == null || collectionOwner == source) { + this.collectionOwners.get(this.collectionOwners); + PropertyValue propertyValue = new OriginCapablePropertyValue( + propertyName, value, propertyName, source); + this.propertyValues.put(propertyName, propertyValue); + return propertyValue; + } } return null; } diff --git a/spring-boot/src/test/java/org/springframework/boot/bind/PropertySourcesPropertyValuesTests.java b/spring-boot/src/test/java/org/springframework/boot/bind/PropertySourcesPropertyValuesTests.java index 2cf79477cd..b480c97486 100644 --- a/spring-boot/src/test/java/org/springframework/boot/bind/PropertySourcesPropertyValuesTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/bind/PropertySourcesPropertyValuesTests.java @@ -17,9 +17,11 @@ package org.springframework.boot.bind; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import org.junit.Before; @@ -31,12 +33,15 @@ import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.PropertySource; import org.springframework.validation.DataBinder; +import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; /** * Tests for {@link PropertySourcesPropertyValues}. * * @author Dave Syer + * @author Phillip Webb */ public class PropertySourcesPropertyValuesTests { @@ -192,7 +197,35 @@ public class PropertySourcesPropertyValuesTests { assertEquals(null, target.getName()); } + @Test + public void testCollectionProperty() throws Exception { + ListBean target = new ListBean(); + DataBinder binder = new DataBinder(target); + Map map = new LinkedHashMap(); + map.put("list[0]", "v0"); + map.put("list[1]", "v1"); + this.propertySources.addFirst(new MapPropertySource("values", map)); + binder.bind(new PropertySourcesPropertyValues(this.propertySources)); + assertThat(target.getList(), equalTo(Arrays.asList("v0", "v1"))); + } + + @Test + public void testFirstCollectionPropertyWins() throws Exception { + ListBean target = new ListBean(); + DataBinder binder = new DataBinder(target); + Map first = new LinkedHashMap(); + first.put("list[0]", "f0"); + Map second = new LinkedHashMap(); + second.put("list[0]", "s0"); + second.put("list[1]", "s1"); + this.propertySources.addFirst(new MapPropertySource("s", second)); + this.propertySources.addFirst(new MapPropertySource("f", first)); + binder.bind(new PropertySourcesPropertyValues(this.propertySources)); + assertThat(target.getList(), equalTo(Collections.singletonList("f0"))); + } + public static class TestBean { + private String name; public String getName() { @@ -205,6 +238,7 @@ public class PropertySourcesPropertyValuesTests { } public static class FooBean { + private String foo; public String getFoo() { @@ -214,6 +248,20 @@ public class PropertySourcesPropertyValuesTests { public void setFoo(String foo) { this.foo = foo; } + + } + + public static class ListBean { + + private List list = new ArrayList(); + + public List getList() { + return this.list; + } + + public void setList(List list) { + this.list = list; + } } }