package io.micronaut.annotation.processing;
import io.micronaut.annotation.processing.visitor.JavaPackageElement;
import io.micronaut.annotation.processing.visitor.JavaVisitorContext;
import io.micronaut.context.annotation.Configuration;
import io.micronaut.core.annotation.AnnotationMetadata;
import io.micronaut.core.annotation.Internal;
import io.micronaut.inject.writer.BeanConfigurationWriter;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.element.Element;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.SimpleElementVisitor8;
import java.io.IOException;
import java.util.Collections;
import java.util.Set;
@SupportedAnnotationTypes({
"io.micronaut.context.annotation.Configuration"
})
@Internal
public class PackageConfigurationInjectProcessor extends AbstractInjectAnnotationProcessor {
@Override
public final synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
}
@Override
public Set<String> getSupportedAnnotationTypes() {
return Collections.singleton("io.micronaut.context.annotation.Configuration");
}
@Override
public final boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (annotations.isEmpty()) {
return false;
}
AnnotationElementScanner scanner = new AnnotationElementScanner();
Set<? extends Element> elements = roundEnv.getRootElements();
ElementFilter.packagesIn(elements).forEach(element -> element.accept(scanner, element));
try {
classWriterOutputVisitor.finish();
} catch (Exception e) {
error("I/O error occurred writing META-INF services information: %s", e);
}
return false;
}
class AnnotationElementScanner extends SimpleElementVisitor8<Object, Object> {
@Override
public Object visitPackage(PackageElement packageElement, Object p) {
Object aPackage = super.visitPackage(packageElement, p);
if (annotationUtils.hasStereotype(packageElement, Configuration.class)) {
String packageName = packageElement.getQualifiedName().toString();
AnnotationMetadata annotationMetadata = annotationUtils.getAnnotationMetadata(packageElement);
BeanConfigurationWriter writer = new BeanConfigurationWriter(
packageName,
new JavaPackageElement(packageElement, annotationMetadata, new JavaVisitorContext(
processingEnv,
messager,
elementUtils,
annotationUtils,
typeUtils,
modelUtils,
genericUtils,
filer,
visitorAttributes
)),
annotationMetadata
);
try {
writer.accept(classWriterOutputVisitor);
} catch (IOException e) {
error("I/O error occurred writing Configuration for package [%s]: %s", packageElement, e);
}
}
return aPackage;
}
}
}