/src/main/java/nodebox/function/JavaLibrary.java

https://github.com/djaddison/nodebox · Java · 111 lines · 90 code · 21 blank · 0 comment · 2 complexity · 705805324244babf0d243e6272db0ee3 MD5 · raw file

  1. package nodebox.function;
  2. import com.google.common.collect.ImmutableList;
  3. import com.google.common.collect.ImmutableMap;
  4. import nodebox.util.LoadException;
  5. import java.io.File;
  6. import java.lang.reflect.Field;
  7. import java.lang.reflect.Method;
  8. import java.lang.reflect.Modifier;
  9. import java.util.ArrayList;
  10. import static com.google.common.base.Preconditions.checkArgument;
  11. public final class JavaLibrary extends FunctionLibrary {
  12. public static JavaLibrary loadStaticClass(String identifier) {
  13. try {
  14. Class c = Class.forName(identifier);
  15. Field instanceField = c.getDeclaredField("LIBRARY");
  16. return (JavaLibrary) instanceField.get(null);
  17. } catch (ClassNotFoundException e) {
  18. throw new LoadException(null, e);
  19. } catch (NoSuchFieldException e) {
  20. throw new LoadException(null, e);
  21. } catch (IllegalAccessException e) {
  22. throw new LoadException(null, e);
  23. } catch (ClassCastException e) {
  24. throw new LoadException(null, e);
  25. } catch (ExceptionInInitializerError e) {
  26. throw new LoadException(null, e);
  27. }
  28. }
  29. public static JavaLibrary ofClass(String namespace, Class c, String... methodNames) {
  30. ArrayList<Function> functions = new ArrayList<Function>();
  31. for (String methodName : methodNames) {
  32. Function function = StaticMethodFunction.find(c, methodName);
  33. functions.add(function);
  34. }
  35. return new JavaLibrary(namespace, c, functions);
  36. }
  37. private final String namespace;
  38. private final Class clazz;
  39. private final ImmutableMap<String, Function> functionMap;
  40. private JavaLibrary(String namespace, Class clazz, Iterable<Function> functions) {
  41. this.namespace = namespace;
  42. this.clazz = clazz;
  43. ImmutableMap.Builder<String, Function> b = ImmutableMap.builder();
  44. for (Function function : functions) {
  45. b.put(function.getName(), function);
  46. }
  47. functionMap = b.build();
  48. }
  49. @Override
  50. public String getLink(File baseFile) {
  51. return "java:" + clazz.getName();
  52. }
  53. public String getSimpleIdentifier() {
  54. return getNamespace();
  55. }
  56. public String getNamespace() {
  57. return namespace;
  58. }
  59. public String getLanguage() {
  60. return "java";
  61. }
  62. public Function getFunction(String name) {
  63. return functionMap.get(name);
  64. }
  65. public boolean hasFunction(String name) {
  66. return functionMap.containsKey(name);
  67. }
  68. private static class StaticMethodFunction implements Function {
  69. public static StaticMethodFunction find(Class c, String methodName) {
  70. Method m = Functions.findMethod(c, methodName, false);
  71. return new StaticMethodFunction(m);
  72. }
  73. private final Method method;
  74. private final ImmutableList<Argument> arguments;
  75. public StaticMethodFunction(Method method) {
  76. checkArgument(Modifier.isStatic(method.getModifiers()), "Method %s is not a static method.", method);
  77. this.method = method;
  78. this.arguments = Functions.introspect(method);
  79. }
  80. public String getName() {
  81. return method.getName();
  82. }
  83. public Object invoke(Object... args) throws Exception {
  84. return method.invoke(null, args);
  85. }
  86. public ImmutableList<Argument> getArguments() {
  87. return arguments;
  88. }
  89. }
  90. }