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

com.greenfrvr.annyprefs.compiler.PreferencesProcessor Maven / Gradle / Ivy

package com.greenfrvr.annyprefs.compiler;

import com.google.auto.service.AutoService;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.greenfrvr.annyprefs.annotation.AnnyPref;
import com.greenfrvr.annyprefs.annotation.BoolPref;
import com.greenfrvr.annyprefs.annotation.DatePref;
import com.greenfrvr.annyprefs.annotation.FloatPref;
import com.greenfrvr.annyprefs.annotation.IntPref;
import com.greenfrvr.annyprefs.annotation.LongPref;
import com.greenfrvr.annyprefs.annotation.ObjectPref;
import com.greenfrvr.annyprefs.annotation.StringPref;
import com.greenfrvr.annyprefs.annotation.StringSetPref;
import com.greenfrvr.annyprefs.compiler.components.AdapterGenerator;
import com.greenfrvr.annyprefs.compiler.utils.Utils;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.Arrays;
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.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.Diagnostic;

/**
 * Created by greenfrvr
 */
@AutoService(Processor.class)
public class PreferencesProcessor extends AbstractProcessor {

    private Types typeUtils;
    private Elements elementUtils;
    private Filer filer;
    private Messager messager;
    private Map map;
    private AdapterGenerator adapter;

    private static final Class ANNY = AnnyPref.class;
    private static final List> CLASSES = Arrays.asList(
            StringPref.class, IntPref.class, LongPref.class, FloatPref.class,
            BoolPref.class, DatePref.class, ObjectPref.class, StringSetPref.class
    );

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        typeUtils = processingEnv.getTypeUtils();
        elementUtils = processingEnv.getElementUtils();
        filer = processingEnv.getFiler();
        messager = processingEnv.getMessager();

        map = Maps.newHashMap();
        adapter = AdapterGenerator.init();
    }

    @Override
    public Set getSupportedAnnotationTypes() {
        Set annotations = Sets.newHashSet(ANNY.getCanonicalName());
        CLASSES.stream().forEach(aClass -> annotations.add(aClass.getCanonicalName()));

        return annotations;
    }

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

    @Override
    public boolean process(Set annotations, RoundEnvironment roundEnv) {
        roundEnv.getRootElements().stream().filter(element1 -> element1 instanceof PackageElement)
                .forEach(pack -> System.out.println(pack.toString()));
        for (Element element : roundEnv.getElementsAnnotatedWith(ANNY)) {

            if (element.getKind() != ElementKind.INTERFACE) {
                error(element, "Only classes can be annotated with @%s", ANNY.getSimpleName());
                return true;
            }

            String className = element.getSimpleName().toString();
            String packageName = elementUtils.getPackageOf(element).toString();
            System.out.println("Got AnnyPref annotation for [" + elementUtils.getPackageOf(element).getQualifiedName() + "." + className + "] class!" + packageName);

            map.put(className, new Anny(className, element.getAnnotation(ANNY).name(), packageName));
            adapter.add(className, className.concat(Utils.PREFS));
        }

        CLASSES.stream().forEach(aClass -> searchAnnotationClass(roundEnv, aClass));
        printAnnyPrefs();

        generatePreferences();
        generateAdapter();

        return true;
    }

    private void searchAnnotationClass(RoundEnvironment roundEnv, Class cls) {
        System.out.println(String.format("Scanning for %s annotation", cls.getSimpleName()));
        roundEnv.getElementsAnnotatedWith(cls).stream()
                .filter(el -> map.get(key(el)) != null)
                .forEach(el -> map.get(key(el)).addElement(el, cls));
    }

    private String key(Element element) {
        return element.getEnclosingElement().getSimpleName().toString();
    }

    private void generatePreferences() {
        map.values().stream().forEach(anny -> {
            try {
                anny.construct().generate(filer);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

    private void generateAdapter() {
        try {
            adapter.construct().generate(filer);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

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

    //TODO - remove, debug purposes only
    private void printAnnyPrefs() {
        map.values().forEach(anny -> anny.getPrefs().forEach(pref -> System.out.println(pref.toString())));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy