AnnoMap.java
/*
* SPDX-FileCopyrightText: 2025 kaumei.io
* SPDX-License-Identifier: Apache-2.0
*/
package io.kaumei.jdbc.anno.model;
import io.kaumei.jdbc.anno.ProcessorException;
import io.kaumei.jdbc.anno.ctx.ConfigService;
import io.kaumei.jdbc.anno.ctx.Context;
import org.jspecify.annotations.Nullable;
import javax.lang.model.AnnotatedConstruct;
import javax.lang.model.element.TypeElement;
import java.util.*;
public class AnnoMap {
public static AnnoMap of(Context ctx, AnnotatedConstruct element) {
var anno2value = new HashMap<JavaAnnoType<?>, Object>();
for (var annoMirror : element.getAnnotationMirrors()) {
if (annoMirror.getAnnotationType().asElement() instanceof TypeElement te) { // sanity-check
var anno = ctx.KAUMEI_ANNO.get(te.getQualifiedName());
if (anno != null) {
if (anno2value.put(anno, anno.getAnno(annoMirror)) != null) { // sanity-check
throw new ProcessorException("Duplicate annotation: " + anno); // sanity-check
}
}
}
}
return new AnnoMap(anno2value);
}
// ------------------------------------------------------------------------
private final Map<JavaAnnoType<?>, Object> anno2value;
private final Set<JavaAnnoType<?>> unused;
private AnnoMap(Map<JavaAnnoType<?>, Object> anno2value) {
this.anno2value = anno2value;
this.unused = new HashSet<>(this.anno2value.keySet());
}
@Override
public String toString() {
return anno2value.toString();
}
// ------------------------------------------------------------------------
public void consume(JavaAnnoType<?> anno) {
unused.remove(anno);
}
@Nullable
public <T> T getOpt(JavaAnnoType<T> anno) {
var value = this.anno2value.get(anno);
if (value != null) {
unused.remove(anno);
return anno.cast(value);
}
return null;
}
public <T> T get(JavaAnnoType<T> anno, T defaultValue) {
var value = this.anno2value.get(anno);
if (value != null) {
unused.remove(anno);
return anno.cast(value);
}
return defaultValue;
}
@Nullable
public <T> T getOpt(ConfigService.Option<T> option) {
var value = this.anno2value.get(option.anno());
if (value != null) {
unused.remove(option.anno());
return option.cast(value);
}
return null;
}
@Nullable
public <T> T getIfNotDefault(ConfigService.Option<T> option) {
var value = this.anno2value.get(option.anno());
if (option.isNotDefaultValue(value)) {
unused.remove(option.anno());
return option.cast(value);
}
return null;
}
@Nullable
public <T> T getIfDefault(ConfigService.Option<T> option) {
var value = this.anno2value.get(option.anno());
if (option.isDefaultValue(value)) {
unused.remove(option.anno());
return option.cast(value);
}
return null;
}
// ------------------------------------------------------------------------
public boolean hasUnused() {
return !unused.isEmpty();
}
public Set<JavaAnnoType<?>> unused() {
return Collections.unmodifiableSet(unused);
}
}