Search in sources :

Example 1 with MethodSpec

use of com.squareup.javapoet.MethodSpec in project DeepLinkDispatch by airbnb.

the class DeepLinkProcessor method generateDeepLinkDelegate.

private void generateDeepLinkDelegate(String packageName, List<TypeElement> loaderClasses) throws IOException {
    MethodSpec notifyListenerMethod = MethodSpec.methodBuilder("notifyListener").addModifiers(Modifier.PRIVATE, Modifier.STATIC).returns(void.class).addParameter(ANDROID_CONTEXT, "context").addParameter(boolean.class, "isError").addParameter(ClassName.get("android.net", "Uri"), "uri").addParameter(String.class, "errorMessage").addStatement("$T intent = new Intent()", ANDROID_INTENT).addStatement("intent.setAction($T.ACTION)", DeepLinkHandler.class).addStatement("intent.putExtra($T.EXTRA_URI, uri != null ? uri.toString() : $S)", DeepLinkHandler.class, "").addStatement("intent.putExtra($T.EXTRA_SUCCESSFUL, !isError)", DeepLinkHandler.class).beginControlFlow("if (isError)").addStatement("intent.putExtra($T.EXTRA_ERROR_MESSAGE, errorMessage)", DeepLinkHandler.class).endControlFlow().addStatement("$T.getInstance(context).sendBroadcast(intent)", ClassName.get("android.support.v4.content", "LocalBroadcastManager")).build();
    ClassName deepLinkResult = ClassName.get(DLD_PACKAGE_NAME, "DeepLinkResult");
    MethodSpec createResultAndNotifyMethod = MethodSpec.methodBuilder("createResultAndNotify").addModifiers(Modifier.PRIVATE, Modifier.STATIC).returns(deepLinkResult).addParameter(ANDROID_CONTEXT, "context").addParameter(TypeName.BOOLEAN, "successful", Modifier.FINAL).addParameter(ANDROID_URI, "uri", Modifier.FINAL).addParameter(ClassName.get(String.class), "error", Modifier.FINAL).addStatement("notifyListener(context, !successful, uri, error)").addStatement("return new $T(successful, uri != null ? uri.toString() : null, error)", deepLinkResult).build();
    FieldSpec tag = FieldSpec.builder(String.class, "TAG", Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL).initializer("DeepLinkDelegate.class.getSimpleName()").build();
    FieldSpec loaders = FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(List.class), WildcardTypeName.subtypeOf(Parser.class)), "loaders", Modifier.PRIVATE, Modifier.FINAL).build();
    CodeBlock.Builder loadersInitializer = CodeBlock.builder().add("this.loaders = $T.asList(\n", ClassName.get(Arrays.class)).indent();
    int totalElements = loaderClasses.size();
    for (int i = 0; i < totalElements; i++) {
        loadersInitializer.add("$L$L", decapitalize(moduleNameToLoaderName(loaderClasses.get(i))), i < totalElements - 1 ? "," : "");
    }
    MethodSpec constructor = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC).addParameters(FluentIterable.from(loaderClasses).transform(new Function<TypeElement, ParameterSpec>() {

        @Override
        public ParameterSpec apply(TypeElement typeElement) {
            return ParameterSpec.builder(moduleElementToLoaderClassName(typeElement), decapitalize(moduleNameToLoaderName(typeElement))).build();
        }
    }).toList()).addCode(loadersInitializer.unindent().add(");\n").build()).build();
    MethodSpec supportsUri = MethodSpec.methodBuilder("supportsUri").addModifiers(Modifier.PUBLIC).returns(TypeName.BOOLEAN).addParameter(String.class, "uriString").addStatement("return findEntry(uriString) != null").build();
    MethodSpec findEntry = MethodSpec.methodBuilder("findEntry").addModifiers(Modifier.PRIVATE).returns(CLASS_DLD_ENTRY).addParameter(String.class, "uriString").beginControlFlow("for (Parser loader : loaders)").addStatement("$T entry = loader.parseUri(uriString)", CLASS_DLD_ENTRY).beginControlFlow("if (entry != null)").addStatement("return entry").endControlFlow().endControlFlow().addStatement("return null").build();
    MethodSpec dispatchFromMethod = MethodSpec.methodBuilder("dispatchFrom").addModifiers(Modifier.PUBLIC).returns(deepLinkResult).addParameter(ANDROID_ACTIVITY, "activity").beginControlFlow("if (activity == null)").addStatement("throw new $T($S)", NullPointerException.class, "activity == null").endControlFlow().addStatement("return dispatchFrom(activity, activity.getIntent())").build();
    MethodSpec dispatchFromMethodWithIntent = MethodSpec.methodBuilder("dispatchFrom").addModifiers(Modifier.PUBLIC).returns(deepLinkResult).addParameter(ANDROID_ACTIVITY, "activity").addParameter(ANDROID_INTENT, "sourceIntent").beginControlFlow("if (activity == null)").addStatement("throw new $T($S)", NullPointerException.class, "activity == null").endControlFlow().beginControlFlow("if (sourceIntent == null)").addStatement("throw new $T($S)", NullPointerException.class, "sourceIntent == null").endControlFlow().addStatement("$T uri = sourceIntent.getData()", ANDROID_URI).beginControlFlow("if (uri == null)").addStatement("return createResultAndNotify(activity, false, null, $S)", "No Uri in given activity's intent.").endControlFlow().addStatement("String uriString = uri.toString()").addStatement("$T entry = findEntry(uriString)", CLASS_DLD_ENTRY).beginControlFlow("if (entry != null)").addStatement("$T deepLinkUri = DeepLinkUri.parse(uriString)", CLASS_DLD_URI).addStatement("$T<String, String> parameterMap = entry.getParameters(uriString)", Map.class).beginControlFlow("for (String queryParameter : deepLinkUri.queryParameterNames())").beginControlFlow("for (String queryParameterValue : deepLinkUri.queryParameterValues(queryParameter))").beginControlFlow("if (parameterMap.containsKey(queryParameter))").addStatement("$T.w(TAG, \"Duplicate parameter name in path and query param: \" + queryParameter)", ClassName.get("android.util", "Log")).endControlFlow().addStatement("parameterMap.put(queryParameter, queryParameterValue)").endControlFlow().endControlFlow().addStatement("parameterMap.put($T.URI, uri.toString())", ClassName.get(DLD_PACKAGE_NAME, "DeepLink")).addStatement("$T parameters", ANDROID_BUNDLE).beginControlFlow("if (sourceIntent.getExtras() != null)").addStatement("parameters = new Bundle(sourceIntent.getExtras())").nextControlFlow("else").addStatement("parameters = new Bundle()").endControlFlow().beginControlFlow("for (Map.Entry<String, String> parameterEntry : parameterMap.entrySet())").addStatement("parameters.putString(parameterEntry.getKey(), parameterEntry.getValue())").endControlFlow().beginControlFlow("try").addStatement("Class<?> c = entry.getActivityClass()").addStatement("$T newIntent", ANDROID_INTENT).addStatement("$T taskStackBuilder = null", TASK_STACK_BUILDER).beginControlFlow("if (entry.getType() == DeepLinkEntry.Type.CLASS)").addStatement("newIntent = new Intent(activity, c)").nextControlFlow("else").addStatement("$T method", Method.class).beginControlFlow("try").addStatement("method = c.getMethod(entry.getMethod(), $T.class)", ANDROID_CONTEXT).beginControlFlow("if (method.getReturnType().equals($T.class))", TASK_STACK_BUILDER).addStatement("taskStackBuilder = (TaskStackBuilder) method.invoke(c, activity)").beginControlFlow("if (taskStackBuilder.getIntentCount() == 0)").addStatement("return createResultAndNotify(activity, false, uri, \"Could not deep " + "link to method: \" + entry.getMethod() + \" intents length == 0\" )").endControlFlow().addStatement("newIntent = taskStackBuilder." + "editIntentAt(taskStackBuilder.getIntentCount()-1)").nextControlFlow("else").addStatement("newIntent = (Intent) method.invoke(c, activity)").endControlFlow().nextControlFlow("catch ($T exception)", NoSuchMethodException.class).addStatement("method = c.getMethod(entry.getMethod(), $T.class, $T.class)", ANDROID_CONTEXT, ANDROID_BUNDLE).beginControlFlow("if (method.getReturnType().equals($T.class))", TASK_STACK_BUILDER).addStatement("taskStackBuilder = " + "(TaskStackBuilder) method.invoke(c, activity, parameters)").beginControlFlow("if (taskStackBuilder.getIntentCount() == 0)").addStatement("return createResultAndNotify(activity, false, uri, \"Could not deep " + "link to method: \" + entry.getMethod() + \" intents length == 0\" )").endControlFlow().addStatement("newIntent = taskStackBuilder." + "editIntentAt(taskStackBuilder.getIntentCount()-1)").nextControlFlow("else").addStatement("newIntent = (Intent) method.invoke(c, activity, parameters)").endControlFlow().endControlFlow().endControlFlow().beginControlFlow("if (newIntent.getAction() == null)").addStatement("newIntent.setAction(sourceIntent.getAction())").endControlFlow().beginControlFlow("if (newIntent.getData() == null)").addStatement("newIntent.setData(sourceIntent.getData())").endControlFlow().addStatement("newIntent.putExtras(parameters)").addStatement("newIntent.putExtra(DeepLink.IS_DEEP_LINK, true)").addStatement("newIntent.putExtra(DeepLink.REFERRER_URI, uri)").beginControlFlow("if (activity.getCallingActivity() != null)").addStatement("newIntent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT)").endControlFlow().beginControlFlow("if (taskStackBuilder != null)").addStatement("taskStackBuilder.startActivities()").nextControlFlow("else").addStatement("activity.startActivity(newIntent)").endControlFlow().addStatement("return createResultAndNotify(activity, true, uri, null)").nextControlFlow("catch (NoSuchMethodException exception)").addStatement("return createResultAndNotify(activity, false, uri, \"Deep link to " + "non-existent method: \" + entry.getMethod())").nextControlFlow("catch (IllegalAccessException exception)").addStatement("return createResultAndNotify(activity, false, uri, \"Could not deep " + "link to method: \" + entry.getMethod())").nextControlFlow("catch ($T  exception)", InvocationTargetException.class).addStatement("return createResultAndNotify(activity, false, uri, \"Could not deep " + "link to method: \" + entry.getMethod())").endControlFlow().nextControlFlow("else").addStatement("return createResultAndNotify(activity, false, uri, " + "\"No registered entity to handle deep link: \" + uri.toString())").endControlFlow().build();
    TypeSpec deepLinkDelegate = TypeSpec.classBuilder("DeepLinkDelegate").addModifiers(Modifier.PUBLIC, Modifier.FINAL).addField(tag).addField(loaders).addMethod(constructor).addMethod(findEntry).addMethod(dispatchFromMethod).addMethod(dispatchFromMethodWithIntent).addMethod(createResultAndNotifyMethod).addMethod(notifyListenerMethod).addMethod(supportsUri).build();
    JavaFile.builder(packageName, deepLinkDelegate).build().writeTo(filer);
}
Also used : MethodSpec(com.squareup.javapoet.MethodSpec) ParameterSpec(com.squareup.javapoet.ParameterSpec) TypeElement(javax.lang.model.element.TypeElement) CodeBlock(com.squareup.javapoet.CodeBlock) Method(java.lang.reflect.Method) FieldSpec(com.squareup.javapoet.FieldSpec) ClassName(com.squareup.javapoet.ClassName) List(java.util.List) ArrayList(java.util.ArrayList) Map(java.util.Map) HashMap(java.util.HashMap) TypeSpec(com.squareup.javapoet.TypeSpec)

