Commit 8a1e010d authored by Andy Wilkinson's avatar Andy Wilkinson

Allow multiple templateLoaderPaths to be configured for FreeMarker

Closes gh-1767
parent ef245593
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
package org.springframework.boot.autoconfigure.freemarker; package org.springframework.boot.autoconfigure.freemarker;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties; import java.util.Properties;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
...@@ -65,10 +67,18 @@ public class FreeMarkerAutoConfiguration { ...@@ -65,10 +67,18 @@ public class FreeMarkerAutoConfiguration {
@PostConstruct @PostConstruct
public void checkTemplateLocationExists() { public void checkTemplateLocationExists() {
if (this.properties.isCheckTemplateLocation()) { if (this.properties.isCheckTemplateLocation()) {
Resource resource = this.resourceLoader.getResource(this.properties Resource templatePathResource = null;
.getTemplateLoaderPath()); List<Resource> resources = new ArrayList<Resource>();
Assert.state(resource.exists(), "Cannot find template location: " + resource for (String templateLoaderPath : this.properties.getTemplateLoaderPath()) {
+ " (please add some templates, " Resource resource = this.resourceLoader.getResource(templateLoaderPath);
resources.add(resource);
if (resource.exists()) {
templatePathResource = resource;
break;
}
}
Assert.notNull(templatePathResource, "Cannot find template location(s): "
+ resources + " (please add some templates, "
+ "check your FreeMarker configuration, or set " + "check your FreeMarker configuration, or set "
+ "spring.freemarker.checkTemplateLocation=false)"); + "spring.freemarker.checkTemplateLocation=false)");
} }
...@@ -80,7 +90,7 @@ public class FreeMarkerAutoConfiguration { ...@@ -80,7 +90,7 @@ public class FreeMarkerAutoConfiguration {
protected FreeMarkerProperties properties; protected FreeMarkerProperties properties;
protected void applyProperties(FreeMarkerConfigurationFactory factory) { protected void applyProperties(FreeMarkerConfigurationFactory factory) {
factory.setTemplateLoaderPath(this.properties.getTemplateLoaderPath()); factory.setTemplateLoaderPaths(this.properties.getTemplateLoaderPath());
factory.setDefaultEncoding(this.properties.getCharSet()); factory.setDefaultEncoding(this.properties.getCharSet());
Properties settings = new Properties(); Properties settings = new Properties();
settings.putAll(this.properties.getSettings()); settings.putAll(this.properties.getSettings());
......
...@@ -40,7 +40,7 @@ public class FreeMarkerProperties extends AbstractTemplateViewResolverProperties ...@@ -40,7 +40,7 @@ public class FreeMarkerProperties extends AbstractTemplateViewResolverProperties
private Map<String, String> settings = new HashMap<String, String>(); private Map<String, String> settings = new HashMap<String, String>();
private String templateLoaderPath = DEFAULT_TEMPLATE_LOADER_PATH; private String[] templateLoaderPath = new String[] { DEFAULT_TEMPLATE_LOADER_PATH };
public FreeMarkerProperties() { public FreeMarkerProperties() {
super(DEFAULT_PREFIX, DEFAULT_SUFFIX); super(DEFAULT_PREFIX, DEFAULT_SUFFIX);
...@@ -54,12 +54,12 @@ public class FreeMarkerProperties extends AbstractTemplateViewResolverProperties ...@@ -54,12 +54,12 @@ public class FreeMarkerProperties extends AbstractTemplateViewResolverProperties
this.settings = settings; this.settings = settings;
} }
public String getTemplateLoaderPath() { public String[] getTemplateLoaderPath() {
return this.templateLoaderPath; return this.templateLoaderPath;
} }
public void setTemplateLoaderPath(String templateLoaderPath) { public void setTemplateLoaderPath(String... templateLoaderPaths) {
this.templateLoaderPath = templateLoaderPath; this.templateLoaderPath = templateLoaderPaths;
} }
} }
...@@ -73,7 +73,7 @@ public class FreeMarkerAutoConfigurationTests { ...@@ -73,7 +73,7 @@ public class FreeMarkerAutoConfigurationTests {
@Test(expected = BeanCreationException.class) @Test(expected = BeanCreationException.class)
public void nonExistentTemplateLocation() { public void nonExistentTemplateLocation() {
registerAndRefreshContext("spring.freemarker.templateLoaderPath:" registerAndRefreshContext("spring.freemarker.templateLoaderPath:"
+ "classpath:/does-not-exist/"); + "classpath:/does-not-exist/,classpath:/also-does-not-exist");
} }
@Test @Test
...@@ -83,6 +83,13 @@ public class FreeMarkerAutoConfigurationTests { ...@@ -83,6 +83,13 @@ public class FreeMarkerAutoConfigurationTests {
+ "classpath:/templates/empty-directory/"); + "classpath:/templates/empty-directory/");
} }
@Test
public void nonExistentLocationAndEmptyLocation() {
new File("target/test-classes/templates/empty-directory").mkdir();
registerAndRefreshContext("spring.freemarker.templateLoaderPath:"
+ "classpath:/does-not-exist/,classpath:/templates/empty-directory/");
}
@Test @Test
public void defaultViewResolution() throws Exception { public void defaultViewResolution() throws Exception {
registerAndRefreshContext(); registerAndRefreshContext();
......
...@@ -123,7 +123,7 @@ content into your application; rather pick only the properties that you need. ...@@ -123,7 +123,7 @@ content into your application; rather pick only the properties that you need.
spring.freemarker.requestContextAttribute= spring.freemarker.requestContextAttribute=
spring.freemarker.settings.*= spring.freemarker.settings.*=
spring.freemarker.suffix=.ftl spring.freemarker.suffix=.ftl
spring.freemarker.templateLoaderPath=classpath:/templates/ spring.freemarker.templateLoaderPath=classpath:/templates/ # comma-separated list
spring.freemarker.viewNames= # whitelist of view names that can be resolved spring.freemarker.viewNames= # whitelist of view names that can be resolved
# GROOVY TEMPLATES ({sc-spring-boot-autoconfigure}/groovy/template/GroovyTemplateAutoConfiguration.{sc-ext}[GroovyTemplateAutoConfiguration]) # GROOVY TEMPLATES ({sc-spring-boot-autoconfigure}/groovy/template/GroovyTemplateAutoConfiguration.{sc-ext}[GroovyTemplateAutoConfiguration])
......
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