commit 0ea43eb64bac1ede702a657a50d38d76fe45e3f3 Author: Dan Callaghan <djc@djc.id.au> Date: Fri, 7 May 2010 17:52:32 +1000 extracted stringtemplate bits; added support for custom AttributeRenderers Diffstat:
A | pom.xml | | | 92 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/main/java/au/id/djc/stringtemplate/AttributeRenderer.java | | | 7 | +++++++ |
A | src/main/java/au/id/djc/stringtemplate/LoggingStringTemplateErrorListener.java | | | 21 | +++++++++++++++++++++ |
A | src/main/java/au/id/djc/stringtemplate/webmvc/StringTemplateView.java | | | 65 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/main/java/au/id/djc/stringtemplate/webmvc/StringTemplateViewResolver.java | | | 72 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
5 files changed, 257 insertions(+), 0 deletions(-) diff --git a/pom.xml b/pom.xml @@ -0,0 +1,92 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>au.id.djc</groupId> + <artifactId>stringtemplate-spring</artifactId> + <packaging>jar</packaging> + <version>1.0-SNAPSHOT</version> + + <name>StringTemplate Spring integration</name> + + <properties> + <spring.version>3.0.2.RELEASE</spring.version> + </properties> + + <build> + <pluginManagement> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.6</source> + <target>1.6</target> + <showDeprecation>true</showDeprecation> + <showWarnings>true</showWarnings> + <encoding>UTF-8</encoding> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <configuration> + <encoding>UTF-8</encoding> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + <executions> + <execution> + <id>attach-sources</id> + <goals> + <goal>jar</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </pluginManagement> + </build> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.8.1</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.antlr</groupId> + <artifactId>stringtemplate</artifactId> + <version>3.2.1</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-beans</artifactId> + <version>${spring.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + <version>${spring.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-web</artifactId> + <version>${spring.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-webmvc</artifactId> + <version>${spring.version}</version> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + <version>2.5</version> + <scope>provided</scope> + </dependency> + </dependencies> + +</project> diff --git a/src/main/java/au/id/djc/stringtemplate/AttributeRenderer.java b/src/main/java/au/id/djc/stringtemplate/AttributeRenderer.java @@ -0,0 +1,7 @@ +package au.id.djc.stringtemplate; + +public interface AttributeRenderer extends org.antlr.stringtemplate.AttributeRenderer { + + public Class<?> getTargetClass(); + +} diff --git a/src/main/java/au/id/djc/stringtemplate/LoggingStringTemplateErrorListener.java b/src/main/java/au/id/djc/stringtemplate/LoggingStringTemplateErrorListener.java @@ -0,0 +1,21 @@ +package au.id.djc.stringtemplate; + +import java.util.logging.Logger; + +import org.antlr.stringtemplate.StringTemplateErrorListener; + +public class LoggingStringTemplateErrorListener implements StringTemplateErrorListener { + + private static final Logger LOG = Logger.getLogger(LoggingStringTemplateErrorListener.class.getName()); + + @Override + public void error(String msg, Throwable e) { + throw new RuntimeException(e); + } + + @Override + public void warning(String msg) { + LOG.warning(msg); + } + +} diff --git a/src/main/java/au/id/djc/stringtemplate/webmvc/StringTemplateView.java b/src/main/java/au/id/djc/stringtemplate/webmvc/StringTemplateView.java @@ -0,0 +1,65 @@ +package au.id.djc.stringtemplate.webmvc; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.nio.charset.Charset; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.antlr.stringtemplate.StringTemplate; +import org.antlr.stringtemplate.StringTemplateErrorListener; +import org.antlr.stringtemplate.StringTemplateGroup; +import org.antlr.stringtemplate.language.DefaultTemplateLexer; +import org.springframework.web.servlet.view.AbstractTemplateView; + +import au.id.djc.stringtemplate.AttributeRenderer; + +public class StringTemplateView extends AbstractTemplateView { + + private String rootTemplateName = "root"; + private Charset charset = Charset.defaultCharset(); + private StringTemplateErrorListener errorListener; + private List<AttributeRenderer> attributeRenderers; + + public void setRootTemplateName(String rootTemplateName) { + this.rootTemplateName = rootTemplateName; + } + + public void setCharset(Charset charset) { + this.charset = charset; + } + + public void setErrorListener(StringTemplateErrorListener errorListener) { + this.errorListener = errorListener; + } + + public void setAttributeRenderers(List<AttributeRenderer> attributeRenderers) { + this.attributeRenderers = attributeRenderers; + } + + @Override + public boolean checkResource(Locale locale) throws Exception { + return getClass().getResourceAsStream(getUrl()) != null; + } + + @Override + protected void renderMergedTemplateModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) + throws Exception { + InputStream groupStream = getClass().getResourceAsStream(getUrl()); + StringTemplateGroup templateGroup = new StringTemplateGroup(new InputStreamReader(groupStream, charset), + DefaultTemplateLexer.class, errorListener); + for (AttributeRenderer attributeRenderer: attributeRenderers) { + templateGroup.registerRenderer(attributeRenderer.getTargetClass(), attributeRenderer); + } + StringTemplate template = templateGroup.getInstanceOf(rootTemplateName); + template.setAttributes(model); + PrintWriter writer = response.getWriter(); + writer.print(template); + } + +} diff --git a/src/main/java/au/id/djc/stringtemplate/webmvc/StringTemplateViewResolver.java b/src/main/java/au/id/djc/stringtemplate/webmvc/StringTemplateViewResolver.java @@ -0,0 +1,72 @@ +package au.id.djc.stringtemplate.webmvc; + +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; + +import org.antlr.stringtemplate.StringTemplateErrorListener; +import org.springframework.beans.factory.BeanFactoryUtils; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.web.servlet.view.AbstractTemplateViewResolver; +import org.springframework.web.servlet.view.AbstractUrlBasedView; + +import au.id.djc.stringtemplate.AttributeRenderer; + +public class StringTemplateViewResolver extends AbstractTemplateViewResolver implements InitializingBean { + + private String rootTemplateName; + private Charset charset; + private StringTemplateErrorListener errorListener; + private List<AttributeRenderer> attributeRenderers; + + @Override + public void afterPropertiesSet() throws Exception { + if (errorListener == null) { + throw new IllegalArgumentException("Property 'errorListener' is required"); + } + if (attributeRenderers == null) { + attributeRenderers = new ArrayList<AttributeRenderer>( + BeanFactoryUtils.beansOfTypeIncludingAncestors(getApplicationContext(), AttributeRenderer.class).values()); + } + } + + public void setRootTemplateName(String rootTemplateName) { + this.rootTemplateName = rootTemplateName; + } + + public void setCharset(Charset charset) { + this.charset = charset; + } + + public void setErrorListener(StringTemplateErrorListener errorListener) { + this.errorListener = errorListener; + } + + /** + * If this property is not set, the default behaviour is to use all + * {@link AttributeRenderer} implementations in the current context. + */ + public void setAttributeRenderers(List<AttributeRenderer> attributeRenderers) { + this.attributeRenderers = attributeRenderers; + } + + public StringTemplateViewResolver() { + setViewClass(requiredViewClass()); + } + + @Override + protected Class<?> requiredViewClass() { + return StringTemplateView.class; + } + + @Override + protected AbstractUrlBasedView buildView(String viewName) throws Exception { + StringTemplateView view = (StringTemplateView) super.buildView(viewName); + if (rootTemplateName != null) view.setRootTemplateName(rootTemplateName); + if (charset != null) view.setCharset(charset); + view.setErrorListener(errorListener); + view.setAttributeRenderers(attributeRenderers); + return view; + } + +}