
net.snowflake.common.util.FunctionPointer Maven / Gradle / Ivy
/*
* Copyright (c) 2013 Snowflake Computing Inc. All right reserved.
*/
package net.snowflake.common.util;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Function Pointer holds a reference to a static function at compiler time,
* resolves it a runtime and invokes it. The function being called must be a
* public static function with 0 to 6 parameters of type Object. i.e. public
* static String callbackFnWith1Param(Object o)
*
* @author amotivala
*/
public class FunctionPointer
{
Method function;
int argCount;
/**
* Create a function pointer reference using a function name of the format
* <class>:<method>. The
*
* @param functionName a function name.
* @param argCount number of Object.class arguments that the function takes
* @throws ClassNotFoundException thrown if class not found
* @throws NoSuchMethodException thrown if no method is found
*/
public FunctionPointer(String functionName, int argCount)
throws ClassNotFoundException, NoSuchMethodException
{
String[] methodStr = functionName.split("\\:", 2);
this.argCount = argCount;
findMethod(methodStr[0], methodStr[1]);
}
/**
* Create a function pointer reference.
*
* @param className name of the class
* @param function static function to call in the class
* @param argCount number of Object.class arguments that the function takes
* @throws ClassNotFoundException thrown if class not found
* @throws NoSuchMethodException thrown if no method is found
*/
public FunctionPointer(String className, String function, int argCount)
throws ClassNotFoundException, NoSuchMethodException
{
this.argCount = argCount;
findMethod(className, function);
}
private void findMethod(String className,
String function)
throws NoSuchMethodException, SecurityException,
ClassNotFoundException
{
Class klass = Class.forName(className);
switch (this.argCount)
{
case 0:
this.function = klass.getMethod(function);
break;
case 1:
this.function = klass.getMethod(function,
Object.class);
break;
case 2:
this.function = klass.getMethod(function,
Object.class,
Object.class);
break;
case 3:
this.function = klass.getMethod(function,
Object.class,
Object.class,
Object.class);
break;
case 4:
this.function = klass.getMethod(function,
Object.class,
Object.class,
Object.class,
Object.class);
break;
case 5:
this.function = klass.getMethod(function,
Object.class,
Object.class,
Object.class,
Object.class,
Object.class);
break;
case 6:
this.function = klass.getMethod(function,
Object.class,
Object.class,
Object.class,
Object.class,
Object.class,
Object.class);
break;
default:
throw new NoSuchMethodException(
"Add support for funciton pointers to"
+ "methods with more than 6 parameters");
}
}
/**
* Invokes the function pointer
*
* @param args the arguments to pass to the function pointer
* @return the object returned by the invocation
* @throws IllegalAccessException thrown if method is not accessible
* @throws InvocationTargetException thrown if target function is invalid
* @throws IllegalArgumentException thrown if the arguments don't match
*/
public Object invoke(Object... args) throws IllegalAccessException,
InvocationTargetException, IllegalArgumentException
{
if (args.length != this.argCount)
{
throw new IllegalArgumentException("Incorrect number of arguments. "
+ "Function " + this.function
.toString() + ", expects "
+ this.argCount + " arguments.");
}
return this.function.invoke(null, args);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy