Commit 07e0af3a by 罗翻

去除apt

parent 519f4e19
apply plugin: 'java'
sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7
// 解决build警告:编码GBK的不可映射字符
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
package com.app.annotation.apt;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by luofan on 2017/11/24.
*/
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface ApiFactory {
}
package com.app.annotation.apt;
/**
* Created by luofan on 2017/11/24.
*/
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
/**
* 实例化注解,会被主动添加到实例化工厂,自动生成newInstance代码
*/
public @interface InstanceFactory {
}
apply plugin: 'java'
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
dependencies {
compile project(':annotation_lib')
compile 'com.google.auto.service:auto-service:1.0-rc2'
compile 'com.squareup:javapoet:1.4.0'
}
// 解决build警告:编码GBK的不可映射字符
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
package com.app.apt;
import com.app.apt.processor.ApiFactoryProcessor;
import com.app.apt.processor.InstanceProcessor;
import com.google.auto.service.AutoService;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.Messager;
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.TypeElement;
import javax.lang.model.util.Elements;
/**
* Created by luofan on 2017/11/24.
*/
@AutoService(Processor.class)//自动生成 javax.annotation.processing.IProcessor 文件
@SupportedSourceVersion(SourceVersion.RELEASE_8)//java版本支持
@SupportedAnnotationTypes({//标注注解处理器支持的注解类型
"com.app.annotation.apt.InstanceFactory",
"com.app.annotation.apt.ApiFactory",
})
public class AnnotationProcessor extends AbstractProcessor {
public Filer mFiler; //文件相关的辅助类
public Elements mElements; //元素相关的辅助类
public Messager mMessager; //日志相关的辅助类
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
mFiler = processingEnv.getFiler();
mElements = processingEnv.getElementUtils();
mMessager = processingEnv.getMessager();
new ApiFactoryProcessor().process(roundEnv, this);
new InstanceProcessor().process(roundEnv, this);
return true;
}
}
package com.app.apt.inter;
import com.app.apt.AnnotationProcessor;
import javax.annotation.processing.RoundEnvironment;
/**
* Created by luofan on 2017/11/24.
* 注解处理器接口
*/
public interface IProcessor {
void process(RoundEnvironment roundEnv, AnnotationProcessor mAbstractProcessor);
}
package com.app.apt.processor;
import com.app.annotation.apt.ApiFactory;
import com.app.apt.AnnotationProcessor;
import com.app.apt.inter.IProcessor;
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.Objects;
import javax.annotation.processing.FilerException;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.ElementFilter;
import javax.tools.Diagnostic;
import static com.squareup.javapoet.TypeSpec.classBuilder;
import static javax.lang.model.element.Modifier.FINAL;
import static javax.lang.model.element.Modifier.PUBLIC;
import static javax.lang.model.element.Modifier.STATIC;
/**
* Created by luofan on 2017/11/24.
*/
public class ApiFactoryProcessor implements IProcessor {
@Override
public void process(RoundEnvironment roundEnv, AnnotationProcessor mAbstractProcessor) {
String CLASS_NAME = "ApiFactory";
TypeSpec.Builder tb = classBuilder(CLASS_NAME).addModifiers(PUBLIC, FINAL).addJavadoc("@ API工厂 代替model类");
try {
for (TypeElement element : ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(ApiFactory.class))) {
mAbstractProcessor.mMessager.printMessage(Diagnostic.Kind.NOTE, "正在处理: " + element.toString());
for (Element e : element.getEnclosedElements()) {
ExecutableElement executableElement = (ExecutableElement) e;
MethodSpec.Builder methodBuilder =
MethodSpec.methodBuilder(e.getSimpleName().toString())
.addJavadoc("@此方法由apt自动生成")
.addModifiers(PUBLIC, STATIC);
// methodBuilder.returns(TypeName.get(executableElement.getReturnType()));
methodBuilder.returns(ClassName.get("io.reactivex", "Observable"));
String paramsString = "";
for (VariableElement ep : executableElement.getParameters()) {
methodBuilder.addParameter(TypeName.get(ep.asType()), ep.getSimpleName().toString());
paramsString += ep.getSimpleName().toString() + ",";
}
if (!(e.getSimpleName().toString()).equals("download")) {
methodBuilder.addStatement(
"return $T.getService()" +
".$L($L)"
+ ".compose($T.applySchedulers())"
, ClassName.get("com.dayu.bigfish.api", "Api")
, e.getSimpleName().toString()
, Objects.equals(paramsString, "") ? "" : paramsString.substring(0, paramsString.length() - 1)
, ClassName.get("com.dayu.bigfish.api", "Api"));
} else {
methodBuilder.addStatement(
"return $T.getService()" +
".$L($L)"
, ClassName.get("com.dayu.bigfish.api", "Api")
, e.getSimpleName().toString()
, paramsString.substring(0, paramsString.length() - 1));
}
tb.addMethod(methodBuilder.build());
}
}
JavaFile javaFile = JavaFile.builder("com.apt", tb.build()).build();// 生成源代码
javaFile.writeTo(mAbstractProcessor.mFiler);// 在 app module/build/generated/source/apt 生成一份源代码
} catch (FilerException e) {
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.app.apt.processor;
import com.app.annotation.apt.InstanceFactory;
import com.app.apt.AnnotationProcessor;
import com.app.apt.inter.IProcessor;
import com.app.apt.util.Utils;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.processing.FilerException;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementFilter;
import static com.squareup.javapoet.TypeSpec.classBuilder;
import static javax.lang.model.element.Modifier.FINAL;
import static javax.lang.model.element.Modifier.PUBLIC;
import static javax.lang.model.element.Modifier.STATIC;
/**
* Created by luofan on 2017/11/24.
*/
public class InstanceProcessor implements IProcessor {
@Override
public void process(RoundEnvironment roundEnv, AnnotationProcessor mAbstractProcessor) {
String CLASS_NAME = "InstanceFactory";
TypeSpec.Builder tb = classBuilder(CLASS_NAME).addModifiers(PUBLIC, FINAL).addJavadoc("@ 实例化工厂 此类由apt自动生成");
MethodSpec.Builder methodBuilder1 = MethodSpec.methodBuilder("create")
.addJavadoc("@此方法由apt自动生成")
.returns(Object.class).addModifiers(PUBLIC, STATIC).addException(IllegalAccessException.class).addException(InstantiationException.class)
.addParameter(Class.class, "mClass");
List<ClassName> mList = new ArrayList<>();
CodeBlock.Builder blockBuilder = CodeBlock.builder();
blockBuilder.beginControlFlow(" switch (mClass.getSimpleName())");//括号开始
try {
for (TypeElement element : ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(InstanceFactory.class))) {
// mAbstractProcessor.mMessager.printMessage(Diagnostic.Kind.NOTE, "正在处理: " + element.toString());
if (!Utils.isValidClass(mAbstractProcessor.mMessager, element)) return;
ClassName currentType = ClassName.get(element);
if (mList.contains(currentType)) continue;
mList.add(currentType);
// String className = null;
// try {
// Class<?> clazz = element.getAnnotation(InstanceFactory.class).value();
// className = clazz.getCanonicalName();
// } catch (MirroredTypeException mte) {
// DeclaredType classTypeMirror = (DeclaredType) mte.getTypeMirror();
// TypeElement classTypeElement = (TypeElement) classTypeMirror.asElement();
// className = classTypeElement.getQualifiedName().toString();
// } catch (Exception e) {
// }
// if (className != null && !className.equals(InstanceFactory.class.getName())) {
// blockBuilder.addStatement("case $S: return new $T()", currentType.simpleName(), Utils.getType(className));//初始化Repository
// } else {
blockBuilder.addStatement("case $S: return new $T()", currentType.simpleName(), currentType);//初始化Presenter
// }
}
// methodBuilder1.returns(ClassName.get("com.dayu.bigfish.base","BasePresenter"));
blockBuilder.addStatement("default: return mClass.newInstance()");
blockBuilder.endControlFlow();
methodBuilder1.addCode(blockBuilder.build());
tb.addMethod(methodBuilder1.build());
JavaFile javaFile = JavaFile.builder(Utils.PackageName, tb.build()).build();// 生成源代码
javaFile.writeTo(mAbstractProcessor.mFiler);// 在 app module/build/generated/source/apt 生成一份源代码
} catch (FilerException e) {
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.app.apt.util;
import javax.lang.model.element.TypeElement;
public class NoPackageNameException extends Exception {
public NoPackageNameException(TypeElement typeElement) {
super("The package of " + typeElement.getSimpleName() + " has no name");
}
}
package com.app.apt.util;
import com.squareup.javapoet.ClassName;
import javax.annotation.processing.Messager;
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.tools.Diagnostic;
import static javax.lang.model.element.Modifier.ABSTRACT;
import static javax.lang.model.element.Modifier.PUBLIC;
/**
* Created by baixiaokang on 16/8/3.
*/
public class Utils {
public static final String PackageName = "com.apt";
public static final String ANNOTATION = "@";
public static boolean isPublic(TypeElement element) {
return element.getModifiers().contains(PUBLIC);
}
public static boolean isAbstract(TypeElement element) {
return element.getModifiers().contains(ABSTRACT);
}
public static boolean isValidClass(Messager messager, TypeElement element) {
if (element.getKind() != ElementKind.CLASS) {
return false;
}
if (!isPublic(element)) {
String message = String.format("Classes annotated with %s must be public.", ANNOTATION);
messager.printMessage(Diagnostic.Kind.ERROR, message, element);
return false;
}
if (isAbstract(element)) {
String message = String.format("Classes annotated with %s must not be abstract.", ANNOTATION);
messager.printMessage(Diagnostic.Kind.ERROR, message, element);
return false;
}
return true;
}
public static String getPackageName(Elements elements, TypeElement typeElement) throws NoPackageNameException {
PackageElement pkg = elements.getPackageOf(typeElement);
if (pkg.isUnnamed()) {
throw new NoPackageNameException(typeElement);
}
return pkg.getQualifiedName().toString();
}
public static String getClassName(TypeElement typeElement) throws ClassNotFoundException {
return ClassName.get(typeElement).simpleName();
}
public static ClassName getType(String className) {
return ClassName.get(className.substring(0, className.lastIndexOf(".")),
className.substring(className.lastIndexOf(".") + 1, className.length()));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment