From 4c91ef010058742940399b3e7e42d6c67cc45600 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 12 Jun 2019 17:04:32 +0200 Subject: [PATCH] make PluginLoader dependency of MustacheTemplateEngine optional --- .../scm/template/MustacheTemplateEngine.java | 36 +++++++++++-------- .../scm/template/ServletMustacheFactory.java | 23 +++++------- .../template/MustacheTemplateEngineTest.java | 34 ++++++++++++++---- 3 files changed, 57 insertions(+), 36 deletions(-) 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 06bd8b0f62..170c0cd641 100644 --- a/scm-webapp/src/main/java/sonia/scm/template/MustacheTemplateEngine.java +++ b/scm-webapp/src/main/java/sonia/scm/template/MustacheTemplateEngine.java @@ -37,27 +37,22 @@ package sonia.scm.template; import com.github.mustachejava.Mustache; import com.github.mustachejava.MustacheException; - import com.google.common.base.Throwables; import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.google.common.util.concurrent.UncheckedExecutionException; import com.google.inject.Inject; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import sonia.scm.Default; import sonia.scm.plugin.PluginLoader; -//~--- JDK imports ------------------------------------------------------------ - +import javax.servlet.ServletContext; import java.io.IOException; import java.io.Reader; - import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; -import javax.servlet.ServletContext; +//~--- JDK imports ------------------------------------------------------------ /** * @@ -67,6 +62,14 @@ import javax.servlet.ServletContext; public class MustacheTemplateEngine implements TemplateEngine { + /** + * Used to implement optional injection for the PluginLoader. + * @see Optional Injection + */ + static class PluginLoaderHolder { + @Inject(optional = true) PluginLoader pluginLoader; + } + /** Field description */ public static final TemplateType TYPE = new TemplateType("mustache", "Mustache", "mustache"); @@ -87,13 +90,12 @@ public class MustacheTemplateEngine implements TemplateEngine * * * @param context - * @param pluginLoader + * @param pluginLoaderHolder */ @Inject - public MustacheTemplateEngine(@Default ServletContext context, - PluginLoader pluginLoader) + public MustacheTemplateEngine(@Default ServletContext context, PluginLoaderHolder pluginLoaderHolder) { - factory = new ServletMustacheFactory(context, pluginLoader); + factory = new ServletMustacheFactory(context, createClassLoader(pluginLoaderHolder.pluginLoader)); ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat(THREAD_NAME).build(); @@ -101,6 +103,13 @@ public class MustacheTemplateEngine implements TemplateEngine factory.setExecutorService(Executors.newCachedThreadPool(threadFactory)); } + private ClassLoader createClassLoader(PluginLoader pluginLoader) { + if (pluginLoader == null) { + return Thread.currentThread().getContextClassLoader(); + } + return pluginLoader.getUberClassLoader(); + } + //~--- get methods ---------------------------------------------------------- /** @@ -112,12 +121,9 @@ public class MustacheTemplateEngine implements TemplateEngine * * @return * - * @throws IOException */ @Override - public Template getTemplate(String templateIdentifier, Reader reader) - throws IOException - { + public Template getTemplate(String templateIdentifier, Reader reader) { if (logger.isTraceEnabled()) { logger.trace("try to create mustache template from reader with id {}", diff --git a/scm-webapp/src/main/java/sonia/scm/template/ServletMustacheFactory.java b/scm-webapp/src/main/java/sonia/scm/template/ServletMustacheFactory.java index c6e5b82441..24c8ff21c9 100644 --- a/scm-webapp/src/main/java/sonia/scm/template/ServletMustacheFactory.java +++ b/scm-webapp/src/main/java/sonia/scm/template/ServletMustacheFactory.java @@ -36,22 +36,17 @@ package sonia.scm.template; //~--- non-JDK imports -------------------------------------------------------- import com.github.mustachejava.DefaultMustacheFactory; - import com.google.common.base.Charsets; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import sonia.scm.plugin.PluginLoader; - -//~--- JDK imports ------------------------------------------------------------ - +import javax.servlet.ServletContext; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; -import javax.servlet.ServletContext; +//~--- JDK imports ------------------------------------------------------------ /** * @@ -73,13 +68,12 @@ public class ServletMustacheFactory extends DefaultMustacheFactory * * * @param servletContext - * @param pluginLoader + * @param classLoader */ - public ServletMustacheFactory(ServletContext servletContext, - PluginLoader pluginLoader) + public ServletMustacheFactory(ServletContext servletContext, ClassLoader classLoader) { this.servletContext = servletContext; - this.pluginLoader = pluginLoader; + this.classLoader = classLoader; } //~--- get methods ---------------------------------------------------------- @@ -116,7 +110,7 @@ public class ServletMustacheFactory extends DefaultMustacheFactory resourceName = resourceName.substring(1); } - is = pluginLoader.getUberClassLoader().getResourceAsStream(resourceName); + is = classLoader.getResourceAsStream(resourceName); } if (is != null) @@ -144,9 +138,8 @@ public class ServletMustacheFactory extends DefaultMustacheFactory //~--- fields --------------------------------------------------------------- - /** Field description */ - private final PluginLoader pluginLoader; - /** Field description */ private ServletContext servletContext; + + private ClassLoader classLoader; } 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 be0c33f098..131db6e44d 100644 --- a/scm-webapp/src/test/java/sonia/scm/template/MustacheTemplateEngineTest.java +++ b/scm-webapp/src/test/java/sonia/scm/template/MustacheTemplateEngineTest.java @@ -35,16 +35,21 @@ package sonia.scm.template; //~--- non-JDK imports -------------------------------------------------------- +import com.google.common.collect.ImmutableMap; +import org.assertj.core.api.Assertions; +import org.junit.Test; import sonia.scm.plugin.PluginLoader; -import static org.mockito.Mockito.*; +import javax.servlet.ServletContext; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; //~--- JDK imports ------------------------------------------------------------ -import java.io.InputStream; - -import javax.servlet.ServletContext; - /** * * @author Sebastian Sdorra @@ -68,7 +73,10 @@ public class MustacheTemplateEngineTest extends TemplateEngineTestBase when(loader.getUberClassLoader()).thenReturn( Thread.currentThread().getContextClassLoader()); - return new MustacheTemplateEngine(context, loader); + MustacheTemplateEngine.PluginLoaderHolder holder = new MustacheTemplateEngine.PluginLoaderHolder(); + holder.pluginLoader = loader; + + return new MustacheTemplateEngine(context, holder); } //~--- get methods ---------------------------------------------------------- @@ -116,4 +124,18 @@ public class MustacheTemplateEngineTest extends TemplateEngineTestBase return MustacheTemplateEngineTest.class.getResourceAsStream( "/sonia/scm/template/".concat(resource).concat(".mustache")); } + + @Test + public void testCreateEngineWithoutPluginLoader() throws IOException { + ServletContext context = mock(ServletContext.class); + MustacheTemplateEngine.PluginLoaderHolder holder = new MustacheTemplateEngine.PluginLoaderHolder(); + MustacheTemplateEngine engine = new MustacheTemplateEngine(context, holder); + + Template template = engine.getTemplate(getTemplateResource()); + + StringWriter writer = new StringWriter(); + template.execute(writer, ImmutableMap.of("name", "World")); + + Assertions.assertThat(writer.toString()).isEqualTo("Hello World!"); + } }