com.socialize.SocializeActionProxy.java Source code

Java tutorial

Introduction

Here is the source code for com.socialize.SocializeActionProxy.java

Source

/*
 * Copyright (c) 2012 Socialize Inc.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize;

import android.app.Activity;
import android.content.Context;
import com.socialize.android.ioc.IOCContainer;
import com.socialize.annotations.NoAuth;
import com.socialize.annotations.Synchronous;
import com.socialize.api.SocializeSession;
import com.socialize.error.AuthCanceledException;
import com.socialize.error.SocializeException;
import com.socialize.listener.SocializeAuthListener;
import com.socialize.listener.SocializeInitListener;
import com.socialize.listener.SocializeListener;
import com.socialize.log.SocializeLogger;
import org.apache.http.MethodNotSupportedException;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * Proxies all requests to top level Socialize interfaces to ensure that clients are both initialized and authenticated.
 * @author Jason Polites
 */
public class SocializeActionProxy implements InvocationHandler {

    private String delegateBean;
    private boolean synchronous = false;

    public SocializeActionProxy(String delegateBean) {
        super();
        this.delegateBean = delegateBean;
    }

    public SocializeActionProxy(String delegateBean, boolean synchronous) {
        this(delegateBean);
        this.synchronous = synchronous;
    }

    /* (non-Javadoc)
     * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        try {
            if (synchronous || method.isAnnotationPresent(Synchronous.class) || !isVoidMethod(method)) {

                Context context = findContext(args);

                if (context != null) {
                    synchronized (this) {
                        SocializeService socialize = Socialize.getSocialize();

                        if (!socialize.isInitialized(context)) {
                            socialize.init(context);
                            if (!socialize.isAuthenticated() && !method.isAnnotationPresent(NoAuth.class)) {
                                socialize.authenticateSynchronous(context);
                            }
                        }
                    }
                }

                return method.invoke(getBean(), args);
            } else {
                Activity context = findActivity(args);

                if (context != null) {
                    SocializeListener listener = findListener(args);

                    // Always init to set the context
                    invokeWithInit(context, listener, method, args);
                } else {
                    throw new MethodNotSupportedException(
                            "No activity found in method arguments for method [" + method.getName() + "]");
                }
            }

            // Always void
            return null;
        } catch (Throwable e) {
            SocializeLogger.e(e.getMessage(), e);
            throw e;
        }
    }

    protected boolean isVoidMethod(Method method) {
        Class<?> returnType = method.getReturnType();
        return (returnType == null || returnType.equals(Void.TYPE));
    }

    protected void invokeWithInit(final Activity context, final SocializeListener listener, final Method method,
            final Object[] args) throws Throwable {

        SocializeServiceImpl service = getSocialize();

        if (service.isInitialized(context)) {
            service.setContext(context);
            invoke(context, listener, method, args);
        } else {
            service.initAsync(context, new SocializeInitListener() {
                @Override
                public void onError(SocializeException error) {
                    if (listener != null) {
                        listener.onError(error);
                    }
                }

                @Override
                public void onInit(Context ctx, IOCContainer container) {
                    // Recurse
                    try {
                        invoke(context, listener, method, args);
                    } catch (Throwable e) {
                        if (listener != null) {
                            listener.onError(SocializeException.wrap(e));
                        }
                    }
                }
            });
        }
    }

    protected void invoke(Activity context, SocializeListener listener, Method method, Object[] args)
            throws Throwable {

        SocializeService service = getSocialize();

        if (!service.isAuthenticated() && !method.isAnnotationPresent(NoAuth.class)) {
            doAuthAsync(context, listener, method, args);
        } else {
            method.invoke(getBean(), args);
        }
    }

    protected Object getBean() throws MethodNotSupportedException {
        Object bean = Socialize.getBean(delegateBean);

        if (bean != null) {
            return bean;
        } else {
            throw new MethodNotSupportedException("No bean with name [" + delegateBean + "] found");
        }
    }

    protected Activity findActivity(Object[] args) {
        for (Object object : args) {
            if (object instanceof Activity) {
                return (Activity) object;
            }
        }
        return null;
    }

    protected Context findContext(Object[] args) {
        for (Object object : args) {
            if (object instanceof Context) {
                return (Context) object;
            }
        }
        return null;
    }

    protected SocializeListener findListener(Object[] args) {
        for (Object object : args) {
            if (object instanceof SocializeListener) {
                return (SocializeListener) object;
            }
        }
        return null;
    }

    protected synchronized <L extends SocializeListener> void doAuthAsync(final Activity context,
            final SocializeListener listener, final Method method, final Object[] args) throws Throwable {
        final SocializeService service = getSocialize();

        if (!service.isAuthenticated()) {

            synchronized (this) {
                if (!service.isAuthenticated()) {
                    context.runOnUiThread(new Runnable() {

                        @Override
                        public void run() {

                            service.authenticate(context, new SocializeAuthListener() {

                                @Override
                                public void onError(SocializeException error) {
                                    if (listener != null) {
                                        listener.onError(error);
                                    }
                                }

                                @Override
                                public void onCancel() {
                                    if (listener != null) {
                                        listener.onError(new AuthCanceledException(
                                                "Authentication was canceled by the user"));
                                    }
                                }

                                @Override
                                public void onAuthSuccess(SocializeSession session) {
                                    // Recurse
                                    try {
                                        invoke(context, listener, method, args);
                                    } catch (Throwable e) {
                                        if (listener != null) {
                                            listener.onError(SocializeException.wrap(e));
                                        }
                                    }
                                }

                                @Override
                                public void onAuthFail(SocializeException error) {
                                    if (listener != null) {
                                        listener.onError(error);
                                    }
                                }
                            });
                        }
                    });
                } else {
                    // Recurse
                    invoke(context, listener, method, args);
                }
            }
        } else {
            // Recurse
            invoke(context, listener, method, args);
        }
    }

    protected SocializeServiceImpl getSocialize() {
        return (SocializeServiceImpl) Socialize.getSocialize();
    }
}