Skip to content

Commit 07b2fe1

Browse files
committed
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
1 parent 3570f77 commit 07b2fe1

File tree

4 files changed

+69
-5
lines changed

4 files changed

+69
-5
lines changed

spring-boot/src/main/java/org/springframework/boot/bind/RelaxedNames.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,13 @@ private static String separatedToCamelCase(String value,
232232
* @return the relaxed names
233233
*/
234234
public static RelaxedNames forCamelCase(String name) {
235-
return new RelaxedNames(Manipulation.CAMELCASE_TO_HYPHEN.apply(name));
235+
StringBuffer result = new StringBuffer();
236+
for (char c : name.toCharArray()) {
237+
result.append(Character.isUpperCase(c) && result.length() > 0
238+
&& result.charAt(result.length() - 1) != '-'
239+
? "-" + Character.toLowerCase(c) : c);
240+
}
241+
return new RelaxedNames(result.toString());
236242
}
237243

238244
}

spring-boot/src/test/java/org/springframework/boot/bind/RelaxedDataBinderTests.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,17 @@ public void testIndexBounds() throws Exception {
653653
assertThat(target.getObjects()).containsExactly("teststring");
654654
}
655655

656+
@Test
657+
public void testMixedWithUpperCaseWord() throws Exception {
658+
// gh-6803
659+
VanillaTarget target = new VanillaTarget();
660+
RelaxedDataBinder binder = getBinder(target, "test");
661+
MutablePropertyValues values = new MutablePropertyValues();
662+
values.add("test.mixed-u-p-p-e-r", "foo");
663+
binder.bind(values);
664+
assertThat(target.getMixedUPPER()).isEqualTo("foo");
665+
}
666+
656667
private void doTestBindCaseInsensitiveEnums(VanillaTarget target) throws Exception {
657668
BindingResult result = bind(target, "bingo: THIS");
658669
assertThat(result.getErrorCount()).isEqualTo(0);
@@ -1013,6 +1024,8 @@ public static class VanillaTarget {
10131024

10141025
private List<Object> objects;
10151026

1027+
private String mixedUPPER;
1028+
10161029
public char[] getBar() {
10171030
return this.bar;
10181031
}
@@ -1077,6 +1090,14 @@ public void setObjects(List<Object> objects) {
10771090
this.objects = objects;
10781091
}
10791092

1093+
public String getMixedUPPER() {
1094+
return this.mixedUPPER;
1095+
}
1096+
1097+
public void setMixedUPPER(String mixedUPPER) {
1098+
this.mixedUPPER = mixedUPPER;
1099+
}
1100+
10801101
}
10811102

10821103
enum Bingo {

spring-boot/src/test/java/org/springframework/boot/bind/RelaxedNamesTests.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,28 @@ public void fromEmpty() throws Exception {
123123
assertThat(iterator.hasNext()).isFalse();
124124
}
125125

126+
@Test
127+
public void forCamelCase() throws Exception {
128+
Iterator<String> iterator = RelaxedNames.forCamelCase("camelCase").iterator();
129+
assertThat(iterator.next()).isEqualTo("camel-case");
130+
assertThat(iterator.next()).isEqualTo("camel_case");
131+
assertThat(iterator.next()).isEqualTo("camelCase");
132+
assertThat(iterator.next()).isEqualTo("camelcase");
133+
assertThat(iterator.next()).isEqualTo("CAMEL-CASE");
134+
assertThat(iterator.next()).isEqualTo("CAMEL_CASE");
135+
assertThat(iterator.next()).isEqualTo("CAMELCASE");
136+
}
137+
138+
@Test
139+
public void forCamelCaseWithCaps() throws Exception {
140+
Iterator<String> iterator = RelaxedNames.forCamelCase("camelCASE").iterator();
141+
assertThat(iterator.next()).isEqualTo("camel-c-a-s-e");
142+
assertThat(iterator.next()).isEqualTo("camel_c_a_s_e");
143+
assertThat(iterator.next()).isEqualTo("camelCASE");
144+
assertThat(iterator.next()).isEqualTo("camelcase");
145+
assertThat(iterator.next()).isEqualTo("CAMEL-C-A-S-E");
146+
assertThat(iterator.next()).isEqualTo("CAMEL_C_A_S_E");
147+
assertThat(iterator.next()).isEqualTo("CAMELCASE");
148+
}
149+
126150
}

spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesBindingPostProcessorTests.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -298,12 +298,14 @@ public void notWritablePropertyException() throws Exception {
298298

299299
@Test
300300
public void relaxedPropertyNamesSame() throws Exception {
301-
testRelaxedPropertyNames("test.FOO_BAR=test1", "test.FOO_BAR=test2");
301+
testRelaxedPropertyNames("test.FOO_BAR=test1", "test.FOO_BAR=test2",
302+
"test.BAR-B-A-Z=testa", "test.BAR-B-A-Z=testb");
302303
}
303304

304305
@Test
305306
public void relaxedPropertyNamesMixed() throws Exception {
306-
testRelaxedPropertyNames("test.FOO_BAR=test2", "test.foo-bar=test1");
307+
testRelaxedPropertyNames("test.FOO_BAR=test2", "test.foo-bar=test1",
308+
"test.BAR-B-A-Z=testb", "test.bar_b_a_z=testa");
307309
}
308310

309311
private void testRelaxedPropertyNames(String... environment) {
@@ -312,8 +314,9 @@ private void testRelaxedPropertyNames(String... environment) {
312314
environment);
313315
this.context.register(RelaxedPropertyNames.class);
314316
this.context.refresh();
315-
assertThat(this.context.getBean(RelaxedPropertyNames.class).getFooBar())
316-
.isEqualTo("test2");
317+
RelaxedPropertyNames bean = this.context.getBean(RelaxedPropertyNames.class);
318+
assertThat(bean.getFooBar()).isEqualTo("test2");
319+
assertThat(bean.getBarBAZ()).isEqualTo("testb");
317320
}
318321

319322
@Test
@@ -670,6 +673,8 @@ public static class RelaxedPropertyNames {
670673

671674
private String fooBar;
672675

676+
private String barBAZ;
677+
673678
public String getFooBar() {
674679
return this.fooBar;
675680
}
@@ -678,6 +683,14 @@ public void setFooBar(String fooBar) {
678683
this.fooBar = fooBar;
679684
}
680685

686+
public String getBarBAZ() {
687+
return this.barBAZ;
688+
}
689+
690+
public void setBarBAZ(String barBAZ) {
691+
this.barBAZ = barBAZ;
692+
}
693+
681694
}
682695

683696
@SuppressWarnings("rawtypes")

0 commit comments

Comments
 (0)