io.dyn.core.handler.Handlers.java Source code

Java tutorial

Introduction

Here is the source code for io.dyn.core.handler.Handlers.java

Source

/*
 * Copyright (c) 2011-2012 by the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.dyn.core.handler;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;

import io.dyn.core.handler.anno.Handler;
import io.dyn.core.handler.anno.On;
import io.dyn.core.sys.Sys;
import io.dyn.el.ScopedEvaluationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;

/**
 * @author Jon Brisbin <jon@jbrisbin.com>
 */
public abstract class Handlers {

    private Handlers() {
    }

    public static final ReflectionUtils.MethodFilter USER_METHODS = new ReflectionUtils.MethodFilter() {
        @Override
        public boolean matches(Method method) {
            return (!method.isSynthetic() && !method.isBridge() && method.getDeclaringClass() != Object.class
                    && !method.getName().contains("$"));
        }
    };

    @SuppressWarnings({ "unchecked" })
    public static <T> T findFirstArgOfType(Class<? extends T> clazz, Object... args) {
        for (Object o : args) {
            if (null != o && ClassUtils.isAssignable(clazz, o.getClass())) {
                return (T) o;
            }
        }
        return null;
    }

    @SuppressWarnings({ "unchecked" })
    public static void invoke(final Object handler, final Object... args) {
        if (handler instanceof io.dyn.core.handler.Handler) {
            int argc = args.length;
            Object argument = (argc > 0 ? args[0] : null);
            Object[] otherArgs = (argc > 1 ? Arrays.copyOfRange(args, 1, args.length - 1) : new Object[0]);
            ((io.dyn.core.handler.Handler) handler).handle(argument, otherArgs);
            return;
        }
        if (Sys.isGroovyPresent()) {
            if (handler instanceof groovy.lang.Closure) {
                groovy.lang.Closure cl = ((groovy.lang.Closure) handler);
                Class[] paramTypes = cl.getParameterTypes();

                if (paramTypes.length == 0) {
                    cl.call();
                } else {
                    Object[] params = new Object[paramTypes.length];
                    if (null != args && args.length > 0) {
                        for (int i = 0; i < params.length; i++) {
                            if (null != args[i] && !ClassUtils.isAssignable(args[i].getClass(), paramTypes[i])) {
                                params[i] = Sys.DEFAULT_CONVERSION_SERVICE.convert(args[i], paramTypes[i]);
                            } else {
                                params[i] = args[i];
                            }
                        }
                        cl.call(params);
                    } else {
                        cl.call(args);
                    }
                }
                return;
            }
        }
        /*
        if (Sys.isScalaPresent()) {
          if (handler instanceof scala.Function1) {
            ((scala.Function1) handler).apply(argument);
            return;
          }
        }
        */
        /*
        if (Sys.isClojurePresent()) {
          if (handler instanceof clojure.lang.IFn) {
            ((clojure.lang.IFn) handler).invoke(argument);
            return;
          }
        }
        */
        if (handler instanceof Runnable) {
            ((Runnable) handler).run();
        }
    }

    public static String findEventName(Method method) {
        On on = find(On.class, method);
        if (null != on) {
            return on.value();
        } else if (null != AnnotationUtils.findAnnotation(method.getDeclaringClass(), Handler.class)) {
            return method.getName();
        }
        return null;
    }

    public static <A extends Annotation> A find(Class<A> anno, Method method) {
        if (null == method) {
            return null;
        }

        A on = AnnotationUtils.findAnnotation(method, anno);
        if (null != on) {
            return on;
        }

        Class<?>[] implClasses = method.getDeclaringClass().getInterfaces();
        for (Class<?> cl : implClasses) {
            try {
                Method m = cl.getDeclaredMethod(method.getName(), method.getParameterTypes());
                if (null != m) {
                    on = find(anno, m);
                    if (null != on) {
                        return on;
                    }
                }
            } catch (NoSuchMethodException e) {
            }
        }

        return null;
    }

    @SuppressWarnings({ "unchecked" })
    public static boolean eventsMatch(EvaluationContext evalCtx, Object lhs, Object rhs) {
        if (lhs == null && rhs != null) {
            return false;
        }
        if (lhs == rhs || lhs.equals(rhs)) {
            return true;
        }
        if (lhs instanceof Comparable) {
            try {
                return ((Comparable) lhs).compareTo(rhs) == 0;
            } catch (ClassCastException e) {
            }
        }
        if (lhs instanceof Expression) {
            ScopedEvaluationContext ec = new ScopedEvaluationContext(evalCtx, rhs);
            Object obj = ((Expression) lhs).getValue(ec);
            if (obj instanceof Boolean) {
                return (Boolean) obj;
            } else {
                return eventsMatch(evalCtx, obj, rhs);
            }
        }
        if (lhs instanceof Guard) {
            return ((Guard) lhs).checkGuard(rhs, evalCtx);
        }
        if (rhs instanceof Guard) {
            return ((Guard) rhs).checkGuard(lhs, evalCtx);
        }
        if (lhs instanceof Class && rhs instanceof Class) {
            return ClassUtils.isAssignable((Class<?>) lhs, (Class<?>) rhs);
        }

        return false;
    }

}