From 3741d857d08d1199f4b428d040718c420fab47b2 Mon Sep 17 00:00:00 2001 From: Emanuel Alves Date: Sun, 3 Sep 2023 17:13:53 +0100 Subject: [PATCH] Support dynamic keys in a map's key (#986) --- .../config/source/yaml/YamlConfigSource.java | 59 ++++++++++++------- .../source/yaml/YamlConfigSourceTest.java | 22 +++++++ 2 files changed, 59 insertions(+), 22 deletions(-) diff --git a/sources/yaml/src/main/java/io/smallrye/config/source/yaml/YamlConfigSource.java b/sources/yaml/src/main/java/io/smallrye/config/source/yaml/YamlConfigSource.java index 19400f14b..6a416bf12 100644 --- a/sources/yaml/src/main/java/io/smallrye/config/source/yaml/YamlConfigSource.java +++ b/sources/yaml/src/main/java/io/smallrye/config/source/yaml/YamlConfigSource.java @@ -135,29 +135,15 @@ private static void flattenYaml(String path, Map source, Map) value, target, false); - } else if (value instanceof List) { - final List list = (List) value; - flattenList(key, list, target); - for (int i = 0; i < list.size(); i++) { - flattenYaml(key, Collections.singletonMap("[" + i + "]", list.get(i)), target, true); - } + if (!key.startsWith("%")) { + processEntry(key, value, path, target, indexed); } else { - if (value != null) { - target.put(key, value.toString()); + for (String e : key.split(",")) { + if (!e.contains("%")) { + processEntry("%" + e, value, path, target, indexed); + } else { + processEntry(e, value, path, target, indexed); + } } } }); @@ -190,6 +176,35 @@ private static void flattenList(String key, List source, Map target, boolean indexed) { + if (key.contains(".")) { + key = "\"" + key + "\""; + } + + if (!key.isEmpty() && path != null && !path.isEmpty()) { + key = indexed ? path + key : path + "." + key; + } else if (path != null && !path.isEmpty()) { + key = path; + } + + if (value instanceof String) { + target.put(key, (String) value); + } else if (value instanceof Map) { + flattenYaml(key, (Map) value, target, false); + } else if (value instanceof List) { + final List list = (List) value; + flattenList(key, list, target); + for (int i = 0; i < list.size(); i++) { + flattenYaml(key, Collections.singletonMap("[" + i + "]", list.get(i)), target, true); + } + } else { + if (value != null) { + target.put(key, value.toString()); + } + } + } + private static void escapeCommas(StringBuilder b, String src, int escapeLevel) { int cp; for (int i = 0; i < src.length(); i += Character.charCount(cp)) { diff --git a/sources/yaml/src/test/java/io/smallrye/config/source/yaml/YamlConfigSourceTest.java b/sources/yaml/src/test/java/io/smallrye/config/source/yaml/YamlConfigSourceTest.java index 71910281b..5ab91a787 100644 --- a/sources/yaml/src/test/java/io/smallrye/config/source/yaml/YamlConfigSourceTest.java +++ b/sources/yaml/src/test/java/io/smallrye/config/source/yaml/YamlConfigSourceTest.java @@ -68,6 +68,28 @@ void list() { assertEquals("TLSv1.3", list.get(1)); } + @Test + void listOfKeys() { + String yaml = "\"%dev,test\":\n" + + " http:\n" + + " ssl:\n" + + " protocols:\n" + + " - TLSv1.2\n" + + " - TLSv1.3"; + + SmallRyeConfig config = new SmallRyeConfigBuilder().withSources(new YamlConfigSource("Yaml", yaml)).build(); + String[] values = config.getValue("%dev.http.ssl.protocols", String[].class); + assertEquals(2, values.length); + assertEquals("TLSv1.2", values[0]); + assertEquals("TLSv1.3", values[1]); + + List list = config.getValues("%test.http.ssl.protocols", String.class, + ArrayList::new); + assertEquals(2, list.size()); + assertEquals("TLSv1.2", list.get(0)); + assertEquals("TLSv1.3", list.get(1)); + } + @Test void indentSpaces() { String yaml;