package jeql.engine.function; import java.lang.reflect.Method; import java.util.List; import jeql.api.function.SplittingFunction; import jeql.engine.CompilationException; import jeql.engine.ConfigurationException; import jeql.engine.FunctionRegistry; import jeql.engine.Scope; /** * Evaluates a split function. * * @author Martin Davis * */ public class SplitFunctionEvaluator implements FunctionEvaluator { private String className = null; private String name; private SplittingFunction splitFun; private List args; private MethodFunctionInvoker funcInvoker; public SplitFunctionEvaluator(String className, String name, List args) { this.className = className; this.name = name; this.args = args; } public void bind(Scope scope, List args) { String fullName = FunctionRegistry.functionName(className, name); Method method = scope.getContext().getFunction(fullName, args.size()); if (method == null) throw new CompilationException("Unknown function - " + fullName); if (method.getReturnType() != SplittingFunction.class) { throw new CompilationException("Function " + fullName + " is not a Split function"); } splitFun = (SplittingFunction) MethodFunctionInvoker.invoke(method, null); // call split function via methodInvoker because # of args is only known at runtime funcInvoker = new MethodFunctionInvoker(findExecuteMethod(splitFun.getClass())); } private static final String SPLIT_FN_EXECUTE_METHOD = "execute"; private static Method findExecuteMethod(Class functionClass) { Method[] method = functionClass.getMethods(); for (int i = 0; i < method.length; i++) { if (method[i].getName().equals(SPLIT_FN_EXECUTE_METHOD)) { return method[i]; } } throw new ConfigurationException("Method 'execute' not found in SplitFunction class " + functionClass.getName()); } public Object eval(Scope scope) { return funcInvoker.eval(scope, splitFun, args); } public Class getType(Scope scope) { return splitFun.getType(); } }