Browse Source

Special case for YAML ParseException caused by bad document boundary

YAML documents can be text literals, so some common typos can be misleading
and not generate the expected exception (Boot fails to cast the
document to a Map, rather than reporting the underlying exception).

Fixes gh-235
pull/252/head
Dave Syer 12 years ago
parent
commit
7e4ee4f720
  1. 5
      spring-boot/src/main/java/org/springframework/boot/config/YamlProcessor.java
  2. 19
      spring-boot/src/main/java/org/springframework/boot/context/listener/ConfigFileApplicationListener.java
  3. 26
      spring-boot/src/test/java/org/springframework/boot/config/YamlProcessorTests.java

5
spring-boot/src/main/java/org/springframework/boot/config/YamlProcessor.java

@ -167,6 +167,11 @@ public class YamlProcessor {
private Map<String, Object> asMap(Object object) { private Map<String, Object> asMap(Object object) {
// YAML can have numbers as keys // YAML can have numbers as keys
Map<String, Object> result = new LinkedHashMap<String, Object>(); Map<String, Object> result = new LinkedHashMap<String, Object>();
if (!(object instanceof Map)) {
// A document can be a text literal
result.put("document", object);
return result;
}
Map<Object, Object> map = (Map<Object, Object>) object; Map<Object, Object> map = (Map<Object, Object>) object;
for (Entry<Object, Object> entry : map.entrySet()) { for (Entry<Object, Object> entry : map.entrySet()) {
Object value = entry.getValue(); Object value = entry.getValue();

19
spring-boot/src/main/java/org/springframework/boot/context/listener/ConfigFileApplicationListener.java

@ -328,21 +328,22 @@ public class ConfigFileApplicationListener implements
private PropertySource<?> getPropertySource(String name, Resource resource, private PropertySource<?> getPropertySource(String name, Resource resource,
String profile, List<PropertySourceLoader> loaders) { String profile, List<PropertySourceLoader> loaders) {
if (resource == null || !resource.exists()) {
return null;
}
String key = resource.getDescription() + (profile == null ? "" : "#" + profile); String key = resource.getDescription() + (profile == null ? "" : "#" + profile);
if (this.cached.containsKey(key)) { if (this.cached.containsKey(key)) {
return this.cached.get(key); return this.cached.get(key);
} }
boolean satisfied = true; boolean satisfied = true;
for (PropertySourceLoader loader : loaders) { for (PropertySourceLoader loader : loaders) {
if (resource != null && resource.exists()) { if (loader.supports(resource)) {
if (loader.supports(resource)) { PropertySource<?> propertySource = loader.load(name, resource);
PropertySource<?> propertySource = loader.load(name, resource); this.cached.put(key, propertySource);
this.cached.put(key, propertySource); return propertySource;
return propertySource; }
} else {
else { satisfied = false;
satisfied = false;
}
} }
} }
if (!satisfied) { if (!satisfied) {

26
spring-boot/src/test/java/org/springframework/boot/config/YamlProcessorTests.java

@ -24,6 +24,7 @@ import org.junit.rules.ExpectedException;
import org.springframework.boot.config.YamlProcessor.MatchCallback; import org.springframework.boot.config.YamlProcessor.MatchCallback;
import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.yaml.snakeyaml.parser.ParserException;
import org.yaml.snakeyaml.scanner.ScannerException; import org.yaml.snakeyaml.scanner.ScannerException;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -55,6 +56,31 @@ public class YamlProcessorTests {
}); });
} }
@Test
public void testStringResource() throws Exception {
this.processor.setResources(new Resource[] { new ByteArrayResource(
"foo # a document that is a literal".getBytes()) });
this.processor.process(new MatchCallback() {
@Override
public void process(Properties properties, Map<String, Object> map) {
assertEquals("foo", map.get("document"));
}
});
}
@Test
public void testBadDocumentStart() throws Exception {
this.processor.setResources(new Resource[] { new ByteArrayResource(
"foo # a document\nbar: baz".getBytes()) });
this.exception.expect(ParserException.class);
this.exception.expectMessage("line 2, column 1");
this.processor.process(new MatchCallback() {
@Override
public void process(Properties properties, Map<String, Object> map) {
}
});
}
@Test @Test
public void testBadResource() throws Exception { public void testBadResource() throws Exception {
this.processor.setResources(new Resource[] { new ByteArrayResource( this.processor.setResources(new Resource[] { new ByteArrayResource(

Loading…
Cancel
Save