123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- package cn.binarywang.wx.graal;
- import lombok.Data;
- import lombok.extern.slf4j.Slf4j;
- import javax.annotation.processing.AbstractProcessor;
- 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.TypeElement;
- import javax.lang.model.type.DeclaredType;
- import javax.lang.model.type.TypeKind;
- import javax.lang.model.type.TypeMirror;
- import javax.lang.model.util.ElementFilter;
- import javax.tools.FileObject;
- import javax.tools.StandardLocation;
- import java.io.IOException;
- import java.io.Writer;
- import java.util.Set;
- import java.util.SortedSet;
- import java.util.TreeSet;
- /**
- * 目前仅仅处理@Data,且必须在lombok自己的processor之前执行,千万注意!!!!!
- *
- * @author outersky
- */
- @SupportedAnnotationTypes("lombok.Data")
- @SupportedSourceVersion(SourceVersion.RELEASE_7)
- public class GraalProcessor extends AbstractProcessor {
- private static final String REFLECTION_CONFIG_JSON = "reflection-config.json";
- private static final String NATIVE_IMAGE_PROPERTIES = "native-image.properties";
- private SortedSet<String> classSet = new TreeSet<>();
- private String shortestPackageName = null;
- @Override
- public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
- for (TypeElement annotatedClass : ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(Data.class))) {
- registerClass(annotatedClass.getQualifiedName().toString());
- handleSuperClass(annotatedClass);
- }
- //只有最后一轮才可以写文件,否则文件会被重复打开,报错!
- if (!roundEnv.processingOver()) {
- return false;
- }
- // 如果没有文件要写,跳过
- if (classSet.isEmpty()) {
- return false;
- }
- writeFiles();
- //必须返回false,以便让lombok能继续处理。
- return false;
- }
- /**
- * 设置当前最短的package名称
- *
- * @param packageName 包名
- */
- private void setShortestPackageName(String packageName) {
- if (shortestPackageName == null) {
- shortestPackageName = packageName;
- } else if (packageName.length() < shortestPackageName.length()) {
- shortestPackageName = packageName;
- }
- }
- /**
- * 更加完整的类名来获取package名称
- *
- * @param fullClassName 完整的类名
- * @return package name
- */
- private String getPackageName(String fullClassName) {
- int last = fullClassName.lastIndexOf('.');
- if (last == -1) {
- return fullClassName;
- }
- return fullClassName.substring(0, last);
- }
- /**
- * 保存文件
- * META-INF/native-image/.../reflection-config.json
- * META-INF/native-image/.../native-image.properties
- */
- private void writeFiles() {
- String basePackage = shortestPackageName;
- String module;
- if (basePackage.contains(".")) {
- final int i = basePackage.lastIndexOf('.');
- module = basePackage.substring(i + 1);
- basePackage = basePackage.substring(0, i);
- } else {
- module = basePackage;
- }
- String path = "META-INF/native-image/" + basePackage + "/" + module + "/";
- String reflectFile = path + REFLECTION_CONFIG_JSON;
- String propsFile = path + NATIVE_IMAGE_PROPERTIES;
- try {
- FileObject fileObject = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", propsFile);
- try (Writer writer = fileObject.openWriter();) {
- writer.append("Args = -H:ReflectionConfigurationResources=${.}/" + REFLECTION_CONFIG_JSON);
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- try {
- FileObject fileObject = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", reflectFile);
- try (Writer writer = fileObject.openWriter();) {
- writer.write("[\n");
- boolean first = true;
- for (String name : classSet) {
- if (first) {
- first = false;
- } else {
- writer.write(",");
- }
- writer.write(assetGraalJsonElement(name));
- writer.append('\n');
- }
- writer.write("]");
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- private String assetGraalJsonElement(String className) {
- return "{\n" +
- " \"name\" : \"" + className + "\",\n" +
- " \"allDeclaredFields\":true,\n" +
- " \"allDeclaredMethods\":true,\n" +
- " \"allDeclaredConstructors\":true,\n" +
- " \"allPublicMethods\" : true\n" +
- "}";
- }
- /**
- * 登记一个class
- *
- * @param className 完整的类名
- */
- private void registerClass(String className) {
- classSet.add(className);
- setShortestPackageName(getPackageName(className));
- }
- /**
- * 获取一个类型的所有的父类,并登记
- *
- * @param typeElement 类型元素
- */
- private void handleSuperClass(TypeElement typeElement) {
- TypeMirror superclass = typeElement.getSuperclass();
- if (superclass.getKind() == TypeKind.DECLARED) {
- TypeElement s = (TypeElement) ((DeclaredType) superclass).asElement();
- String sName = s.toString();
- // ignore java.**/javax.**
- if (sName.startsWith("java.") || sName.startsWith("javax.")) {
- return;
- }
- registerClass(sName);
- handleSuperClass(s);
- }
- }
- }
|