Fix relaxed binding of camel-case properties

Extended RelaxedDataBinder to include a case insensitive version of
SEPARATED_TO_CAMELCASE. This allow properties of the form TEST_THE_VALUE
to to bound to a @ConfigurationProperties class with a prefix of "test"
and a field of `theValue`.

Fixes gh-2304
pull/2280/merge
Phillip Webb 10 years ago
parent 3cd40e2488
commit 6056b96828

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2014 the original author or authors. * Copyright 2012-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -201,7 +201,6 @@ public class RelaxedDataBinder extends DataBinder {
} }
private String initializePath(BeanWrapper wrapper, BeanPath path, int index) { private String initializePath(BeanWrapper wrapper, BeanPath path, int index) {
String prefix = path.prefix(index); String prefix = path.prefix(index);
String key = path.name(index); String key = path.name(index);
if (path.isProperty(index)) { if (path.isProperty(index)) {

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2013 the original author or authors. * Copyright 2012-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -158,8 +158,23 @@ public final class RelaxedNames implements Iterable<String> {
SEPARATED_TO_CAMELCASE { SEPARATED_TO_CAMELCASE {
@Override @Override
public String apply(String value) { public String apply(String value) {
return separatedToCamelCase(value, false);
}
},
CASE_INSENSITIVE_SEPARATED_TO_CAMELCASE {
@Override
public String apply(String value) {
return separatedToCamelCase(value, true);
}
};
public abstract String apply(String value);
private static String separatedToCamelCase(String value, boolean caseInsensitive) {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
for (String field : value.split("[_\\-.]")) { for (String field : value.split("[_\\-.]")) {
field = (caseInsensitive ? field.toLowerCase() : field);
builder.append(builder.length() == 0 ? field : StringUtils builder.append(builder.length() == 0 ? field : StringUtils
.capitalize(field)); .capitalize(field));
} }
@ -169,11 +184,8 @@ public final class RelaxedNames implements Iterable<String> {
} }
} }
return builder.toString(); return builder.toString();
}
};
public abstract String apply(String value);
} }
}
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2013 the original author or authors. * Copyright 2012-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -37,6 +37,7 @@ public class RelaxedNamesTests {
assertThat(iterator.next(), equalTo("my-RELAXED-property")); assertThat(iterator.next(), equalTo("my-RELAXED-property"));
assertThat(iterator.next(), equalTo("my_RELAXED_property")); assertThat(iterator.next(), equalTo("my_RELAXED_property"));
assertThat(iterator.next(), equalTo("myRELAXEDProperty")); assertThat(iterator.next(), equalTo("myRELAXEDProperty"));
assertThat(iterator.next(), equalTo("myRelaxedProperty"));
assertThat(iterator.next(), equalTo("my-relaxed-property")); assertThat(iterator.next(), equalTo("my-relaxed-property"));
assertThat(iterator.next(), equalTo("my_relaxed_property")); assertThat(iterator.next(), equalTo("my_relaxed_property"));
assertThat(iterator.next(), equalTo("myrelaxedproperty")); assertThat(iterator.next(), equalTo("myrelaxedproperty"));

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2014 the original author or authors. * Copyright 2012-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -136,10 +136,20 @@ public class ConfigurationPropertiesBindingPostProcessorTests {
@Test @Test
public void testPropertyWithEnum() throws Exception { public void testPropertyWithEnum() throws Exception {
this.context = new AnnotationConfigApplicationContext(); this.context = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(this.context, "test.value:foo"); EnvironmentTestUtils.addEnvironment(this.context, "test.the-value:foo");
this.context.register(PropertyWithEnum.class); this.context.register(PropertyWithEnum.class);
this.context.refresh(); this.context.refresh();
assertThat(this.context.getBean(PropertyWithEnum.class).getValue(), assertThat(this.context.getBean(PropertyWithEnum.class).getTheValue(),
equalTo(FooEnum.FOO));
}
@Test
public void testRelaxedPropertyWithEnum() throws Exception {
this.context = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(this.context, "TEST_THE_VALUE:FoO");
this.context.register(PropertyWithEnum.class);
this.context.refresh();
assertThat(this.context.getBean(PropertyWithEnum.class).getTheValue(),
equalTo(FooEnum.FOO)); equalTo(FooEnum.FOO));
} }
@ -349,14 +359,14 @@ public class ConfigurationPropertiesBindingPostProcessorTests {
@ConfigurationProperties(prefix = "test") @ConfigurationProperties(prefix = "test")
public static class PropertyWithEnum { public static class PropertyWithEnum {
private FooEnum value; private FooEnum theValue;
public void setValue(FooEnum value) { public void setTheValue(FooEnum value) {
this.value = value; this.theValue = value;
} }
public FooEnum getValue() { public FooEnum getTheValue() {
return this.value; return this.theValue;
} }
} }

Loading…
Cancel
Save