diff --git a/spring-boot-autoconfigure/pom.xml b/spring-boot-autoconfigure/pom.xml index 1b510bdf7d1..7b40548dfb8 100644 --- a/spring-boot-autoconfigure/pom.xml +++ b/spring-boot-autoconfigure/pom.xml @@ -66,6 +66,11 @@ tomcat-jdbc true + + org.codehaus.groovy + groovy-templates + true + com.zaxxer HikariCP diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAutoConfiguration.java new file mode 100644 index 00000000000..210dfea3a7b --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAutoConfiguration.java @@ -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; + } + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAvailabilityProvider.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAvailabilityProvider.java new file mode 100644 index 00000000000..b188d2dd351 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAvailabilityProvider.java @@ -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; + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateProperties.java new file mode 100644 index 00000000000..b60031c84dd --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateProperties.java @@ -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; + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/web/GroovyTemplateView.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/web/GroovyTemplateView.java new file mode 100644 index 00000000000..423834ebbd1 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/web/GroovyTemplateView.java @@ -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 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()); + } + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/web/GroovyTemplateViewResolver.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/web/GroovyTemplateViewResolver.java new file mode 100644 index 00000000000..3f2d07ff23e --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/web/GroovyTemplateViewResolver.java @@ -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; + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/web/LocaleAwareTemplate.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/web/LocaleAwareTemplate.java new file mode 100644 index 00000000000..8a5d1e739e8 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/web/LocaleAwareTemplate.java @@ -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 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; + } + +} diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAutoConfigurationTests.java new file mode 100644 index 00000000000..d9d12304c71 --- /dev/null +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAutoConfigurationTests.java @@ -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(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; + } +} diff --git a/spring-boot-autoconfigure/src/test/resources/custom-templates/custom.tpl b/spring-boot-autoconfigure/src/test/resources/custom-templates/custom.tpl new file mode 100644 index 00000000000..06b9992513a --- /dev/null +++ b/spring-boot-autoconfigure/src/test/resources/custom-templates/custom.tpl @@ -0,0 +1 @@ +yield "custom" \ No newline at end of file diff --git a/spring-boot-autoconfigure/src/test/resources/templates/home.tpl b/spring-boot-autoconfigure/src/test/resources/templates/home.tpl new file mode 100644 index 00000000000..eb07ff6f939 --- /dev/null +++ b/spring-boot-autoconfigure/src/test/resources/templates/home.tpl @@ -0,0 +1 @@ +yield "home" \ No newline at end of file diff --git a/spring-boot-autoconfigure/src/test/resources/templates/included.tpl b/spring-boot-autoconfigure/src/test/resources/templates/included.tpl new file mode 100644 index 00000000000..a1bbaa02e9a --- /dev/null +++ b/spring-boot-autoconfigure/src/test/resources/templates/included.tpl @@ -0,0 +1 @@ +yield "here" \ No newline at end of file diff --git a/spring-boot-autoconfigure/src/test/resources/templates/included_fr.tpl b/spring-boot-autoconfigure/src/test/resources/templates/included_fr.tpl new file mode 100644 index 00000000000..035e2e95759 --- /dev/null +++ b/spring-boot-autoconfigure/src/test/resources/templates/included_fr.tpl @@ -0,0 +1 @@ +yield "voila" \ No newline at end of file diff --git a/spring-boot-autoconfigure/src/test/resources/templates/includes.tpl b/spring-boot-autoconfigure/src/test/resources/templates/includes.tpl new file mode 100644 index 00000000000..9ea4039123d --- /dev/null +++ b/spring-boot-autoconfigure/src/test/resources/templates/includes.tpl @@ -0,0 +1,2 @@ +yield "include" +include template: "included.tpl" \ No newline at end of file diff --git a/spring-boot-autoconfigure/src/test/resources/templates/message.tpl b/spring-boot-autoconfigure/src/test/resources/templates/message.tpl new file mode 100644 index 00000000000..6a9df3b50d1 --- /dev/null +++ b/spring-boot-autoconfigure/src/test/resources/templates/message.tpl @@ -0,0 +1 @@ +yield "Message: ${greeting}" \ No newline at end of file diff --git a/spring-boot-autoconfigure/src/test/resources/templates/prefix/prefixed.tpl b/spring-boot-autoconfigure/src/test/resources/templates/prefix/prefixed.tpl new file mode 100644 index 00000000000..c9c6c42d6c9 --- /dev/null +++ b/spring-boot-autoconfigure/src/test/resources/templates/prefix/prefixed.tpl @@ -0,0 +1 @@ +yield "prefixed" \ No newline at end of file diff --git a/spring-boot-autoconfigure/src/test/resources/templates/suffixed.groovytemplate b/spring-boot-autoconfigure/src/test/resources/templates/suffixed.groovytemplate new file mode 100644 index 00000000000..3539f6d6f4a --- /dev/null +++ b/spring-boot-autoconfigure/src/test/resources/templates/suffixed.groovytemplate @@ -0,0 +1,3 @@ +yield """ +suffixed +""" \ No newline at end of file diff --git a/spring-boot-dependencies/pom.xml b/spring-boot-dependencies/pom.xml index d9d2b382dc1..0b92ca8cdc8 100644 --- a/spring-boot-dependencies/pom.xml +++ b/spring-boot-dependencies/pom.xml @@ -106,8 +106,9 @@ 1.1.0.RELEASE 1.3.2.RELEASE 1.1.1.RELEASE + 1.1.0.RELEASE 3.2.3.RELEASE - 2.0.0.RC2 + 2.0.0.RELEASE 1.0.2.RELEASE 2.1.3.RELEASE 2.1.1.RELEASE @@ -994,6 +995,11 @@ spring-mobile-device ${spring-mobile.version} + + org.springframework.retry + spring-retry + ${spring-retry.version} + org.springframework.security spring-security-acl