From f038da1fe5c918a318a85d8824b26d620675e701 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 10 Jan 2014 17:09:39 +0000 Subject: [PATCH] Throw an exception if a config file that exists cannot be parsed Fixes gh-209 in a general way --- .../ConfigFileApplicationListener.java | 56 +++++++++++++++---- .../ConfigFileApplicationListenerTests.java | 38 +++++++++++++ 2 files changed, 84 insertions(+), 10 deletions(-) diff --git a/spring-boot/src/main/java/org/springframework/boot/context/listener/ConfigFileApplicationListener.java b/spring-boot/src/main/java/org/springframework/boot/context/listener/ConfigFileApplicationListener.java index d762b6a95d..33c9352c3f 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/listener/ConfigFileApplicationListener.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/listener/ConfigFileApplicationListener.java @@ -104,6 +104,8 @@ public class ConfigFileApplicationListener implements private PropertySourceAnnotations propertySourceAnnotations = new PropertySourceAnnotations(); + private PropertySourceLoaderFactory propertySourceLoaderFactory = new DefaultPropertySourceLoaderFactory(); + /** * Binds the early {@link Environment} to the {@link SpringApplication}. This makes it * possible to set {@link SpringApplication} properties dynamically, like the sources @@ -284,12 +286,8 @@ public class ConfigFileApplicationListener implements return null; } - List loaders = new ArrayList(); - loaders.add(new PropertiesPropertySourceLoader()); - if (ClassUtils.isPresent("org.yaml.snakeyaml.Yaml", null)) { - loaders.add(YamlPropertySourceLoader.springProfileAwareLoader(environment - .getActiveProfiles())); - } + List loaders = this.propertySourceLoaderFactory + .getLoaders(environment); Resource resource = resourceLoader.getResource(location); String name = this.propertySourceAnnotations.name(location); @@ -334,13 +332,23 @@ public class ConfigFileApplicationListener implements if (this.cached.containsKey(key)) { return this.cached.get(key); } + boolean satisfied = true; for (PropertySourceLoader loader : loaders) { - if (resource != null && resource.exists() && loader.supports(resource)) { - PropertySource propertySource = loader.load(name, resource); - this.cached.put(key, propertySource); - return propertySource; + if (resource != null && resource.exists()) { + if (loader.supports(resource)) { + PropertySource propertySource = loader.load(name, resource); + this.cached.put(key, propertySource); + return propertySource; + } + else { + satisfied = false; + } } } + if (!satisfied) { + throw new IllegalStateException( + "No supported loader found for configuration resource: " + resource); + } return null; } @@ -368,6 +376,14 @@ public class ConfigFileApplicationListener implements this.searchLocations = (searchLocations == null ? null : searchLocations.clone()); } + /** + * @param propertySourceLoaderFactory the factory to set + */ + public void setPropertySourceLoaderFactory( + PropertySourceLoaderFactory propertySourceLoaderFactory) { + this.propertySourceLoaderFactory = propertySourceLoaderFactory; + } + private static class RandomValuePropertySource extends PropertySource { public RandomValuePropertySource(String name) { @@ -444,4 +460,24 @@ public class ConfigFileApplicationListener implements } } + public static interface PropertySourceLoaderFactory { + List getLoaders(Environment environment); + } + + private static class DefaultPropertySourceLoaderFactory implements + PropertySourceLoaderFactory { + + @Override + public List getLoaders(Environment environment) { + ArrayList loaders = new ArrayList(); + loaders.add(new PropertiesPropertySourceLoader()); + if (ClassUtils.isPresent("org.yaml.snakeyaml.Yaml", null)) { + loaders.add(YamlPropertySourceLoader.springProfileAwareLoader(environment + .getActiveProfiles())); + } + return loaders; + } + + } + } diff --git a/spring-boot/src/test/java/org/springframework/boot/context/listener/ConfigFileApplicationListenerTests.java b/spring-boot/src/test/java/org/springframework/boot/context/listener/ConfigFileApplicationListenerTests.java index ce7a6c6307..f844892a6e 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/listener/ConfigFileApplicationListenerTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/listener/ConfigFileApplicationListenerTests.java @@ -18,20 +18,27 @@ package org.springframework.boot.context.listener; import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.junit.After; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplicationEnvironmentAvailableEvent; +import org.springframework.boot.config.PropertySourceLoader; +import org.springframework.boot.context.listener.ConfigFileApplicationListener.PropertySourceLoaderFactory; import org.springframework.boot.test.EnvironmentTestUtils; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.SimpleCommandLinePropertySource; import org.springframework.core.env.StandardEnvironment; +import org.springframework.core.io.Resource; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.equalTo; @@ -57,6 +64,9 @@ public class ConfigFileApplicationListenerTests { private ConfigFileApplicationListener initializer = new ConfigFileApplicationListener(); + @Rule + public ExpectedException expected = ExpectedException.none(); + @After public void cleanup() { System.clearProperty("my.property"); @@ -198,6 +208,34 @@ public class ConfigFileApplicationListenerTests { assertThat(this.environment.getPropertySources().contains(location), is(true)); } + @Test + public void unsupportedResource() throws Exception { + this.initializer + .setPropertySourceLoaderFactory(new PropertySourceLoaderFactory() { + @Override + public List getLoaders(Environment environment) { + return Arrays + . asList(new PropertySourceLoader() { + + @Override + public boolean supports(Resource resource) { + return false; + } + + @Override + public org.springframework.core.env.PropertySource load( + String name, Resource resource) { + return null; + } + + }); + } + }); + this.expected.expect(IllegalStateException.class); + this.expected.expectMessage("No supported loader"); + this.initializer.onApplicationEvent(this.event); + } + @Test public void specificResourceDefaultsToFile() throws Exception { String location = "src/test/resources/specificlocation.properties";