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

com.github.dakusui.valid8j_pcond.experimentals.currying.multi.MultiFunctionUtils Maven / Gradle / Ivy

The newest version!
package com.github.dakusui.valid8j_pcond.experimentals.currying.multi;

import com.github.dakusui.valid8j_pcond.core.printable.PrintableFunctionFactory;
import com.github.dakusui.valid8j_pcond.internals.InternalUtils;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;

/**
 * A utility class that collects helper methods for the multi-parameters function.
 */
public enum MultiFunctionUtils {
  ;
  private static final ThreadLocal, MultiFunction>> METHOD_BASED_FUNCTION_POOL = new ThreadLocal<>();

  @SuppressWarnings("unchecked")
  public static  MultiFunction multifunction(int[] order, Class aClass, String methodName, Class... parameterTypes) {
    Map, MultiFunction> methodBasedMultiParameterFunctionPool = methodBasedMultiParameterFunctionPool();
    List multiParamFuncDef = composeFuncDef(order, aClass, methodName, parameterTypes);
    methodBasedMultiParameterFunctionPool.computeIfAbsent(
        multiParamFuncDef,
        MultiFunctionUtils::createMultiParameterFunctionForStaticMethod);
    return (MultiFunction) methodBasedMultiParameterFunctionPool.get(multiParamFuncDef);
  }

  private static List composeFuncDef(int[] order, Class aClass, String methodName, Class[] parameterTypes) {
    return asList(InternalUtils.getMethod(aClass, methodName, parameterTypes), Arrays.stream(order).boxed().collect(toList()));
  }

  private static  MultiFunction createMultiParameterFunctionForStaticMethod(List multiParamFuncDef) {
    final Method method = (Method) multiParamFuncDef.get(0);
    @SuppressWarnings("unchecked") final List paramOrder = (List) multiParamFuncDef.get(1);
    return PrintableFunctionFactory.multifunction(method, paramOrder);
  }

  private static Map, MultiFunction> methodBasedMultiParameterFunctionPool() {
    if (METHOD_BASED_FUNCTION_POOL.get() == null)
      METHOD_BASED_FUNCTION_POOL.set(new HashMap<>());
    return METHOD_BASED_FUNCTION_POOL.get();
  }
}