diff --git a/implementation/src/main/java/io/smallrye/config/ConfigMappingProvider.java b/implementation/src/main/java/io/smallrye/config/ConfigMappingProvider.java index 9bb9aad98..905a8b18a 100644 --- a/implementation/src/main/java/io/smallrye/config/ConfigMappingProvider.java +++ b/implementation/src/main/java/io/smallrye/config/ConfigMappingProvider.java @@ -439,11 +439,22 @@ private void processLazyMap( addAction(currentPath, property, (mc, ni) -> { StringBuilder sb = mc.getStringBuilder(); - sb.setLength(0); - sb.append(ni.getAllPreviousSegments()); + // We may need to reset the StringBuilder because the delegate may not be a Map + boolean restore = false; + if (ni.getPosition() != -1) { + restore = true; + ni.previous(); + sb.setLength(0); + sb.append(ni.getAllPreviousSegments()); + } + Map map = getEnclosingMap.apply(mc, ni); + if (restore) { + ni.next(); + sb.setLength(0); + sb.append(ni.getAllPreviousSegments()); + } String configKey = sb.toString(); String rawMapKey = ni.getPreviousSegment(); - Map map = getEnclosingMap.apply(mc, ni); Converter keyConv; SmallRyeConfig config = mc.getConfig(); if (keyConvertWith != null) { @@ -463,7 +474,9 @@ private void processLazyMap( } else if (valueProperty.isMap()) { currentPath.addLast("*"); processLazyMap(currentPath, matchActions, defaultValues, valueProperty.asMap(), (mc, ni) -> { + ni.previous(); Map enclosingMap = getEnclosingMap.apply(mc, ni); + ni.next(); String rawMapKey = ni.getPreviousSegment(); Converter keyConv; SmallRyeConfig config = mc.getConfig(); @@ -626,7 +639,9 @@ static class GetOrCreateEnclosingGroupInMap implements BiFunction ourEnclosing = getEnclosingMap.apply(context, ni); + ni.next(); String mapKey = mapKey(ni); Converter keyConverter = context.getKeyConverter(enclosingGroup.getInterfaceType(), enclosingMap.getMethod().getName(), enclosingMap.getLevels() - 1); @@ -693,23 +708,7 @@ static class GetOrCreateEnclosingMapInGroup implements BiFunction enclosingType = enclosingGroup.getInterfaceType(); diff --git a/implementation/src/test/java/io/smallrye/config/ConfigMappingInterfaceTest.java b/implementation/src/test/java/io/smallrye/config/ConfigMappingInterfaceTest.java index 26b2e9c38..cdab95343 100644 --- a/implementation/src/test/java/io/smallrye/config/ConfigMappingInterfaceTest.java +++ b/implementation/src/test/java/io/smallrye/config/ConfigMappingInterfaceTest.java @@ -1488,4 +1488,47 @@ void nestedOptionalsGroupMap() { assertEquals("value", mapping.first().get().second().get().third().get().properties().get("key")); assertEquals("value", mapping.first().get().second().get().third().get().value()); } + + @ConfigMapping(prefix = "optional-map") + public interface NestedOptionalMapGroup { + Optional enable(); + + Map> map(); + + interface MessageUtilConfiguration { + Optional enable(); + } + } + + @Test + void nestedOptionalAndMaps() { + SmallRyeConfig config = new SmallRyeConfigBuilder() + .withMapping(NestedOptionalMapGroup.class) + .withSources(config("optional-map.enable", "true")) + .withSources(config("optional-map.map.filter.default.enable", "false", + "optional-map.map.filter.get-jokes-uni.enable", "true")) + .withSources(config("optional-map.map.client.reaction-api.enable", "true", + "optional-map.map.client.setup-api.enable", "true")) + .build(); + + NestedOptionalMapGroup mapping = config.getConfigMapping(NestedOptionalMapGroup.class); + assertTrue(mapping.enable().isPresent()); + assertTrue(mapping.enable().get()); + + assertEquals(2, mapping.map().size()); + assertTrue(mapping.map().containsKey("filter")); + assertTrue(mapping.map().get("filter").containsKey("default")); + assertTrue(mapping.map().get("filter").containsKey("get-jokes-uni")); + assertTrue(mapping.map().containsKey("client")); + assertTrue(mapping.map().get("client").containsKey("reaction-api")); + assertTrue(mapping.map().get("client").containsKey("setup-api")); + assertTrue(mapping.map().get("filter").get("default").enable().isPresent()); + assertFalse(mapping.map().get("filter").get("default").enable().get()); + assertTrue(mapping.map().get("filter").get("get-jokes-uni").enable().isPresent()); + assertTrue(mapping.map().get("filter").get("get-jokes-uni").enable().get()); + assertTrue(mapping.map().get("client").get("reaction-api").enable().isPresent()); + assertTrue(mapping.map().get("client").get("reaction-api").enable().get()); + assertTrue(mapping.map().get("client").get("setup-api").enable().isPresent()); + assertTrue(mapping.map().get("client").get("setup-api").enable().get()); + } }