From 07b2fe1d670c3d954577a3b498a1dec7df6781a2 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Fri, 9 Sep 2016 15:36:38 -0700 Subject: [PATCH] Support relaxed binding to 'mixedCASE' names Update relaxed binding so that names of the form `initSQL` can now be bound against properties of the form `init-s-q-l`. Fixes gh-6803 --- .../boot/bind/RelaxedNames.java | 8 ++++++- .../boot/bind/RelaxedDataBinderTests.java | 21 ++++++++++++++++ .../boot/bind/RelaxedNamesTests.java | 24 +++++++++++++++++++ ...onPropertiesBindingPostProcessorTests.java | 21 ++++++++++++---- 4 files changed, 69 insertions(+), 5 deletions(-) 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 819943dabe..cbcd549d94 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 @@ -232,7 +232,13 @@ public final class RelaxedNames implements Iterable { * @return the relaxed names */ public static RelaxedNames forCamelCase(String name) { - return new RelaxedNames(Manipulation.CAMELCASE_TO_HYPHEN.apply(name)); + StringBuffer result = new StringBuffer(); + for (char c : name.toCharArray()) { + result.append(Character.isUpperCase(c) && result.length() > 0 + && result.charAt(result.length() - 1) != '-' + ? "-" + Character.toLowerCase(c) : c); + } + return new RelaxedNames(result.toString()); } } diff --git a/spring-boot/src/test/java/org/springframework/boot/bind/RelaxedDataBinderTests.java b/spring-boot/src/test/java/org/springframework/boot/bind/RelaxedDataBinderTests.java index e5ab4a48cb..2a8716df60 100644 --- a/spring-boot/src/test/java/org/springframework/boot/bind/RelaxedDataBinderTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/bind/RelaxedDataBinderTests.java @@ -653,6 +653,17 @@ public class RelaxedDataBinderTests { assertThat(target.getObjects()).containsExactly("teststring"); } + @Test + public void testMixedWithUpperCaseWord() throws Exception { + // gh-6803 + VanillaTarget target = new VanillaTarget(); + RelaxedDataBinder binder = getBinder(target, "test"); + MutablePropertyValues values = new MutablePropertyValues(); + values.add("test.mixed-u-p-p-e-r", "foo"); + binder.bind(values); + assertThat(target.getMixedUPPER()).isEqualTo("foo"); + } + private void doTestBindCaseInsensitiveEnums(VanillaTarget target) throws Exception { BindingResult result = bind(target, "bingo: THIS"); assertThat(result.getErrorCount()).isEqualTo(0); @@ -1013,6 +1024,8 @@ public class RelaxedDataBinderTests { private List objects; + private String mixedUPPER; + public char[] getBar() { return this.bar; } @@ -1077,6 +1090,14 @@ public class RelaxedDataBinderTests { this.objects = objects; } + public String getMixedUPPER() { + return this.mixedUPPER; + } + + public void setMixedUPPER(String mixedUPPER) { + this.mixedUPPER = mixedUPPER; + } + } enum Bingo { 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 bd316896ba..ccf0e7a58f 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 @@ -123,4 +123,28 @@ public class RelaxedNamesTests { assertThat(iterator.hasNext()).isFalse(); } + @Test + public void forCamelCase() throws Exception { + Iterator iterator = RelaxedNames.forCamelCase("camelCase").iterator(); + assertThat(iterator.next()).isEqualTo("camel-case"); + assertThat(iterator.next()).isEqualTo("camel_case"); + assertThat(iterator.next()).isEqualTo("camelCase"); + assertThat(iterator.next()).isEqualTo("camelcase"); + assertThat(iterator.next()).isEqualTo("CAMEL-CASE"); + assertThat(iterator.next()).isEqualTo("CAMEL_CASE"); + assertThat(iterator.next()).isEqualTo("CAMELCASE"); + } + + @Test + public void forCamelCaseWithCaps() throws Exception { + Iterator iterator = RelaxedNames.forCamelCase("camelCASE").iterator(); + assertThat(iterator.next()).isEqualTo("camel-c-a-s-e"); + assertThat(iterator.next()).isEqualTo("camel_c_a_s_e"); + assertThat(iterator.next()).isEqualTo("camelCASE"); + assertThat(iterator.next()).isEqualTo("camelcase"); + assertThat(iterator.next()).isEqualTo("CAMEL-C-A-S-E"); + assertThat(iterator.next()).isEqualTo("CAMEL_C_A_S_E"); + assertThat(iterator.next()).isEqualTo("CAMELCASE"); + } + } diff --git a/spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesBindingPostProcessorTests.java b/spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesBindingPostProcessorTests.java index d2dea28738..f327c535b9 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesBindingPostProcessorTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesBindingPostProcessorTests.java @@ -298,12 +298,14 @@ public class ConfigurationPropertiesBindingPostProcessorTests { @Test public void relaxedPropertyNamesSame() throws Exception { - testRelaxedPropertyNames("test.FOO_BAR=test1", "test.FOO_BAR=test2"); + testRelaxedPropertyNames("test.FOO_BAR=test1", "test.FOO_BAR=test2", + "test.BAR-B-A-Z=testa", "test.BAR-B-A-Z=testb"); } @Test public void relaxedPropertyNamesMixed() throws Exception { - testRelaxedPropertyNames("test.FOO_BAR=test2", "test.foo-bar=test1"); + testRelaxedPropertyNames("test.FOO_BAR=test2", "test.foo-bar=test1", + "test.BAR-B-A-Z=testb", "test.bar_b_a_z=testa"); } private void testRelaxedPropertyNames(String... environment) { @@ -312,8 +314,9 @@ public class ConfigurationPropertiesBindingPostProcessorTests { environment); this.context.register(RelaxedPropertyNames.class); this.context.refresh(); - assertThat(this.context.getBean(RelaxedPropertyNames.class).getFooBar()) - .isEqualTo("test2"); + RelaxedPropertyNames bean = this.context.getBean(RelaxedPropertyNames.class); + assertThat(bean.getFooBar()).isEqualTo("test2"); + assertThat(bean.getBarBAZ()).isEqualTo("testb"); } @Test @@ -670,6 +673,8 @@ public class ConfigurationPropertiesBindingPostProcessorTests { private String fooBar; + private String barBAZ; + public String getFooBar() { return this.fooBar; } @@ -678,6 +683,14 @@ public class ConfigurationPropertiesBindingPostProcessorTests { this.fooBar = fooBar; } + public String getBarBAZ() { + return this.barBAZ; + } + + public void setBarBAZ(String barBAZ) { + this.barBAZ = barBAZ; + } + } @SuppressWarnings("rawtypes")