All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.kyle.component.kdb.annotation.compiler.ORMAnnotationProcessor Maven / Gradle / Ivy

package com.kyle.component.kdb.annotation.compiler;

import com.google.auto.service.AutoService;
import com.kyle.component.kdb.annotation.Column;
import com.kyle.component.kdb.annotation.ORMAnnotation;
import com.kyle.component.kdb.condition.ORMMapper;
import com.kyle.component.kdb.condition.ValueSet;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.tools.Diagnostic;

@AutoService(Processor.class)
public class ORMAnnotationProcessor extends AbstractProcessor {
    private Filer filer;
    private Messager mMessager;
    private Elements elementUtils;
    private Map> annotationMap = new HashMap<>();

    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);
        mMessager = processingEnv.getMessager();
        filer = processingEnv.getFiler();
        elementUtils = processingEnv.getElementUtils();
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }

    @Override
    public Set getSupportedAnnotationTypes() {
        Set annotations = new LinkedHashSet<>();
        annotations.add(ORMAnnotation.class.getCanonicalName());
        annotations.add(Column.class.getCanonicalName());
        return annotations;
    }

    private void error(Element e, String msg, Object... args) {
        mMessager.printMessage(Diagnostic.Kind.ERROR, String.format(msg, args), e);
    }

    private void analysisAnnotated() {
        for (String key : annotationMap.keySet()) {
            List fields = annotationMap.get(key);
            if (!fields.isEmpty()) {
                builderMapperClass(key, fields);
                builderValueClass(key, fields);
            }
        }
    }

    public void builderMapperClass(String clsName, List fields) {
        String newClsName = clsName.substring(clsName.lastIndexOf(".") + 1) + "Mapper";
        String pkgName = clsName.substring(0, clsName.lastIndexOf(".") + 1) + "mapper";
        TypeSpec.Builder typeCls = TypeSpec.classBuilder(newClsName).addModifiers(Modifier.PUBLIC).superclass(ORMMapper.class);
        List allMethods = new ArrayList<>();
        ClassName staticName = ClassName.get(pkgName, newClsName);
        allMethods.add(MapperFieldBuilder.builderCreateMethod(staticName));
        allMethods.addAll(MapperFieldBuilder.builderPrimaryKeyMethod(staticName));
        for (AnnotationField annotationField : fields) {
            allMethods.addAll(MapperFieldBuilder.builderMethod(staticName, annotationField));
        }
        allMethods.add(MapperFieldBuilder.builderLimitMethod(staticName));
        writeJavaFile(typeCls, pkgName, allMethods);
    }

    public void builderValueClass(String clsName, List fields) {
        String newClsName = clsName.substring(clsName.lastIndexOf(".") + 1) + "ValueSet";
        String pkgName = clsName.substring(0, clsName.lastIndexOf(".") + 1) + "value.set";
        TypeSpec.Builder typeCls = TypeSpec.classBuilder(newClsName).addModifiers(Modifier.PUBLIC).superclass(ValueSet.class);
        List allMethods = new ArrayList<>();
        ClassName staticName = ClassName.get(pkgName, newClsName);
        allMethods.add(com.kyle.component.kdb.annotation.compiler.ValueSetFieldBuilder.builderCreateMethod(staticName));
        for (AnnotationField annotationField : fields) {
            allMethods.addAll(ValueSetFieldBuilder.builderMethod(staticName, annotationField));
        }
        writeJavaFile(typeCls, pkgName, allMethods);
    }

    private void writeJavaFile(TypeSpec.Builder builder, String pkgName, List methodSpecs) {
        try {
            builder.addMethods(methodSpecs);
            JavaFile javaFile = JavaFile.builder(pkgName, builder.build())
                    .addFileComment(" This codes are generated automatically. Do not modify!")
                    .build();
            javaFile.writeTo(filer);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private void annotationField(Element element) {
        TypeElement classElement = (TypeElement) element.getEnclosingElement();
        PackageElement packageElement = elementUtils.getPackageOf(classElement);
        String clsName = classElement.getSimpleName().toString();
        String pkgName = packageElement.getQualifiedName().toString();
        String key = pkgName + "." + clsName;
        List fields = annotationMap.get(key);
        if (fields == null)
            return;
        TypeMirror typeMirror = element.asType();
        String fieldName = element.getAnnotation(Column.class).name();
        fieldName = (fieldName == null || fieldName.isEmpty()) ? element.getSimpleName().toString() : fieldName;
        fields.add(new AnnotationField(fieldName.isEmpty() ? element.getSimpleName().toString() : fieldName, TypeName.get(typeMirror)));
    }

    @Override
    public boolean process(Set set, RoundEnvironment roundEnvironment) {
        annotationMap.clear();
        for (Element annotatedElement : roundEnvironment.getElementsAnnotatedWith(ORMAnnotation.class)) {
            if (annotatedElement.getKind() == ElementKind.CLASS) {
                PackageElement packageElement = (PackageElement) annotatedElement.getEnclosingElement();
                String key = packageElement.getQualifiedName().toString() + "." + annotatedElement.getSimpleName().toString();
                annotationMap.put(key, new ArrayList());
            }
        }
        if (annotationMap.isEmpty())
            return false;
        for (Element annotatedElement : roundEnvironment.getElementsAnnotatedWith(Column.class)) {
            if (annotatedElement.getKind() == ElementKind.FIELD) {
                annotationField(annotatedElement);
            }
        }
        analysisAnnotated();
        return false;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy