package org.rendersnake;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.antlr.stringtemplate.NoIndentWriter;
import org.rendersnake.internal.RenderableAttributeRenderer;
/**
* StringTemplate is a Renderable component that encapsulates a String template.
* This template may contain attribute references that are filled with values found in the PageContext of the HtmlCanvas.
* Templates are read from file resources found on the classpath (using @see StringResource).
* The syntax rules for attribute references in a template can be found at
* <a href="http://www.antlr.org/wiki/display/ST/Expressions">StringTemplate expressions</a>.
*
* Usage:
* <pre>
* html.getPageContext().set("today", new Date());
* ProductListUI productList = new ProductListUI(products);
* html.getPageContext().set("productList", new RenderableAttribute(html,productList));
*
* // the template will contain references to the attributes "today" (a Date) and "productList" (a Renderable)
* html.render(StringTemplate.get("templates/productlistpage.html"));
* </pre>
*
* @author ernestmicklei
*/
public class StringTemplate implements Renderable {
/**
* Cache of template content read from resources on the classpath.
*/
private final static Map<String, StringTemplate> CACHE = new HashMap<String, StringTemplate>();
/**
* Intention revealing constant to emphasize that caching for an item is not needed
*/
public final static boolean DO_NOT_CACHE = false;
/**
* The actual template instance that can perform the transformation to the output String content.
*/
private org.antlr.stringtemplate.StringTemplate template;
/**
* Access the StringTemplate constructed from the given resource location.
* @param location
* @return resource contents , never null
*/
public static StringTemplate get(String location) {
return get(location, true);
}
/**
* Access the StringTemplate constructed from the given resource location.
* @param location
* @param doCache
* @return resource contents , never null
*/
public static StringTemplate get(String location, boolean doCache) {
StringTemplate st = null;
if (doCache) {
st = CACHE.get(location);
}
if (st == null) {
String src = StringResource.get(location,false);
if (src == null) {
src = "[StringTemplate] Missing or error reading resource:" + location;
} else {
st = new StringTemplate();
st.template = new org.antlr.stringtemplate.StringTemplate(src);
st.template.registerRenderer(RenderableAttribute.class, new RenderableAttributeRenderer());
if (doCache) {
synchronized (CACHE) {
CACHE.put(location, st);
}
}
}
}
return st;
}
public void renderOn(HtmlCanvas canvas) throws IOException {
// provide the complete context variables map to the template
template.setAttributes(canvas.getPageContext().attributes);
template.write(new NoIndentWriter(canvas.getOutputWriter()));
}
}