package org.enumerable.lambda.support.groovy; import org.enumerable.lambda.Fn0; import org.enumerable.lambda.Fn1; import org.enumerable.lambda.Fn2; import org.enumerable.lambda.Fn3; import org.enumerable.lambda.annotation.NewLambda; import org.enumerable.lambda.exception.LambdaWeavingNotEnabledException; import groovy.lang.Closure; import sun.org.mozilla.javascript.internal.Function; /** * This is class is similar {@link org.enumerable.lambda.Lambda}, but instead of creating * lambdas inheriting from {@link org.enumerable.lambda.Fn0} it creates lambdas extending * {@link Function} to be used together with Groovy. */ @SuppressWarnings("serial") public class LambdaGroovy { public static abstract class ClosureFn0 extends Closure<Object> { public ClosureFn0() { super(LambdaGroovy.class); Fn0.getAndCheckArityForMethod(getImplementingClass(), getMethod()); } Class<?> getImplementingClass() { return getClass(); } String getMethod() { return "doCall"; } public abstract Object doCall(); } public static abstract class ClosureFn1 extends ClosureFn0 { public Object doCall() { return doCall(default$1()); } protected Object default$1() { return null; } public abstract Object doCall(Object a1); } public static abstract class ClosureFn2 extends ClosureFn1 { public Object doCall(Object a1) { return doCall(a1, default$2()); } protected Object default$2() { return null; } public abstract Object doCall(Object a1, Object a2); } public static abstract class ClosureFn3 extends ClosureFn2 { public Object doCall(Object a1, Object a2) { return doCall(a1, a2, default$3()); } protected Object default$3() { return null; } public abstract Object doCall(Object a1, Object a2, Object a3); } /** * Creates a new function implementing {@link Function} taking no arguments. */ @NewLambda public static ClosureFn0 closure(Object block) { throw new LambdaWeavingNotEnabledException(); } /** * Creates a new function implementing {@link Function} taking one argument. */ @NewLambda public static ClosureFn1 closure(Object a1, Object block) { throw new LambdaWeavingNotEnabledException(); } /** * Creates a new function implementing {@link Function} taking two * arguments. */ @NewLambda public static ClosureFn2 closure(Object a1, Object a2, Object block) { throw new LambdaWeavingNotEnabledException(); } /** * Creates a new function implementing {@link Function} taking three * arguments. */ @NewLambda public static ClosureFn3 closure(Object a1, Object a2, Object a3, Object block) { throw new LambdaWeavingNotEnabledException(); } /** * Wraps the {@link Function} in a {@link Fn0}. */ public static Fn0<Object> toFn0(final Closure<?> closure) { return new Fn0<Object>() { public Object call() { return closure.call(); } }; } /** * Wraps the {@link Function} in a {@link Fn1}. */ public static Fn1<Object, Object> toFn1(final Closure<?> closure) { return new Fn1<Object, Object>() { public Object call(Object a1) { return closure.call(new Object[] { a1 }); } }; } /** * Wraps the {@link Function} in a {@link Fn2}. */ public static Fn2<Object, Object, Object> toFn2(final Closure<?> closure) { return new Fn2<Object, Object, Object>() { public Object call(Object a1, Object a2) { return closure.call(new Object[] { a1, a2 }); } }; } /** * Wraps the {@link Function} in a {@link Fn3}. */ public static Fn3<Object, Object, Object, Object> toFn3(final Closure<?> closure) { return new Fn3<Object, Object, Object, Object>() { public Object call(Object a1, Object a2, Object a3) { return closure.call(new Object[] { a1, a2, a3 }); } }; } /** * Wraps the {@link Fn0} in a {@link Closure}. */ @SuppressWarnings("rawtypes") public static ClosureFn0 toClosure(final Fn0 fn) { return new ClosureFn0() { public Object doCall() { return fn.call(); } }; } /** * Wraps the {@link Fn1} in a {@link Closure}. */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static ClosureFn1 toClosure(final Fn1 fn) { return new ClosureFn1() { public Object doCall() { return fn.call(); } public Object doCall(Object a1) { return fn.call(a1); } Class<?> getImplementingClass() { return fn.getClass(); } String getMethod() { return "call"; } }; } /** * Wraps the {@link Fn2} in a {@link Closure}. */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static ClosureFn2 toClosure(final Fn2 fn) { return new ClosureFn2() { public Object doCall() { return fn.call(); } public Object doCall(Object a1) { return fn.call(a1); } public Object doCall(Object a1, Object a2) { return fn.call(a1, a2); } Class<?> getImplementingClass() { return fn.getClass(); } String getMethod() { return "call"; } }; } /** * Wraps the {@link Fn3} in a {@link Closure}. */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static ClosureFn3 toClosure(final Fn3 fn) { return new ClosureFn3() { public Object doCall() { return fn.call(); } public Object doCall(Object a1) { return fn.call(a1); } public Object doCall(Object a1, Object a2) { return fn.call(a1, a2); } public Object doCall(Object a1, Object a2, Object a3) { return fn.call(a1, a2, a3); } Class<?> getImplementingClass() { return fn.getClass(); } String getMethod() { return "call"; } }; } }