From a47c251c5cb07c63fec99b5c8ee1f32f43845662 Mon Sep 17 00:00:00 2001 From: Madhura Bhave Date: Wed, 8 Mar 2017 16:07:52 -0800 Subject: [PATCH] Do not convert key nodes to originTrackedValue Fixes gh-8540 --- .../boot/env/OriginTrackedYamlLoader.java | 31 ++++++++++++++++++- .../env/OriginTrackedYamlLoaderTests.java | 16 ++++++++++ .../springframework/boot/env/test-yaml.yml | 7 +++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/spring-boot/src/main/java/org/springframework/boot/env/OriginTrackedYamlLoader.java b/spring-boot/src/main/java/org/springframework/boot/env/OriginTrackedYamlLoader.java index 8ca5e35078..2699efbe05 100644 --- a/spring-boot/src/main/java/org/springframework/boot/env/OriginTrackedYamlLoader.java +++ b/spring-boot/src/main/java/org/springframework/boot/env/OriginTrackedYamlLoader.java @@ -21,13 +21,16 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.regex.Pattern; +import java.util.stream.Collectors; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.BaseConstructor; import org.yaml.snakeyaml.constructor.Constructor; import org.yaml.snakeyaml.error.Mark; +import org.yaml.snakeyaml.nodes.MappingNode; import org.yaml.snakeyaml.nodes.Node; +import org.yaml.snakeyaml.nodes.NodeTuple; import org.yaml.snakeyaml.nodes.ScalarNode; import org.yaml.snakeyaml.nodes.Tag; import org.yaml.snakeyaml.representer.Representer; @@ -92,7 +95,15 @@ class OriginTrackedYamlLoader extends YamlProcessor { @Override protected Object constructObject(Node node) { if (node instanceof ScalarNode) { - return constructTrackedObject(node, super.constructObject(node)); + if (!(node instanceof KeyScalarNode)) { + return constructTrackedObject(node, super.constructObject(node)); + } + } + else if (node instanceof MappingNode) { + List value = ((MappingNode) node).getValue(); + List updatedValues = value.stream().map(nt -> new NodeTuple(KeyScalarNode.get(nt.getKeyNode()), + nt.getValueNode())).collect(Collectors.toList()); + ((MappingNode) node).setValue(updatedValues); } return super.constructObject(node); } @@ -111,6 +122,24 @@ class OriginTrackedYamlLoader extends YamlProcessor { } + /** + * {@link ScalarNode} that replaces the key node in a {@link NodeTuple}. + */ + private static class KeyScalarNode extends ScalarNode { + + KeyScalarNode(ScalarNode node) { + super(node.getTag(), node.getValue(), node.getStartMark(), node.getEndMark(), node.getStyle()); + } + + private static Node get(Node node) { + if (node instanceof ScalarNode) { + return new KeyScalarNode((ScalarNode) node); + } + return node; + } + + } + /** * {@link Resolver} that limits {@link Tag#TIMESTAMP} tags. */ diff --git a/spring-boot/src/test/java/org/springframework/boot/env/OriginTrackedYamlLoaderTests.java b/spring-boot/src/test/java/org/springframework/boot/env/OriginTrackedYamlLoaderTests.java index 1d0bedf0a8..ad4b3e1a5b 100644 --- a/spring-boot/src/test/java/org/springframework/boot/env/OriginTrackedYamlLoaderTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/env/OriginTrackedYamlLoaderTests.java @@ -96,6 +96,22 @@ public class OriginTrackedYamlLoaderTests { assertThat(result.get("name").toString()).isEqualTo("Test Name"); } + @Test + public void processListOfMaps() throws Exception { + OriginTrackedValue name = getValue("example.foo[0].name"); + OriginTrackedValue url = getValue("example.foo[0].url"); + OriginTrackedValue bar1 = getValue("example.foo[0].bar[0].bar1"); + OriginTrackedValue bar2 = getValue("example.foo[0].bar[1].bar2"); + assertThat(name.toString()).isEqualTo("springboot"); + assertThat(getLocation(name)).isEqualTo("22:15"); + assertThat(url.toString()).isEqualTo("http://springboot.com"); + assertThat(getLocation(url)).isEqualTo("23:14"); + assertThat(bar1.toString()).isEqualTo("baz"); + assertThat(getLocation(bar1)).isEqualTo("25:19"); + assertThat(bar2.toString()).isEqualTo("bling"); + assertThat(getLocation(bar2)).isEqualTo("26:19"); + } + private OriginTrackedValue getValue(String name) { if (this.result == null) { this.result = this.loader.load(); diff --git a/spring-boot/src/test/resources/org/springframework/boot/env/test-yaml.yml b/spring-boot/src/test/resources/org/springframework/boot/env/test-yaml.yml index 0adebf9261..dd5c3ed6e6 100644 --- a/spring-boot/src/test/resources/org/springframework/boot/env/test-yaml.yml +++ b/spring-boot/src/test/resources/org/springframework/boot/env/test-yaml.yml @@ -17,6 +17,13 @@ education: | 4 GCSEs 3 A-Levels BSc in the Internet of Things +example: + foo: + - name: springboot + url: http://springboot.com + bar: + - bar1: baz + - bar2: bling --- spring: