Merge branch '2.0.x'
This commit is contained in:
@@ -57,7 +57,7 @@ class CollectionBinder extends IndexedElementsBinder<Collection<Object>> {
|
||||
@Override
|
||||
protected Collection<Object> merge(Supplier<Collection<Object>> existing,
|
||||
Collection<Object> additional) {
|
||||
Collection<Object> existingCollection = existing.get();
|
||||
Collection<Object> existingCollection = getExistingIfPossible(existing);
|
||||
if (existingCollection == null) {
|
||||
return additional;
|
||||
}
|
||||
@@ -71,6 +71,15 @@ class CollectionBinder extends IndexedElementsBinder<Collection<Object>> {
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<Object> getExistingIfPossible(Supplier<Collection<Object>> existing) {
|
||||
try {
|
||||
return existing.get();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<Object> copyIfPossible(Collection<Object> collection) {
|
||||
try {
|
||||
return createNewCollection(collection);
|
||||
|
||||
@@ -85,26 +85,45 @@ class MapBinder extends AggregateBinder<Map<Object, Object>> {
|
||||
@Override
|
||||
protected Map<Object, Object> merge(Supplier<Map<Object, Object>> existing,
|
||||
Map<Object, Object> additional) {
|
||||
Map<Object, Object> existingMap = existing.get();
|
||||
Map<Object, Object> existingMap = getExistingIfPossible(existing);
|
||||
if (existingMap == null) {
|
||||
return additional;
|
||||
}
|
||||
existingMap.putAll(additional);
|
||||
return copyIfPossible(existingMap);
|
||||
try {
|
||||
existingMap.putAll(additional);
|
||||
return copyIfPossible(existingMap);
|
||||
}
|
||||
catch (UnsupportedOperationException ex) {
|
||||
Map<Object, Object> result = createNewMap(additional.getClass(), existingMap);
|
||||
result.putAll(additional);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private Map<Object, Object> getExistingIfPossible(Supplier<Map<Object, Object>> existing) {
|
||||
try {
|
||||
return existing.get();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Map<Object, Object> copyIfPossible(Map<Object, Object> map) {
|
||||
try {
|
||||
Map<Object, Object> result = CollectionFactory.createMap(map.getClass(),
|
||||
map.size());
|
||||
result.putAll(map);
|
||||
return result;
|
||||
return createNewMap(map.getClass(), map);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
private Map<Object, Object> createNewMap(Class<?> mapClass, Map<Object, Object> map) {
|
||||
Map<Object, Object> result = CollectionFactory.createMap(mapClass, map.size());
|
||||
result.putAll(map);
|
||||
return result;
|
||||
}
|
||||
|
||||
private class EntryBinder {
|
||||
|
||||
private final ConfigurationPropertyName root;
|
||||
|
||||
@@ -417,6 +417,16 @@ public class CollectionBinderTests {
|
||||
assertThat(bean.getBar()).containsExactly("hello");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindToBeanWithExceptionInGetterForExistingValue() {
|
||||
MockConfigurationPropertySource source = new MockConfigurationPropertySource();
|
||||
source.put("foo.values", "a,b,c");
|
||||
this.sources.add(source);
|
||||
BeanWithGetterException result = this.binder
|
||||
.bind("foo", Bindable.of(BeanWithGetterException.class)).get();
|
||||
assertThat(result.getValues()).containsExactly("a", "b", "c");
|
||||
}
|
||||
|
||||
public static class ExampleCollectionBean {
|
||||
|
||||
private List<String> items = new ArrayList<>();
|
||||
@@ -521,4 +531,18 @@ public class CollectionBinderTests {
|
||||
|
||||
}
|
||||
|
||||
public static class BeanWithGetterException {
|
||||
|
||||
private List<String> values;
|
||||
|
||||
public void setValues(List<String> values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public List<String> getValues() {
|
||||
return Collections.unmodifiableList(this.values);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -615,6 +615,32 @@ public class MapBinderTests {
|
||||
assertThat(result.getItems()).containsExactly(entry("a", "b"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindToImmutableMapShouldReturnPopulatedCollection() {
|
||||
MockConfigurationPropertySource source = new MockConfigurationPropertySource();
|
||||
source.put("foo.values.c", "d");
|
||||
source.put("foo.values.e", "f");
|
||||
this.sources.add(source);
|
||||
Map<String, String> result = this.binder
|
||||
.bind("foo.values",
|
||||
STRING_STRING_MAP
|
||||
.withExistingValue(Collections.singletonMap("a", "b")))
|
||||
.get();
|
||||
assertThat(result).hasSize(3);
|
||||
assertThat(result.entrySet()).containsExactly(entry("a", "b"), entry("c", "d"),
|
||||
entry("e", "f"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindToBeanWithExceptionInGetterForExistingValue() {
|
||||
MockConfigurationPropertySource source = new MockConfigurationPropertySource();
|
||||
source.put("foo.values.a", "b");
|
||||
this.sources.add(source);
|
||||
BeanWithGetterException result = this.binder
|
||||
.bind("foo", Bindable.of(BeanWithGetterException.class)).get();
|
||||
assertThat(result.getValues()).containsExactly(entry("a", "b"));
|
||||
}
|
||||
|
||||
private <K, V> Bindable<Map<K, V>> getMapBindable(Class<K> keyGeneric,
|
||||
ResolvableType valueType) {
|
||||
ResolvableType keyType = ResolvableType.forClass(keyGeneric);
|
||||
@@ -720,4 +746,18 @@ public class MapBinderTests {
|
||||
|
||||
}
|
||||
|
||||
public static class BeanWithGetterException {
|
||||
|
||||
private Map<String, String> values;
|
||||
|
||||
public void setValues(Map<String, String> values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public Map<String, String> getValues() {
|
||||
return Collections.unmodifiableMap(this.values);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user