package cn.bran.japid.util; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import cn.bran.japid.compiler.NamedArgRuntime; import cn.bran.japid.template.JapidTemplateBaseWithoutPlay; import cn.bran.japid.template.RenderResult; public class RenderInvokerUtils { // private static final String RENDER_METHOD = "render"; /** * */ private static final String DELI = ", "; public static <T extends JapidTemplateBaseWithoutPlay> RenderResult render(T t, Object... args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { if (args == null) { // treat it as a single null argument args = new Object[] { null }; } Method m = t.renderMethodInstance; if (m == null) { throw new RuntimeException("The render method cache is not initialized for: " + t.getClass().getName()); } Object invoke; try { invoke = m.invoke(t, args); return (RenderResult) invoke; } catch (IllegalArgumentException e) { String msg = e.getMessage(); String paramTypes = flatArgs(m.getParameterTypes()); msg = msg + ": the arguments do not match the parameters of the template " + t.getClass().getName() + paramTypes; String ss = flatArgs(args); throw new RuntimeException(msg + ": " + ss); // System.err.println(e + ": " + m + args); // throw e; } // } catch (IllegalArgumentException e) { // throw new RuntimeException("Template argument type mismatch: ", e); // } catch (InvocationTargetException e) { // Throwable te = e.getTargetException(); // Throwable cause = te.getCause(); // if (cause != null) // throw new RuntimeException("error in running the renderer: ", cause); // else // throw new RuntimeException("error in running the renderer: ", te); // // te.printStackTrace(); // } catch (Exception e) { // e.printStackTrace(); // throw new RuntimeException(e); // } } /** * @author Bing Ran (bing.ran@hotmail.com) * @param args * @return */ private static String flatArgs(Object[] args) { if (args == null) { return "[]"; } String sb = ""; for (Object o : args) { if (o instanceof Class) { sb += ((Class<?>) o).getName() + DELI; } else sb += o.getClass().getName() + DELI; } if (sb.endsWith(DELI)) { sb = sb.substring(0, sb.length() - 2); } return "[" + sb + "]"; } public static <T extends JapidTemplateBaseWithoutPlay> RenderResult renderWithNamedArgs(T t, NamedArgRuntime... args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { if (args == null) { // treat it as a single null argument args = new NamedArgRuntime[] { null }; } return render(t, t.buildArgs(args)); } /** * @param <T> * @param c * @param args * @return * @throws NoSuchMethodException * @throws InstantiationException * @throws IllegalAccessException * @throws InvocationTargetException */ public static <T extends JapidTemplateBaseWithoutPlay> RenderResult invokeRender(Class<T> c, Object... args) { int modifiers = c.getModifiers(); if (Modifier.isAbstract(modifiers)) { throw new RuntimeException("Cannot init the template class since it's an abstract class: " + c.getName()); } try { // String methodName = "render"; Constructor<T> ctor = c.getConstructor(StringBuilder.class); RenderResult rr = invokeRenderer(ctor, args); // RenderResult rr = (RenderResult) MethodUtils.invokeMethod(t, // methodName, args); return rr; } catch (NoSuchMethodException e) { throw new RuntimeException("Could not match the arguments with the template args."); } catch (Exception e) { if (e instanceof RuntimeException) throw (RuntimeException) e; else throw new RuntimeException("Could not invoke the template object: ", e); } } public static <T extends JapidTemplateBaseWithoutPlay> RenderResult invokeRenderer(Constructor<T> ctor, Object... args) { try { StringBuilder sb = new StringBuilder(8000); T t = ctor.newInstance(sb); RenderResult rr = render(t, args); JapidFlags.logTimeLogs(t); return rr; } catch (InstantiationException e) { // e.printStackTrace(); throw new RuntimeException("Could not instantiate the template object. Abstract?"); } catch (InvocationTargetException e) { // e.printStackTrace(); Throwable te = e.getTargetException(); // if (te instanceof TemplateExecutionException) // throw (TemplateExecutionException) te; Throwable cause = te.getCause(); if (cause != null) if (cause instanceof RuntimeException) throw (RuntimeException) cause; else throw new RuntimeException("error in running the renderer: " + cause.getMessage(), cause); else if (te instanceof RuntimeException) throw (RuntimeException) te; else throw new RuntimeException("error in running the renderer: " + te.getMessage(), te); } catch (Exception e) { if (e instanceof RuntimeException) throw (RuntimeException) e; else throw new RuntimeException("Could not invoke the template object: ", e); // throw new RuntimeException(e); } } public static <T extends JapidTemplateBaseWithoutPlay> RenderResult invokeNamedArgsRender(Class<T> c, NamedArgRuntime[] args) { int modifiers = c.getModifiers(); if (Modifier.isAbstract(modifiers)) { throw new RuntimeException("Cannot init the template class since it's an abstract class: " + c.getName()); } try { // String methodName = "render"; Constructor<T> ctor = c.getConstructor(StringBuilder.class); StringBuilder sb = new StringBuilder(8000); JapidTemplateBaseWithoutPlay t = ctor.newInstance(sb); RenderResult rr = renderWithNamedArgs(t, args); JapidFlags.logTimeLogs(t); return rr; } catch (NoSuchMethodException e) { throw new RuntimeException("Could not match the arguments with the template args."); } catch (InstantiationException e) { // e.printStackTrace(); throw new RuntimeException("Could not instantiate the template object. Abstract?"); } catch (InvocationTargetException e) { // e.printStackTrace(); Throwable e1 = e.getTargetException(); throw new RuntimeException("Could not invoke the template object: ", e1); } catch (Exception e) { if (e instanceof RuntimeException) throw (RuntimeException) e; else throw new RuntimeException("Could not invoke the template object: ", e); // throw new RuntimeException(e); } } }