Commit 49a72b00 authored by Madhura Bhave's avatar Madhura Bhave

Bind to map with numeric key without needing []

Closes gh-10751
parent cebe6579
......@@ -29,7 +29,7 @@ import org.springframework.util.ObjectUtils;
/**
* A configuration property name composed of elements separated by dots. User created
* names may contain the characters "{@code a-z}" "{@code 0-9}") and "{@code -}", they
* must be lower-case and must start with a letter. The "{@code -}" is used purely for
* must be lower-case and must start with an alpha-numeric character. The "{@code -}" is used purely for
* formatting, i.e. "{@code foo-bar}" and "{@code foobar}" are considered equivalent.
* <p>
* The "{@code [}" and "{@code ]}" characters may be used to indicate an associative
......@@ -675,7 +675,7 @@ public final class ConfigurationPropertyName
}
public static boolean isValidChar(char ch, int index) {
return isAlpha(ch) || (index != 0 && (isNumeric(ch) || ch == '-'));
return isAlpha(ch) || isNumeric(ch) || (index != 0 && ch == '-');
}
private static boolean isAlpha(char ch) {
......
......@@ -273,6 +273,20 @@ public class ConfigurationPropertiesBindingPostProcessorTests {
this.context.refresh();
}
@Test
public void bindToMapWithNumericKey() {
this.context = new AnnotationConfigApplicationContext();
MutablePropertySources sources = this.context.getEnvironment()
.getPropertySources();
Map<String, Object> source = new LinkedHashMap<>();
source.put("sample.foos.1.name", "One");
sources.addFirst(new MapPropertySource("test-source", source));
this.context.register(NumericKeyConfiguration.class);
this.context.refresh();
NumericKeyConfiguration foo = this.context.getBean(NumericKeyConfiguration.class);
assertThat(foo.getFoos().get("1")).isNotNull();
}
private void prepareConverterContext(Class<?>... config) {
this.context = new AnnotationConfigApplicationContext();
MutablePropertySources sources = this.context.getEnvironment()
......@@ -604,4 +618,29 @@ public class ConfigurationPropertiesBindingPostProcessorTests {
}
@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "sample")
static class NumericKeyConfiguration {
private Map<String, Foo> foos = new LinkedHashMap<>();
public Map<String, Foo> getFoos() {
return this.foos;
}
static class Foo {
private String name;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
}
}
......@@ -49,13 +49,6 @@ public class ConfigurationPropertyNameTests {
ConfigurationPropertyName.of(null);
}
@Test
public void ofNameShouldNotStartWithNumber() {
this.thrown.expect(InvalidConfigurationPropertyNameException.class);
this.thrown.expectMessage("is not valid");
ConfigurationPropertyName.of("1foo");
}
@Test
public void ofNameShouldNotStartWithDash() {
this.thrown.expect(InvalidConfigurationPropertyNameException.class);
......@@ -107,6 +100,15 @@ public class ConfigurationPropertyNameTests {
assertThat(name.isIndexed(0)).isFalse();
}
@Test
public void ofNameWhenStartsWithNumber() {
ConfigurationPropertyName name = ConfigurationPropertyName.of("1foo");
assertThat(name.toString()).isEqualTo("1foo");
assertThat(name.getNumberOfElements()).isEqualTo(1);
assertThat(name.getElement(0, Form.ORIGINAL)).isEqualTo("1foo");
assertThat(name.isIndexed(0)).isFalse();
}
@Test
public void ofNameWhenRunOnAssociative() {
ConfigurationPropertyName name = ConfigurationPropertyName.of("foo[bar]");
......@@ -420,8 +422,8 @@ public class ConfigurationPropertyNameTests {
@Test
public void appendWhenElementNameIsNotValidShouldThrowException() {
this.thrown.expect(InvalidConfigurationPropertyNameException.class);
this.thrown.expectMessage("Configuration property name '1bar' is not valid");
ConfigurationPropertyName.of("foo").append("1bar");
this.thrown.expectMessage("Configuration property name '-bar' is not valid");
ConfigurationPropertyName.of("foo").append("-bar");
}
@Test
......@@ -589,7 +591,7 @@ public class ConfigurationPropertyNameTests {
@Test
public void isValidWhenNotValidShouldReturnFalse() {
assertThat(ConfigurationPropertyName.isValid(null)).isFalse();
assertThat(ConfigurationPropertyName.isValid("1foo")).isFalse();
assertThat(ConfigurationPropertyName.isValid("-foo")).isFalse();
assertThat(ConfigurationPropertyName.isValid("FooBar")).isFalse();
assertThat(ConfigurationPropertyName.isValid("foo!bar")).isFalse();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment