Commit 18b89293 authored by Brian Clozel's avatar Brian Clozel Committed by Dave Syer

Migrate to groovy templates from Spring 4.1

Update `GroovyTemplateAutoConfiguration` to use Spring 4.1 Groovy
Markup Template infrastructure instead of Boot's.

Fixes gh-1552
parent 7dd6ae76
......@@ -19,13 +19,13 @@ package org.springframework.boot.autoconfigure.groovy.template;
import groovy.text.SimpleTemplateEngine;
import groovy.text.TemplateEngine;
import groovy.text.markup.MarkupTemplateEngine;
import groovy.text.markup.TemplateConfiguration;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.servlet.Servlet;
import org.springframework.beans.factory.BeanClassLoaderAware;
......@@ -47,15 +47,21 @@ import org.springframework.core.Ordered;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;
import org.springframework.web.servlet.view.UrlBasedViewResolver;
import org.springframework.web.servlet.view.groovy.GroovyMarkupConfig;
import org.springframework.web.servlet.view.groovy.GroovyMarkupConfigurer;
import org.springframework.web.servlet.view.groovy.GroovyMarkupViewResolver;
/**
* Autoconfiguration support for Groovy templates in MVC. By default creates a
* {@link MarkupTemplateEngine} configured from {@link GroovyTemplateProperties}, but you
* can override that by providing a {@link TemplateEngine} of a different type.
* can override that by providing your own {@link GroovyMarkupConfig} or even a
* {@link MarkupTemplateEngine} of a different type.
*
* @author Dave Syer
* @author Andy Wilkinson
* @author Brian Clozel
* @since 1.1.0
*/
@Configuration
......@@ -64,13 +70,49 @@ import org.springframework.web.servlet.view.UrlBasedViewResolver;
@EnableConfigurationProperties(GroovyTemplateProperties.class)
public class GroovyTemplateAutoConfiguration {
@Autowired
private final ResourceLoader resourceLoader = new DefaultResourceLoader();
@Configuration
@ConditionalOnClass({ MarkupTemplateEngine.class, GroovyMarkupConfigurer.class })
public static class GroovyMarkupConfiguration {
@Autowired
private final ResourceLoader resourceLoader = new DefaultResourceLoader();
@Autowired
private GroovyTemplateProperties properties;
@Autowired(required = false)
private MarkupTemplateEngine templateEngine;
@PostConstruct
public void checkTemplateLocationExists() {
if (this.properties.isCheckTemplateLocation()) {
Resource resource = this.resourceLoader.getResource(this.properties
.getPrefix());
Assert.state(resource.exists(), "Cannot find template location: "
+ resource + " (please add some templates, "
+ "check your Groovy configuration, or set "
+ "spring.groovy.template.check-template-location=false)");
}
}
@Autowired
private GroovyTemplateProperties properties;
@Bean
@ConditionalOnMissingBean(GroovyMarkupConfig.class)
@ConfigurationProperties(prefix = "spring.groovy.template.configuration")
public GroovyMarkupConfigurer groovyMarkupConfigurer() {
GroovyMarkupConfigurer configurer = new GroovyMarkupConfigurer();
configurer.setResourceLoaderPath(this.properties.getPrefix());
configurer.setCacheTemplates(this.properties.isCache());
if (this.templateEngine != null) {
configurer.setTemplateEngine(this.templateEngine);
}
return configurer;
}
public abstract static class BaseGroovyTemplateConfiguration implements
}
@Configuration
@ConditionalOnMissingClass(name = "groovy.text.markup.MarkupTemplateEngine")
public static class GroovySimpleTemplateEngineConfiguration implements
BeanClassLoaderAware {
@Autowired
......@@ -99,47 +141,12 @@ public class GroovyTemplateAutoConfiguration {
return new URLClassLoader(urls.toArray(new URL[urls.size()]),
this.classLoader);
}
else {
return this.classLoader;
}
return this.classLoader;
}
}
@Configuration
@ConditionalOnClass(MarkupTemplateEngine.class)
public static class GroovyMarkupConfiguration extends BaseGroovyTemplateConfiguration {
@Autowired
private GroovyTemplateProperties properties;
@Bean
@ConfigurationProperties(prefix = "spring.groovy.template.configuration")
public TemplateConfiguration groovyTemplateConfiguration() {
return new TemplateConfiguration();
}
@Bean
@ConditionalOnMissingBean(TemplateEngine.class)
public TemplateEngine groovyTemplateEngine() throws Exception {
TemplateConfiguration configuration = groovyTemplateConfiguration();
configuration.setCacheTemplates(this.properties.isCache());
return new MarkupTemplateEngine(createParentLoaderForTemplates(),
configuration, new GroovyTemplateResolver());
}
}
@Configuration
@ConditionalOnMissingClass(name = "groovy.text.markup.MarkupTemplateEngine")
public static class GroovySimpleConfiguration extends BaseGroovyTemplateConfiguration {
@Autowired
private GroovyTemplateProperties properties;
@Bean
@ConditionalOnMissingBean(TemplateEngine.class)
public TemplateEngine groovyTemplateEngine() throws Exception {
public SimpleTemplateEngine groovyTemplateEngine() throws Exception {
return new SimpleTemplateEngine(createParentLoaderForTemplates());
}
......@@ -154,22 +161,35 @@ public class GroovyTemplateAutoConfiguration {
@Autowired
private GroovyTemplateProperties properties;
@Bean
@ConditionalOnMissingBean(name = "groovyMarkupViewResolver")
@ConditionalOnClass(MarkupTemplateEngine.class)
public GroovyMarkupViewResolver groovyMarkupViewResolver() {
GroovyMarkupViewResolver resolver = new GroovyMarkupViewResolver();
configureViewResolver(resolver);
return resolver;
}
@Bean
@ConditionalOnMissingBean(name = "groovyTemplateViewResolver")
@ConditionalOnMissingClass(MarkupTemplateEngine.class)
public GroovyTemplateViewResolver groovyTemplateViewResolver(TemplateEngine engine) {
GroovyTemplateViewResolver resolver = new GroovyTemplateViewResolver();
configureViewResolver(resolver);
resolver.setPrefix(this.properties.getPrefix());
resolver.setTemplateEngine(engine);
return resolver;
}
private void configureViewResolver(UrlBasedViewResolver resolver) {
resolver.setSuffix(this.properties.getSuffix());
resolver.setCache(this.properties.isCache());
resolver.setContentType(this.properties.getContentType());
resolver.setViewNames(this.properties.getViewNames());
resolver.setTemplateEngine(engine);
resolver.setRequestContextAttribute("spring");
// This resolver acts as a fallback resolver (e.g. like a
// InternalResourceViewResolver) so it needs to have low precedence
resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 6);
return resolver;
}
}
......
......@@ -23,6 +23,8 @@ import java.io.IOException;
import java.net.URL;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.servlet.view.groovy.GroovyMarkupConfigurer;
import org.springframework.web.servlet.view.groovy.GroovyMarkupViewResolver;
/**
* A custom {@link groovy.text.markup.TemplateResolver template resolver} which resolves
......@@ -31,8 +33,12 @@ import org.springframework.context.i18n.LocaleContextHolder;
*
* @author Cédric Champeau
* @since 1.1.0
* @deprecated since 1.2 in favor of Spring 4.1's {@link GroovyMarkupViewResolver} and
* {@link GroovyMarkupConfigurer}.
*/
@Deprecated
public class GroovyTemplateResolver implements TemplateResolver {
private ClassLoader templateClassLoader;
@Override
......@@ -57,4 +63,5 @@ public class GroovyTemplateResolver implements TemplateResolver {
}
return resource;
}
}
......@@ -46,8 +46,6 @@ public class GroovyTemplateView extends AbstractUrlBasedView {
protected void renderMergedOutputModel(Map<String, Object> model,
HttpServletRequest request, HttpServletResponse response) throws Exception {
applyContentType(response);
model.put("spring", new RequestContext(request, response, getServletContext(),
model));
this.template.make(model).writeTo(new BufferedWriter(response.getWriter()));
}
......
......@@ -16,7 +16,7 @@
package org.springframework.boot.autoconfigure.groovy.template;
import groovy.text.TemplateEngine;
import groovy.text.markup.MarkupTemplateEngine;
import java.io.File;
import java.io.StringWriter;
......@@ -30,7 +30,6 @@ import javax.servlet.http.HttpServletRequest;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.autoconfigure.groovy.template.web.GroovyTemplateViewResolver;
import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.core.io.ClassPathResource;
......@@ -40,6 +39,8 @@ import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.support.RequestContext;
import org.springframework.web.servlet.view.groovy.GroovyMarkupConfig;
import org.springframework.web.servlet.view.groovy.GroovyMarkupViewResolver;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
......@@ -47,7 +48,7 @@ import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
/**
* Tests for GroovyTemplateAutoConfiguration.
* Tests for {@link GroovyTemplateAutoConfiguration}.
*
* @author Dave Syer
*/
......@@ -71,7 +72,7 @@ public class GroovyTemplateAutoConfigurationTests {
@Test
public void defaultConfiguration() {
registerAndRefreshContext();
assertThat(this.context.getBean(GroovyTemplateViewResolver.class), notNullValue());
assertThat(this.context.getBean(GroovyMarkupViewResolver.class), notNullValue());
}
@Test
......@@ -101,7 +102,6 @@ public class GroovyTemplateAutoConfigurationTests {
@Test
public void localeViewResolution() throws Exception {
LocaleContextHolder.setLocale(Locale.FRENCH);
registerAndRefreshContext();
MockHttpServletResponse response = render("includes", Locale.FRENCH);
String result = response.getContentAsString();
......@@ -145,15 +145,15 @@ public class GroovyTemplateAutoConfigurationTests {
@Test
public void disableCache() {
registerAndRefreshContext("spring.groovy.template.cache:false");
assertThat(
this.context.getBean(GroovyTemplateViewResolver.class).getCacheLimit(),
assertThat(this.context.getBean(GroovyMarkupViewResolver.class).getCacheLimit(),
equalTo(0));
}
@Test
public void renderTemplate() throws Exception {
registerAndRefreshContext();
TemplateEngine engine = this.context.getBean(TemplateEngine.class);
GroovyMarkupConfig config = this.context.getBean(GroovyMarkupConfig.class);
MarkupTemplateEngine engine = config.getTemplateEngine();
Writer writer = new StringWriter();
engine.createTemplate(new ClassPathResource("templates/message.tpl").getFile())
.make(new HashMap<String, Object>(Collections.singletonMap("greeting",
......@@ -173,8 +173,9 @@ public class GroovyTemplateAutoConfigurationTests {
private MockHttpServletResponse render(String viewName, Locale locale)
throws Exception {
GroovyTemplateViewResolver resolver = this.context
.getBean(GroovyTemplateViewResolver.class);
LocaleContextHolder.setLocale(locale);
GroovyMarkupViewResolver resolver = this.context
.getBean(GroovyMarkupViewResolver.class);
View view = resolver.resolveViewName(viewName, locale);
assertThat(view, notNullValue());
HttpServletRequest request = new MockHttpServletRequest();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment