package com.openxc.remote.sources;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import android.util.Log;

import com.openxc.remote.sources.SourceCallback;

/**
 * The BaseVehicleDataSource contains functions common to all vehicle data
 * sources.
 */
public class BaseVehicleDataSource implements VehicleDataSource {

    private static final String TAG = "BaseVehicleDataSource";
    private static final String RECEIVE_METHOD_NAME = "receive";

    private SourceCallback mCallback;

    public BaseVehicleDataSource() { }

    /**
     * Construct a new instance and set the callback.
     *
     * @param callback An object implementing the
     *      SourceCallback interface that should receive data from this
     *      source.
     */
    public BaseVehicleDataSource(SourceCallback callback) {
        setCallback(callback);
    }

    public void setCallback(SourceCallback callback) {
        mCallback = callback;
    }

    public void stop() {
        // do nothing by default
    }

    protected void handleMessage(String name, Object value) {
        handleMessage(name, value, null);
    }

    protected void handleMessage(String name, Object value, Object event) {
        if(mCallback != null) {
            Method method;
            // TODO since we now have an interace, I think all of this
            // metaprogramming is unnecessary. yay!
            try {
                method = SourceCallback.class.getMethod(
                        RECEIVE_METHOD_NAME, String.class, Object.class,
                        Object.class);
            } catch(NoSuchMethodException e) {
                String logMessage = "Received data of an unsupported type " +
                    "from the data source: " + value + ", a " +
                    value.getClass();
                if(event != null) {
                    logMessage += " and event " + event + ", a " +
                        event.getClass();
                }
                Log.w(TAG, logMessage);
                return;
            }

            try {
                method.invoke(mCallback, name, value, event);
            } catch(IllegalAccessException e) {
                Log.w(TAG, "Data receiver method is private", e);
            } catch(InvocationTargetException e) {
                Log.w(TAG, "Unable to call data receive method", e);
            }
        }
    }

    protected SourceCallback getCallback() {
        return mCallback;
    }
}

@@ -1270,1129 +1270,46 @@
     
-Method method;%0A            // TODO since we now have an interace, I think all of this%0A            // metaprogramming is unnecessary. yay!%0A            try %7B%0A                method = SourceCallback.class.getMethod(%0A                        RECEIVE_METHOD_NAME, String.class, Object.class,%0A                        Object.class);%0A            %7D catch(NoSuchMethodException e) %7B%0A                String logMessage = %22Received data of an unsupported type %22 +%0A                    %22from the data source: %22 + value + %22, a %22 +%0A                    value.getClass();%0A                if(event != null) %7B%0A                    logMessage += %22 and event %22 + event + %22, a %22 +%0A                        event.getClass();%0A                %7D%0A                Log.w(TAG, logMessage);%0A                return;%0A            %7D%0A%0A            try %7B%0A                method.invoke(mCallback, name, value, event);%0A            %7D catch(IllegalAccessException e) %7B%0A                Log.w(TAG, %22Data receiver method is private%22, e);%0A            %7D catch(InvocationTargetException e) %7B%0A                Log.w(TAG, %22Unable to call data receive method%22, e);%0A            %7D
+mCallback.receive(name, value, event);
 %0A   

Remove some now unnecessary metaprogramming.