Example 2 with MethodSpec

use of com.squareup.javapoet.MethodSpec in project epoxy by airbnb.

the class EpoxyProcessor method generateDefaultMethodImplementations.

/**
   * Generates default implementations of certain model methods if the model is abstract and doesn't
   * implement them.
   */
private Iterable<MethodSpec> generateDefaultMethodImplementations(ClassToGenerateInfo info) {
    List<MethodSpec> methods = new ArrayList<>();
    TypeElement originalClassElement = info.getOriginalClassElement();
    addCreateHolderMethodIfNeeded(originalClassElement, methods);
    addDefaultLayoutMethodIfNeeded(originalClassElement, methods);
    return methods;
}
Also used : MethodSpec(com.squareup.javapoet.MethodSpec) TypeElement(javax.lang.model.element.TypeElement) ArrayList(java.util.ArrayList)

Example 3 with MethodSpec

use of com.squareup.javapoet.MethodSpec in project epoxy by airbnb.

the class EpoxyProcessor method generateMethodsReturningClassType.

private Iterable<MethodSpec> generateMethodsReturningClassType(ClassToGenerateInfo info) {
    List<MethodSpec> methods = new ArrayList<>(info.getMethodsReturningClassType().size());
    for (MethodInfo methodInfo : info.getMethodsReturningClassType()) {
        Builder builder = MethodSpec.methodBuilder(methodInfo.name).addModifiers(methodInfo.modifiers).addParameters(methodInfo.params).addAnnotation(Override.class).varargs(methodInfo.varargs).returns(info.getParameterizedGeneratedName());
        StringBuilder statementBuilder = new StringBuilder(String.format("super.%s(", methodInfo.name));
        generateParams(statementBuilder, methodInfo.params);
        methods.add(builder.addStatement(statementBuilder.toString()).addStatement("return this").build());
    }
    return methods;
}
Also used : MethodSpec(com.squareup.javapoet.MethodSpec) Builder(com.squareup.javapoet.MethodSpec.Builder) ArrayList(java.util.ArrayList) MethodInfo(com.airbnb.epoxy.ClassToGenerateInfo.MethodInfo)

