Skip to content

Commit 8840ebc

Browse files
authored
4.x: Fix wrong method generated for factory methods in builder (helidon-io#10522)
* Config factory methods for types that are also configured blueprints no longer generate an invalid method if the return type is a list. Added tests
1 parent 06b0f6c commit 8840ebc

5 files changed

Lines changed: 152 additions & 7 deletions

File tree

builder/codegen/src/main/java/io/helidon/builder/codegen/TypeHandlerCollection.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,11 @@ private void factorySetterConsumer(InnerClass.Builder classBuilder,
344344
Javadoc blueprintJavadoc,
345345
FactoryMethods factoryMethods,
346346
FactoryMethods.FactoryMethod factoryMethod) {
347+
if (!configured.singular()) {
348+
// if singular is not defined, we are not instructed to create add methods, so it does not make sense
349+
// to create an add method with a builder consumer
350+
return;
351+
}
347352
// if there is a factory method for the return type, we also have setters for the type (probably config object)
348353
TypeName builderType;
349354
if (factoryMethod.factoryMethodReturnType().className().equals("Builder")) {
@@ -382,14 +387,20 @@ private void factorySetterConsumer(InnerClass.Builder classBuilder,
382387
builder.addContentLine("this." + name() + "(builder.build());")
383388
.addContentLine("return self();");
384389
classBuilder.addMethod(builder);
385-
} else if (configured.singular()) {
386-
String singularName = configured.singularName();
387-
String methodName = "add" + capitalize(singularName);
388-
builder.name(methodName)
389-
.addContentLine("this." + name() + ".add(builder.build());")
390-
.addContentLine("return self();");
391-
classBuilder.addMethod(builder);
390+
return;
391+
}
392+
393+
String singularName = configured.singularName();
394+
String methodName;
395+
if (configured.singularAddPrefix()) {
396+
methodName = "add" + capitalize(singularName);
397+
} else {
398+
methodName = singularName;
392399
}
400+
builder.name(methodName)
401+
.addContentLine("this." + name() + ".add(builder.build());")
402+
.addContentLine("return self();");
403+
classBuilder.addMethod(builder);
393404
}
394405

395406
private void singularSetter(InnerClass.Builder classBuilder,
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright (c) 2025 Oracle and/or its affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.helidon.builder.test.testsubjects;
18+
19+
import java.util.List;
20+
21+
import io.helidon.builder.api.Option;
22+
import io.helidon.builder.api.Prototype;
23+
24+
@Prototype.Configured
25+
@Prototype.Blueprint
26+
@Prototype.CustomMethods(OtelTracingSupport.class)
27+
interface OtelTracingBlueprint {
28+
@Option.Configured
29+
List<SpanProcessorConfig> processors();
30+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (c) 2025 Oracle and/or its affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.helidon.builder.test.testsubjects;
18+
19+
import java.util.List;
20+
21+
import io.helidon.builder.api.Prototype;
22+
import io.helidon.common.config.Config;
23+
24+
final class OtelTracingSupport {
25+
private OtelTracingSupport() {
26+
}
27+
28+
@Prototype.FactoryMethod
29+
static List<SpanProcessorConfig> createProcessors(Config config) {
30+
return List.of(SpanProcessorConfig.builder()
31+
.configured("some-value")
32+
.build());
33+
}
34+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (c) 2025 Oracle and/or its affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.helidon.builder.test.testsubjects;
18+
19+
import io.helidon.builder.api.Option;
20+
import io.helidon.builder.api.Prototype;
21+
22+
@Prototype.Blueprint
23+
@Prototype.Configured
24+
interface SpanProcessorConfigBlueprint {
25+
@Option.Configured
26+
String configured();
27+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (c) 2025 Oracle and/or its affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.helidon.builder.test;
18+
19+
import java.util.Map;
20+
21+
import io.helidon.builder.test.testsubjects.OtelTracing;
22+
import io.helidon.config.Config;
23+
import io.helidon.config.ConfigSources;
24+
25+
import org.junit.jupiter.api.Test;
26+
27+
import static org.hamcrest.CoreMatchers.is;
28+
import static org.hamcrest.MatcherAssert.assertThat;
29+
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
30+
31+
class TestFactoryMethod {
32+
@Test
33+
void testConfigFactory() {
34+
var config = Config.just(ConfigSources.create(Map.of("processors", "")));
35+
36+
var otelConfig = OtelTracing.create(config);
37+
var processors = otelConfig.processors();
38+
39+
assertThat(processors, hasSize(1));
40+
// returned from here: io.helidon.builder.test.testsubjects.OtelTracingSupport.createProcessors
41+
assertThat(processors.getFirst().configured(), is("some-value"));
42+
}
43+
}

0 commit comments

Comments
 (0)