Commit 9384e5c3 authored by Madhura Bhave's avatar Madhura Bhave

Fix binding to bean with cloned arrays

Fixes gh-12478
parent cb3da28b
......@@ -57,10 +57,10 @@ abstract class AggregateBinder<T> {
AggregateElementBinder elementBinder) {
Object result = bindAggregate(name, target, elementBinder);
Supplier<?> value = target.getValue();
if (result == null || value == null || value.get() == null) {
if (result == null || value == null) {
return result;
}
return merge((T) value.get(), (T) result);
return merge(value, (T) result);
}
/**
......@@ -75,11 +75,11 @@ abstract class AggregateBinder<T> {
/**
* Merge any additional elements into the existing aggregate.
* @param existing the existing value
* @param existing the supplier for the existing value
* @param additional the additional elements to merge
* @return the merged result
*/
protected abstract T merge(T existing, T additional);
protected abstract T merge(Supplier<?> existing, T additional);
/**
* Return the context being used by this binder.
......
......@@ -19,6 +19,7 @@ package org.springframework.boot.context.properties.bind;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import org.springframework.boot.context.properties.bind.Binder.Context;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
......@@ -55,7 +56,7 @@ class ArrayBinder extends IndexedElementsBinder<Object> {
}
@Override
protected Object merge(Object existing, Object additional) {
protected Object merge(Supplier<?> existing, Object additional) {
return additional;
}
......
......@@ -18,6 +18,7 @@ package org.springframework.boot.context.properties.bind;
import java.util.Collection;
import java.util.List;
import java.util.function.Supplier;
import org.springframework.boot.context.properties.bind.Binder.Context;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
......@@ -54,12 +55,17 @@ class CollectionBinder extends IndexedElementsBinder<Collection<Object>> {
}
@Override
protected Collection<Object> merge(Collection<Object> existing,
@SuppressWarnings("unchecked")
protected Collection<Object> merge(Supplier<?> existing,
Collection<Object> additional) {
Collection<Object> existingCollection = (Collection<Object>) existing.get();
if (existingCollection == null) {
return additional;
}
try {
existing.clear();
existing.addAll(additional);
return existing;
existingCollection.clear();
existingCollection.addAll(additional);
return existingCollection;
}
catch (UnsupportedOperationException ex) {
return createNewCollection(additional);
......
......@@ -19,6 +19,7 @@ package org.springframework.boot.context.properties.bind;
import java.util.Collection;
import java.util.Map;
import java.util.Properties;
import java.util.function.Supplier;
import org.springframework.boot.context.properties.bind.Binder.Context;
import org.springframework.boot.context.properties.source.ConfigurationProperty;
......@@ -82,10 +83,15 @@ class MapBinder extends AggregateBinder<Map<Object, Object>> {
}
@Override
protected Map<Object, Object> merge(Map<Object, Object> existing,
@SuppressWarnings("unchecked")
protected Map<Object, Object> merge(Supplier<?> existing,
Map<Object, Object> additional) {
existing.putAll(additional);
return existing;
Map<Object, Object> existingMap = (Map<Object, Object>) existing.get();
if (existingMap == null) {
return additional;
}
existingMap.putAll(additional);
return existingMap;
}
private class EntryBinder {
......
......@@ -384,6 +384,17 @@ public class CollectionBinderTests {
this.binder.bind("foo", target);
}
@Test
public void bindToBeanWithClonedArray() {
MockConfigurationPropertySource source = new MockConfigurationPropertySource();
source.put("foo.bar[0]", "hello");
this.sources.add(source);
Bindable<ClonedArrayBean> target = Bindable
.of(ClonedArrayBean.class);
ClonedArrayBean bean = this.binder.bind("foo", target).get();
assertThat(bean.getBar()).contains("hello");
}
public static class ExampleCollectionBean {
private List<String> items = new ArrayList<>();
......@@ -457,4 +468,19 @@ public class CollectionBinderTests {
}
}
public static class ClonedArrayBean {
private String[] bar;
public String[] getBar() {
return this.bar.clone();
}
public void setBar(String[] bar) {
this.bar = bar;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment