KaumeiClassBuilder.java
/*
* SPDX-FileCopyrightText: 2025 kaumei.io
* SPDX-License-Identifier: Apache-2.0
*/
package io.kaumei.jdbc.anno.gen;
import com.palantir.javapoet.*;
import io.kaumei.jdbc.JdbcConnectionProvider;
import io.kaumei.jdbc.anno.ProcessorException;
import io.kaumei.jdbc.anno.ctx.Context;
import org.jspecify.annotations.Nullable;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import java.util.HashMap;
import java.util.Map;
import static io.kaumei.jdbc.anno.Processor.GENERATED;
public class KaumeiClassBuilder implements KaumeiBuilder {
// ----- state
private final TypeElement iface;
private final String packageName;
private final TypeSpec.Builder typeSpecBuilder;
private final Map<String, TargetMethod> classNames = new HashMap<>();
KaumeiClassBuilder(Context ctx, String packageName, TypeElement iface) {
this.iface = iface;
this.packageName = packageName;
var simpleName = iface.getSimpleName() + ctx.kaumeiConfig.generatedClassSuffix();
var generationAnno = ctx.JDBC_GENERATION.getAnnoOpt(iface);
this.typeSpecBuilder = TypeSpec.classBuilder(simpleName)
.addModifiers(Modifier.PUBLIC)
.addSuperinterface(ClassName.get(iface));
this.typeSpecBuilder.addAnnotation(GENERATED);
// ----- copy all annotations
for (var mirror : iface.getAnnotationMirrors()) {
var spec = ctx.kaumeiJdbcGenerator.annotationSpec(mirror);
if (spec != null) {
typeSpecBuilder.addAnnotation(AnnotationSpec.get(mirror));
}
}
// ----- add additional specified annotations
if (generationAnno != null) {
for (TypeMirror anno : generationAnno.classAnnotations()) {
this.typeSpecBuilder.addAnnotation(ClassName.get(ctx.asTypeElement(anno)));
}
}
// ----- Add supplier field
typeSpecBuilder.addField(
FieldSpec.builder(JdbcConnectionProvider.class, "supplier", Modifier.PRIVATE, Modifier.FINAL).build());
var constructor = MethodSpec.constructorBuilder()
.addModifiers(Modifier.PUBLIC)
.addParameter(JdbcConnectionProvider.class, "supplier")
.addStatement("this.supplier = $L", KaumeiLib.requireNonNull("supplier"));
// ----- add additional specified annotations
if (generationAnno != null) {
for (var anno : generationAnno.constructorAnnotations()) {
constructor.addAnnotation(ClassName.get(ctx.asTypeElement(anno)));
}
}
// ----- Add constructor
this.typeSpecBuilder.addMethod(constructor.build());
}
@Override
public TypeElement type() {
return this.iface;
}
@Override
public TypeSpec build() {
return this.typeSpecBuilder.build();
}
public String packageName() {
return packageName;
}
@Nullable TargetMethod containsClass(String name) {
return classNames.get(name);
}
void addClass(String name, TypeSpec typeSpec, TargetMethod targetMethod) {
if (classNames.put(name, targetMethod) != null) { // sanity-check
throw new ProcessorException("Name already known: " + name); // sanity-check
}
this.typeSpecBuilder.addType(typeSpec);
}
public void addMethod(MethodSpec methodSpec) {
this.typeSpecBuilder.addMethod(methodSpec);
}
}