Skip to content

Commit c3d70c2

Browse files
authored
Fix builder with @EachProperty(list = true) (#11747)
* Fix builder with `@EachProperty(list = true)` * Correct
1 parent b2332d4 commit c3d70c2

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

core-processor/src/main/java/io/micronaut/inject/writer/BeanDefinitionWriter.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -2917,7 +2917,7 @@ private StatementDef visitConfigBuilderMethodInternal(
29172917
boolean zeroArgs = paramType == null;
29182918

29192919
// Optional optional = AbstractBeanDefinition.getValueForPath(...)
2920-
String localName = builderVar.name() + "_optional" + NameUtils.capitalize(propertyPath.replace('.', '_').replace('-', '_'));
2920+
String localName = builderVar.name() + "_optional" + NameUtils.capitalize(propertyPath.replace("[*]", "__all__").replace('.', '_').replace('-', '_'));
29212921
return getGetValueForPathCall(injectMethodSignature, paramType, propertyName, propertyPath, zeroArgs, generics)
29222922
.newLocal(localName, optionalVar -> {
29232923
return optionalVar.invoke(OPTIONAL_IS_PRESENT_METHOD)

inject-java/src/test/groovy/io/micronaut/inject/configproperties/ConfigPropertiesParseSpec.groovy

+53
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,59 @@ import java.time.Duration
1717

1818
class ConfigPropertiesParseSpec extends AbstractTypeElementSpec {
1919

20+
void "test builder with @EachProperty(list = true)"() {
21+
when:
22+
def context = buildContext('test.MeteringBucketConfigProperties', '''
23+
package test;
24+
25+
import io.micronaut.context.annotation.ConfigurationBuilder;
26+
import io.micronaut.context.annotation.EachProperty;
27+
28+
@EachProperty(value = "buckets", list = true)
29+
class MeteringBucketConfigProperties {
30+
@ConfigurationBuilder(
31+
prefixes = {""}
32+
)
33+
public MeteringBucketConfigBuilder bucketConfig = new MeteringBucketConfigBuilder();
34+
}
35+
36+
class MeteringBucketConfigBuilder {
37+
38+
private String name;
39+
40+
public MeteringBucketConfigBuilder() {
41+
}
42+
43+
public MeteringBucketConfigBuilder name(String name) {
44+
this.name = name;
45+
return this;
46+
}
47+
48+
public MeteringBucket build() {
49+
return new MeteringBucket(name);
50+
}
51+
52+
}
53+
54+
class MeteringBucket {
55+
private final String name;
56+
57+
MeteringBucket(String name) {
58+
this.name = name;
59+
}
60+
61+
public String getName() {
62+
return name;
63+
}
64+
}
65+
''', false, ["buckets":[["name": "xyz"], ["name": "bar"]]])
66+
def beans = context.getBeansOfType(context.classLoader.loadClass('test.MeteringBucketConfigProperties'))
67+
68+
then:
69+
beans.size() == 2
70+
beans.collect { it -> it.bucketConfig.build().name }.sort() == ["bar", "xyz"]
71+
}
72+
2073
void "test configuration properties implementing interface"() {
2174
when:
2275
def context = buildContext('''

0 commit comments

Comments
 (0)