SourceMethodService.java
/*
* SPDX-FileCopyrightText: 2025 kaumei.io
* SPDX-License-Identifier: Apache-2.0
*/
package io.kaumei.jdbc.anno.model;
import io.kaumei.jdbc.anno.ProcessorEnvironment;
import io.kaumei.jdbc.anno.ProcessorSteps;
import io.kaumei.jdbc.anno.ctx.Context;
import org.jspecify.annotations.Nullable;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import static java.util.Objects.requireNonNull;
public class SourceMethodService implements ProcessorSteps {
// ----- services
private final Context ctx;
// ----- state
private final Map<ExecutableElement, SourceMethod> methods = new LinkedHashMap<>();
private final Map<ExecutableElement, RuntimeException> failures = new LinkedHashMap<>();
public SourceMethodService(Context ctx) {
this.ctx = requireNonNull(ctx);
}
// ------------------------------------------------------------------------
@Override
public void process(ProcessorEnvironment roundEnv) {
for (var entry : roundEnv.jdbcInterfaces()) {
this.ctx.logger.acceptWithDebugFlag(entry, this::resolveMethods);
}
}
private void resolveMethods(TypeElement iface) {
this.ctx.logger.info("Resolve methods", iface);
for (var child : iface.getEnclosedElements()) {
var modifiers = child.getModifiers();
if (child.getKind() == ElementKind.METHOD
&& modifiers.contains(Modifier.ABSTRACT)
&& !modifiers.contains(Modifier.PRIVATE)
&& !modifiers.contains(Modifier.STATIC)
&& child instanceof ExecutableElement method) {
resolveMethod(method);
}
}
}
private void resolveMethod(ExecutableElement method) {
try {
var source = SourceMethod.of(this.ctx, method);
var old = this.methods.put(method, source);
if (old != null) {
throw new IllegalStateException("duplicate: " + method);
}
} catch (RuntimeException e) {
this.methods.remove(method);
this.failures.put(method, e);
}
}
// ------------------------------------------------------------------------
public @Nullable SourceMethod getOpt(ExecutableElement method) {
var exp = this.failures.get(method);
if (exp != null) {
throw exp; // throw the exception saved in the init stage
}
return this.methods.get(method);
}
public Collection<SourceMethod> values() {
return this.methods.values();
}
}