Skip to content

Commit a533243

Browse files
authored
Pojo with constructor support for @ConfigValueExtractor (#197)
1 parent c89c1e6 commit a533243

File tree

3 files changed

+217
-142
lines changed

3 files changed

+217
-142
lines changed

config/config-annotation-processor/src/main/java/ru/tinkoff/kora/config/annotation/processor/ConfigParserGenerator.java

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,14 @@
1212
import javax.lang.model.element.ElementKind;
1313
import javax.lang.model.element.Modifier;
1414
import javax.lang.model.element.TypeElement;
15+
import javax.lang.model.element.VariableElement;
1516
import javax.lang.model.type.DeclaredType;
1617
import javax.lang.model.util.Elements;
1718
import javax.lang.model.util.Types;
1819
import java.io.IOException;
1920
import java.io.StringWriter;
20-
import java.util.List;
21-
import java.util.Map;
22-
import java.util.Objects;
23-
import java.util.Optional;
21+
import java.util.*;
22+
import java.util.stream.Collectors;
2423

2524
public class ConfigParserGenerator {
2625
private static final Logger log = LoggerFactory.getLogger(ConfigParserGenerator.class);
@@ -106,6 +105,11 @@ public Either<Void, List<ProcessingError>> generateForInterface(RoundEnvironment
106105
}
107106

108107
private MethodSpec buildExtractMethod(TypeElement element, TypeName typeName, ClassName implClassName, List<ConfigUtils.ConfigField> fields) {
108+
var constructors = CommonUtils.findConstructors(element, m -> m.contains(Modifier.PUBLIC));
109+
var emptyConstructor = constructors.stream().filter(e -> e.getParameters().isEmpty()).findFirst().orElse(null);
110+
var nonEmptyConstructor = constructors.stream().filter(e -> !e.getParameters().isEmpty()).findFirst().orElse(null);
111+
var constructorParams = nonEmptyConstructor == null ? Set.of() : nonEmptyConstructor.getParameters().stream().map(VariableElement::getSimpleName).map(Objects::toString).collect(Collectors.toSet());
112+
109113
var rootParse = MethodSpec.methodBuilder("extract")
110114
.addModifiers(Modifier.PUBLIC)
111115
.addAnnotation(Override.class)
@@ -126,12 +130,23 @@ private MethodSpec buildExtractMethod(TypeElement element, TypeName typeName, Cl
126130
}
127131
if (element.getKind() == ElementKind.CLASS) {
128132
if (element.getTypeParameters().isEmpty()) {
129-
rootParse.addStatement("var _result = new $T()", implClassName);
133+
rootParse.addCode("var _result = new $T(", implClassName);
130134
} else {
131-
rootParse.addStatement("var _result = new $T<>()", implClassName);
135+
rootParse.addCode("var _result = new $T<>(", implClassName);
136+
}
137+
if (nonEmptyConstructor != null && emptyConstructor == null) {
138+
for (int i = 0; i < nonEmptyConstructor.getParameters().size(); i++) {
139+
if (i > 0) {
140+
rootParse.addCode(", ");
141+
}
142+
rootParse.addCode("$N", nonEmptyConstructor.getParameters().get(i).getSimpleName());
143+
}
132144
}
145+
rootParse.addCode(");\n");
133146
for (var field : fields) {
134-
rootParse.addStatement("_result.set$N($N)", CommonUtils.capitalize(field.name()), field.name());
147+
if (!constructorParams.contains(field.name()) || emptyConstructor != null) {
148+
rootParse.addStatement("_result.set$N($N)", CommonUtils.capitalize(field.name()), field.name());
149+
}
135150
}
136151
rootParse.addStatement("return _result");
137152
} else {
@@ -202,9 +217,12 @@ public Either<Void, List<ProcessingError>> generateForPojo(RoundEnvironment roun
202217
var fields = Objects.requireNonNull(f.left());
203218

204219
var implClassName = ClassName.get(element);
205-
var defaults = FieldSpec.builder(implClassName, "DEFAULTS", Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
206-
.initializer(CodeBlock.of("new $T()", implClassName));
207-
typeBuilder.addField(defaults.build());
220+
var hasDefault = CommonUtils.findConstructors(element, m -> m.contains(Modifier.PUBLIC)).stream().anyMatch(e -> e.getParameters().isEmpty());
221+
if (hasDefault) {
222+
var defaults = FieldSpec.builder(implClassName, "DEFAULTS", Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
223+
.initializer(CodeBlock.of("new $T()", implClassName));
224+
typeBuilder.addField(defaults.build());
225+
}
208226

209227

210228
var constructor = buildConstructor(typeBuilder, fields);

0 commit comments

Comments
 (0)