Package net.sourceforge.javautil.common.event

Source Code of net.sourceforge.javautil.common.event.EventDelegator

package net.sourceforge.javautil.common.event;

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

import net.sourceforge.javautil.common.ReflectionUtil;
import net.sourceforge.javautil.common.proxy.CollectionProxyCondition;
import net.sourceforge.javautil.common.proxy.DefaultReturnValue;
import net.sourceforge.javautil.common.proxy.pojo.Pojo;
import net.sourceforge.javautil.common.reflection.cache.ClassCache;
import net.sourceforge.javautil.common.reflection.cache.ClassDescriptor;
import net.sourceforge.javautil.common.reflection.cache.ClassMethod;

/**
* The delegator of events for pojo listeners, thus this supports the {@link Pojo} annotation.
*
* @author elponderador
* @author $Author$
* @version $Id$
*/
public class EventDelegator implements InvocationHandler {
 
  /**
   * This assumes the current thread local class loader.
   *
   * @see #createProxy(ClassLoader, Class, Object)
   */
  public static <T extends java.util.EventListener> T createProxy (Class<T> listenerType, Object pojoTarget) {
    return createProxy(Thread.currentThread().getContextClassLoader(), listenerType, pojoTarget);
  }
 
  /**
   * @param <T> The type of event listener
   * @param loader The loader to use for creating the proxy
   * @param listenerType The class of the listener type
   * @param pojoTarget The target for event notifications
   * @return The proxy for dealing with the pojo in a typed fashion
   */
  public static <T extends java.util.EventListener> T createProxy (ClassLoader loader, Class<T> listenerType, Object pojoTarget) {
    return (T) Proxy.newProxyInstance(loader, new Class[] { listenerType }, new EventDelegator(listenerType, pojoTarget));
  }
 
  protected final Object target;
  protected final ClassDescriptor<?> targetType;
  protected final ClassDescriptor<? extends java.util.EventListener> listenerType;
 
  protected final ClassMethod allEventHandler;

  protected EventDelegator(Class<? extends java.util.EventListener> listenerType, Object target) {
    this.target = target;
    this.targetType = ClassCache.getFor( target.getClass() );
    this.listenerType = ClassCache.getFor( listenerType );
    this.allEventHandler = targetType.getMethod(EventHandler.class);
  }

  /**
   * @return The target this proxy is delegating to.
   */
  public Object getTarget() { return target; }

  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if (method.getDeclaringClass() == Object.class) return method.invoke(target, args);
   
    Pojo pojo = method.getAnnotation(Pojo.class);
    ClassMethod cm = null;
    Object returnValue = null;
    if (pojo != null) {
      cm = targetType.getMethod(pojo.value());
    } else {
      cm = targetType.findMethod(method.getName(), args);
    }
    if (cm != null) returnValue = cm.invoke(target, args);
    else if (this.allEventHandler != null && method.getAnnotation(CollectionProxyCondition.class) == null) {
      returnValue = this.allEventHandler.invoke(target, args);
    }
   
    if (method.getReturnType() == void.class) return null;
    if (returnValue != null && method.getReturnType().isInstance(returnValue))
      return returnValue;
   
    DefaultReturnValue drv = method.getAnnotation(DefaultReturnValue.class);
    if (drv != null) {
      return ReflectionUtil.coerceString(method.getReturnType(), drv.value());
    } else if (method.getReturnType().isPrimitive()) {
      return ReflectionUtil.getPrimitiveDefault(method.getReturnType());
    }
   
    return null;
  }

}
TOP

Related Classes of net.sourceforge.javautil.common.event.EventDelegator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.