All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.andromedaioc.annotation.processor.OnEventAnnotationProcessor Maven / Gradle / Ivy

The newest version!
package net.sf.andromedaioc.annotation.processor;

import android.app.Activity;
import android.view.*;
import net.sf.andromedaioc.annotation.Inject;
import net.sf.andromedaioc.annotation.Property;
import net.sf.andromedaioc.annotation.Resource;
import net.sf.andromedaioc.annotation.android.AndromedaView;
import net.sf.andromedaioc.annotation.android.EventSource;
import net.sf.andromedaioc.annotation.android.OnEvent;
import net.sf.andromedaioc.context.AndromedaContext;
import net.sf.andromedaioc.exception.IllegalReturnTypeException;
import net.sf.andromedaioc.exception.OnEventProcessingException;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;

/**
 * Process OnEvent annotation
 *
 * @author Alexey Mitrov
 */
public class OnEventAnnotationProcessor implements AnnotationProcessor {

    public void process(final Object target, final Activity activity, AnnotatedElement annotated, final AndromedaContext andromedaContext) throws Exception {
        OnEvent onEvent = annotated.getAnnotation(OnEvent.class);
        int targetId = onEvent.target();
        EventSource eventSource = onEvent.source();
        View view = activity.findViewById(targetId);
        final Method onEventMethod = (Method) annotated;
        validateOnEventMethod(onEventMethod, eventSource);
        onEventMethod.setAccessible(true);
        if(eventSource.equals(EventSource.ON_CLICK)) {
            view.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    try {
                        Object[] parameters = collectParameters(onEventMethod, activity, andromedaContext, null);
                        onEventMethod.invoke(target, parameters);
                    } catch (Exception e) {
                        throw new OnEventProcessingException(String.format("Error processing onEvent for method %s. Reason: %s", onEventMethod, e.getMessage()), e);
                    }
                }
            });
        } else if(eventSource.equals(EventSource.ON_LONG_CLICK)) {
            view.setOnLongClickListener(new View.OnLongClickListener() {
                public boolean onLongClick(View v) {
                    try {
                        Object[] parameters = collectParameters(onEventMethod, activity, andromedaContext, null);
                        Object result = onEventMethod.invoke(target, parameters);
                        return (Boolean) result;
                    } catch (Exception e) {
                        throw new OnEventProcessingException(String.format("Error processing onEvent for method %s. Reason: %s", onEventMethod, e.getMessage()), e);
                    }
                }
            });
        } else if(eventSource.equals(EventSource.ON_TOUCH)) {
            view.setOnTouchListener(new View.OnTouchListener() {
                public boolean onTouch(View v, MotionEvent event) {
                    try {
                        Object[] parameters = collectParameters(onEventMethod, activity, andromedaContext, new Object[]{event});
                        Object result = onEventMethod.invoke(target, parameters);
                        return (Boolean) result;
                    } catch (Exception e) {
                        throw new OnEventProcessingException(String.format("Error processing onEvent for method %s. Reason: %s", onEventMethod, e.getMessage()), e);
                    }
                }
            });
        } else if(eventSource.equals(EventSource.ON_KEY)) {
            view.setOnKeyListener(new View.OnKeyListener() {
                public boolean onKey(View v, int keyCode, KeyEvent event) {
                    try {
                        Object[] parameters = collectParameters(onEventMethod, activity, andromedaContext, new Object[]{keyCode, event});
                        Object result = onEventMethod.invoke(target, parameters);
                        return (Boolean) result;
                    } catch (Exception e) {
                        throw new OnEventProcessingException(String.format("Error processing onEvent for method %s. Reason: %s", onEventMethod, e.getMessage()), e);
                    }
                }
            });
        } else if(eventSource.equals(EventSource.ON_FOCUS_CHANGE)) {
            view.setOnFocusChangeListener(new View.OnFocusChangeListener() {
                public void onFocusChange(View v, boolean hasFocus) {
                    try {
                        Object[] parameters = collectParameters(onEventMethod, activity, andromedaContext, new Object[]{hasFocus});
                        onEventMethod.invoke(target, parameters);
                    } catch (Exception e) {
                        throw new OnEventProcessingException(String.format("Error processing onEvent for method %s. Reason: %s", onEventMethod, e.getMessage()), e);
                    }
                }
            });
        } else if(eventSource.equals(EventSource.ON_CREATE_CONTEXT_MENU)) {
            view.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
                public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
                    try {
                        Object[] parameters = collectParameters(onEventMethod, activity, andromedaContext, new Object[]{menu, menuInfo});
                        onEventMethod.invoke(target, parameters);
                    } catch (Exception e) {
                        throw new OnEventProcessingException(String.format("Error processing onEvent for method %s. Reason: %s", onEventMethod, e.getMessage()), e);
                    }
                }
            });
        }
    }

    private void validateOnEventMethod(Method onEventMethod, EventSource eventSource) {
        if(eventSource.getReturnType() != null && !eventSource.getReturnType().equals(onEventMethod.getReturnType())) {
            throw new IllegalReturnTypeException(String.format("Illegal return type of method %s. The return type for %s event source should be %s", onEventMethod.getName(), eventSource.name(), eventSource.getReturnType().getName()));
        }
    }

    private Object[] collectParameters(Method onEventMethod, Activity activity, AndromedaContext andromedaContext, Object[] additionalParameters) {
        Annotation[][] parametersAnnotations = onEventMethod.getParameterAnnotations();
        Class[] parameterTypes = onEventMethod.getParameterTypes();
        Object[] parameters = new Object[parameterTypes.length];
        for(int i = 0; i < parameterTypes.length; i++) {
            if(parametersAnnotations[i].length > 0) {
                for(Annotation parameterAnnotation : parametersAnnotations[i]) {
                    if(Inject.class.equals(parameterAnnotation.annotationType())) {
                        Inject inject = (Inject) parameterAnnotation;
                        if(inject.id() != null && inject.id().length() > 0) {
                            parameters[i] = andromedaContext.getBean(inject.id());
                        } else {
                            parameters[i] = andromedaContext.getBean(parameterTypes[i]);
                        }
                    } else if(Resource.class.equals(parameterAnnotation.annotationType())) {
                        Resource resource = (Resource) parameterAnnotation;
                        parameters[i] = andromedaContext.getResourceProvider().getAndroidResource(resource.id());
                    } else if(Property.class.equals(parameterAnnotation.annotationType())) {
                        Property property = (Property) parameterAnnotation;
                        parameters[i] = andromedaContext.getResourceProvider().getProperty(property.name());
                    } else if(AndromedaView.class.equals(parameterAnnotation.annotationType())) {
                        AndromedaView andromedaView = (AndromedaView) parameterAnnotation;
                        parameters[i] = activity.findViewById(andromedaView.id());
                    }
                }
            } else {
                Object additionalParameter = searchInAdditionalParameters(parameterTypes[i], additionalParameters);
                parameters[i] = additionalParameter == null ? andromedaContext.getBean(parameterTypes[i]) : additionalParameter;
            }
        }
        return parameters;
    }

    private Object searchInAdditionalParameters(Class type, Object[] additionalParameters) {
        if(additionalParameters == null || additionalParameters.length <= 0) {
            return null;
        } else {
            for(Object parameter : additionalParameters) {
                if(parameter != null && type.equals(parameter.getClass())) {
                    return parameter;
                }
            }
            return null;
        }
    }

    public boolean canProcessService() {
        return false;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy