Skip to content

Instantly share code, notes, and snippets.

@kaiyan910
Created December 3, 2018 07:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kaiyan910/95f2646912258461fb5abd8459d6be6d to your computer and use it in GitHub Desktop.
Save kaiyan910/95f2646912258461fb5abd8459d6be6d to your computer and use it in GitHub Desktop.
package com.qbssystem.libs.router_processor;
import com.google.auto.service.AutoService;
import com.google.common.collect.ImmutableSet;
import com.qbssystem.libs.router_annotation.Router;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;
import java.io.IOException;
import java.util.HashMap;
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.annotation.processing.SupportedSourceVersion;
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.TypeElement;
import javax.lang.model.util.Elements;
import javax.tools.Diagnostic;
@AutoService(Processor.class)
public class RouterProcessor extends AbstractProcessor {
private static final String METHOD_PREFIX = "start";
private static final ClassName classIntent = ClassName.get("android.content", "Intent");
private static final ClassName classContext = ClassName.get("android.content", "Context");
private Filer filer;
private Messager messager;
private Elements elements;
private Map<String, String> activitiesWithPackage;
@Override
public synchronized void init(ProcessingEnvironment processingEnvironment) {
super.init(processingEnvironment);
filer = processingEnvironment.getFiler();
messager = processingEnvironment.getMessager();
elements = processingEnvironment.getElementUtils();
activitiesWithPackage = new HashMap<>();
messager.printMessage(Diagnostic.Kind.NOTE, "RouterProcessor is under init() function.");
}
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
messager.printMessage(Diagnostic.Kind.NOTE, "RouterProcessor is under process() function.");
if (!roundEnvironment.errorRaised() && !roundEnvironment.processingOver()) {
messager.printMessage(Diagnostic.Kind.NOTE, "RouterProcessor is under process() function. (running)");
try {
/**
* 1- Find all annotated element
*/
for (Element element : roundEnvironment.getElementsAnnotatedWith(Router.class)) {
if (element.getKind() != ElementKind.CLASS) {
messager.printMessage(Diagnostic.Kind.ERROR, "Can be applied to class.");
return true;
}
TypeElement typeElement = (TypeElement) element;
activitiesWithPackage.put(
typeElement.getSimpleName().toString(),
elements.getPackageOf(typeElement).getQualifiedName().toString());
}
/**
* 2- Generate a class
*/
TypeSpec.Builder navigatorClass = TypeSpec
.classBuilder("Navigator")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
for (Map.Entry<String, String> element : activitiesWithPackage.entrySet()) {
String activityName = element.getKey();
String packageName = element.getValue();
ClassName activityClass = ClassName.get(packageName, activityName);
MethodSpec intentMethod = MethodSpec
.methodBuilder(METHOD_PREFIX + activityName)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.returns(classIntent)
.addParameter(classContext, "context")
.addStatement("return new $T($L, $L)", classIntent, "context", activityClass + ".class")
.build();
navigatorClass.addMethod(intentMethod);
}
/**
* 3- Write generated class to a file
*/
JavaFile.builder("com.annotationsample", navigatorClass.build()).build().writeTo(filer);
} catch (IOException e) {
messager.printMessage(Diagnostic.Kind.ERROR, "RouterProcessor create class file fail.");
e.printStackTrace();
}
}
return false;
}
@Override
public Set<String> getSupportedAnnotationTypes() {
return ImmutableSet.of(Router.class.getCanonicalName());
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment