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;
+ }
}
}