nl.hsac.fitnesse.fixture.util.LambdaMetaHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hsac-fitnesse-fixtures Show documentation
Show all versions of hsac-fitnesse-fixtures Show documentation
Fixtures to assist in testing via FitNesse
package nl.hsac.fitnesse.fixture.util;
import java.lang.invoke.CallSite;
import java.lang.invoke.LambdaMetafactory;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import static java.lang.invoke.MethodType.methodType;
/**
* Helper to create Functions based on reflection types.
*/
public class LambdaMetaHelper {
private final static Map, Class>> PRIMITIVE_TYPES = new HashMap<>();
static {
PRIMITIVE_TYPES.put(boolean.class, Boolean.class);
PRIMITIVE_TYPES.put(byte.class, Byte.class);
PRIMITIVE_TYPES.put(short.class, Short.class);
PRIMITIVE_TYPES.put(char.class, Character.class);
PRIMITIVE_TYPES.put(int.class, Integer.class);
PRIMITIVE_TYPES.put(long.class, Long.class);
PRIMITIVE_TYPES.put(float.class, Float.class);
PRIMITIVE_TYPES.put(double.class, Double.class);
}
/**
* Gets no-arg constructor as Supplier.
* @param clazz class to get constructor for.
* @param clazz.
* @return supplier.
*/
public Supplier getConstructor(Class extends T> clazz) {
return getConstructorAs(Supplier.class, "get", clazz);
}
/**
* Gets single arg constructor as Function.
* @param clazz class to get constructor for.
* @param arg constructor argument type.
* @param clazz.
* @param argument class.
* @return function.
*/
public Function getConstructor(Class extends T> clazz, Class arg) {
return getConstructorAs(Function.class, "apply", clazz, arg);
}
/**
* Gets two arg constructor as BiFunction.
* @param clazz class to get constructor for.
* @param arg1 first argument class.
* @param arg2 second argument class.
* @param clazz.
* @param first argument class
* @param second argument class.
* @return bifunction.
*/
public BiFunction getConstructor(Class extends T> clazz, Class arg1, Class arg2) {
return getConstructorAs(BiFunction.class, "apply", clazz, new Class>[] {arg1, arg2});
}
protected T getConstructorAs(Class targetClass, String methodName, Class extends R> clazz, Class>... args) {
try {
Class>[] lambdaArgs = new Class>[args.length];
for (int i = 0; i < args.length; i++) {
Class> arg = args[i];
if (arg.isPrimitive()) {
lambdaArgs[i] = PRIMITIVE_TYPES.get(arg);
} else {
lambdaArgs[i] = arg;
}
}
MethodType methodType = methodType(clazz, lambdaArgs);
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle handle = lookup.findConstructor(clazz, methodType(void.class, args));
MethodType targetType = methodType(targetClass);
CallSite callSite = LambdaMetafactory.metafactory(lookup, methodName, targetType, methodType.generic(), handle, methodType);
return (T) callSite.getTarget().invoke();
} catch (Throwable t) {
throw new RuntimeException("Unable to create function for constructor of " + clazz.getName(), t);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy