cn.taketoday.annotation.config.processor.AnnotationConfigAnnotationProcessor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of infra-annotation-config-processor Show documentation
Show all versions of infra-annotation-config-processor Show documentation
TODAY Infrastructure Annotation config Annotation Processor
The newest version!
/*
* Copyright 2017 - 2023 the original author or authors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see [http://www.gnu.org/licenses/]
*/
package cn.taketoday.annotation.config.processor;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Stream;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.tools.FileObject;
import javax.tools.StandardLocation;
/**
* Annotation processor to store certain annotations from auto-configuration classes in a
* property file.
*
* @author Madhura Bhave
* @author Phillip Webb
* @author Moritz Halbritter
* @author Harry Yang
* @since 4.0
*/
@SupportedAnnotationTypes({
"cn.taketoday.context.condition.ConditionalOnClass",
"cn.taketoday.context.condition.ConditionalOnBean",
"cn.taketoday.context.condition.ConditionalOnSingleCandidate",
"cn.taketoday.context.condition.ConditionalOnWebApplication",
"cn.taketoday.context.annotation.config.AutoConfigureBefore",
"cn.taketoday.context.annotation.config.AutoConfigureAfter",
"cn.taketoday.context.annotation.config.AutoConfigureOrder",
"cn.taketoday.context.annotation.config.AutoConfiguration",
"cn.taketoday.context.annotation.config.DisableDIAutoConfiguration"
})
public class AnnotationConfigAnnotationProcessor extends AbstractProcessor {
protected static final String PROPERTIES_PATH = "META-INF/infra-autoconfigure-metadata.properties";
private final Map properties = new TreeMap<>();
private final List propertyGenerators;
public AnnotationConfigAnnotationProcessor() {
this.propertyGenerators = Collections.unmodifiableList(getPropertyGenerators());
}
protected List getPropertyGenerators() {
List generators = new ArrayList<>();
addConditionPropertyGenerators(generators);
addAutoConfigurePropertyGenerators(generators);
return generators;
}
private void addConditionPropertyGenerators(List generators) {
String annotationPackage = "cn.taketoday.context.condition";
generators.add(PropertyGenerator.of(annotationPackage, "ConditionalOnClass")
.withAnnotation(new OnClassConditionValueExtractor()));
generators.add(PropertyGenerator.of(annotationPackage, "ConditionalOnBean")
.withAnnotation(new OnBeanConditionValueExtractor()));
generators.add(PropertyGenerator.of(annotationPackage, "ConditionalOnSingleCandidate")
.withAnnotation(new OnBeanConditionValueExtractor()));
generators.add(PropertyGenerator.of(annotationPackage, "ConditionalOnWebApplication")
.withAnnotation(ValueExtractor.allFrom("type")));
}
private void addAutoConfigurePropertyGenerators(List generators) {
String annotationPackage = "cn.taketoday.context.annotation.config";
generators.add(PropertyGenerator.of(annotationPackage, "AutoConfigureBefore", true)
.withAnnotation(ValueExtractor.allFrom("value", "name"))
.withAnnotation("AutoConfiguration", ValueExtractor.allFrom("before", "beforeName")));
generators.add(PropertyGenerator.of(annotationPackage, "AutoConfigureAfter", true)
.withAnnotation(ValueExtractor.allFrom("value", "name"))
.withAnnotation("AutoConfiguration", ValueExtractor.allFrom("after", "afterName")));
generators.add(PropertyGenerator.of(annotationPackage, "AutoConfigureBefore", true)
.withAnnotation(ValueExtractor.allFrom("value", "name"))
.withAnnotation("DisableDIAutoConfiguration", ValueExtractor.allFrom("before", "beforeName")));
generators.add(PropertyGenerator.of(annotationPackage, "AutoConfigureAfter", true)
.withAnnotation(ValueExtractor.allFrom("value", "name"))
.withAnnotation("DisableDIAutoConfiguration", ValueExtractor.allFrom("after", "afterName")));
generators.add(PropertyGenerator.of(annotationPackage, "AutoConfigureOrder")
.withAnnotation(ValueExtractor.allFrom("value")));
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
@Override
public boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (PropertyGenerator generator : this.propertyGenerators) {
process(roundEnv, generator);
}
if (roundEnv.processingOver()) {
try {
writeProperties();
}
catch (Exception ex) {
throw new IllegalStateException("Failed to write metadata", ex);
}
}
return false;
}
private void process(RoundEnvironment roundEnv, PropertyGenerator generator) {
for (String annotationName : generator.getSupportedAnnotations()) {
TypeElement annotationType = this.processingEnv.getElementUtils().getTypeElement(annotationName);
if (annotationType != null) {
for (Element element : roundEnv.getElementsAnnotatedWith(annotationType)) {
processElement(element, generator, annotationName);
}
}
}
}
private void processElement(Element element, PropertyGenerator generator, String annotationName) {
try {
String qualifiedName = Elements.getQualifiedName(element);
AnnotationMirror annotation = getAnnotation(element, annotationName);
if (qualifiedName != null && annotation != null) {
List
© 2015 - 2024 Weber Informatics LLC | Privacy Policy