Package net.sourceforge.javautil.common.proxy.pojo

Source Code of net.sourceforge.javautil.common.proxy.pojo.PojoProxy

package net.sourceforge.javautil.common.proxy.pojo;

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

import net.sourceforge.javautil.common.ReflectionUtil;
import net.sourceforge.javautil.common.proxy.AbstractProxy;
import net.sourceforge.javautil.common.proxy.AdaptableProxyHandlerAbstract;
import net.sourceforge.javautil.common.proxy.DefaultReturnValue;
import net.sourceforge.javautil.common.reflection.cache.ClassCache;
import net.sourceforge.javautil.common.reflection.cache.ClassDescriptor;
import net.sourceforge.javautil.common.reflection.cache.ClassMethod;

/**
* This allows an interface to be used along with annotations to invoke methods on a POJO
* that does not actually implement the interface. Interface proxy methods that do not
* have annotations set on them will simply be passed on to a method with the same name
* on the target POJO. Interface proxy methods that do have annotations will use those
* annotations to search for corresponding methods in the target POJO independent of the
* method name. Any methods not found will simply return.
*
* @author elponderador
* @author $Author: ponderator $
* @version $Id: PojoProxy.java 2700 2010-12-30 15:59:51Z ponderator $
*/
public class PojoProxy extends AbstractProxy {
 
  /**
   * Assumes current thread based class loader.
   *
   * @see #create(ClassLoader, Class, Object)
   */
  public static <T> T create (Class<T> iface, Object pojo) {
    return create(Thread.currentThread().getContextClassLoader(), iface, pojo);
  }
 
  /**
   * @param <T> The type of proxy
   * @param cl The class loader to use to create the proxy
   * @param iface The interface of the type
   * @param pojo The pojo target
   * @return A proxy for invoking available methods on the pojo
   */
  public static <T> T create (ClassLoader cl, Class<T> iface, Object pojo) {
    return (T) Proxy.newProxyInstance(cl, new Class[] { iface }, new PojoProxy(pojo));
  }
 
  protected Object pojo;
  protected ClassDescriptor pojoDescriptor;
 
  public PojoProxy (Object pojo) {
    this.pojo = pojo;
    this.pojoDescriptor = ClassCache.getFor(pojo.getClass());
  }

  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    Method target = this.adapters.size() > 0 ? this.adapter.translatedMethod(this, method, args) : method;
   
    Pojo pojo = target.getAnnotation(Pojo.class);
    if (pojo != null) {
      ClassMethod cm = pojoDescriptor.getMethod(pojo.value());
      if (cm != null) target = cm.getJavaMember(); else target = null;
    } else {
      ClassMethod cm = pojoDescriptor.findMethod(target.getName(), args);
      if (cm != null) target = cm.getJavaMember(); else target = null;
    }
   
    Object returnValue = null;
    if (target == null) {
      DefaultReturnValue drv = method.getAnnotation(DefaultReturnValue.class);
      if (drv != null) {
        returnValue = drv.value();
      } else {
        returnValue = method.getReturnType().isPrimitive() ? ReflectionUtil.getPrimitiveDefault(method.getReturnType()) : null;
      }
    } else {
      returnValue = super.invoke(proxy, target, args);
    }
   
    return method.getReturnType() == void.class ? null : ReflectionUtil.coerce(method.getReturnType(), returnValue);
  }

  @Override protected Object getTarget(Method method, Object[] args) {
    return this.pojo;
  }

}
TOP

Related Classes of net.sourceforge.javautil.common.proxy.pojo.PojoProxy

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.