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

net.snowflake.common.util.FunctionPointer Maven / Gradle / Ivy

There is a newer version: 5.1.4
Show newest version
/*
 * 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