Add support for RelaxedDataBinder aliases
Update RelaxedDataBinder to support property aliases and change DataSourceBuilder to use them. Fixes gh-1384
This commit is contained in:
parent
a6e6e1e07a
commit
8476a79dd2
|
|
@ -23,7 +23,6 @@ import javax.sql.DataSource;
|
|||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.PropertyValues;
|
||||
import org.springframework.boot.bind.RelaxedDataBinder;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
|
|
@ -84,15 +83,8 @@ public class DataSourceBuilder {
|
|||
}
|
||||
|
||||
private void bind(DataSource result) {
|
||||
new RelaxedDataBinder(result).bind(getPropertyValues());
|
||||
}
|
||||
|
||||
private PropertyValues getPropertyValues() {
|
||||
if (getType().getName().contains("Hikari") && this.properties.containsKey("url")) {
|
||||
this.properties.put("jdbcUrl", this.properties.get("url"));
|
||||
this.properties.remove("url");
|
||||
}
|
||||
return new MutablePropertyValues(this.properties);
|
||||
MutablePropertyValues properties = new MutablePropertyValues(this.properties);
|
||||
new RelaxedDataBinder(result).withAlias("url", "jdbcUrl").bind(properties);
|
||||
}
|
||||
|
||||
public DataSourceBuilder type(Class<? extends DataSource> type) {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.springframework.boot.bind;
|
|||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -29,6 +30,8 @@ import org.springframework.beans.InvalidPropertyException;
|
|||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.PropertyValue;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.validation.DataBinder;
|
||||
|
||||
|
|
@ -47,6 +50,8 @@ public class RelaxedDataBinder extends DataBinder {
|
|||
|
||||
private boolean ignoreNestedProperties;
|
||||
|
||||
private MultiValueMap<String, String> nameAliases = new LinkedMultiValueMap<String, String>();
|
||||
|
||||
/**
|
||||
* Create a new {@link RelaxedDataBinder} instance.
|
||||
* @param target the target into which properties are bound
|
||||
|
|
@ -76,6 +81,27 @@ public class RelaxedDataBinder extends DataBinder {
|
|||
this.ignoreNestedProperties = ignoreNestedProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set name aliases.
|
||||
* @param aliases a map of property name to aliases
|
||||
*/
|
||||
public void setNameAliases(Map<String, List<String>> aliases) {
|
||||
this.nameAliases = new LinkedMultiValueMap<String, String>(aliases);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add aliases to the {@link DataBinder}.
|
||||
* @param name the property name to alias
|
||||
* @param alias aliases for the property names
|
||||
* @return this instance
|
||||
*/
|
||||
public RelaxedDataBinder withAlias(String name, String... alias) {
|
||||
for (String value : alias) {
|
||||
this.nameAliases.add(name, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initBeanPropertyAccess() {
|
||||
super.initBeanPropertyAccess();
|
||||
|
|
@ -262,19 +288,33 @@ public class RelaxedDataBinder extends DataBinder {
|
|||
|
||||
private String getActualPropertyName(BeanWrapper target, String prefix, String name) {
|
||||
prefix = StringUtils.hasText(prefix) ? prefix + "." : "";
|
||||
for (String candidate : new RelaxedNames(name)) {
|
||||
try {
|
||||
if (target.getPropertyType(prefix + candidate) != null) {
|
||||
return candidate;
|
||||
Iterable<String> names = getNameAndAliases(name);
|
||||
for (String nameOrAlias : names) {
|
||||
for (String candidate : new RelaxedNames(nameOrAlias)) {
|
||||
try {
|
||||
if (target.getPropertyType(prefix + candidate) != null) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
catch (InvalidPropertyException ex) {
|
||||
// swallow and continue
|
||||
}
|
||||
}
|
||||
catch (InvalidPropertyException ex) {
|
||||
// swallow and continue
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private Iterable<String> getNameAndAliases(String name) {
|
||||
List<String> aliases = this.nameAliases.get(name);
|
||||
if (aliases == null) {
|
||||
return Collections.singleton(name);
|
||||
}
|
||||
List<String> nameAndAliases = new ArrayList<String>(aliases.size() + 1);
|
||||
nameAndAliases.add(name);
|
||||
nameAndAliases.addAll(aliases);
|
||||
return nameAndAliases;
|
||||
}
|
||||
|
||||
private static Object wrapTarget(Object target) {
|
||||
if (target instanceof Map) {
|
||||
@SuppressWarnings("unchecked")
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
|||
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
|
@ -444,6 +445,28 @@ public class RelaxedDataBinderTests {
|
|||
doTestBindCaseInsensitiveEnums(target);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindWithoutAlais() throws Exception {
|
||||
VanillaTarget target = new VanillaTarget();
|
||||
MutablePropertyValues properties = new MutablePropertyValues();
|
||||
properties.add("flub", "a");
|
||||
properties.add("foo", "b");
|
||||
new RelaxedDataBinder(target).bind(properties);
|
||||
assertThat(target.getFooBaz(), nullValue());
|
||||
assertThat(target.getFoo(), equalTo("b"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindWithAlias() throws Exception {
|
||||
VanillaTarget target = new VanillaTarget();
|
||||
MutablePropertyValues properties = new MutablePropertyValues();
|
||||
properties.add("flub", "a");
|
||||
properties.add("foo", "b");
|
||||
new RelaxedDataBinder(target).withAlias("flub", "fooBaz").bind(properties);
|
||||
assertThat(target.getFooBaz(), equalTo("a"));
|
||||
assertThat(target.getFoo(), equalTo("b"));
|
||||
}
|
||||
|
||||
private void doTestBindCaseInsensitiveEnums(VanillaTarget target) throws Exception {
|
||||
BindingResult result = bind(target, "bingo: THIS");
|
||||
assertThat(result.getErrorCount(), equalTo(0));
|
||||
|
|
|
|||
Loading…
Reference in New Issue