package org.webpieces.templating.impl; import java.io.PrintWriter; import java.io.StringWriter; import java.util.HashMap; import java.util.Map; import javax.inject.Inject; import org.webpieces.templating.api.HtmlTagLookup; import org.webpieces.templating.api.RouterLookup; import org.webpieces.templating.api.Template; import org.webpieces.templating.api.TemplateResult; import org.webpieces.templating.api.TemplateService; import org.webpieces.templating.api.TemplateUtil; public class ProdTemplateService implements TemplateService { private HtmlTagLookup lookup; private boolean isInitialized = false; protected RouterLookup urlLookup; @Inject public ProdTemplateService(RouterLookup urlLookup, HtmlTagLookup lookup) { this.urlLookup = urlLookup; this.lookup = lookup; } @Override public void loadAndRunTemplate(String templatePath, StringWriter out, Map<String, Object> pageArgs) { Template template = loadTemplate(templatePath); runTemplate(template, out, pageArgs); } @Override public String loadAndRunTemplate(String templatePath, Map<String, Object> pageArgs, Map<Object, Object> setTagProps) { Template template = loadTemplate(templatePath); return runTemplate(template, pageArgs, setTagProps); } protected final Template loadTemplate(String templatePath) { if(!templatePath.startsWith("/")) throw new IllegalArgumentException("templatePath must start with / and be absolute reference from base of classpath"); else if(templatePath.contains("_")) throw new IllegalArgumentException("template names cannot contain _ in them(This is reserved for _extension in the classname). name="+templatePath); if(!isInitialized) { lookup.initialize(this); isInitialized = true; } String fullClassName = TemplateUtil.convertTemplatePathToClass(templatePath); return loadTemplate(templatePath, fullClassName); } protected Template loadTemplate(String fullTemplatePath, String fullClassName) { ClassLoader cl = getClass().getClassLoader(); try { Class<?> compiledTemplate = cl.loadClass(fullClassName); return new TemplateImpl(urlLookup, lookup, compiledTemplate); } catch(ClassNotFoundException e) { throw new RuntimeException(e); } } protected final void runTemplate(Template template, StringWriter out, Map<String, Object> pageArgs) { String result = runTemplate(template, pageArgs, new HashMap<>()); out.write(result); } public String runTemplate(Template template, Map<String, Object> pageArgs, Map<Object, Object> setTagProps) { Map<String, Object> copy = new HashMap<>(pageArgs); StringWriter out = new StringWriter(); PrintWriter writer = new PrintWriter(out); copy.put(GroovyTemplateSuperclass.OUT_PROPERTY_NAME, writer); TemplateResult info = template.run(copy, setTagProps); //cache results of writer into templateProps for body so that template can use #{get 'body'}# Map<Object, Object> setTagProperties = info.getSetTagProperties(); setTagProperties.put("body", out.toString()); String className = info.getTemplateClassName(); String templatePath = TemplateUtil.convertTemplateClassToPath(className); String superTemplateFilePath = info.getSuperTemplateClassName(); try { if(superTemplateFilePath != null) { return loadAndRunTemplate(superTemplateFilePath, pageArgs, setTagProperties); } else return out.toString(); } catch(Exception e) { throw new RuntimeException("template failed="+superTemplateFilePath+" called from template=" +templatePath+" See below exception messages for more information", e); } } }