mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-08-29 03:06:45 +08:00
Add Groovy template engine support for Spring MVC apps
Default suffix .tpl. If groovy-templates is on the classpath user can now add templates and get them rendered and resolved in an MVC app. TODO: Macro helpers for message rendering etc. See gh-878
This commit is contained in:
parent
938609fdc0
commit
da2e25f90d
@ -66,6 +66,11 @@
|
||||
<artifactId>tomcat-jdbc</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-templates</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
|
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.groovy.template;
|
||||
|
||||
import groovy.text.TemplateEngine;
|
||||
import groovy.text.markup.BaseTemplate;
|
||||
import groovy.text.markup.MarkupTemplateEngine;
|
||||
import groovy.text.markup.TemplateConfiguration;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.servlet.Servlet;
|
||||
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.groovy.template.web.GroovyTemplateViewResolver;
|
||||
import org.springframework.boot.autoconfigure.groovy.template.web.LocaleAwareTemplate;
|
||||
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @since 1.1.0
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass(TemplateEngine.class)
|
||||
@AutoConfigureAfter(WebMvcAutoConfiguration.class)
|
||||
@EnableConfigurationProperties(GroovyTemplateProperties.class)
|
||||
public class GroovyTemplateAutoConfiguration {
|
||||
|
||||
@Autowired
|
||||
private final ResourceLoader resourceLoader = new DefaultResourceLoader();
|
||||
|
||||
@Autowired
|
||||
private GroovyTemplateProperties properties;
|
||||
|
||||
@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 "
|
||||
+ "or check your FreeMarker configuration)");
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass({ Servlet.class, LocaleContextHolder.class })
|
||||
@ConditionalOnWebApplication
|
||||
public static class GroovyWebConfiguration implements BeanClassLoaderAware {
|
||||
|
||||
@Autowired
|
||||
private final ResourceLoader resourceLoader = new DefaultResourceLoader();
|
||||
|
||||
@Autowired
|
||||
private GroovyTemplateProperties properties;
|
||||
|
||||
private ClassLoader classLoader = GroovyWebConfiguration.class.getClassLoader();
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(TemplateEngine.class)
|
||||
public TemplateEngine groovyTemplateEngine() throws Exception {
|
||||
TemplateConfiguration configuration = this.properties.getConfiguration();
|
||||
if (configuration.getBaseTemplateClass() == BaseTemplate.class) {
|
||||
// Enable locale-dependent includes
|
||||
configuration.setBaseTemplateClass(LocaleAwareTemplate.class);
|
||||
}
|
||||
return new MarkupTemplateEngine(createParentLoaderForTemplates(),
|
||||
configuration);
|
||||
}
|
||||
|
||||
private ClassLoader createParentLoaderForTemplates() throws Exception {
|
||||
return new URLClassLoader(new URL[] { this.resourceLoader.getResource(
|
||||
this.properties.getPrefix()).getURL() }, this.classLoader);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "groovyTemplateViewResolver")
|
||||
public GroovyTemplateViewResolver groovyTemplateViewResolver(TemplateEngine engine) {
|
||||
GroovyTemplateViewResolver resolver = new GroovyTemplateViewResolver();
|
||||
resolver.setPrefix(this.properties.getPrefix());
|
||||
resolver.setSuffix(this.properties.getSuffix());
|
||||
resolver.setCache(this.properties.isCache());
|
||||
resolver.setContentType(this.properties.getContentType());
|
||||
resolver.setCharSet(this.properties.getCharSet());
|
||||
resolver.setViewNames(this.properties.getViewNames());
|
||||
resolver.setTemplateEngine(engine);
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.groovy.template;
|
||||
|
||||
import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* {@link TemplateAvailabilityProvider} that provides availability information for Groovy
|
||||
* view templates
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public class GroovyTemplateAvailabilityProvider implements TemplateAvailabilityProvider {
|
||||
|
||||
@Override
|
||||
public boolean isTemplateAvailable(String view, Environment environment,
|
||||
ClassLoader classLoader, ResourceLoader resourceLoader) {
|
||||
if (ClassUtils.isPresent("groovy.text.TemplateEngine", classLoader)) {
|
||||
String prefix = environment.getProperty("spring.groovy.template.prefix",
|
||||
GroovyTemplateProperties.DEFAULT_PREFIX);
|
||||
String suffix = environment.getProperty("spring.groovy.template.suffix",
|
||||
GroovyTemplateProperties.DEFAULT_SUFFIX);
|
||||
return resourceLoader.getResource(prefix + view + suffix).exists();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.groovy.template;
|
||||
|
||||
import groovy.text.markup.TemplateConfiguration;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @since 1.1.0
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.groovy.template")
|
||||
public class GroovyTemplateProperties {
|
||||
|
||||
public static final String DEFAULT_PREFIX = "classpath:/templates/";
|
||||
|
||||
public static final String DEFAULT_SUFFIX = ".tpl";
|
||||
|
||||
private String prefix = DEFAULT_PREFIX;
|
||||
|
||||
private String suffix = DEFAULT_SUFFIX;
|
||||
|
||||
private boolean cache;
|
||||
|
||||
private String contentType = "text/html";
|
||||
|
||||
private String charSet = "UTF-8";
|
||||
|
||||
private String[] viewNames;
|
||||
|
||||
private boolean checkTemplateLocation = true;
|
||||
|
||||
private TemplateConfiguration configuration = new TemplateConfiguration();
|
||||
|
||||
public void setCheckTemplateLocation(boolean checkTemplateLocation) {
|
||||
this.checkTemplateLocation = checkTemplateLocation;
|
||||
}
|
||||
|
||||
public boolean isCheckTemplateLocation() {
|
||||
return this.checkTemplateLocation;
|
||||
}
|
||||
|
||||
public String[] getViewNames() {
|
||||
return this.viewNames;
|
||||
}
|
||||
|
||||
public void setViewNames(String[] viewNames) {
|
||||
this.viewNames = viewNames;
|
||||
}
|
||||
|
||||
public boolean isCache() {
|
||||
return this.cache;
|
||||
}
|
||||
|
||||
public void setCache(boolean cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return this.contentType
|
||||
+ (this.contentType.contains(";charset=") ? "" : ";charset="
|
||||
+ this.charSet);
|
||||
}
|
||||
|
||||
public void setContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
public String getCharSet() {
|
||||
return this.charSet;
|
||||
}
|
||||
|
||||
public void setCharSet(String charSet) {
|
||||
this.charSet = charSet;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return this.prefix;
|
||||
}
|
||||
|
||||
public void setPrefix(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
public String getSuffix() {
|
||||
return this.suffix;
|
||||
}
|
||||
|
||||
public void setSuffix(String suffix) {
|
||||
this.suffix = suffix;
|
||||
}
|
||||
|
||||
public void setConfiguration(TemplateConfiguration configuration) {
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
public TemplateConfiguration getConfiguration() {
|
||||
return this.configuration;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.groovy.template.web;
|
||||
|
||||
import groovy.text.Template;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.web.servlet.view.AbstractUrlBasedView;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public class GroovyTemplateView extends AbstractUrlBasedView {
|
||||
|
||||
private final Template template;
|
||||
|
||||
public GroovyTemplateView(Template template) {
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderMergedOutputModel(Map<String, Object> model,
|
||||
HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
applyContentType(response);
|
||||
this.template.make(model).writeTo(new BufferedWriter(response.getWriter()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply this view's content type as specified in the "contentType" bean property to
|
||||
* the given response.
|
||||
* @param response current HTTP response
|
||||
* @see #setContentType
|
||||
*/
|
||||
protected void applyContentType(HttpServletResponse response) {
|
||||
if (response.getContentType() == null) {
|
||||
response.setContentType(getContentType());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.groovy.template.web;
|
||||
|
||||
import groovy.text.SimpleTemplateEngine;
|
||||
import groovy.text.Template;
|
||||
import groovy.text.TemplateEngine;
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.springframework.beans.propertyeditors.LocaleEditor;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.web.servlet.View;
|
||||
import org.springframework.web.servlet.view.UrlBasedViewResolver;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public class GroovyTemplateViewResolver extends UrlBasedViewResolver {
|
||||
|
||||
private TemplateEngine engine = new SimpleTemplateEngine();
|
||||
|
||||
private String charSet = "UTF-8";
|
||||
|
||||
public GroovyTemplateViewResolver() {
|
||||
setViewClass(GroovyTemplateView.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param engine the engine to set
|
||||
*/
|
||||
public void setTemplateEngine(TemplateEngine engine) {
|
||||
this.engine = engine;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param charSet the charSet to set
|
||||
*/
|
||||
public void setCharSet(String charSet) {
|
||||
this.charSet = charSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View loadView(String viewName, Locale locale) throws Exception {
|
||||
Resource resource = resolveResource(viewName, locale);
|
||||
if (resource == null) {
|
||||
return null;
|
||||
}
|
||||
Template template = this.engine.createTemplate(new InputStreamReader(resource
|
||||
.getInputStream(), this.charSet));
|
||||
GroovyTemplateView view = new GroovyTemplateView(template);
|
||||
view.setApplicationContext(getApplicationContext());
|
||||
view.setServletContext(getServletContext());
|
||||
view.setContentType(getContentType());
|
||||
return view;
|
||||
}
|
||||
|
||||
private Resource resolveResource(String viewName, Locale locale) {
|
||||
String l10n = "";
|
||||
if (locale != null) {
|
||||
LocaleEditor localeEditor = new LocaleEditor();
|
||||
localeEditor.setValue(locale);
|
||||
l10n = "_" + localeEditor.getAsText();
|
||||
}
|
||||
return resolveFromLocale(viewName, l10n);
|
||||
}
|
||||
|
||||
private Resource resolveFromLocale(String viewName, String locale) {
|
||||
Resource resource = getApplicationContext().getResource(
|
||||
getPrefix() + viewName + locale + getSuffix());
|
||||
if (resource == null || !resource.exists()) {
|
||||
if (locale.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
int index = locale.lastIndexOf("_");
|
||||
return resolveFromLocale(viewName, locale.substring(0, index));
|
||||
}
|
||||
return resource;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.groovy.template.web;
|
||||
|
||||
import groovy.text.markup.BaseTemplate;
|
||||
import groovy.text.markup.MarkupTemplateEngine;
|
||||
import groovy.text.markup.TemplateConfiguration;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public abstract class LocaleAwareTemplate extends BaseTemplate {
|
||||
|
||||
public LocaleAwareTemplate(MarkupTemplateEngine templateEngine, Map<?, ?> model,
|
||||
Map<String, String> modelTypes, TemplateConfiguration configuration) {
|
||||
super(localize(templateEngine), model, modelTypes, localize(configuration));
|
||||
}
|
||||
|
||||
private static MarkupTemplateEngine localize(MarkupTemplateEngine templateEngine) {
|
||||
TemplateConfiguration templateConfiguration = templateEngine
|
||||
.getTemplateConfiguration();
|
||||
ClassLoader parent = templateEngine.getTemplateLoader().getParent();
|
||||
return new MarkupTemplateEngine(parent, localize(templateConfiguration));
|
||||
}
|
||||
|
||||
private static TemplateConfiguration localize(TemplateConfiguration configuration) {
|
||||
TemplateConfiguration result = new TemplateConfiguration(configuration);
|
||||
result.setLocale(LocaleContextHolder.getLocale());
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.groovy.template;
|
||||
|
||||
import groovy.text.TemplateEngine;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
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;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
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 static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for GroovyTemplateAutoConfiguration.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class GroovyTemplateAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
|
||||
|
||||
@Before
|
||||
public void setupContext() {
|
||||
this.context.setServletContext(new MockServletContext());
|
||||
}
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
LocaleContextHolder.resetLocaleContext();
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultConfiguration() {
|
||||
registerAndRefreshContext();
|
||||
assertThat(this.context.getBean(GroovyTemplateViewResolver.class), notNullValue());
|
||||
}
|
||||
|
||||
@Test(expected = BeanCreationException.class)
|
||||
public void nonExistentTemplateLocation() {
|
||||
registerAndRefreshContext("spring.groovy.template.prefix:"
|
||||
+ "classpath:/does-not-exist/");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyTemplateLocation() {
|
||||
new File("target/test-classes/templates/empty-directory").mkdir();
|
||||
registerAndRefreshContext("spring.groovy.template.prefix:"
|
||||
+ "classpath:/templates/empty-directory/");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultViewResolution() throws Exception {
|
||||
registerAndRefreshContext();
|
||||
MockHttpServletResponse response = render("home");
|
||||
String result = response.getContentAsString();
|
||||
assertThat(result, containsString("home"));
|
||||
assertThat(response.getContentType(), equalTo("text/html;charset=UTF-8"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void includesViewResolution() throws Exception {
|
||||
registerAndRefreshContext();
|
||||
MockHttpServletResponse response = render("includes");
|
||||
String result = response.getContentAsString();
|
||||
assertThat(result, containsString("here"));
|
||||
assertThat(response.getContentType(), equalTo("text/html;charset=UTF-8"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void localeViewResolution() throws Exception {
|
||||
LocaleContextHolder.setLocale(Locale.FRENCH);
|
||||
registerAndRefreshContext();
|
||||
MockHttpServletResponse response = render("includes", Locale.FRENCH);
|
||||
String result = response.getContentAsString();
|
||||
assertThat(result, containsString("voila"));
|
||||
assertThat(response.getContentType(), equalTo("text/html;charset=UTF-8"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customContentType() throws Exception {
|
||||
registerAndRefreshContext("spring.groovy.template.contentType:application/json");
|
||||
MockHttpServletResponse response = render("home");
|
||||
String result = response.getContentAsString();
|
||||
assertThat(result, containsString("home"));
|
||||
assertThat(response.getContentType(), equalTo("application/json;charset=UTF-8"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customPrefix() throws Exception {
|
||||
registerAndRefreshContext("spring.groovy.template.prefix:classpath:/templates/prefix/");
|
||||
MockHttpServletResponse response = render("prefixed");
|
||||
String result = response.getContentAsString();
|
||||
assertThat(result, containsString("prefixed"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customSuffix() throws Exception {
|
||||
registerAndRefreshContext("spring.groovy.template.suffix:.groovytemplate");
|
||||
MockHttpServletResponse response = render("suffixed");
|
||||
String result = response.getContentAsString();
|
||||
assertThat(result, containsString("suffixed"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customTemplateLoaderPath() throws Exception {
|
||||
registerAndRefreshContext("spring.groovy.template.prefix:classpath:/custom-templates/");
|
||||
MockHttpServletResponse response = render("custom");
|
||||
String result = response.getContentAsString();
|
||||
assertThat(result, containsString("custom"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disableCache() {
|
||||
registerAndRefreshContext("spring.groovy.template.cache:false");
|
||||
assertThat(
|
||||
this.context.getBean(GroovyTemplateViewResolver.class).getCacheLimit(),
|
||||
equalTo(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderTemplate() throws Exception {
|
||||
registerAndRefreshContext();
|
||||
TemplateEngine engine = this.context.getBean(TemplateEngine.class);
|
||||
Writer writer = new StringWriter();
|
||||
engine.createTemplate(new ClassPathResource("templates/message.tpl").getFile())
|
||||
.make(new HashMap<String, Object>(Collections.singletonMap("greeting",
|
||||
"Hello World"))).writeTo(writer);
|
||||
assertThat(writer.toString(), containsString("Hello World"));
|
||||
}
|
||||
|
||||
private void registerAndRefreshContext(String... env) {
|
||||
EnvironmentTestUtils.addEnvironment(this.context, env);
|
||||
this.context.register(GroovyTemplateAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
private MockHttpServletResponse render(String viewName) throws Exception {
|
||||
return render(viewName, Locale.UK);
|
||||
}
|
||||
|
||||
private MockHttpServletResponse render(String viewName, Locale locale)
|
||||
throws Exception {
|
||||
GroovyTemplateViewResolver resolver = this.context
|
||||
.getBean(GroovyTemplateViewResolver.class);
|
||||
View view = resolver.resolveViewName(viewName, locale);
|
||||
assertThat(view, notNullValue());
|
||||
HttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setAttribute(RequestContext.WEB_APPLICATION_CONTEXT_ATTRIBUTE,
|
||||
this.context);
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
view.render(null, request, response);
|
||||
return response;
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
yield "custom"
|
@ -0,0 +1 @@
|
||||
yield "home"
|
@ -0,0 +1 @@
|
||||
yield "here"
|
@ -0,0 +1 @@
|
||||
yield "voila"
|
@ -0,0 +1,2 @@
|
||||
yield "include"
|
||||
include template: "included.tpl"
|
@ -0,0 +1 @@
|
||||
yield "Message: ${greeting}"
|
@ -0,0 +1 @@
|
||||
yield "prefixed"
|
@ -0,0 +1,3 @@
|
||||
yield """
|
||||
suffixed
|
||||
"""
|
@ -106,8 +106,9 @@
|
||||
<spring-plugin.version>1.1.0.RELEASE</spring-plugin.version>
|
||||
<spring-amqp.version>1.3.2.RELEASE</spring-amqp.version>
|
||||
<spring-mobile.version>1.1.1.RELEASE</spring-mobile.version>
|
||||
<spring-retry.version>1.1.0.RELEASE</spring-retry.version>
|
||||
<spring-security.version>3.2.3.RELEASE</spring-security.version>
|
||||
<spring-security-oauth.version>2.0.0.RC2</spring-security-oauth.version>
|
||||
<spring-security-oauth.version>2.0.0.RELEASE</spring-security-oauth.version>
|
||||
<spring-security-jwt.version>1.0.2.RELEASE</spring-security-jwt.version>
|
||||
<thymeleaf.version>2.1.3.RELEASE</thymeleaf.version>
|
||||
<thymeleaf-extras-springsecurity3.version>2.1.1.RELEASE</thymeleaf-extras-springsecurity3.version>
|
||||
@ -994,6 +995,11 @@
|
||||
<artifactId>spring-mobile-device</artifactId>
|
||||
<version>${spring-mobile.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.retry</groupId>
|
||||
<artifactId>spring-retry</artifactId>
|
||||
<version>${spring-retry.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-acl</artifactId>
|
||||
|
Loading…
Reference in New Issue
Block a user