
package android.hardware.photography.utils;

import java.lang.reflect.*;

/**
 * This is an implementation of the 'decorator' design pattern using Java's proxy mechanism.
 *
 * @see android.hardware.photography.utils.Decorator#newInstance
 *
 * @hide
 */
public class Decorator<T> implements InvocationHandler {

    public interface DecoratorListener {
        /**
         * This method is called before the target method is invoked
         * @param args arguments to target method
         * @param m Method being called
         */
        void onBeforeInvocation(Method m, Object[] args);
        /**
         * This function is called after the target method is invoked
         * if there were no uncaught exceptions
         * @param args arguments to target method
         * @param m Method being called
         * @param result return value of target method
         */
        void onAfterInvocation(Method m, Object[] args, Object result);
        /**
         * This method is called only if there was an exception thrown by the target method
         * during its invocation.
         *
         * @param args arguments to target method
         * @param m Method being called
         * @param t Throwable that was thrown
         * @return false to rethrow exception, true if the exception was handled
         */
        boolean onCatchException(Method m, Object[] args, Throwable t);
        /**
         * This is called after the target method is invoked, regardless of whether or not
         * there were any exceptions.
         * @param args arguments to target method
         * @param m Method being called
         */
        void onFinally(Method m, Object[] args);
    }

    private final T mObject;
    private final DecoratorListener mListener;

    /**
     * Create a decorator wrapping the specified object's method calls.
     *
     * @param obj the object whose method calls you want to intercept
     * @param listener the decorator handler for intercepted method calls
     * @param <T> the type of the element you want to wrap. This must be an interface.
     * @return a wrapped interface-compatible T
     */
    @SuppressWarnings("unchecked")
    public static<T> T newInstance(T obj, DecoratorListener listener) {
        return (T)java.lang.reflect.Proxy.newProxyInstance(
                obj.getClass().getClassLoader(),
                obj.getClass().getInterfaces(),
                new Decorator<T>(obj, listener));
    }

    private Decorator(T obj, DecoratorListener listener) {
        this.mObject = obj;
        this.mListener = listener;
    }

    @Override
    public Object invoke(Object proxy, Method m, Object[] args)
            throws Throwable
    {
        Object result = null;
        try {
            mListener.onBeforeInvocation(m, args);
            result = m.invoke(mObject, args);
            mListener.onAfterInvocation(m, args, result);
        } catch (InvocationTargetException e) {
            Throwable t = e.getTargetException();
            if (!mListener.onCatchException(m, args, t)) {
                throw t;
            }
        } finally {
            mListener.onFinally(m, args);
        }
        return result;
    }
}
