de.knightsoftnet.navigation.annotation.processor.InfoProcessor Maven / Gradle / Ivy
package de.knightsoftnet.navigation.annotation.processor;
import com.google.auto.service.AutoService;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.ExecutableType;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
@SupportedAnnotationTypes("de.knightsoftnet.navigation.annotation.processor.InfoProperty")
@SupportedSourceVersion(SourceVersion.RELEASE_17)
@AutoService(Processor.class)
public class InfoProcessor extends AbstractProcessor {
@Override
public boolean process(final Set extends TypeElement> annotations,
final RoundEnvironment roundEnv) {
for (final TypeElement annotation : annotations) {
final Set extends Element> annotatedElements =
roundEnv.getElementsAnnotatedWith(annotation);
final Map> annotatedMethods = annotatedElements.stream()
.collect(Collectors.partitioningBy(
element -> ((ExecutableType) element.asType()).getParameterTypes().size() == 1
&& element.getSimpleName().toString().startsWith("set")));
final List setters = annotatedMethods.get(true);
final List otherMethods = annotatedMethods.get(false);
otherMethods
.forEach(element -> processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
"@BuilderProperty must be applied to a setXxx method with a single argument",
element));
if (setters.isEmpty()) {
continue;
}
final String className =
((TypeElement) setters.get(0).getEnclosingElement()).getQualifiedName().toString();
final Map setterMap = setters.stream()
.collect(Collectors.toMap(setter -> setter.getSimpleName().toString(), setter -> {
final InfoProperty infoProperty = setter.getAnnotation(InfoProperty.class);
final ResourceBundle bundle = ResourceBundle.getBundle(infoProperty.file());
return bundle.getString(infoProperty.value());
}));
try {
writeGeneratedFile(className, setterMap);
} catch (final IOException e) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage());
e.printStackTrace();
}
}
return true;
}
private void writeGeneratedFile(final String className, final Map setterMap)
throws IOException {
String packageName = null;
final int lastDot = className.lastIndexOf('.');
if (lastDot > 0) {
packageName = className.substring(0, lastDot);
}
final String builderClassName = className + "AptGenerated";
final String builderSimpleClassName = builderClassName.substring(lastDot + 1);
final JavaFileObject builderFile = processingEnv.getFiler().createSourceFile(builderClassName);
try (PrintWriter out = new PrintWriter(builderFile.openWriter())) {
if (packageName != null) {
out.print("package ");
out.print(packageName);
out.println(";");
out.println();
}
out.print("public class ");
out.print(builderSimpleClassName);
out.print(" extends ");
out.print(className.substring(lastDot + 1));
out.println(" {");
out.println();
out.print(" public ");
out.print(builderSimpleClassName);
out.println("() {");
out.println(" super();");
setterMap.entrySet().forEach(setter -> {
final String setterName = setter.getKey();
final String value = setter.getValue();
out.print(" ");
out.print(setterName);
out.print("(\"");
out.print(value);
out.println("\");");
});
out.println(" }");
out.println("}");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy