Browse Source

Allow nested square brackets in map key when binding

Fixes gh-3202
pull/8534/merge
Madhura Bhave 9 years ago
parent
commit
233ef67a04
  1. 23
      spring-boot/src/main/java/org/springframework/boot/context/properties/source/ConfigurationPropertyName.java
  2. 9
      spring-boot/src/test/java/org/springframework/boot/context/properties/bind/MapBinderTests.java
  3. 15
      spring-boot/src/test/java/org/springframework/boot/context/properties/source/ConfigurationPropertyNameTests.java

23
spring-boot/src/main/java/org/springframework/boot/context/properties/source/ConfigurationPropertyName.java

@ -513,17 +513,24 @@ public final class ConfigurationPropertyName @@ -513,17 +513,24 @@ public final class ConfigurationPropertyName
int start = 0;
boolean indexed = false;
int length = name.length();
int openBracketCount = 0;
for (int i = 0; i < length; i++) {
char ch = name.charAt(i);
if (indexed && ch == ']') {
processElement(processor, name, start, i + 1, indexed);
start = i + 1;
indexed = false;
if (ch == ']') {
openBracketCount--;
if (openBracketCount == 0) {
processElement(processor, name, start, i + 1, indexed);
start = i + 1;
indexed = false;
}
}
else if (!indexed && ch == '[') {
processElement(processor, name, start, i, indexed);
start = i;
indexed = true;
else if (ch == '[') {
openBracketCount++;
if (!indexed) {
processElement(processor, name, start, i, indexed);
start = i;
indexed = true;
}
}
else if (!indexed && ch == separator) {
processElement(processor, name, start, i, indexed);

9
spring-boot/src/test/java/org/springframework/boot/context/properties/bind/MapBinderTests.java

@ -503,6 +503,15 @@ public class MapBinderTests { @@ -503,6 +503,15 @@ public class MapBinderTests {
assertThat(map.get(0)).containsExactly(8, 9);
}
@Test
public void bindingWithSquareBracketMap() throws Exception {
MockConfigurationPropertySource source = new MockConfigurationPropertySource();
source.put("foo.[x [B] y]", "[ball]");
this.sources.add(source);
Map<String, String> map = this.binder.bind("foo", STRING_STRING_MAP).get();
assertThat(map).containsEntry("x [B] y", "[ball]");
}
private <K, V> Bindable<Map<K, V>> getMapBindable(Class<K> keyGeneric, ResolvableType valueType) {
ResolvableType keyType = ResolvableType.forClass(keyGeneric);
return Bindable.of(ResolvableType.forClassWithGenerics(Map.class, keyType, valueType));

15
spring-boot/src/test/java/org/springframework/boot/context/properties/source/ConfigurationPropertyNameTests.java

@ -175,6 +175,21 @@ public class ConfigurationPropertyNameTests { @@ -175,6 +175,21 @@ public class ConfigurationPropertyNameTests {
ConfigurationPropertyName.of("bar]");
}
@Test
public void ofNameWhenMultipleMismatchedBrackets() throws Exception {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("is not valid");
ConfigurationPropertyName.of("[a[[[b]ar]");
}
@Test
public void ofNameWhenNestedBrackets() throws Exception {
ConfigurationPropertyName name = ConfigurationPropertyName.of("foo[a[c][[b]ar]]");
assertThat(name.toString()).isEqualTo("foo[a[c][[b]ar]]");
assertThat(name.getElement(0, Form.ORIGINAL)).isEqualTo("foo");
assertThat(name.getElement(1, Form.ORIGINAL)).isEqualTo("a[c][[b]ar]");
}
@Test
public void ofNameWithWhitespaceInName() throws Exception {
this.thrown.expect(IllegalArgumentException.class);

Loading…
Cancel
Save