Package net.sourceforge.javautil.poly

Source Code of net.sourceforge.javautil.poly.PojoViewInvocationHandler

package net.sourceforge.javautil.poly;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

import net.sourceforge.javautil.common.CollectionUtil;
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;
import net.sourceforge.javautil.common.reflection.cache.ClassMethodAbstract.ArgumentMatch;
import net.sourceforge.javautil.interceptor.IInterceptorManager;
import net.sourceforge.javautil.interceptor.type.InterceptorInvocationHandler;

/**
* This will handle invocations for dynamic pojo abilities.
*
* @author elponderador
* @author $Author$
* @version $Id$
*/
public class PojoViewInvocationHandler implements InvocationHandler {

  protected final Object target;
  protected final IInterceptorManager interceptor;
  protected final ClassDescriptor targetDesc;
  protected final Map<Method, ClassMethod> cache = new HashMap<Method, ClassMethod>();
  protected final Object defaultTarget;
 
  public PojoViewInvocationHandler(IInterceptorManager interceptor, Object target, Object defaultTarget) {
    if (Proxy.isProxyClass(target.getClass())) {
      InvocationHandler handler = Proxy.getInvocationHandler(target);
      if (handler instanceof InterceptorInvocationHandler) {
        this.target = InterceptorInvocationHandler.getTarget((InterceptorInvocationHandler)handler);
      } else {
        this.target = target;
      }
    } else {
      this.target = target;
    }
    this.interceptor = interceptor;
    this.targetDesc = ClassCache.getFor(this.target.getClass().getSuperclass());
    this.defaultTarget = defaultTarget;
  }

  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if (!cache.containsKey(method)) {
      Pojo pojo = method.getAnnotation(Pojo.class);
      cache.put(method, pojo == null ? null : targetDesc.getMethod(pojo.value()));
    }
   
    ClassMethod cm = cache.get(method);
    if (cm != null) {
      Object[] modifiedArguments = null;
      if (cm.getParameterTypes().length == 0) {
        modifiedArguments = CollectionUtil.EMPTY_OBJECT_ARRAY;
      } else if (cm.getParameterTypes().length == 1 && cm.getParameterTypes()[0] == method.getDeclaringClass()) {
        modifiedArguments = new Object[] { defaultTarget };
      } else if (cm.compareArguments(args) == ArgumentMatch.FUNCTIONAL) {
        modifiedArguments = args;
      } else {
        throw new IllegalArgumentException("Cannot call method appropriately");
      }
     
      return interceptor.invoke(target, cm.getJavaMember(), modifiedArguments);
    } else {
      return interceptor.invoke(defaultTarget, method, args);
    }
  }
 
}
TOP

Related Classes of net.sourceforge.javautil.poly.PojoViewInvocationHandler

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.