diff --git a/builder/processor/src/main/java/io/helidon/builder/processor/TypeHandlerMap.java b/builder/processor/src/main/java/io/helidon/builder/processor/TypeHandlerMap.java index 75928efcfe0..2dda8ca9792 100644 --- a/builder/processor/src/main/java/io/helidon/builder/processor/TypeHandlerMap.java +++ b/builder/processor/src/main/java/io/helidon/builder/processor/TypeHandlerMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Oracle and/or its affiliates. + * Copyright (c) 2023, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,7 @@ import io.helidon.common.processor.classmodel.Method; import io.helidon.common.processor.classmodel.TypeArgument; import io.helidon.common.types.TypeName; +import io.helidon.common.types.TypeNames; import static io.helidon.builder.processor.Types.STRING_TYPE; import static io.helidon.common.types.TypeNames.LIST; @@ -98,12 +99,18 @@ TypeName actualType() { void generateFromConfig(Method.Builder method, AnnotationDataOption configured, FactoryMethods factoryMethods) { - method.addLine(configGet(configured) - + ".asNodeList().ifPresent(nodes -> nodes.forEach" - + "(node -> " - + name() + ".put(node.get(\"name\").asString().orElse(node.name()), node" - + generateFromConfig(factoryMethods) - + ".get())));"); + List typeArguments = declaredType().typeArguments(); + if (TypeNames.STRING.equals(typeArguments.get(0)) && TypeNames.STRING.equals(typeArguments.get(1))) { + // the special case of Map + method.addLine(configGet(configured) + ".detach().asMap().ifPresent(this::" + name() + ");"); + } else { + method.addLine(configGet(configured) + + ".asNodeList().ifPresent(nodes -> nodes.forEach" + + "(node -> " + + name() + ".put(node.get(\"name\").asString().orElse(node.name()), node" + + generateFromConfig(factoryMethods) + + ".get())));"); + } } @Override diff --git a/builder/tests/builder/src/main/java/io/helidon/builder/test/testsubjects/ConfigMapBlueprint.java b/builder/tests/builder/src/main/java/io/helidon/builder/test/testsubjects/ConfigMapBlueprint.java new file mode 100644 index 00000000000..b9af63c3592 --- /dev/null +++ b/builder/tests/builder/src/main/java/io/helidon/builder/test/testsubjects/ConfigMapBlueprint.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.helidon.builder.test.testsubjects; + +import java.util.Map; + +import io.helidon.builder.api.Option; +import io.helidon.builder.api.Prototype; + +@Prototype.Configured +@Prototype.Blueprint +interface ConfigMapBlueprint { + @Option.Configured + @Option.Singular + Map properties(); +} diff --git a/builder/tests/builder/src/test/java/io/helidon/builder/test/ConfigMapTest.java b/builder/tests/builder/src/test/java/io/helidon/builder/test/ConfigMapTest.java new file mode 100644 index 00000000000..daa57f3a4e6 --- /dev/null +++ b/builder/tests/builder/src/test/java/io/helidon/builder/test/ConfigMapTest.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.helidon.builder.test; + +import java.util.Map; + +import io.helidon.builder.test.testsubjects.ConfigMap; +import io.helidon.config.Config; +import io.helidon.config.ConfigSources; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasEntry; + +public class ConfigMapTest { + private static Config config; + + @BeforeAll + static void beforeAll() { + config = Config.just(ConfigSources.classpath("config-map-test.yaml")); + } + + @Test + void testMap() { + ConfigMap configMap = ConfigMap.create(config); + Map properties = configMap.properties(); + + assertThat(properties, hasEntry("my.first.key", "firstValue")); + assertThat(properties, hasEntry("my.second.key", "secondValue")); + } +} diff --git a/builder/tests/builder/src/test/resources/config-map-test.yaml b/builder/tests/builder/src/test/resources/config-map-test.yaml new file mode 100644 index 00000000000..1b16c2103a7 --- /dev/null +++ b/builder/tests/builder/src/test/resources/config-map-test.yaml @@ -0,0 +1,21 @@ +# +# Copyright (c) 2024 Oracle and/or its affiliates. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Used in ConfigMapTest +properties: + my.first.key: "firstValue" + my.second.key: "secondValue" +