Search in sources :

Example 1 with Router

use of com.didi.drouter.annotation.Router in project DRouter by didi.

the class RouterCollect method generate.

@Override
public void generate(File routerDir) throws Exception {
    CtClass ctClass = pool.makeClass(getPackageName() + ".RouterLoader");
    CtClass superClass = pool.get("com.didi.drouter.store.MetaLoader");
    ctClass.setSuperclass(superClass);
    StringBuilder builder = new StringBuilder();
    builder.append("public void load(java.util.Map data) {\n");
    for (CtClass routerCc : routerClass.values()) {
        try {
            StringBuilder interceptorClass = null;
            StringBuilder interceptorName = null;
            String uriValue = "";
            String schemeValue = "";
            String hostValue = "";
            String pathValue = "";
            Annotation annotation = null;
            String type;
            int thread = 0;
            int priority = 0;
            boolean hold = false;
            if (routerCc.hasAnnotation(Router.class)) {
                uriValue = ((Router) routerCc.getAnnotation(Router.class)).uri();
                schemeValue = ((Router) routerCc.getAnnotation(Router.class)).scheme();
                hostValue = ((Router) routerCc.getAnnotation(Router.class)).host();
                pathValue = ((Router) routerCc.getAnnotation(Router.class)).path();
                thread = ((Router) routerCc.getAnnotation(Router.class)).thread();
                priority = ((Router) routerCc.getAnnotation(Router.class)).priority();
                hold = ((Router) routerCc.getAnnotation(Router.class)).hold();
                annotation = getAnnotation(routerCc, Router.class);
                if (checkSuper(routerCc, "android.app.Activity")) {
                    type = "com.didi.drouter.store.RouterMeta.ACTIVITY";
                } else if (checkSuper(routerCc, "android.support.v4.app.Fragment", "androidx.fragment.app.Fragment")) {
                    type = "com.didi.drouter.store.RouterMeta.FRAGMENT";
                } else if (checkSuper(routerCc, "android.view.View")) {
                    type = "com.didi.drouter.store.RouterMeta.VIEW";
                } else if (checkSuper(routerCc, "com.didi.drouter.router.IRouterHandler")) {
                    type = "com.didi.drouter.store.RouterMeta.HANDLER";
                } else {
                    throw new Exception("@Router target class illegal, " + "support only Activity/Fragment/View/IRouterHandler");
                }
            } else {
                pathValue = "/" + routerCc.getName().replace(".", "/");
                type = "com.didi.drouter.store.RouterMeta.ACTIVITY";
            }
            if (isNonStaticInnerClass(routerCc)) {
                throw new Exception("@Router can not use non static inner class");
            }
            if (!uriValue.isEmpty()) {
                if (!schemeValue.isEmpty() || !hostValue.isEmpty() || !pathValue.isEmpty()) {
                    throw new Exception("@Router uri can be used alone");
                }
                schemeValue = parseScheme(uriValue);
                hostValue = parseHost(uriValue);
                pathValue = parsePath(uriValue);
            }
            if (schemeValue.contains("/") || hostValue.contains("/")) {
                throw new Exception("@Router scheme and host can't use \"/\"");
            }
            // if (!isRegex(pathValue) && !pathValue.isEmpty() && !pathValue.startsWith("/")) {
            // throw new Exception("@Router path must start with \"/\"");
            // }
            // because of Escape character, \ will drop one, \\\\->\\, \\->empty(can't be one)
            schemeValue = schemeValue.replace("\\", "\\\\");
            hostValue = hostValue.replace("\\", "\\\\");
            pathValue = pathValue.replace("\\", "\\\\");
            if (annotation != null) {
                ArrayMemberValue interceptorClassArrayValue = (ArrayMemberValue) annotation.getMemberValue("interceptor");
                if (interceptorClassArrayValue != null) {
                    interceptorClass = new StringBuilder();
                    interceptorClass.append("new Class[]{");
                    for (MemberValue mv : interceptorClassArrayValue.getValue()) {
                        final ClassMemberValue cmv = (ClassMemberValue) mv;
                        interceptorClass.append(cmv.getValue());
                        interceptorClass.append(".class,");
                    }
                    interceptorClass.deleteCharAt(interceptorClass.length() - 1);
                    interceptorClass.append("}");
                }
                ArrayMemberValue interceptorNameArrayValue = (ArrayMemberValue) annotation.getMemberValue("interceptorName");
                if (interceptorNameArrayValue != null) {
                    interceptorName = new StringBuilder();
                    interceptorName.append("new String[]{");
                    for (MemberValue mv : interceptorNameArrayValue.getValue()) {
                        final StringMemberValue smv = (StringMemberValue) mv;
                        interceptorName.append("\"");
                        interceptorName.append(smv.getValue());
                        interceptorName.append("\",");
                    }
                    interceptorName.deleteCharAt(interceptorName.length() - 1);
                    interceptorName.append("}");
                }
            }
            StringBuilder metaBuilder = new StringBuilder();
            metaBuilder.append("com.didi.drouter.store.RouterMeta.build(");
            metaBuilder.append(type);
            metaBuilder.append(").assembleRouter(");
            metaBuilder.append("\"").append(schemeValue).append("\"");
            metaBuilder.append(",");
            metaBuilder.append("\"").append(hostValue).append("\"");
            metaBuilder.append(",");
            metaBuilder.append("\"").append(pathValue).append("\"");
            metaBuilder.append(",");
            if ("com.didi.drouter.store.RouterMeta.ACTIVITY".equals(type)) {
                if (!setting.isUseActivityRouterClass()) {
                    metaBuilder.append("\"").append(routerCc.getName()).append("\"");
                } else {
                    metaBuilder.append(routerCc.getName()).append(".class");
                }
            } else {
                metaBuilder.append(routerCc.getName()).append(".class");
            }
            metaBuilder.append(", ");
            CtClass proxyCc = null;
            try {
                if (type.endsWith("HANDLER") || type.endsWith("FRAGMENT")) {
                    CtConstructor constructor = routerCc.getDeclaredConstructor(null);
                    if (constructor != null) {
                        CtClass proxyInterface = pool.get("com.didi.drouter.store.IRouterProxy");
                        proxyCc = pool.makeClass(PROXY + routerCc.getName().replace(".", "_"));
                        proxyCc.addInterface(proxyInterface);
                        String method1 = String.format("public java.lang.Object newInstance(android.content.Context context) {" + "{  return new %s();} }", routerCc.getName());
                        generatorClass(routerDir, proxyCc, method1, METHOD2);
                    }
                } else if (type.endsWith("VIEW")) {
                    CtConstructor constructor = routerCc.getDeclaredConstructor(new CtClass[] { pool.get("android.content.Context") });
                    if (constructor != null) {
                        CtClass proxyInterface = pool.get("com.didi.drouter.store.IRouterProxy");
                        proxyCc = pool.makeClass(PROXY + routerCc.getName().replace(".", "_"));
                        proxyCc.addInterface(proxyInterface);
                        String method1 = String.format("public java.lang.Object newInstance(android.content.Context context) {" + "{  return new %s(context);} }", routerCc.getName());
                        generatorClass(routerDir, proxyCc, method1, METHOD2);
                    }
                }
            } catch (NotFoundException ignore) {
            }
            metaBuilder.append(proxyCc != null ? "new " + proxyCc.getName() + "()" : "null");
            metaBuilder.append(", ");
            metaBuilder.append(interceptorClass != null ? interceptorClass.toString() : "null");
            metaBuilder.append(", ");
            metaBuilder.append(interceptorName != null ? interceptorName.toString() : "null");
            metaBuilder.append(", ");
            metaBuilder.append(thread);
            metaBuilder.append(", ");
            metaBuilder.append(priority);
            metaBuilder.append(", ");
            metaBuilder.append(hold);
            metaBuilder.append(")");
            String uri = schemeValue + "@@" + hostValue + "$$" + pathValue;
            if (!isPlaceholderLegal(schemeValue, hostValue, pathValue)) {
                throw new Exception("\"" + uri + "\" on " + routerCc.getName() + "\ncan't use regex outside placeholder <>," + "\nand must be unique legal identifier inside placeholder <>");
            }
            boolean isAnyRegex = isRegex(schemeValue, hostValue, pathValue);
            if (isAnyRegex) {
                items.add("    put(\"" + uri + "\", " + metaBuilder + ", data); \n");
            // builder.append("    put(\"").append(uri).append("\", ").append(metaBuilder).append(", data); \n");
            } else {
                items.add("    data.put(\"" + uri + "\", " + metaBuilder + "); \n");
            // builder.append("    data.put(\"").append(uri).append("\", ").append(metaBuilder).append("); \n");
            }
            String duplicate = StoreUtil.insertUri(uri, routerCc);
            if (duplicate != null) {
                throw new Exception("\"" + uri + "\" on " + routerCc.getName() + "\nhas duplication of name with class: " + duplicate);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("Class: === " + routerCc.getName() + " ===\nCause: " + e.getMessage());
        }
    }
    Collections.sort(items);
    for (String item : items) {
        builder.append(item);
    }
    builder.append("}");
    Logger.d("\nclass RouterLoader" + "\n" + builder.toString());
    generatorClass(routerDir, ctClass, builder.toString());
}
Also used : StringMemberValue(javassist.bytecode.annotation.StringMemberValue) Router(com.didi.drouter.annotation.Router) NotFoundException(javassist.NotFoundException) Annotation(javassist.bytecode.annotation.Annotation) NotFoundException(javassist.NotFoundException) ClassMemberValue(javassist.bytecode.annotation.ClassMemberValue) CtConstructor(javassist.CtConstructor) CtClass(javassist.CtClass) MemberValue(javassist.bytecode.annotation.MemberValue) ArrayMemberValue(javassist.bytecode.annotation.ArrayMemberValue) StringMemberValue(javassist.bytecode.annotation.StringMemberValue) ClassMemberValue(javassist.bytecode.annotation.ClassMemberValue) ArrayMemberValue(javassist.bytecode.annotation.ArrayMemberValue)

Aggregations

Router (com.didi.drouter.annotation.Router)1 CtClass (javassist.CtClass)1 CtConstructor (javassist.CtConstructor)1 NotFoundException (javassist.NotFoundException)1 Annotation (javassist.bytecode.annotation.Annotation)1 ArrayMemberValue (javassist.bytecode.annotation.ArrayMemberValue)1 ClassMemberValue (javassist.bytecode.annotation.ClassMemberValue)1 MemberValue (javassist.bytecode.annotation.MemberValue)1 StringMemberValue (javassist.bytecode.annotation.StringMemberValue)1