Example 4 with MethodSpec

use of com.squareup.javapoet.MethodSpec in project epoxy by airbnb.

the class EpoxyProcessor method generateConstructors.

/** Include any constructors that are in the super class. */
private Iterable<MethodSpec> generateConstructors(ClassToGenerateInfo info) {
    List<MethodSpec> constructors = new ArrayList<>(info.getConstructors().size());
    for (ConstructorInfo constructorInfo : info.getConstructors()) {
        Builder builder = MethodSpec.constructorBuilder().addModifiers(constructorInfo.modifiers).addParameters(constructorInfo.params).varargs(constructorInfo.varargs);
        StringBuilder statementBuilder = new StringBuilder("super(");
        generateParams(statementBuilder, constructorInfo.params);
        constructors.add(builder.addStatement(statementBuilder.toString()).build());
    }
    return constructors;
}
Also used : MethodSpec(com.squareup.javapoet.MethodSpec) Builder(com.squareup.javapoet.MethodSpec.Builder) ArrayList(java.util.ArrayList) ConstructorInfo(com.airbnb.epoxy.ClassToGenerateInfo.ConstructorInfo)

Example 5 with MethodSpec

use of com.squareup.javapoet.MethodSpec in project epoxy by airbnb.

the class EpoxyProcessor method addCreateHolderMethodIfNeeded.

