From 6564fb3d960b5901695f2b0a7fc65df951b6274c Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 10 Apr 2017 13:35:24 +0100 Subject: [PATCH] Consider all loader paths when checking template availability Closes gh-8842 --- ...reeMarkerTemplateAvailabilityProvider.java | 66 ++++++++++++++---- .../GroovyTemplateAvailabilityProvider.java | 65 ++++++++++++++---- .../VelocityTemplateAvailabilityProvider.java | 68 +++++++++++++++---- ...rkerTemplateAvailabilityProviderTests.java | 10 ++- ...oovyTemplateAvailabilityProviderTests.java | 8 +++ ...cityTemplateAvailabilityProviderTests.java | 10 ++- 6 files changed, 188 insertions(+), 39 deletions(-) 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 2c38d40a98..e011c66d0c 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2017 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. @@ -16,8 +16,14 @@ package org.springframework.boot.autoconfigure.freemarker; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider; -import org.springframework.boot.bind.RelaxedPropertyResolver; +import org.springframework.boot.bind.PropertySourcesPropertyValues; +import org.springframework.boot.bind.RelaxedDataBinder; +import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; import org.springframework.core.io.ResourceLoader; import org.springframework.util.ClassUtils; @@ -36,18 +42,54 @@ public class FreeMarkerTemplateAvailabilityProvider public boolean isTemplateAvailable(String view, Environment environment, ClassLoader classLoader, ResourceLoader resourceLoader) { if (ClassUtils.isPresent("freemarker.template.Configuration", classLoader)) { - RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(environment, - "spring.freemarker."); - String loaderPath = resolver.getProperty("template-loader-path", - FreeMarkerProperties.DEFAULT_TEMPLATE_LOADER_PATH); - String prefix = resolver.getProperty("prefix", - FreeMarkerProperties.DEFAULT_PREFIX); - String suffix = resolver.getProperty("suffix", - FreeMarkerProperties.DEFAULT_SUFFIX); - return resourceLoader.getResource(loaderPath + prefix + view + suffix) - .exists(); + FreeMarkerTemplateAvailabilityProperties properties = new FreeMarkerTemplateAvailabilityProperties(); + RelaxedDataBinder binder = new RelaxedDataBinder(properties, + "spring.freemarker"); + binder.bind(new PropertySourcesPropertyValues( + ((ConfigurableEnvironment) environment).getPropertySources())); + for (String loaderPath : properties.getTemplateLoaderPath()) { + if (resourceLoader.getResource(loaderPath + properties.getPrefix() + view + + properties.getSuffix()).exists()) { + return true; + } + } } return false; } + static final class FreeMarkerTemplateAvailabilityProperties { + + private List templateLoaderPath = new ArrayList( + Arrays.asList(FreeMarkerProperties.DEFAULT_TEMPLATE_LOADER_PATH)); + + private String prefix = FreeMarkerProperties.DEFAULT_PREFIX; + + private String suffix = FreeMarkerProperties.DEFAULT_SUFFIX; + + public List getTemplateLoaderPath() { + return this.templateLoaderPath; + } + + public void setTemplateLoaderPath(List templateLoaderPath) { + this.templateLoaderPath = templateLoaderPath; + } + + 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; + } + + } + } 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 index f2ce6b6621..363fffae9e 100644 --- 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 @@ -16,10 +16,15 @@ package org.springframework.boot.autoconfigure.groovy.template; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider; -import org.springframework.boot.bind.RelaxedPropertyResolver; +import org.springframework.boot.bind.PropertySourcesPropertyValues; +import org.springframework.boot.bind.RelaxedDataBinder; +import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; -import org.springframework.core.env.PropertyResolver; import org.springframework.core.io.ResourceLoader; import org.springframework.util.ClassUtils; @@ -36,18 +41,54 @@ public class GroovyTemplateAvailabilityProvider implements TemplateAvailabilityP public boolean isTemplateAvailable(String view, Environment environment, ClassLoader classLoader, ResourceLoader resourceLoader) { if (ClassUtils.isPresent("groovy.text.TemplateEngine", classLoader)) { - PropertyResolver resolver = new RelaxedPropertyResolver(environment, - "spring.groovy.template."); - String loaderPath = resolver.getProperty("resource-loader-path", - GroovyTemplateProperties.DEFAULT_RESOURCE_LOADER_PATH); - String prefix = resolver.getProperty("prefix", - GroovyTemplateProperties.DEFAULT_PREFIX); - String suffix = resolver.getProperty("suffix", - GroovyTemplateProperties.DEFAULT_SUFFIX); - return resourceLoader.getResource(loaderPath + prefix + view + suffix) - .exists(); + GroovyTemplateAvailabilityProperties properties = new GroovyTemplateAvailabilityProperties(); + RelaxedDataBinder binder = new RelaxedDataBinder(properties, + "spring.groovy.template"); + binder.bind(new PropertySourcesPropertyValues( + ((ConfigurableEnvironment) environment).getPropertySources())); + for (String loaderPath : properties.getResourceLoaderPath()) { + if (resourceLoader.getResource(loaderPath + properties.getPrefix() + view + + properties.getSuffix()).exists()) { + return true; + } + } } return false; } + static final class GroovyTemplateAvailabilityProperties { + + private List resourceLoaderPath = new ArrayList( + Arrays.asList(GroovyTemplateProperties.DEFAULT_RESOURCE_LOADER_PATH)); + + private String prefix = GroovyTemplateProperties.DEFAULT_PREFIX; + + private String suffix = GroovyTemplateProperties.DEFAULT_SUFFIX; + + public List getResourceLoaderPath() { + return this.resourceLoaderPath; + } + + public void setResourceLoaderPath(List resourceLoaderPath) { + this.resourceLoaderPath = resourceLoaderPath; + } + + 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; + } + + } + } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/velocity/VelocityTemplateAvailabilityProvider.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/velocity/VelocityTemplateAvailabilityProvider.java index 1dd1791213..8253ef76b3 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/velocity/VelocityTemplateAvailabilityProvider.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/velocity/VelocityTemplateAvailabilityProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-2017 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. @@ -16,10 +16,15 @@ package org.springframework.boot.autoconfigure.velocity; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider; -import org.springframework.boot.bind.RelaxedPropertyResolver; +import org.springframework.boot.bind.PropertySourcesPropertyValues; +import org.springframework.boot.bind.RelaxedDataBinder; +import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; -import org.springframework.core.env.PropertyResolver; import org.springframework.core.io.ResourceLoader; import org.springframework.util.ClassUtils; @@ -40,18 +45,55 @@ public class VelocityTemplateAvailabilityProvider public boolean isTemplateAvailable(String view, Environment environment, ClassLoader classLoader, ResourceLoader resourceLoader) { if (ClassUtils.isPresent("org.apache.velocity.app.VelocityEngine", classLoader)) { - PropertyResolver resolver = new RelaxedPropertyResolver(environment, - "spring.velocity."); - String loaderPath = resolver.getProperty("resource-loader-path", - VelocityProperties.DEFAULT_RESOURCE_LOADER_PATH); - String prefix = resolver.getProperty("prefix", - VelocityProperties.DEFAULT_PREFIX); - String suffix = resolver.getProperty("suffix", - VelocityProperties.DEFAULT_SUFFIX); - return resourceLoader.getResource(loaderPath + prefix + view + suffix) - .exists(); + VelocityTemplateAvailabilityProperties properties = new VelocityTemplateAvailabilityProperties(); + RelaxedDataBinder binder = new RelaxedDataBinder(properties, + "spring.velocity"); + binder.bind(new PropertySourcesPropertyValues( + ((ConfigurableEnvironment) environment).getPropertySources())); + for (String path : properties.getResourceLoaderPath()) { + if (resourceLoader.getResource( + path + properties.getPrefix() + view + properties.getSuffix()) + .exists()) { + return true; + } + } } return false; } + static class VelocityTemplateAvailabilityProperties { + + private List resourceLoaderPath = new ArrayList( + Arrays.asList(VelocityProperties.DEFAULT_RESOURCE_LOADER_PATH)); + + private String prefix = VelocityProperties.DEFAULT_PREFIX; + + private String suffix = VelocityProperties.DEFAULT_SUFFIX; + + public List getResourceLoaderPath() { + return this.resourceLoaderPath; + } + + public void setResourceLoaderPath(List resourceLoaderPath) { + this.resourceLoaderPath = resourceLoaderPath; + } + + 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; + } + + } + } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProviderTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProviderTests.java index 243d0e4559..755e74cb56 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProviderTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProviderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-2017 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. @@ -58,6 +58,14 @@ public class FreeMarkerTemplateAvailabilityProviderTests { getClass().getClassLoader(), this.resourceLoader)).isTrue(); } + @Test + public void availabilityOfTemplateWithCustomLoaderPathConfiguredAsAList() { + this.environment.setProperty("spring.freemarker.template-loader-path[0]", + "classpath:/custom-templates/"); + assertThat(this.provider.isTemplateAvailable("custom", this.environment, + getClass().getClassLoader(), this.resourceLoader)).isTrue(); + } + @Test public void availabilityOfTemplateWithCustomPrefix() { this.environment.setProperty("spring.freemarker.prefix", "prefix/"); diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAvailabilityProviderTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAvailabilityProviderTests.java index 9ab21fa818..75d1760471 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAvailabilityProviderTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAvailabilityProviderTests.java @@ -58,6 +58,14 @@ public class GroovyTemplateAvailabilityProviderTests { getClass().getClassLoader(), this.resourceLoader)).isTrue(); } + @Test + public void availabilityOfTemplateWithCustomLoaderPathConfiguredAsAList() { + this.environment.setProperty("spring.groovy.template.resource-loader-path[0]", + "classpath:/custom-templates/"); + assertThat(this.provider.isTemplateAvailable("custom", this.environment, + getClass().getClassLoader(), this.resourceLoader)).isTrue(); + } + @Test public void availabilityOfTemplateWithCustomPrefix() { this.environment.setProperty("spring.groovy.template.prefix", "prefix/"); diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/velocity/VelocityTemplateAvailabilityProviderTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/velocity/VelocityTemplateAvailabilityProviderTests.java index 30c7eb906f..4aca3ddd96 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/velocity/VelocityTemplateAvailabilityProviderTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/velocity/VelocityTemplateAvailabilityProviderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-2017 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. @@ -59,6 +59,14 @@ public class VelocityTemplateAvailabilityProviderTests { getClass().getClassLoader(), this.resourceLoader)).isTrue(); } + @Test + public void availabilityOfTemplateWithCustomLoaderPathConfiguredAsAList() { + this.environment.setProperty("spring.velocity.resource-loader-path[0]", + "classpath:/custom-templates/"); + assertThat(this.provider.isTemplateAvailable("custom", this.environment, + getClass().getClassLoader(), this.resourceLoader)).isTrue(); + } + @Test public void availabilityOfTemplateWithCustomPrefix() { this.environment.setProperty("spring.velocity.prefix", "prefix/");