diff --git a/scm-core/src/main/java/sonia/scm/template/TemplateEngine.java b/scm-core/src/main/java/sonia/scm/template/TemplateEngine.java index d3649e445e..bfeca8f42c 100644 --- a/scm-core/src/main/java/sonia/scm/template/TemplateEngine.java +++ b/scm-core/src/main/java/sonia/scm/template/TemplateEngine.java @@ -30,28 +30,30 @@ */ + package sonia.scm.template; //~--- JDK imports ------------------------------------------------------------ import java.io.IOException; +import java.io.Reader; /** - * The {@link TemplateEngine} searches for {@link Template}s and prepares the + * The {@link TemplateEngine} searches for {@link Template}s and prepares the * template for the rendering process. * * @author Sebastian Sdorra * @since 1.19 - * + * * @apiviz.uses sonia.scm.template.Template */ public interface TemplateEngine { /** - * Returns the template associated with the given path. The template engine - * will search the template in the folder of the web application and in - * the classpath. This method will return null, + * Returns the template associated with the given path. The template engine + * will search the template in the folder of the web application and in + * the classpath. This method will return null, * if no template could be found for the given path. * * @@ -63,6 +65,23 @@ public interface TemplateEngine */ public Template getTemplate(String templatePath) throws IOException; + /** + * Creates a template of the given reader. Note some template implementations + * will cache the template by its id. + * + * + * @param templateIdentifier id of the template + * @param reader template reader + * + * @return template created from the reader + * + * @throws IOException + * + * @since 1.22 + */ + public Template getTemplate(String templateIdentifier, Reader reader) + throws IOException; + /** * Returns the type of this template engine. * diff --git a/scm-core/src/test/java/sonia/scm/template/TemplateEngineFactoryTest.java b/scm-core/src/test/java/sonia/scm/template/TemplateEngineFactoryTest.java index 9eb47aa061..b676b4bbaf 100644 --- a/scm-core/src/test/java/sonia/scm/template/TemplateEngineFactoryTest.java +++ b/scm-core/src/test/java/sonia/scm/template/TemplateEngineFactoryTest.java @@ -30,6 +30,7 @@ */ + package sonia.scm.template; //~--- non-JDK imports -------------------------------------------------------- @@ -43,6 +44,7 @@ import static org.junit.Assert.*; //~--- JDK imports ------------------------------------------------------------ import java.io.IOException; +import java.io.Reader; import java.util.Collection; import java.util.HashSet; @@ -166,6 +168,24 @@ public class TemplateEngineFactoryTest throw new UnsupportedOperationException("Not supported yet."); } + /** + * Method description + * + * + * @param templateIdentifier + * @param reader + * + * @return + * + * @throws IOException + */ + @Override + public Template getTemplate(String templateIdentifier, Reader reader) + throws IOException + { + throw new UnsupportedOperationException("Not supported yet."); + } + /** * Method description * @@ -190,6 +210,24 @@ public class TemplateEngineFactoryTest private static class FakeTemplateEngine2 implements TemplateEngine { + /** + * Method description + * + * + * @param templateIdentifier + * @param reader + * + * @return + * + * @throws IOException + */ + @Override + public Template getTemplate(String templateIdentifier, Reader reader) + throws IOException + { + throw new UnsupportedOperationException("Not supported yet."); + } + /** * Method description * diff --git a/scm-webapp/src/main/java/sonia/scm/template/FreemarkerTemplateEngine.java b/scm-webapp/src/main/java/sonia/scm/template/FreemarkerTemplateEngine.java index 23c875bac3..b247159169 100644 --- a/scm-webapp/src/main/java/sonia/scm/template/FreemarkerTemplateEngine.java +++ b/scm-webapp/src/main/java/sonia/scm/template/FreemarkerTemplateEngine.java @@ -51,6 +51,7 @@ import org.slf4j.LoggerFactory; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.Reader; import java.util.Locale; @@ -152,6 +153,34 @@ public class FreemarkerTemplateEngine implements TemplateEngine return template; } + /** + * Method description + * + * + * @param templateIdentifier + * @param reader + * + * @return + * + * @throws IOException + */ + @Override + public Template getTemplate(String templateIdentifier, Reader reader) + throws IOException + { + if (logger.isTraceEnabled()) + { + logger.trace("try to create freemarker template from reader with id {}", + templateIdentifier); + } + + freemarker.template.Template t = + new freemarker.template.Template(templateIdentifier, reader, + configuration, ENCODING); + + return new FreemarkerTemplate(t); + } + /** * Method description * diff --git a/scm-webapp/src/main/java/sonia/scm/template/MustacheTemplateEngine.java b/scm-webapp/src/main/java/sonia/scm/template/MustacheTemplateEngine.java index e0b56cd824..60085664a1 100644 --- a/scm-webapp/src/main/java/sonia/scm/template/MustacheTemplateEngine.java +++ b/scm-webapp/src/main/java/sonia/scm/template/MustacheTemplateEngine.java @@ -47,6 +47,7 @@ import org.slf4j.LoggerFactory; //~--- JDK imports ------------------------------------------------------------ import java.io.IOException; +import java.io.Reader; import java.util.concurrent.Executors; @@ -87,6 +88,32 @@ public class MustacheTemplateEngine implements TemplateEngine //~--- get methods ---------------------------------------------------------- + /** + * Method description + * + * + * @param templateIdentifier + * @param reader + * + * @return + * + * @throws IOException + */ + @Override + public Template getTemplate(String templateIdentifier, Reader reader) + throws IOException + { + if (logger.isTraceEnabled()) + { + logger.trace("try to create mustache template from reader with id {}", + templateIdentifier); + } + + Mustache mustache = factory.compile(reader, templateIdentifier); + + return new MustacheTemplate(templateIdentifier, mustache); + } + /** * Method description * diff --git a/scm-webapp/src/test/java/sonia/scm/template/FreemarkerTemplateEngineTest.java b/scm-webapp/src/test/java/sonia/scm/template/FreemarkerTemplateEngineTest.java index ecb9b6270a..34e1a54d7a 100644 --- a/scm-webapp/src/test/java/sonia/scm/template/FreemarkerTemplateEngineTest.java +++ b/scm-webapp/src/test/java/sonia/scm/template/FreemarkerTemplateEngineTest.java @@ -30,10 +30,13 @@ */ + package sonia.scm.template; //~--- JDK imports ------------------------------------------------------------ +import java.io.InputStream; + import javax.servlet.ServletContext; /** @@ -82,4 +85,19 @@ public class FreemarkerTemplateEngineTest extends TemplateEngineTestBase { return "sonia/scm/template/002.ftl"; } + + /** + * Method description + * + * + * @param resource + * + * @return + */ + @Override + protected InputStream getResource(String resource) + { + return FreemarkerTemplateEngineTest.class.getResourceAsStream( + "/sonia/scm/template/".concat(resource).concat(".ftl")); + } } diff --git a/scm-webapp/src/test/java/sonia/scm/template/MustacheTemplateEngineTest.java b/scm-webapp/src/test/java/sonia/scm/template/MustacheTemplateEngineTest.java index 4d1d15de49..c53a5183c7 100644 --- a/scm-webapp/src/test/java/sonia/scm/template/MustacheTemplateEngineTest.java +++ b/scm-webapp/src/test/java/sonia/scm/template/MustacheTemplateEngineTest.java @@ -30,10 +30,13 @@ */ + package sonia.scm.template; //~--- JDK imports ------------------------------------------------------------ +import java.io.InputStream; + import javax.servlet.ServletContext; /** @@ -82,4 +85,19 @@ public class MustacheTemplateEngineTest extends TemplateEngineTestBase { return "sonia/scm/template/001.mustache"; } + + /** + * Method description + * + * + * @param resource + * + * @return + */ + @Override + protected InputStream getResource(String resource) + { + return MustacheTemplateEngineTest.class.getResourceAsStream( + "/sonia/scm/template/".concat(resource).concat(".mustache")); + } } diff --git a/scm-webapp/src/test/java/sonia/scm/template/TemplateEngineTestBase.java b/scm-webapp/src/test/java/sonia/scm/template/TemplateEngineTestBase.java index 0be0908581..29e3d0c8cc 100644 --- a/scm-webapp/src/test/java/sonia/scm/template/TemplateEngineTestBase.java +++ b/scm-webapp/src/test/java/sonia/scm/template/TemplateEngineTestBase.java @@ -30,10 +30,12 @@ */ + package sonia.scm.template; //~--- non-JDK imports -------------------------------------------------------- +import com.google.common.collect.Maps; import com.google.common.io.Closeables; import org.junit.Test; @@ -46,9 +48,13 @@ import static org.mockito.Mockito.*; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringWriter; import java.net.URL; +import java.util.Map; + import javax.servlet.ServletContext; /** @@ -86,6 +92,16 @@ public abstract class TemplateEngineTestBase */ public abstract String getTemplateResource(); + /** + * Method description + * + * + * @param resource + * + * @return + */ + protected abstract InputStream getResource(String resource); + //~--- methods -------------------------------------------------------------- /** @@ -135,6 +151,45 @@ public abstract class TemplateEngineTestBase assertNotNull(engine.getTemplate(getTemplateResource())); } + /** + * Method description + * + * + * @throws IOException + */ + @Test + public void testGetTemplateFromReader() throws IOException + { + ServletContext context = mock(ServletContext.class); + TemplateEngine engine = createEngine(context); + + InputStream input = null; + + try + { + input = getResource("007"); + + Template template = engine.getTemplate("007", + new InputStreamReader(input)); + + assertNotNull(template); + + Map env = Maps.newHashMap(); + + env.put("time", "Lunchtime"); + + StringWriter writer = new StringWriter(); + + template.execute(writer, env); + assertEquals("Time is an illusion. Lunchtime doubly so.", + writer.toString()); + } + finally + { + Closeables.closeQuietly(input); + } + } + /** * Method description * diff --git a/scm-webapp/src/test/resources/sonia/scm/template/007.ftl b/scm-webapp/src/test/resources/sonia/scm/template/007.ftl new file mode 100644 index 0000000000..a256c0b966 --- /dev/null +++ b/scm-webapp/src/test/resources/sonia/scm/template/007.ftl @@ -0,0 +1 @@ +Time is an illusion. ${time} doubly so. \ No newline at end of file diff --git a/scm-webapp/src/test/resources/sonia/scm/template/007.mustache b/scm-webapp/src/test/resources/sonia/scm/template/007.mustache new file mode 100644 index 0000000000..fec988010e --- /dev/null +++ b/scm-webapp/src/test/resources/sonia/scm/template/007.mustache @@ -0,0 +1 @@ +Time is an illusion. {{time}} doubly so. \ No newline at end of file