/**
   * If the model is a holder and doesn't implement the "createNewHolder" method we can generate a
   * default implementation by getting the class type and creating a new instance of it.
   */
private void addCreateHolderMethodIfNeeded(TypeElement originalClassElement, List<MethodSpec> methods) {
    if (!isEpoxyModelWithHolder(originalClassElement)) {
        return;
    }
    MethodSpec createHolderMethod = MethodSpec.methodBuilder(CREATE_NEW_HOLDER_METHOD_NAME).addAnnotation(Override.class).addModifiers(Modifier.PROTECTED).build();
    if (implementsMethod(originalClassElement, createHolderMethod, typeUtils)) {
        return;
    }
    TypeMirror epoxyObjectType = getEpoxyObjectType(originalClassElement, typeUtils);
    if (epoxyObjectType == null) {
        logError("Return type for createNewHolder method could not be found. (class: %s)", originalClassElement.getSimpleName());
        return;
    }
    createHolderMethod = createHolderMethod.toBuilder().returns(TypeName.get(epoxyObjectType)).addStatement("return new $T()", epoxyObjectType).build();
    methods.add(createHolderMethod);
}
Also used : MethodSpec(com.squareup.javapoet.MethodSpec) TypeMirror(javax.lang.model.type.TypeMirror)

Aggregations

MethodSpec (com.squareup.javapoet.MethodSpec)153 ParameterizedTypeName (com.squareup.javapoet.ParameterizedTypeName)43 TypeName (com.squareup.javapoet.TypeName)42 ArrayList (java.util.ArrayList)38 ClassName (com.squareup.javapoet.ClassName)33 TypeSpec (com.squareup.javapoet.TypeSpec)29 ParameterSpec (com.squareup.javapoet.ParameterSpec)24 CodeBlock (com.squareup.javapoet.CodeBlock)23 WildcardTypeName (com.squareup.javapoet.WildcardTypeName)20 Nonnull (javax.annotation.Nonnull)17 TypeMirror (javax.lang.model.type.TypeMirror)15 WireField (com.squareup.wire.WireField)14 Field (com.squareup.wire.schema.Field)14 TypeElement (javax.lang.model.element.TypeElement)14 ByteString (okio.ByteString)13 JvmLanguages.builtInAdapterString (com.squareup.wire.schema.internal.JvmLanguages.builtInAdapterString)12 List (java.util.List)11 VariableElement (javax.lang.model.element.VariableElement)11 Utf8String (org.fisco.bcos.web3j.abi.datatypes.Utf8String)11 FieldSpec (com.squareup.javapoet.FieldSpec)10