Android Open Source - Kite Service Facade






From Project

Back to project page Kite.

License

The source code is released under:

Apache License

If you think the Android project Kite listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package org.kite.wire;
//from   ww w . j av a 2 s .  co m
import android.app.Service;
import android.util.Log;

import org.kite.annotations.Provided;
import org.kite.async.AsyncHandler;
import org.kite.async.AsyncType;
import org.kite.async.ResultQueue;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executor;

/**
 * Encapsulates all provided fields and methods by {@link org.kite.wire.WiredService}
 * with {@link org.kite.annotations.Provided} annotation.
 *
 * @author Nikolay Soroka
 */
public class ServiceFacade {

    private static final String TAG = "ServiceFacade";
    /**Constructs new {@code ServiceFacade} upon given service, scope and intent action.
     *
     * @param service
     * @param scope
     * @param action
     * @return new {@code ServiceFacade} built upon given service, scope and intent action.
     */
    public static ServiceFacade build(Class<? extends Service> service, Provided.Scope scope, String action) {
        ServiceFacade serviceFacade = new ServiceFacade();
        // check all methods
        Map<Class<?>, Method> allMethods = InterfaceFinder.findAllProvidedMethods(service);
        for (Class<?> key : allMethods.keySet()) {
            Method method = allMethods.get(key);
            // findAllProvidedMethods insures that method has provided annotation
            Provided provided = method.getAnnotation(Provided.class);
            if (satisfies(provided, scope, action)){
                putOrThrow(serviceFacade, key, method);
            }
        }
        // check all fields
        Map<Class<?>, Field> allFields = InterfaceFinder.findAllProvidedFields(service);
        for (Class<?> key : allFields.keySet()) {
            Field field = allFields.get(key);
            Provided provided = field.getAnnotation(Provided.class);
            if (satisfies(provided, scope, action)){
                putOrThrow(serviceFacade, key, field);
            }
        }

        return serviceFacade;
    }

    /**Returns the provided value of given {@code type} from given
     * {@code instance} to use in injection.
     *
     *
     * @param type
     * @param instance
     * @param queue
     * @return the value of given {@code type} from given
     * {@code instance}.
     */
    public Object getValue(Class<?> type, Executor instance, ResultQueue queue) {
        Object value = null;
        AsyncType async = null;
        try {
            if (methods.containsKey(type)) {
                Method method = methods.get(type);
                method.setAccessible(true);
                async = method.getAnnotation(Provided.class).async();
                value = method.invoke(instance);
            } else if (fields.containsKey(type)) {
                Field field = fields.get(type);
                field.setAccessible(true);
                async = field.getAnnotation(Provided.class).async();
                value = field.get(instance);
            } else { // was not found
                return null;
            }
            if ( !AsyncType.NONE.equals(async) ){
                value = wrapAsync(value, async, type, instance, queue);
            }
        } catch (IllegalAccessException e) {
            Log.e(TAG, "Can't access ", e);
        } catch (InvocationTargetException e) {
            Log.e(TAG, "Can't invoke ", e);
        }
        return value;
    }



    private Object wrapAsync(Object value, AsyncType async, Class<?> type, Executor instance, ResultQueue queue) {
        if (AsyncType.NONE.equals(async)){
            return value;
        }
        Object result = value;
        AsyncHandler handler = null;
        if ( AsyncType.ALL.equals(async)){
            handler = AsyncHandler.wrapAll(value, type, instance);
        } else if (AsyncType.METHODS.equals(async)){
            handler = AsyncHandler.wrapMethods(value, type, instance);
        }
        handler.setResultQueue(queue);
        result = handler.getProxy();
        return result;
    }

    private static boolean satisfies(Provided provided, Provided.Scope neededScope, String neededAction){
        Provided.Scope declaredScope = provided.scope();
        String declaredAction = provided.action();
        boolean forAll = Provided.Scope.ALL.equals(declaredScope);
        boolean forDefault = Provided.Scope.DEFAULT.equals(neededScope)
                && Provided.Scope.DEFAULT.equals(declaredScope);
        boolean forAction = (Provided.Scope.ACTION.equals(neededScope)
                && Provided.Scope.ACTION.equals(declaredScope)
                && declaredAction.equals(neededAction));
        return forAll || forDefault || forAction;

    }

    private static void putOrThrow(ServiceFacade serviceFacade, Class<?> key, Field field) {
        if (serviceFacade.contains(key)){
            throw new IllegalArgumentException("Service must contain only one class for each scope");
        }
        serviceFacade.putValue(key, field);
    }

    private static void putOrThrow(ServiceFacade serviceFacade, Class<?> key, Method method) {
        if (serviceFacade.contains(key)) {
            throw new IllegalArgumentException("Service must contain only one class for each scope");
        }
        serviceFacade.putValue(key, method);
    }

    private void putValue(Class<?> key, Field field) {
        fields.put(key, field);
    }

    private void putValue(Class<?> key, Method method) {
        methods.put(key, method);
    }

    private boolean contains(Class<?> key) {
        return methods.containsKey(key) || fields.containsKey(key);
    }

    private Map<Class<?>, Method> methods = new HashMap<Class<?>, Method>();

    private Map<Class<?>, Field> fields = new HashMap<Class<?>, Field>();

    private ServiceFacade() {
    }
}




Java Source Code List

org.kite.annotations.AsyncMethod.java
org.kite.annotations.AsyncResult.java
org.kite.annotations.Provided.java
org.kite.annotations.Wired.java
org.kite.async.AsyncHandler.java
org.kite.async.AsyncType.java
org.kite.async.MethodResult.java
org.kite.async.ResultQueue.java
org.kite.sample.CalcFragment.java
org.kite.sample.CalcInterface.java
org.kite.sample.Calculator.java
org.kite.sample.MainActivity.java
org.kite.sample.SampleService.java
org.kite.sample.Substractor.java
org.kite.services.CommandService.java
org.kite.services.MainThreadExecutor.java
org.kite.wire.ClientFacade.java
org.kite.wire.InterfaceFinder.java
org.kite.wire.ServiceFacade.java
org.kite.wire.WireBinder.java
org.kite.wire.WireCallback.java
org.kite.wire.Wire.java
org.kite.wire.WiredService.java
org.kite.wire.package-info.java