Package net.sourceforge.javautil.groovy.util

Source Code of net.sourceforge.javautil.groovy.util.ClosureUtil$ClosureProxy

package net.sourceforge.javautil.groovy.util;

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

import net.sourceforge.javautil.common.CollectionUtil;
import net.sourceforge.javautil.common.proxy.AbstractProxy;
import net.sourceforge.javautil.common.proxy.AdaptableProxyHandlerAbstract;

import org.codehaus.groovy.runtime.GroovyCategorySupport;
import org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl;

import groovy.lang.Closure;
import groovy.lang.GroovySystem;
import groovy.lang.MetaClassRegistry;

/**
* This is a group of utility methods for dealing with and calling {@link Closure}'s
*
* @author elponderador
*
*/
public class ClosureUtil {
 
  /**
   * @param <T> The type of proxy
   * @param iface The class of the proxy type
   * @param closure The closure to handle method calls
   * @return The new proxy
   */
  public static <T> T createProxy (Class<T> iface, Closure closure) {
    return (T) ClosureProxy.createProxy(Thread.currentThread().getContextClassLoader(), new Class[] { iface }, closure);
  }
 
  /**
   * This allows one to call a closure without requiring a certain amount of parameters to be declared.
   * If the amount of parameters passed is greater than what it can take (determined
   * by calling {@link Closure#getMaximumNumberOfParameters()}) a new {@link Object}[]
   * that will have the first parameters up to what the closure can take. If the closure
   * cannot take any parameters, it will call {@link Closure#call()} otherwise it will
   * call {@link Closure#call(Object[])}.
   *
   * @param closure The closure to execute
   * @param parameters The possible parameters to pass
   * @return Whatever the closure returns
   */
  public static Object call (Closure closure, Object... parameters) {
    Object[] newpars = parameters;
    if (newpars.length > closure.getMaximumNumberOfParameters()) {
      newpars = new Object[closure.getMaximumNumberOfParameters()];
      if (newpars.length > 0) {
        System.arraycopy(parameters, 0, newpars, 0, newpars.length);
      }
    }
    return newpars.length == 0 ? closure.call() : closure.call(newpars);
  }
 
  /**
   * This makes calling closures with dynamic parameters (using {@link ClosureUtil#call(Closure, Object...)}
   * along with {@link GroovyCategorySupport} much easier.
   *
   * @param clazz The category class
   * @param closure The closure to be executed
   * @param parameters The parameters
   * @return The result of the closure execution
   */
  public static Object callUsing (Class clazz, final Closure closure, final Object... parameters) {
    return GroovyCategorySupport.use(clazz, new Closure (closure) {
      public Object call () { return ClosureUtil.call(closure, parameters); }
    });
  }
 
  /**
   * This allows a closure to be used as the target for a proxy.
   *
   * @author elponderador
   * @author $Author: ponderator $
   * @version $Id: ClosureUtil.java 1081 2009-09-24 14:12:31Z ponderator $
   */
  public static class ClosureProxy extends AbstractProxy {
   
    public static Object createProxy (ClassLoader loader, Class[] ifaces, Closure target) {
      return Proxy.newProxyInstance(loader, ifaces, new ClosureProxy(target));
    }
   
    protected Closure closure;

    private ClosureProxy(Closure closure) { this.closure = closure; }

    @Override protected Object call(Object target, Method method, Object... args) throws Throwable {
      return closure.call(new Object[] { args, method });
    }

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

  }

}
TOP

Related Classes of net.sourceforge.javautil.groovy.util.ClosureUtil$ClosureProxy

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.