diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfiguration.java index a927151852..515a84f36c 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfiguration.java @@ -29,12 +29,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; -import org.springframework.boot.bind.RelaxedPropertyResolver; -import org.springframework.context.EnvironmentAware; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; -import org.springframework.core.env.Environment; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; @@ -49,65 +47,45 @@ import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver; * {@link EnableAutoConfiguration Auto-configuration} for FreeMarker. * * @author Andy Wilkinson + * @author Dave Syer * @since 1.1.0 */ @Configuration @ConditionalOnClass(freemarker.template.Configuration.class) @AutoConfigureAfter(WebMvcAutoConfiguration.class) -public class FreeMarkerAutoConfiguration implements EnvironmentAware { - - public static final String DEFAULT_TEMPLATE_LOADER_PATH = "classpath:/templates/"; - - public static final String DEFAULT_PREFIX = ""; - - public static final String DEFAULT_SUFFIX = ".ftl"; +@EnableConfigurationProperties(FreeMarkerProperties.class) +public class FreeMarkerAutoConfiguration { @Autowired private final ResourceLoader resourceLoader = new DefaultResourceLoader(); - private RelaxedPropertyResolver environment; - - @Override - public void setEnvironment(Environment environment) { - this.environment = new RelaxedPropertyResolver(environment, "spring.freemarker."); - } + @Autowired + private FreeMarkerProperties properties; @PostConstruct public void checkTemplateLocationExists() { - Boolean checkTemplateLocation = this.environment.getProperty( - "checkTemplateLocation", Boolean.class, true); - if (checkTemplateLocation) { - Resource resource = this.resourceLoader.getResource(this.environment - .getProperty("templateLoaderPath", DEFAULT_TEMPLATE_LOADER_PATH)); + if (this.properties.isCheckTemplateLocation()) { + Resource resource = this.resourceLoader + .getResource(this.properties.getPath()); Assert.state(resource.exists(), "Cannot find template location: " + resource + " (please add some templates " + "or check your FreeMarker configuration)"); } } - protected static class FreeMarkerConfiguration implements EnvironmentAware { - - private RelaxedPropertyResolver properties; + protected static class FreeMarkerConfiguration { - @Override - public void setEnvironment(Environment environment) { - this.properties = new RelaxedPropertyResolver(environment, - "spring.freemarker."); - } + @Autowired + protected FreeMarkerProperties properties; protected void applyProperties(FreeMarkerConfigurationFactory factory) { - factory.setTemplateLoaderPath(this.properties.getProperty( - "templateLoaderPath", DEFAULT_TEMPLATE_LOADER_PATH)); - factory.setDefaultEncoding(this.properties.getProperty("templateEncoding", - "UTF-8")); + factory.setTemplateLoaderPath(this.properties.getPath()); + factory.setDefaultEncoding(this.properties.getCharSet()); Properties settings = new Properties(); - settings.putAll(this.properties.getSubProperties("settings.")); + settings.putAll(this.properties.getSettings()); factory.setFreemarkerSettings(settings); } - protected final RelaxedPropertyResolver getProperties() { - return this.properties; - } } @Configuration @@ -147,24 +125,20 @@ public class FreeMarkerAutoConfiguration implements EnvironmentAware { @ConditionalOnMissingBean(name = "freeMarkerViewResolver") public FreeMarkerViewResolver freeMarkerViewResolver() { FreeMarkerViewResolver resolver = new FreeMarkerViewResolver(); - RelaxedPropertyResolver properties = getProperties(); - resolver.setPrefix(properties.getProperty("prefix", DEFAULT_PREFIX)); - resolver.setSuffix(properties.getProperty("suffix", DEFAULT_SUFFIX)); - resolver.setCache(properties.getProperty("cache", Boolean.class, true)); - resolver.setContentType(properties.getProperty("contentType", "text/html")); - resolver.setViewNames(properties.getProperty("viewNames", String[].class)); - resolver.setExposeRequestAttributes(properties.getProperty( - "exposeRequestAttributes", Boolean.class, false)); - resolver.setAllowRequestOverride(properties.getProperty( - "allowRequestOverride", Boolean.class, false)); - resolver.setExposeSessionAttributes(properties.getProperty( - "exposeSessionAttributes", Boolean.class, false)); - resolver.setAllowSessionOverride(properties.getProperty( - "allowSessionOverride", Boolean.class, false)); - resolver.setExposeSpringMacroHelpers(properties.getProperty( - "exposeSpringMacroHelpers", Boolean.class, true)); - resolver.setRequestContextAttribute(properties - .getProperty("requestContextAttribute")); + resolver.setPrefix(this.properties.getPrefix()); + resolver.setSuffix(this.properties.getSuffix()); + resolver.setCache(this.properties.isCache()); + resolver.setContentType(this.properties.getContentType()); + resolver.setViewNames(this.properties.getViewNames()); + resolver.setExposeRequestAttributes(this.properties + .isExposeRequestAttributes()); + resolver.setExposeRequestAttributes(this.properties.isAllowRequestOverride()); + resolver.setExposeRequestAttributes(this.properties + .isExposeSessionAttributes()); + resolver.setExposeRequestAttributes(this.properties + .isExposeSpringMacroHelpers()); + resolver.setRequestContextAttribute(this.properties + .getRequestContextAttribute()); // This resolver acts as a fallback resolver (e.g. like a // InternalResourceViewResolver) so it needs to have low precedence diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerProperties.java new file mode 100644 index 0000000000..cc4b185974 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerProperties.java @@ -0,0 +1,180 @@ +/* + * 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.freemarker; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * @author Dave Syer + * + * @since 1.1.0 + */ +@ConfigurationProperties(prefix = "spring.freemarker") +public class FreeMarkerProperties { + + public static final String DEFAULT_TEMPLATE_LOADER_PATH = "classpath:/templates/"; + + public static final String DEFAULT_PREFIX = ""; + + public static final String DEFAULT_SUFFIX = ".ftl"; + + private String prefix = DEFAULT_PREFIX; + + private String suffix = DEFAULT_SUFFIX; + + private String path = DEFAULT_TEMPLATE_LOADER_PATH; + + private boolean cache; + + private String contentType = "text/html"; + + private String charSet = "UTF-8"; + + private String[] viewNames; + + private boolean checkTemplateLocation = true; + + private String requestContextAttribute; + + private boolean exposeRequestAttributes = false; + + private boolean exposeSessionAttributes = false; + + private boolean allowRequestOverride = false; + + private boolean exposeSpringMacroHelpers = true; + + private Map settings = new HashMap(); + + 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 String getPath() { + return this.path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getRequestContextAttribute() { + return this.requestContextAttribute; + } + + public void setRequestContextAttribute(String requestContextAttribute) { + this.requestContextAttribute = requestContextAttribute; + } + + public boolean isExposeRequestAttributes() { + return this.exposeRequestAttributes; + } + + public void setExposeRequestAttributes(boolean exposeRequestAttributes) { + this.exposeRequestAttributes = exposeRequestAttributes; + } + + public boolean isExposeSessionAttributes() { + return this.exposeSessionAttributes; + } + + public void setExposeSessionAttributes(boolean exposeSessionAttributes) { + this.exposeSessionAttributes = exposeSessionAttributes; + } + + public boolean isAllowRequestOverride() { + return this.allowRequestOverride; + } + + public void setAllowRequestOverride(boolean allowRequestOverride) { + this.allowRequestOverride = allowRequestOverride; + } + + public boolean isExposeSpringMacroHelpers() { + return this.exposeSpringMacroHelpers; + } + + public void setExposeSpringMacroHelpers(boolean exposeSpringMacroHelpers) { + this.exposeSpringMacroHelpers = exposeSpringMacroHelpers; + } + + public Map getSettings() { + return this.settings; + } + + public void setSettings(Map settings) { + this.settings = settings; + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProvider.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProvider.java index 0ee5c4cbf9..f0d159a76c 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProvider.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProvider.java @@ -35,13 +35,12 @@ public class FreeMarkerTemplateAvailabilityProvider implements public boolean isTemplateAvailable(String view, Environment environment, ClassLoader classLoader, ResourceLoader resourceLoader) { if (ClassUtils.isPresent("freemarker.template.Configuration", classLoader)) { - String loaderPath = environment.getProperty( - "spring.freemarker.templateLoaderPath", - FreeMarkerAutoConfiguration.DEFAULT_TEMPLATE_LOADER_PATH); + String loaderPath = environment.getProperty("spring.freemarker.path", + FreeMarkerProperties.DEFAULT_TEMPLATE_LOADER_PATH); String prefix = environment.getProperty("spring.freemarker.prefix", - FreeMarkerAutoConfiguration.DEFAULT_PREFIX); + FreeMarkerProperties.DEFAULT_PREFIX); String suffix = environment.getProperty("spring.freemarker.suffix", - FreeMarkerAutoConfiguration.DEFAULT_SUFFIX); + FreeMarkerProperties.DEFAULT_SUFFIX); return resourceLoader.getResource(loaderPath + prefix + view + suffix) .exists(); } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfigurationTests.java index 720796df77..b889e026de 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfigurationTests.java @@ -72,14 +72,14 @@ public class FreeMarkerAutoConfigurationTests { @Test(expected = BeanCreationException.class) public void nonExistentTemplateLocation() { - registerAndRefreshContext("spring.freemarker.templateLoaderPath:" + registerAndRefreshContext("spring.freemarker.path:" + "classpath:/does-not-exist/"); } @Test public void emptyTemplateLocation() { new File("target/test-classes/templates/empty-directory").mkdir(); - registerAndRefreshContext("spring.freemarker.templateLoaderPath:" + registerAndRefreshContext("spring.freemarker.path:" + "classpath:/templates/empty-directory/"); } @@ -89,7 +89,7 @@ public class FreeMarkerAutoConfigurationTests { MockHttpServletResponse response = render("home"); String result = response.getContentAsString(); assertThat(result, containsString("home")); - assertThat(response.getContentType(), equalTo("text/html")); + assertThat(response.getContentType(), equalTo("text/html;charset=UTF-8")); } @Test @@ -98,7 +98,7 @@ public class FreeMarkerAutoConfigurationTests { MockHttpServletResponse response = render("home"); String result = response.getContentAsString(); assertThat(result, containsString("home")); - assertThat(response.getContentType(), equalTo("application/json")); + assertThat(response.getContentType(), equalTo("application/json;charset=UTF-8")); } @Test @@ -119,7 +119,7 @@ public class FreeMarkerAutoConfigurationTests { @Test public void customTemplateLoaderPath() throws Exception { - registerAndRefreshContext("spring.freemarker.templateLoaderPath:classpath:/custom-templates/"); + registerAndRefreshContext("spring.freemarker.path:classpath:/custom-templates/"); MockHttpServletResponse response = render("custom"); String result = response.getContentAsString(); assertThat(result, containsString("custom"));