From 452281ca8d200c61b2ca35054658a9961d77b9ba Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Fri, 10 Jun 2016 20:54:50 -0700 Subject: [PATCH] Fix property detection in SpringApplicationBuilder Update SpringApplicationBuilder so that properties of the form `abc=d:e:f` are correctly parsed. Prior to this commit the `:` delimiter would always be chosen over `=`, even if `=` occurred first. Fixes gh-6121 --- .../builder/SpringApplicationBuilder.java | 24 ++++++++++++------- .../SpringApplicationBuilderTests.java | 15 ++++++++++++ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/spring-boot/src/main/java/org/springframework/boot/builder/SpringApplicationBuilder.java b/spring-boot/src/main/java/org/springframework/boot/builder/SpringApplicationBuilder.java index 7578e89e722..282e2ef9dfa 100644 --- a/spring-boot/src/main/java/org/springframework/boot/builder/SpringApplicationBuilder.java +++ b/spring-boot/src/main/java/org/springframework/boot/builder/SpringApplicationBuilder.java @@ -394,20 +394,28 @@ public class SpringApplicationBuilder { return properties(getMapFromKeyValuePairs(defaultProperties)); } - private Map getMapFromKeyValuePairs(String[] args) { + private Map getMapFromKeyValuePairs(String[] properties) { Map map = new HashMap(); - for (String pair : args) { - int index = pair.indexOf(":"); - if (index <= 0) { - index = pair.indexOf("="); - } - String key = pair.substring(0, index > 0 ? index : pair.length()); - String value = index > 0 ? pair.substring(index + 1) : ""; + for (String property : properties) { + int index = lowestIndexOf(property, ":", "="); + String key = property.substring(0, index > 0 ? index : property.length()); + String value = index > 0 ? property.substring(index + 1) : ""; map.put(key, value); } return map; } + private int lowestIndexOf(String property, String... candidates) { + int index = -1; + for (String candidate : candidates) { + int candidateIndex = property.indexOf(candidate); + if (candidateIndex > 0) { + index = (index == -1 ? candidateIndex : Math.min(index, candidateIndex)); + } + } + return index; + } + /** * Default properties for the environment in the form {@code key=value} or * {@code key:value}. diff --git a/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java b/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java index 7967755522c..129b407d952 100644 --- a/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java @@ -31,6 +31,7 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.StaticApplicationContext; +import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.StandardEnvironment; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.ResourceLoader; @@ -91,6 +92,20 @@ public class SpringApplicationBuilderTests { assertThat(this.context.getEnvironment().getProperty("bar"), is(equalTo("foo"))); } + @Test + public void propertiesWithRepeatSeparator() throws Exception { + SpringApplicationBuilder application = new SpringApplicationBuilder() + .sources(ExampleConfig.class).contextClass(StaticApplicationContext.class) + .properties("one=c:\\logging.file", "two=a:b", "three:c:\\logging.file", + "four:a:b"); + this.context = application.run(); + ConfigurableEnvironment environment = this.context.getEnvironment(); + assertThat(environment.getProperty("one"), is(equalTo("c:\\logging.file"))); + assertThat(environment.getProperty("two"), is(equalTo("a:b"))); + assertThat(environment.getProperty("three"), is(equalTo("c:\\logging.file"))); + assertThat(environment.getProperty("four"), is(equalTo("a:b"))); + } + @Test public void specificApplicationContextClass() throws Exception { SpringApplicationBuilder application = new SpringApplicationBuilder()