Merge branch '2.0.x'

This commit is contained in:
Madhura Bhave
2018-06-01 14:59:27 -07:00
4 changed files with 100 additions and 8 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}