Throw an exception if a config file that exists cannot be parsed

Fixes gh-209 in a general way
pull/234/head
Dave Syer 11 years ago
parent cc996ce7f9
commit f038da1fe5

@ -104,6 +104,8 @@ public class ConfigFileApplicationListener implements
private PropertySourceAnnotations propertySourceAnnotations = new PropertySourceAnnotations(); private PropertySourceAnnotations propertySourceAnnotations = new PropertySourceAnnotations();
private PropertySourceLoaderFactory propertySourceLoaderFactory = new DefaultPropertySourceLoaderFactory();
/** /**
* Binds the early {@link Environment} to the {@link SpringApplication}. This makes it * Binds the early {@link Environment} to the {@link SpringApplication}. This makes it
* possible to set {@link SpringApplication} properties dynamically, like the sources * possible to set {@link SpringApplication} properties dynamically, like the sources
@ -284,12 +286,8 @@ public class ConfigFileApplicationListener implements
return null; return null;
} }
List<PropertySourceLoader> loaders = new ArrayList<PropertySourceLoader>(); List<PropertySourceLoader> loaders = this.propertySourceLoaderFactory
loaders.add(new PropertiesPropertySourceLoader()); .getLoaders(environment);
if (ClassUtils.isPresent("org.yaml.snakeyaml.Yaml", null)) {
loaders.add(YamlPropertySourceLoader.springProfileAwareLoader(environment
.getActiveProfiles()));
}
Resource resource = resourceLoader.getResource(location); Resource resource = resourceLoader.getResource(location);
String name = this.propertySourceAnnotations.name(location); String name = this.propertySourceAnnotations.name(location);
@ -334,13 +332,23 @@ public class ConfigFileApplicationListener implements
if (this.cached.containsKey(key)) { if (this.cached.containsKey(key)) {
return this.cached.get(key); return this.cached.get(key);
} }
boolean satisfied = true;
for (PropertySourceLoader loader : loaders) { for (PropertySourceLoader loader : loaders) {
if (resource != null && resource.exists() && loader.supports(resource)) { if (resource != null && resource.exists()) {
PropertySource<?> propertySource = loader.load(name, resource); if (loader.supports(resource)) {
this.cached.put(key, propertySource); PropertySource<?> propertySource = loader.load(name, resource);
return propertySource; 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; return null;
} }
@ -368,6 +376,14 @@ public class ConfigFileApplicationListener implements
this.searchLocations = (searchLocations == null ? null : searchLocations.clone()); 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<Random> { private static class RandomValuePropertySource extends PropertySource<Random> {
public RandomValuePropertySource(String name) { public RandomValuePropertySource(String name) {
@ -444,4 +460,24 @@ public class ConfigFileApplicationListener implements
} }
} }
public static interface PropertySourceLoaderFactory {
List<PropertySourceLoader> getLoaders(Environment environment);
}
private static class DefaultPropertySourceLoaderFactory implements
PropertySourceLoaderFactory {
@Override
public List<PropertySourceLoader> getLoaders(Environment environment) {
ArrayList<PropertySourceLoader> loaders = new ArrayList<PropertySourceLoader>();
loaders.add(new PropertiesPropertySourceLoader());
if (ClassUtils.isPresent("org.yaml.snakeyaml.Yaml", null)) {
loaders.add(YamlPropertySourceLoader.springProfileAwareLoader(environment
.getActiveProfiles()));
}
return loaders;
}
}
} }

@ -18,20 +18,27 @@ package org.springframework.boot.context.listener;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.junit.After; import org.junit.After;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationEnvironmentAvailableEvent; 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.boot.test.EnvironmentTestUtils;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.SimpleCommandLinePropertySource; import org.springframework.core.env.SimpleCommandLinePropertySource;
import org.springframework.core.env.StandardEnvironment; import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.Resource;
import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
@ -57,6 +64,9 @@ public class ConfigFileApplicationListenerTests {
private ConfigFileApplicationListener initializer = new ConfigFileApplicationListener(); private ConfigFileApplicationListener initializer = new ConfigFileApplicationListener();
@Rule
public ExpectedException expected = ExpectedException.none();
@After @After
public void cleanup() { public void cleanup() {
System.clearProperty("my.property"); System.clearProperty("my.property");
@ -198,6 +208,34 @@ public class ConfigFileApplicationListenerTests {
assertThat(this.environment.getPropertySources().contains(location), is(true)); assertThat(this.environment.getPropertySources().contains(location), is(true));
} }
@Test
public void unsupportedResource() throws Exception {
this.initializer
.setPropertySourceLoaderFactory(new PropertySourceLoaderFactory() {
@Override
public List<PropertySourceLoader> getLoaders(Environment environment) {
return Arrays
.<PropertySourceLoader> 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 @Test
public void specificResourceDefaultsToFile() throws Exception { public void specificResourceDefaultsToFile() throws Exception {
String location = "src/test/resources/specificlocation.properties"; String location = "src/test/resources/specificlocation.properties";

Loading…
Cancel
Save