Make use of custom types configurable in YamlProcessor
Prior to this commit, there was no easy way to restrict what types could be loaded from a YAML document in subclasses of YamlProcessor such as YamlPropertiesFactoryBean and YamlMapFactoryBean. This commit introduces a setSupportedTypes(Class<?>...) method in YamlProcessor in order to address this. If no supported types are configured, all types encountered in YAML documents will be supported. If an unsupported type is encountered, an IllegalStateException will be thrown when the corresponding YAML node is processed. Closes gh-25152
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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,12 +16,15 @@
|
||||
|
||||
package org.springframework.beans.factory.config;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.yaml.snakeyaml.constructor.ConstructorException;
|
||||
import org.yaml.snakeyaml.parser.ParserException;
|
||||
import org.yaml.snakeyaml.scanner.ScannerException;
|
||||
|
||||
@@ -34,6 +37,7 @@ import static org.junit.Assert.*;
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
public class YamlProcessorTests {
|
||||
|
||||
@@ -45,7 +49,7 @@ public class YamlProcessorTests {
|
||||
|
||||
@Test
|
||||
public void arrayConvertedToIndexedBeanReference() {
|
||||
this.processor.setResources(new ByteArrayResource("foo: bar\nbar: [1,2,3]".getBytes()));
|
||||
setYaml("foo: bar\nbar: [1,2,3]");
|
||||
this.processor.process((properties, map) -> {
|
||||
assertEquals(4, properties.size());
|
||||
assertEquals("bar", properties.get("foo"));
|
||||
@@ -61,13 +65,13 @@ public class YamlProcessorTests {
|
||||
|
||||
@Test
|
||||
public void testStringResource() {
|
||||
this.processor.setResources(new ByteArrayResource("foo # a document that is a literal".getBytes()));
|
||||
setYaml("foo # a document that is a literal");
|
||||
this.processor.process((properties, map) -> assertEquals("foo", map.get("document")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBadDocumentStart() {
|
||||
this.processor.setResources(new ByteArrayResource("foo # a document\nbar: baz".getBytes()));
|
||||
setYaml("foo # a document\nbar: baz");
|
||||
this.exception.expect(ParserException.class);
|
||||
this.exception.expectMessage("line 2, column 1");
|
||||
this.processor.process((properties, map) -> {});
|
||||
@@ -75,7 +79,7 @@ public class YamlProcessorTests {
|
||||
|
||||
@Test
|
||||
public void testBadResource() {
|
||||
this.processor.setResources(new ByteArrayResource("foo: bar\ncd\nspam:\n foo: baz".getBytes()));
|
||||
setYaml("foo: bar\ncd\nspam:\n foo: baz");
|
||||
this.exception.expect(ScannerException.class);
|
||||
this.exception.expectMessage("line 3, column 1");
|
||||
this.processor.process((properties, map) -> {});
|
||||
@@ -83,7 +87,7 @@ public class YamlProcessorTests {
|
||||
|
||||
@Test
|
||||
public void mapConvertedToIndexedBeanReference() {
|
||||
this.processor.setResources(new ByteArrayResource("foo: bar\nbar:\n spam: bucket".getBytes()));
|
||||
setYaml("foo: bar\nbar:\n spam: bucket");
|
||||
this.processor.process((properties, map) -> {
|
||||
assertEquals("bucket", properties.get("bar.spam"));
|
||||
assertEquals(2, properties.size());
|
||||
@@ -92,7 +96,7 @@ public class YamlProcessorTests {
|
||||
|
||||
@Test
|
||||
public void integerKeyBehaves() {
|
||||
this.processor.setResources(new ByteArrayResource("foo: bar\n1: bar".getBytes()));
|
||||
setYaml("foo: bar\n1: bar");
|
||||
this.processor.process((properties, map) -> {
|
||||
assertEquals("bar", properties.get("[1]"));
|
||||
assertEquals(2, properties.size());
|
||||
@@ -101,7 +105,7 @@ public class YamlProcessorTests {
|
||||
|
||||
@Test
|
||||
public void integerDeepKeyBehaves() {
|
||||
this.processor.setResources(new ByteArrayResource("foo:\n 1: bar".getBytes()));
|
||||
setYaml("foo:\n 1: bar");
|
||||
this.processor.process((properties, map) -> {
|
||||
assertEquals("bar", properties.get("foo[1]"));
|
||||
assertEquals(1, properties.size());
|
||||
@@ -111,7 +115,7 @@ public class YamlProcessorTests {
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void flattenedMapIsSameAsPropertiesButOrdered() {
|
||||
this.processor.setResources(new ByteArrayResource("foo: bar\nbar:\n spam: bucket".getBytes()));
|
||||
setYaml("foo: bar\nbar:\n spam: bucket");
|
||||
this.processor.process((properties, map) -> {
|
||||
assertEquals("bucket", properties.get("bar.spam"));
|
||||
assertEquals(2, properties.size());
|
||||
@@ -124,4 +128,47 @@ public class YamlProcessorTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customTypeSupportedByDefault() throws Exception {
|
||||
URL url = new URL("https://localhost:9000/");
|
||||
setYaml("value: !!java.net.URL [\"" + url + "\"]");
|
||||
|
||||
this.processor.process((properties, map) -> {
|
||||
assertEquals(1, properties.size());
|
||||
assertEquals(1, map.size());
|
||||
assertEquals(url, properties.get("value"));
|
||||
assertEquals(url, map.get("value"));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customTypesSupportedDueToExplicitConfiguration() throws Exception {
|
||||
this.processor.setSupportedTypes(URL.class, String.class);
|
||||
|
||||
URL url = new URL("https://localhost:9000/");
|
||||
setYaml("value: !!java.net.URL [!!java.lang.String [\"" + url + "\"]]");
|
||||
|
||||
this.processor.process((properties, map) -> {
|
||||
assertEquals(1, properties.size());
|
||||
assertEquals(1, map.size());
|
||||
assertEquals(url, properties.get("value"));
|
||||
assertEquals(url, map.get("value"));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customTypeNotSupportedDueToExplicitConfiguration() {
|
||||
this.processor.setSupportedTypes(List.class);
|
||||
|
||||
setYaml("value: !!java.net.URL [\"https://localhost:9000/\"]");
|
||||
|
||||
this.exception.expect(ConstructorException.class);
|
||||
this.exception.expectMessage("Unsupported type encountered in YAML document: java.net.URL");
|
||||
this.processor.process((properties, map) -> {});
|
||||
}
|
||||
|
||||
private void setYaml(String yaml) {
|
||||
this.processor.setResources(new ByteArrayResource(yaml.getBytes()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user