All Downloads are FREE. Search and download functionalities are using the official Maven repository.

prompto.intrinsic.PromptoMethod Maven / Gradle / Ivy

The newest version!
package prompto.intrinsic;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;

public abstract class PromptoMethod {

	static Map> consumerProducers = getConsumerProducers();
	static Map> supplierProducers = getSupplierProducers();
	
	private static Map> getConsumerProducers() {
		Map> result = new HashMap<>();
		result.put(0, PromptoMethod::newRunnable);
		result.put(1, PromptoMethod::newConsumer);
		return result;
	}


	private static Map> getSupplierProducers() {
		Map> result = new HashMap<>();
		result.put(1, PromptoMethod::newFunction);
		return result;
	}

	// TODO use LambdaMetaFactory
	public static Object newMethodReference(Class klass, String methodName, Object instance) {
		Method method = Arrays.asList(klass.getDeclaredMethods()).stream()
				.filter(m->methodName.equals(m.getName()))
				.findFirst()
				.orElse(null);
		if(method.getReturnType()==void.class)
			return newConsumerReference(method, instance);
		else
			return newSupplierReference(method, instance);
	}

	
	private static Object newSupplierReference(Method method, Object instance) {
		BiFunction supplier = supplierProducers.get(method.getParameterCount());
		if(supplier==null)	
			throw new UnsupportedOperationException("newSupplierReference with " + method.getParameterCount() + " parameter(s)");
		return supplier.apply(method, instance);
	}


	private static Object newConsumerReference(Method method, Object instance) {
		BiFunction consumer = consumerProducers.get(method.getParameterCount());
		if(consumer==null)	
			throw new UnsupportedOperationException("newConsumerReference with " + method.getParameterCount() + " parameter(s)");
		return consumer.apply(method, instance);
	}
	
	private static Object safeInvoke(Method method, Object instance, Object ... args) {
		try {
			return method.invoke(instance, args);
		} catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
			throw new RuntimeException(e);
		}
	}

	private static Runnable newRunnable(Method method, Object instance) {
		return ()->safeInvoke(method, instance);
	}

	private static Consumer newConsumer(Method method, Object instance) {
		return (a)->safeInvoke(method, instance, a);
	}

	private static Function newFunction(Method method, Object instance) {
		return (a)->safeInvoke(method, instance, a);
	}
}