public class

CallbackReceiver

extends java.lang.Object

 java.lang.Object

↳androidx.remotecallback.compiler.CallbackReceiver

Gradle dependencies

compile group: 'androidx.remotecallback', name: 'remotecallback-processor', version: '1.0.0-alpha02'

  • groupId: androidx.remotecallback
  • artifactId: remotecallback-processor
  • version: 1.0.0-alpha02

Artifact androidx.remotecallback:remotecallback-processor:1.0.0-alpha02 it located at Google repository (https://maven.google.com/)

Overview

Holder class that is created for each class instance that is a CallbackReceiver and has methods tagged with @RemoteCallable.

Summary

Constructors
publicCallbackReceiver(javax.lang.model.element.Element c, javax.annotation.processing.ProcessingEnvironment env, javax.annotation.processing.Messager messager)

Methods
public voidaddMethod(javax.lang.model.element.Element element)

Adds a method tagged with @RemoteCallable to this receiver.

public voidfinish(javax.annotation.processing.ProcessingEnvironment env, javax.annotation.processing.Messager messager)

Generates the code to handle creating and executing callbacks.

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructors

public CallbackReceiver(javax.lang.model.element.Element c, javax.annotation.processing.ProcessingEnvironment env, javax.annotation.processing.Messager messager)

Methods

public void addMethod(javax.lang.model.element.Element element)

Adds a method tagged with @RemoteCallable to this receiver.

public void finish(javax.annotation.processing.ProcessingEnvironment env, javax.annotation.processing.Messager messager)

Generates the code to handle creating and executing callbacks. The code is assembled in one class that implements runnable that when run, registers all of the CallbackHandlers.

Source

/*
 * Copyright 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.remotecallback.compiler;

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.ArrayList;

import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
import javax.tools.Diagnostic;

/**
 * Holder class that is created for each class instance that is a
 * CallbackReceiver and has methods tagged with @RemoteCallable.
 */
public class CallbackReceiver {

    private static final String RESET = "reset";
    private static final String GET_METHOD = "getMethod";
    private static final String GET_ARGUMENTS = "getArguments";
    private static final String GET_CLS_NAME = "getClsName";

    private final ProcessingEnvironment mEnv;
    private final Element mElement;
    private final String mClsName;
    private final ArrayList<CallableMethod> mMethods = new ArrayList<>();
    private final Messager mMessager;

    public CallbackReceiver(Element c, ProcessingEnvironment env,
            Messager messager) {
        mEnv = env;
        mElement = c;
        mClsName = c.toString();
        mMessager = messager;
    }

    /**
     * Adds a method tagged with @RemoteCallable to this receiver.
     */
    public void addMethod(Element element) {
        for (CallableMethod method: mMethods) {
            if (method.getName().equals(element.getSimpleName().toString())) {
                mMessager.printMessage(Diagnostic.Kind.ERROR,
                        "Multiple methods named " + element.getSimpleName());
                return;
            }
        }
        mMethods.add(new CallableMethod(mClsName, element, mEnv));
    }

    /**
     * Generates the code to handle creating and executing callbacks. The code
     * is assembled in one class that implements runnable that when run,
     * registers all of the CallbackHandlers.
     */
    public void finish(ProcessingEnvironment env, Messager messager) {
        if (mMethods.size() == 0) {
            messager.printMessage(Diagnostic.Kind.ERROR, "No methods found for " + mClsName);
            return;
        }
        TypeSpec.Builder genClass = TypeSpec
                .classBuilder(findInitClass(mElement))
                .superclass(TypeName.get(mElement.asType()))
                .addModifiers(Modifier.PUBLIC);

        MethodSpec.Builder runBuilder = MethodSpec
                .constructorBuilder()
                .addModifiers(Modifier.PUBLIC);
        for (CallableMethod method: mMethods) {
            method.addMethods(genClass, runBuilder, env, messager);
        }
        genClass.addMethod(runBuilder.build());
        try {
            TypeSpec typeSpec = genClass.build();
            String pkg = getPkg(mElement);
            JavaFile.builder(pkg, typeSpec)
                    .build()
                    .writeTo(mEnv.getFiler());
        } catch (IOException e) {
            messager.printMessage(Diagnostic.Kind.ERROR, "Exception writing " + e);
        }
    }

    private String findInitClass(Element element) {
        return String.format("%sInitializer", element.getSimpleName());
    }

    private String getPkg(Element s) {
        String pkg = mEnv.getElementUtils().getPackageOf(s).toString();
        return pkg;
    }
}