diff --git a/spring-boot/src/main/java/org/springframework/boot/bind/RelaxedNames.java b/spring-boot/src/main/java/org/springframework/boot/bind/RelaxedNames.java index 6940df604c2..83b02dcc00d 100644 --- a/spring-boot/src/main/java/org/springframework/boot/bind/RelaxedNames.java +++ b/spring-boot/src/main/java/org/springframework/boot/bind/RelaxedNames.java @@ -97,13 +97,19 @@ public final class RelaxedNames implements Iterable { return value; } }, - UNDERSCORE { + HYPHEN_TO_UNDERSCORE { @Override public String apply(String value) { return value.replace("-", "_"); } }, - UNCAMELCASE { + PERIOD_TO_UNDERSCORE { + @Override + public String apply(String value) { + return value.replace(".", "_"); + } + }, + CAMELCASE_TO_UNDERSCORE { @Override public String apply(String value) { value = value.replaceAll("([^A-Z-])([A-Z])", "$1_$2"); @@ -119,14 +125,18 @@ public final class RelaxedNames implements Iterable { return builder.toString(); } }, - CAMELCASE { + UNDERSCORE_TO_CAMELCASE { @Override public String apply(String value) { StringBuilder builder = new StringBuilder(); - for (String field : UNDERSCORE.apply(value).split("_")) { + for (String field : value.split("[_\\-.]")) { builder.append(builder.length() == 0 ? field : StringUtils .capitalize(field)); } + for (String suffix : new String[] { "_", "-", "." }) + if (value.endsWith(suffix)) { + builder.append(suffix); + } return builder.toString(); } }; diff --git a/spring-boot/src/main/java/org/springframework/boot/bind/RelaxedPropertyResolver.java b/spring-boot/src/main/java/org/springframework/boot/bind/RelaxedPropertyResolver.java index 541adf7938d..d37a9e02776 100644 --- a/spring-boot/src/main/java/org/springframework/boot/bind/RelaxedPropertyResolver.java +++ b/spring-boot/src/main/java/org/springframework/boot/bind/RelaxedPropertyResolver.java @@ -81,10 +81,9 @@ public class RelaxedPropertyResolver implements PropertyResolver { @Override public T getProperty(String key, Class targetType, T defaultValue) { - for (String relaxedKey : new RelaxedNames(key)) { - if (this.resolver.containsProperty(this.prefix + relaxedKey)) { - return this.resolver.getProperty(this.prefix + relaxedKey, targetType, - defaultValue); + for (String relaxedKey : new RelaxedNames(this.prefix + key)) { + if (this.resolver.containsProperty(relaxedKey)) { + return this.resolver.getProperty(relaxedKey, targetType, defaultValue); } } return defaultValue; @@ -92,10 +91,9 @@ public class RelaxedPropertyResolver implements PropertyResolver { @Override public Class getPropertyAsClass(String key, Class targetType) { - for (String relaxedKey : new RelaxedNames(key)) { - if (this.resolver.containsProperty(this.prefix + relaxedKey)) { - return this.resolver.getPropertyAsClass(this.prefix + relaxedKey, - targetType); + for (String relaxedKey : new RelaxedNames(this.prefix + key)) { + if (this.resolver.containsProperty(relaxedKey)) { + return this.resolver.getPropertyAsClass(relaxedKey, targetType); } } return null; @@ -103,8 +101,8 @@ public class RelaxedPropertyResolver implements PropertyResolver { @Override public boolean containsProperty(String key) { - for (String relaxedKey : new RelaxedNames(key)) { - if (this.resolver.containsProperty(this.prefix + relaxedKey)) { + for (String relaxedKey : new RelaxedNames(this.prefix + key)) { + if (this.resolver.containsProperty(relaxedKey)) { return true; } } @@ -126,7 +124,7 @@ public class RelaxedPropertyResolver implements PropertyResolver { /** * Return a Map of all values from all underlying properties that start with the - * specified key. NOTE: this method can only be used in the underlying resolver is a + * specified key. NOTE: this method can only be used if the underlying resolver is a * {@link ConfigurableEnvironment}. * @param keyPrefix the key prefix used to filter results * @return a map of all sub properties starting with the specified key prefix. diff --git a/spring-boot/src/test/java/org/springframework/boot/bind/RelaxedNamesTests.java b/spring-boot/src/test/java/org/springframework/boot/bind/RelaxedNamesTests.java index 6d99910a5b2..41728ea56fb 100644 --- a/spring-boot/src/test/java/org/springframework/boot/bind/RelaxedNamesTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/bind/RelaxedNamesTests.java @@ -76,4 +76,27 @@ public class RelaxedNamesTests { assertThat(iterator.hasNext(), equalTo(false)); } + @Test + public void fromPeriods() throws Exception { + Iterator iterator = new RelaxedNames("spring.value").iterator(); + assertThat(iterator.next(), equalTo("spring.value")); + assertThat(iterator.next(), equalTo("spring_value")); + assertThat(iterator.next(), equalTo("springValue")); + assertThat(iterator.next(), equalTo("springvalue")); + assertThat(iterator.next(), equalTo("SPRING.VALUE")); + assertThat(iterator.next(), equalTo("SPRING_VALUE")); + assertThat(iterator.next(), equalTo("SPRINGVALUE")); + assertThat(iterator.hasNext(), equalTo(false)); + } + + @Test + public void fromPrefixEndingInPeriod() throws Exception { + Iterator iterator = new RelaxedNames("spring.").iterator(); + assertThat(iterator.next(), equalTo("spring.")); + assertThat(iterator.next(), equalTo("spring_")); + assertThat(iterator.next(), equalTo("SPRING.")); + assertThat(iterator.next(), equalTo("SPRING_")); + assertThat(iterator.hasNext(), equalTo(false)); + } + } diff --git a/spring-boot/src/test/java/org/springframework/boot/bind/RelaxedPropertyResolverTests.java b/spring-boot/src/test/java/org/springframework/boot/bind/RelaxedPropertyResolverTests.java index fdcbd3c22b8..c9ec646a11f 100644 --- a/spring-boot/src/test/java/org/springframework/boot/bind/RelaxedPropertyResolverTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/bind/RelaxedPropertyResolverTests.java @@ -144,6 +144,14 @@ public class RelaxedPropertyResolverTests { assertThat(this.resolver.getProperty("d"), equalTo("test")); } + @Test + public void prefixedRelaxed() throws Exception { + this.resolver = new RelaxedPropertyResolver(this.environment, "a."); + this.source.put("A_B", "test"); + assertThat(this.resolver.containsProperty("b"), equalTo(true)); + assertThat(this.resolver.getProperty("b"), equalTo("test")); + } + @Test public void subProperties() throws Exception { this.source.put("x.y.my-sub.a.b", "1");