package com.zane.easyrouter_compiler.entity; import com.zane.easyrouter_compiler.Constant; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.FieldSpec; import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.ParameterSpec; import com.squareup.javapoet.TypeSpec; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; import javax.annotation.processing.Filer; import javax.lang.model.element.Modifier; import javax.lang.model.util.Elements; /** * RouterAnntationClass的holder类 * Created by Zane on 2016/12/20. * Email: [email protected] * Blog: zane96.github.io */ public class RouterAnnotationGenerator { private Map<String, ClassName> routers; private List<RouterAnnotationClass> datas; private RouterAnnotationGenerator(){ routers = new HashMap<>(); datas = new ArrayList<>(); } private static class SingltonHokder{ public static final RouterAnnotationGenerator instance = new RouterAnnotationGenerator(); } public static RouterAnnotationGenerator getInstance(){return SingltonHokder.instance;} /** * 添加到map中 */ public void put(RouterAnnotationClass data){ datas.add(data); String url = data.getUrl(); ClassName target = data.getClassName(); routers.put(url, target); } /** * 在map中查询 * @param url * @return */ public ClassName get(String url){ return routers.get(url); } /** * 这个方法给参数注入的Holder类持有类给调用 * 回去到类对应的url,用url去构建注入类。方便开发者自定义url * @param className * @return */ public String getUrl(String className) { Set<Map.Entry<String, ClassName>> routerSet = routers.entrySet(); Iterator<Map.Entry<String, ClassName>> iterator = routerSet.iterator(); String url = ""; while (iterator.hasNext()) { Map.Entry<String, ClassName> entry = iterator.next(); if (entry.getValue().toString().equals(className)) { url = getAuthority(entry.getKey()); break; } } return url; } /** * 清空 */ public void clear(){ routers.clear(); } /** * 根据之前收集到的数据信息(String url, Class target) * 生成路由表的.java文件代码 * @param elementUtils * @param filer * @throws IOException */ public void generateCode(Elements elementUtils, Filer filer) throws IOException{ if (datas.size() > 0){ FieldSpec routerTable = getTableField(); MethodSpec queryTable = getQueryMethod(); MethodSpec initTable = getInjectMethod(); MethodSpec constructor = getConstructorMethod(routerTable, initTable); TypeSpec routerTableClass = getClassType(routerTable, queryTable, initTable, constructor); String packageName = Constant.GENERATED_PACKAGENAME; JavaFile javaFile = JavaFile.builder(packageName, routerTableClass).build(); javaFile.writeTo(filer); } } private TypeSpec getClassType(FieldSpec routerTable, MethodSpec queryTable, MethodSpec initTable, MethodSpec constructor) { return TypeSpec.classBuilder("EasyRouterTable") .addModifiers(Modifier.PUBLIC) .addMethod(constructor) .addMethod(initTable) .addMethod(queryTable) .addField(routerTable) .build(); } /** * 构造函数 * private RouterTableExample() { routerTable = new HashMap<>(); initTable(); } */ private MethodSpec getConstructorMethod(FieldSpec routerTable, MethodSpec initTable) { ClassName hashMap = ClassName.get(HashMap.class); ClassName activity = ClassName.get("android.app", "Activity"); return MethodSpec.constructorBuilder() .addModifiers(Modifier.PUBLIC) .addStatement("$N = new $T<String, Class<? extends $T>>()", routerTable, hashMap, activity) .addStatement("$N()", initTable) .build(); } /** * private void initTable(){ //添加信息到routerTable中 } */ private MethodSpec getInjectMethod() { MethodSpec.Builder initTableBuilder = MethodSpec.methodBuilder("initTable") .addModifiers(Modifier.PRIVATE); Set<Map.Entry<String, ClassName>> routerSet = routers.entrySet(); Iterator<Map.Entry<String, ClassName>> iterator = routerSet.iterator(); while (iterator.hasNext()) { Map.Entry<String, ClassName> entry = iterator.next(); initTableBuilder.addStatement("routerTable.put($S, $T.class)", entry.getKey(), entry.getValue()); } return initTableBuilder.build(); } /** *表查询函数 * public Class queryTable(String url){ Class<?> target = routerTable.get(url); if (target == null){ return null; } return target; } */ private MethodSpec getQueryMethod() { ParameterSpec url = ParameterSpec.builder(String.class, "url").build(); return MethodSpec.methodBuilder("queryTable") .addModifiers(Modifier.PUBLIC) .addParameter(url) .addStatement("Class<? extends Activity> target = (Class<? extends Activity>) routerTable.get(url)") .beginControlFlow("if (target == null)") .addStatement("throw new $T(url)", NoSuchElementException.class) .endControlFlow() .addStatement("return target") .returns(Class.class) .build(); } private FieldSpec getTableField() { return FieldSpec.builder(Map.class, "routerTable") .addModifiers(Modifier.PRIVATE) .build(); } /** * 获取url的authority * @param url * @return */ private String getAuthority(String url){ return url.substring(url.indexOf(":") + 3, url.length()); } }