public static String generate(XNode x, Map<String, String> expressions, Map<String, String> constants, Class<?> modelType) { String body; switch (x.op) { case OP_ROOT: return "{" + join("", x.children, expressions, constants, modelType) + "}"; case OP_TEXT: return U.notEmpty(x.text) ? print(literal(x.text), constants) : ""; case OP_PRINT: return val(x.text, true, expressions); case OP_PRINT_RAW: return val(x.text, false, expressions); case OP_IF_NOT: body = join("", x.children, expressions, constants, modelType); return U.frmt("if (!$1.cond(%s)) { %s }", literal(x.text), body); case OP_IF: body = join("", x.children, expressions, constants, modelType); return U.frmt("if ($1.cond(%s)) { %s }", literal(x.text), body); case OP_INCLUDE: return U.frmt("$1.call(%s);", literal(x.text)); case OP_FOREACH: body = join("", x.children, expressions, constants, modelType); String retrId = expr(expressions, x.text); return iterList(body, retrId); default: throw Err.notExpected(); } }
private static String join(String separator, List<XNode> nodes, Map<String, String> expressions, Map<String, String> constants, Class<?> modelType) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < nodes.size(); i++) { if (i > 0) { sb.append(separator); } String code = TemplateToCode.generate(nodes.get(i), expressions, constants, modelType); sb.append(code); } return sb.toString(); }
private static String iterArr(String body, String retrId) { String arr = "v" + ID_GEN.incrementAndGet(); String ind = "v" + ID_GEN.incrementAndGet(); String code = "Object[] %s = $1.iter(%s);" + " for (int %s = 0; %s < %s.length; %s++) {\n" + " %s\n }"; return U.frmt(code, arr, retrId, ind, ind, arr, ind, scopedArr(ind, arr, body)); }
static String val(String s, boolean escape, Map<String, String> expressions) { String[] parts = s.split("\\|\\|", 2); if (parts.length == 2) { String prop = parts[0]; String orElse = literal(parts[1]); String retrId = expr(expressions, prop); return U.frmt("$1.valOr(%s, %s, %s);\n", retrId, orElse, escape); } else { String retrId = expr(expressions, s); return U.frmt("$1.val(%s, %s);\n", retrId, escape); } }
private static String iterList(String body, String retrId) { String list = "v" + ID_GEN.incrementAndGet(); String ind = "v" + ID_GEN.incrementAndGet(); String code = "java.util.List %s = $1.iter(%s);" + " for (int %s = 0; %s < %s.size(); %s++) {\n" + " %s\n }"; return U.frmt(code, list, retrId, ind, ind, list, ind, scopedList(ind, list, body)); }
private static String expr(Map<String, String> expressions, String expr) { expressions.put(expr, literal(expr)); return TemplateCompiler.retrieverId(expr); }
private static String eachIter(String body, String retrId) { String it = "v" + ID_GEN.incrementAndGet(); String var = "v" + ID_GEN.incrementAndGet(); String ind = "v" + ID_GEN.incrementAndGet(); String insideBody = scopedIter(ind, var, body); String code = "java.util.Iterator %s = $1.iter(%s);\n" // it, retrId + "int %s = 0;\n " // ind + "while (%s.hasNext()) {\n" // it + "Object %s = %s.next();\n" // var, it + " %s++;\n" // ind + "%s\n }"; return U.frmt(code, it, retrId, ind, it, var, it, ind, insideBody); }
static String val(String s, boolean escape, Map<String, String> expressions) { String[] parts = s.split("\\|\\|", 2); if (parts.length == 2) { String prop = parts[0]; String orElse = literal(parts[1]); String retrId = expr(expressions, prop); return U.frmt("$1.valOr(%s, %s, %s);\n", retrId, orElse, escape); } else { String retrId = expr(expressions, s); return U.frmt("$1.val(%s, %s);\n", retrId, escape); } }
private static String iterList(String body, String retrId) { String list = "v" + ID_GEN.incrementAndGet(); String ind = "v" + ID_GEN.incrementAndGet(); String code = "java.util.List %s = $1.iter(%s);" + " for (int %s = 0; %s < %s.size(); %s++) {\n" + " %s\n }"; return U.frmt(code, list, retrId, ind, ind, list, ind, scopedList(ind, list, body)); }
private static String expr(Map<String, String> expressions, String expr) { expressions.put(expr, literal(expr)); return TemplateCompiler.retrieverId(expr); }
private static String eachIter(String body, String retrId) { String it = "v" + ID_GEN.incrementAndGet(); String var = "v" + ID_GEN.incrementAndGet(); String ind = "v" + ID_GEN.incrementAndGet(); String insideBody = scopedIter(ind, var, body); String code = "java.util.Iterator %s = $1.iter(%s);\n" // it, retrId + "int %s = 0;\n " // ind + "while (%s.hasNext()) {\n" // it + "Object %s = %s.next();\n" // var, it + " %s++;\n" // ind + "%s\n }"; return U.frmt(code, it, retrId, ind, it, var, it, ind, insideBody); }
public static String generate(XNode x, Map<String, String> expressions, Map<String, String> constants, Class<?> modelType) { String body; switch (x.op) { case OP_ROOT: return "{" + join("", x.children, expressions, constants, modelType) + "}"; case OP_TEXT: return U.notEmpty(x.text) ? print(literal(x.text), constants) : ""; case OP_PRINT: return val(x.text, true, expressions); case OP_PRINT_RAW: return val(x.text, false, expressions); case OP_IF_NOT: body = join("", x.children, expressions, constants, modelType); return U.frmt("if (!$1.cond(%s)) { %s }", literal(x.text), body); case OP_IF: body = join("", x.children, expressions, constants, modelType); return U.frmt("if ($1.cond(%s)) { %s }", literal(x.text), body); case OP_INCLUDE: return U.frmt("$1.call(%s);", literal(x.text)); case OP_FOREACH: body = join("", x.children, expressions, constants, modelType); String retrId = expr(expressions, x.text); return iterList(body, retrId); default: throw Err.notExpected(); } }
public static TemplateRenderer compile(XNode node, Class<?> modelType) { try { Map<String, String> expressions = U.map(); Map<String, String> constants = U.map(); String source = TemplateToCode.generate(node, expressions, constants, modelType); return tryToCompile(source, expressions, constants, modelType); } catch (Exception e) { throw U.rte(e); } }
private static String iterArr(String body, String retrId) { String arr = "v" + ID_GEN.incrementAndGet(); String ind = "v" + ID_GEN.incrementAndGet(); String code = "Object[] %s = $1.iter(%s);" + " for (int %s = 0; %s < %s.length; %s++) {\n" + " %s\n }"; return U.frmt(code, arr, retrId, ind, ind, arr, ind, scopedArr(ind, arr, body)); }
private static String join(String separator, List<XNode> nodes, Map<String, String> expressions, Map<String, String> constants, Class<?> modelType) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < nodes.size(); i++) { if (i > 0) { sb.append(separator); } String code = TemplateToCode.generate(nodes.get(i), expressions, constants, modelType); sb.append(code); } return sb.toString(); }
public static TemplateRenderer compile(XNode node, Class<?> modelType) { try { Map<String, String> expressions = U.map(); Map<String, String> constants = U.map(); String source = TemplateToCode.generate(node, expressions, constants, modelType); return tryToCompile(source, expressions, constants, modelType); } catch (Exception e) { throw U.rte(e); } }