public void compile() { if (compiledTemplate == null) { try { long start = System.currentTimeMillis(); TClassLoader tClassLoader = new TClassLoader(); // Let's compile the groovy source final List<GroovyClass> groovyClassesForThisTemplate = new ArrayList<GroovyClass>(); // ~~~ Please ! CompilerConfiguration compilerConfiguration = new CompilerConfiguration(); compilerConfiguration.setSourceEncoding("utf-8"); // ouf CompilationUnit compilationUnit = new CompilationUnit(compilerConfiguration); compilationUnit.addSource(new SourceUnit(name, compiledSource, compilerConfiguration, tClassLoader, compilationUnit.getErrorCollector())); Field phasesF = compilationUnit.getClass().getDeclaredField("phaseOperations"); phasesF.setAccessible(true); LinkedList[] phases = (LinkedList[]) phasesF.get(compilationUnit); LinkedList<GroovyClassOperation> output = new LinkedList<GroovyClassOperation>(); phases[Phases.OUTPUT] = output; output.add(new GroovyClassOperation() { public void call(GroovyClass gclass) { groovyClassesForThisTemplate.add(gclass); } }); compilationUnit.compile(); // ouf // Define script classes StringBuilder sb = new StringBuilder(); sb.append("LINESMATRIX" + "\n"); sb.append(Codec.encodeBASE64(Java.serialize(linesMatrix)).replaceAll("\\s", "")); sb.append("\n"); sb.append("DOBODYLINES" + "\n"); sb.append(Codec.encodeBASE64(Java.serialize(doBodyLines)).replaceAll("\\s", "")); sb.append("\n"); for (GroovyClass gclass : groovyClassesForThisTemplate) { tClassLoader.defineTemplate(gclass.getName(), gclass.getBytes()); sb.append(gclass.getName() + "\n"); sb.append(Codec.encodeBASE64(gclass.getBytes()).replaceAll("\\s", "")); sb.append("\n"); } // Cache BytecodeCache.cacheBytecode(sb.toString().getBytes("utf-8"), name, source); compiledTemplate = tClassLoader.loadClass(groovyClassesForThisTemplate.get(0).getName()); if (System.getProperty("precompile") != null) { try { // emit bytecode to standard class layout as well File f = Play.getFile("precompiled/templates/" + name.replaceAll("\\{(.*)\\}", "from_$1").replace(":", "_").replace("..", "parent")); f.getParentFile().mkdirs(); FileOutputStream fos = new FileOutputStream(f); fos.write(sb.toString().getBytes("utf-8")); fos.close(); } catch (Exception e) { e.printStackTrace(); } } Logger.trace("%sms to compile template %s to %d classes", System.currentTimeMillis() - start, name, groovyClassesForThisTemplate.size()); } catch (MultipleCompilationErrorsException e) { if (e.getErrorCollector().getLastError() != null) { SyntaxErrorMessage errorMessage = (SyntaxErrorMessage) e.getErrorCollector().getLastError(); SyntaxException syntaxException = errorMessage.getCause(); Integer line = this.linesMatrix.get(syntaxException.getLine()); if (line == null) { line = 0; } String message = syntaxException.getMessage(); if (message.indexOf("@") > 0) { message = message.substring(0, message.lastIndexOf("@")); } throw new TemplateCompilationException(this, line, message); } throw new UnexpectedException(e); } catch (Exception e) { throw new UnexpectedException(e); } } compiledTemplateName = compiledTemplate.getName(); }
public String render(Map<String, Object> args) { compile(); Binding binding = new Binding(args); binding.setVariable("play", new Play()); binding.setVariable("messages", new Messages()); binding.setVariable("lang", Lang.get()); StringWriter writer = null; Boolean applyLayouts = false; if (!args.containsKey("out")) { applyLayouts = true; layout.set(null); writer = new StringWriter(); binding.setProperty("out", new PrintWriter(writer)); currentTemplate.set(this); } if (!args.containsKey("_body") && !args.containsKey("_isLayout") && !args.containsKey("_isInclude")) { layoutData.set(new HashMap<Object, Object>()); TagContext.init(); } ExecutableTemplate t = (ExecutableTemplate) InvokerHelper.createScript(compiledTemplate, binding); t.template = this; Monitor monitor = null; try { monitor = MonitorFactory.start(name); long start = System.currentTimeMillis(); t.run(); monitor.stop(); monitor = null; Logger.trace("%sms to render template %s", System.currentTimeMillis() - start, name); } catch (NoRouteFoundException e) { if (e.isSourceAvailable()) { throw e; } throwException(e); } catch (PlayException e) { throw (PlayException) cleanStackTrace(e); } catch (DoBodyException e) { if (Play.mode == Mode.DEV) { compiledTemplate = null; BytecodeCache.deleteBytecode(name); } Exception ex = (Exception) e.getCause(); throwException(ex); } catch (Throwable e) { if (Play.mode == Mode.DEV) { compiledTemplate = null; BytecodeCache.deleteBytecode(name); } throwException(e); } finally { if (monitor != null) { monitor.stop(); } } if (applyLayouts && layout.get() != null) { Map<String, Object> layoutArgs = new HashMap<String, Object>(args); layoutArgs.remove("out"); layoutArgs.put("_isLayout", true); String layoutR = layout.get().render(layoutArgs); return layoutR.replace("____%LAYOUT%____", writer.toString().trim()); } if (writer != null) { return writer.toString(); } return null; }