package com.tek271.funj; import com.google.common.annotations.Beta; import com.google.common.collect.ObjectArrays; import java.util.List; import static com.tek271.funj.ReflectionTools.callMethod; import static com.tek271.funj.ReflectionTools.callStatic; @Beta public class StepFunction { private String staticPath; private Object dynamicContext; private String functionName; private Object[] extraArgs; private boolean isIgnoreNulls; private TransformType transformType = TransformType.MAP; public static StepFunction create() { return new StepFunction(); } public StepFunction staticClass(String staticPath) { this.staticPath = staticPath; this.dynamicContext = null; return this; } public StepFunction staticClass(Class<?> cls) { return staticClass(cls.getName()); } public StepFunction dynamicContext(Object context) { this.dynamicContext = context; this.staticPath = null; return this; } public StepFunction functionName(String functionName) { this.functionName = functionName; return this; } public StepFunction extraArgs(Object... args) { if (ArrayTools.size(this.extraArgs) == 0) { this.extraArgs = args; } else { this.extraArgs = ObjectArrays.concat(this.extraArgs, args, Object.class); } return this; } public StepFunction initialValueForMap(Object arg) { this.extraArgs = new Object[] {arg}; return this; } public StepFunction ignoreNulls(boolean isIgnoreNulls) { this.isIgnoreNulls = isIgnoreNulls; return this; } public StepFunction ignoreNulls() { return ignoreNulls(true); } public boolean isIgnoreNulls() { return isIgnoreNulls; } public StepFunction transformType(TransformType transformType) { this.transformType = transformType; return this; } private <OUT> OUT call(Object[] args) { if (dynamicContext == null) { String callback = staticPath + "." + functionName; return callStatic(callback, args); } return callMethod(dynamicContext, functionName, args); } public <OUT> OUT call(Object arg) { Object[] args; if (ArrayTools.size(this.extraArgs) == 0) { args = new Object[] {arg}; } else { args = ObjectArrays.concat(arg, this.extraArgs); } return call(args); } public <IN, OUT> List<OUT> apply(Iterable<IN> iterable) { return transformType.apply(iterable, this); } }