Commit 4e3d2803 authored by Madhura Bhave's avatar Madhura Bhave Committed by Phillip Webb

Delete deprecate relaxed binder code

Remove the deprecated relaxed binder code that has now been replaced
with the configuration properties binder.

Closes gh-9000
parent 5edb1194
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.bind;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
* {@link PropertyNamePatternsMatcher} that matches when a property name exactly matches
* one of the given names, or starts with one of the given names followed by a delimiter.
* This implementation is optimized for frequent calls.
*
* @author Phillip Webb
* @since 1.2.0
*/
@Deprecated
class DefaultPropertyNamePatternsMatcher implements PropertyNamePatternsMatcher {
private final char[] delimiters;
private final boolean ignoreCase;
private final String[] names;
protected DefaultPropertyNamePatternsMatcher(char[] delimiters, String... names) {
this(delimiters, false, names);
}
protected DefaultPropertyNamePatternsMatcher(char[] delimiters, boolean ignoreCase,
String... names) {
this(delimiters, ignoreCase, new HashSet<>(Arrays.asList(names)));
}
DefaultPropertyNamePatternsMatcher(char[] delimiters, boolean ignoreCase,
Set<String> names) {
this.delimiters = delimiters;
this.ignoreCase = ignoreCase;
this.names = names.toArray(new String[names.size()]);
}
@Override
public boolean matches(String propertyName) {
char[] propertyNameChars = propertyName.toCharArray();
boolean[] match = new boolean[this.names.length];
boolean noneMatched = true;
for (int i = 0; i < this.names.length; i++) {
if (this.names[i].length() <= propertyNameChars.length) {
match[i] = true;
noneMatched = false;
}
}
if (noneMatched) {
return false;
}
for (int charIndex = 0; charIndex < propertyNameChars.length; charIndex++) {
for (int nameIndex = 0; nameIndex < this.names.length; nameIndex++) {
if (match[nameIndex]) {
match[nameIndex] = false;
if (charIndex < this.names[nameIndex].length()) {
if (isCharMatch(this.names[nameIndex].charAt(charIndex),
propertyNameChars[charIndex])) {
match[nameIndex] = true;
noneMatched = false;
}
}
else {
char charAfter = propertyNameChars[this.names[nameIndex]
.length()];
if (isDelimiter(charAfter)) {
match[nameIndex] = true;
noneMatched = false;
}
}
}
}
if (noneMatched) {
return false;
}
}
for (int i = 0; i < match.length; i++) {
if (match[i]) {
return true;
}
}
return false;
}
private boolean isCharMatch(char c1, char c2) {
if (this.ignoreCase) {
return Character.toLowerCase(c1) == Character.toLowerCase(c2);
}
return c1 == c2;
}
private boolean isDelimiter(char c) {
for (char delimiter : this.delimiters) {
if (c == delimiter) {
return true;
}
}
return false;
}
}
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.bind;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.PropertySources;
/**
* Convenience class for manipulating PropertySources.
*
* @author Dave Syer
* @see PropertySource
* @see PropertySources
*/
@Deprecated
public abstract class PropertySourceUtils {
/**
* Return a Map of all values from the specified {@link PropertySources} that start
* with a particular key.
* @param propertySources the property sources to scan
* @param keyPrefix the key prefixes to test
* @return a map of all sub properties starting with the specified key prefixes.
* @see PropertySourceUtils#getSubProperties(PropertySources, String, String)
*/
public static Map<String, Object> getSubProperties(PropertySources propertySources,
String keyPrefix) {
return PropertySourceUtils.getSubProperties(propertySources, null, keyPrefix);
}
/**
* Return a Map of all values from the specified {@link PropertySources} that start
* with a particular key.
* @param propertySources the property sources to scan
* @param rootPrefix a root prefix to be prepended to the keyPrefix (can be
* {@code null})
* @param keyPrefix the key prefixes to test
* @return a map of all sub properties starting with the specified key prefixes.
* @see #getSubProperties(PropertySources, String, String)
*/
public static Map<String, Object> getSubProperties(PropertySources propertySources,
String rootPrefix, String keyPrefix) {
RelaxedNames keyPrefixes = new RelaxedNames(keyPrefix);
Map<String, Object> subProperties = new LinkedHashMap<>();
for (PropertySource<?> source : propertySources) {
if (source instanceof EnumerablePropertySource) {
for (String name : ((EnumerablePropertySource<?>) source)
.getPropertyNames()) {
String key = PropertySourceUtils.getSubKey(name, rootPrefix,
keyPrefixes);
if (key != null && !subProperties.containsKey(key)) {
subProperties.put(key, source.getProperty(name));
}
}
}
}
return Collections.unmodifiableMap(subProperties);
}
private static String getSubKey(String name, String rootPrefixes,
RelaxedNames keyPrefix) {
rootPrefixes = (rootPrefixes == null ? "" : rootPrefixes);
for (String rootPrefix : new RelaxedNames(rootPrefixes)) {
for (String candidateKeyPrefix : keyPrefix) {
if (name.startsWith(rootPrefix + candidateKeyPrefix)) {
return name.substring((rootPrefix + candidateKeyPrefix).length());
}
}
}
return null;
}
}
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.bind;
import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.PropertySources;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindException;
/**
* Helper extracting info from {@link PropertySources}.
*
* @author Stephane Nicoll
* @since 1.4.0
*/
@Deprecated
public class PropertySourcesBinder {
private PropertySources propertySources;
private ConversionService conversionService;
/**
* Create a new instance.
* @param propertySources the {@link PropertySources} to use
*/
public PropertySourcesBinder(PropertySources propertySources) {
this.propertySources = propertySources;
}
/**
* Create a new instance from a single {@link PropertySource}.
* @param propertySource the {@link PropertySource} to use
*/
public PropertySourcesBinder(PropertySource<?> propertySource) {
this(createPropertySources(propertySource));
}
/**
* Create a new instance using the {@link Environment} as the property sources.
* @param environment the environment
*/
public PropertySourcesBinder(ConfigurableEnvironment environment) {
this(environment.getPropertySources());
}
public void setPropertySources(PropertySources propertySources) {
this.propertySources = propertySources;
}
public PropertySources getPropertySources() {
return this.propertySources;
}
public void setConversionService(ConversionService conversionService) {
this.conversionService = conversionService;
}
public ConversionService getConversionService() {
return this.conversionService;
}
/**
* Extract the keys using the specified {@code prefix}. The prefix won't be included.
* <p>
* Any key that starts with the {@code prefix} will be included.
* @param prefix the prefix to use
* @return the keys matching the prefix
*/
public Map<String, Object> extractAll(String prefix) {
Map<String, Object> content = new LinkedHashMap<>();
bindTo(prefix, content);
return content;
}
/**
* Bind the specified {@code target} from the environment using the {@code prefix}.
* <p>
* Any key that starts with the {@code prefix} will be bound to the {@code target}.
* @param prefix the prefix to use
* @param target the object to bind to
*/
public void bindTo(String prefix, Object target) {
PropertiesConfigurationFactory<Object> factory = new PropertiesConfigurationFactory<>(
target);
if (StringUtils.hasText(prefix)) {
factory.setTargetName(prefix);
}
if (this.conversionService != null) {
factory.setConversionService(this.conversionService);
}
factory.setPropertySources(this.propertySources);
try {
factory.bindPropertiesToTarget();
}
catch (BindException ex) {
throw new IllegalStateException("Cannot bind to " + target, ex);
}
}
private static PropertySources createPropertySources(
PropertySource<?> propertySource) {
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addLast(propertySource);
return propertySources;
}
}
......@@ -30,7 +30,6 @@ import org.springframework.util.StringUtils;
* @author Phillip Webb
* @author Dave Syer
* @see RelaxedDataBinder
* @see RelaxedPropertyResolver
*/
@Deprecated
public final class RelaxedNames implements Iterable<String> {
......
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.bind;
import java.util.Map;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertyResolver;
import org.springframework.core.env.PropertySourcesPropertyResolver;
import org.springframework.util.Assert;
/**
* {@link PropertyResolver} that attempts to resolve values using {@link RelaxedNames}.
*
* @author Phillip Webb
* @see RelaxedNames
*/
@Deprecated
public class RelaxedPropertyResolver implements PropertyResolver {
private final PropertyResolver resolver;
private final String prefix;
public RelaxedPropertyResolver(PropertyResolver resolver) {
this(resolver, null);
}
public RelaxedPropertyResolver(PropertyResolver resolver, String prefix) {
Assert.notNull(resolver, "PropertyResolver must not be null");
this.resolver = resolver;
this.prefix = (prefix == null ? "" : prefix);
}
@Override
public String getRequiredProperty(String key) throws IllegalStateException {
return getRequiredProperty(key, String.class);
}
@Override
public <T> T getRequiredProperty(String key, Class<T> targetType)
throws IllegalStateException {
T value = getProperty(key, targetType);
Assert.state(value != null, String.format("required key [%s] not found", key));
return value;
}
@Override
public String getProperty(String key) {
return getProperty(key, String.class, null);
}
@Override
public String getProperty(String key, String defaultValue) {
return getProperty(key, String.class, defaultValue);
}
@Override
public <T> T getProperty(String key, Class<T> targetType) {
return getProperty(key, targetType, null);
}
@Override
public <T> T getProperty(String key, Class<T> targetType, T defaultValue) {
RelaxedNames prefixes = new RelaxedNames(this.prefix);
RelaxedNames keys = new RelaxedNames(key);
for (String prefix : prefixes) {
for (String relaxedKey : keys) {
if (this.resolver.containsProperty(prefix + relaxedKey)) {
return this.resolver.getProperty(prefix + relaxedKey, targetType);
}
}
}
return defaultValue;
}
@Override
public boolean containsProperty(String key) {
RelaxedNames prefixes = new RelaxedNames(this.prefix);
RelaxedNames keys = new RelaxedNames(key);
for (String prefix : prefixes) {
for (String relaxedKey : keys) {
if (this.resolver.containsProperty(prefix + relaxedKey)) {
return true;
}
}
}
return false;
}
@Override
public String resolvePlaceholders(String text) {
throw new UnsupportedOperationException(
"Unable to resolve placeholders with relaxed properties");
}
@Override
public String resolveRequiredPlaceholders(String text)
throws IllegalArgumentException {
throw new UnsupportedOperationException(
"Unable to resolve placeholders with relaxed properties");
}
/**
* Return a Map of all values from all underlying properties that start with the
* specified key. NOTE: this method can only be used if the underlying resolver is a
* {@link ConfigurableEnvironment}.
* @param keyPrefix the key prefix used to filter results
* @return a map of all sub properties starting with the specified key prefix.
* @see PropertySourceUtils#getSubProperties
*/
public Map<String, Object> getSubProperties(String keyPrefix) {
Assert.isInstanceOf(ConfigurableEnvironment.class, this.resolver,
"SubProperties not available.");
ConfigurableEnvironment env = (ConfigurableEnvironment) this.resolver;
return PropertySourceUtils.getSubProperties(env.getPropertySources(), this.prefix,
keyPrefix);
}
/**
* Return a property resolver for the environment, preferring one that ignores
* unresolvable nested placeholders.
* @param environment the source environment
* @param prefix the prefix
* @return a property resolver for the environment
* @since 1.4.3
*/
public static RelaxedPropertyResolver ignoringUnresolvableNestedPlaceholders(
Environment environment, String prefix) {
Assert.notNull(environment, "Environment must not be null");
PropertyResolver resolver = environment;
if (environment instanceof ConfigurableEnvironment) {
resolver = new PropertySourcesPropertyResolver(
((ConfigurableEnvironment) environment).getPropertySources());
((PropertySourcesPropertyResolver) resolver)
.setIgnoreUnresolvableNestedPlaceholders(true);
}
return new RelaxedPropertyResolver(resolver, prefix);
}
}
/*
* Copyright 2012-2016 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.bind;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link DefaultPropertyNamePatternsMatcher}.
*
* @author Phillip Webb
*/
public class DefaultPropertyNamePatternsMatcherTests {
private static final char[] DELIMITERS = { '.', '_' };
@Test
public void namesShorter() {
assertThat(new DefaultPropertyNamePatternsMatcher(DELIMITERS, "aaaa", "bbbb")
.matches("zzzzz")).isFalse();
}
@Test
public void namesExactMatch() {
assertThat(
new DefaultPropertyNamePatternsMatcher(DELIMITERS, "aaaa", "bbbb", "cccc")
.matches("bbbb")).isTrue();
}
@Test
public void namesLonger() {
assertThat(new DefaultPropertyNamePatternsMatcher(DELIMITERS, "aaaaa", "bbbbb",
"ccccc").matches("bbbb")).isFalse();
}
@Test
public void nameWithDot() throws Exception {
assertThat(
new DefaultPropertyNamePatternsMatcher(DELIMITERS, "aaaa", "bbbb", "cccc")
.matches("bbbb.anything")).isTrue();
}
@Test
public void nameWithUnderscore() throws Exception {
assertThat(
new DefaultPropertyNamePatternsMatcher(DELIMITERS, "aaaa", "bbbb", "cccc")
.matches("bbbb_anything")).isTrue();
}
@Test
public void namesMatchWithDifferentLengths() throws Exception {
assertThat(
new DefaultPropertyNamePatternsMatcher(DELIMITERS, "aaa", "bbbb", "ccccc")
.matches("bbbb")).isTrue();
}
@Test
public void withSquareBrackets() throws Exception {
char[] delimiters = "._[".toCharArray();
PropertyNamePatternsMatcher matcher = new DefaultPropertyNamePatternsMatcher(
delimiters, "aaa", "bbbb", "ccccc");
assertThat(matcher.matches("bbbb")).isTrue();
assertThat(matcher.matches("bbbb[4]")).isTrue();
assertThat(matcher.matches("bbb[4]")).isFalse();
}
}
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.bind;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.junit.Test;
import org.springframework.context.support.StaticMessageSource;
import org.springframework.core.env.CompositePropertySource;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.validation.Validator;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link PropertiesConfigurationFactory} binding to a map.
*
* @author Dave Syer
*/
public class PropertiesConfigurationFactoryMapTests {
private PropertiesConfigurationFactory<Foo> factory;
private Validator validator;
private boolean ignoreUnknownFields = true;
private String targetName = null;
@Test
public void testValidPropertiesLoadsWithNoErrors() throws Exception {
Foo foo = createFoo("map.name: blah\nmap.bar: blah");
assertThat(foo.map.get("bar")).isEqualTo("blah");
assertThat(foo.map.get("name")).isEqualTo("blah");
}
@Test
public void testBindToNamedTarget() throws Exception {
this.targetName = "foo";
Foo foo = createFoo("hi: hello\nfoo.map.name: foo\nfoo.map.bar: blah");
assertThat(foo.map.get("bar")).isEqualTo("blah");
}
@Test
public void testBindFromPropertySource() throws Exception {
this.targetName = "foo";
setupFactory();
MutablePropertySources sources = new MutablePropertySources();
sources.addFirst(new MapPropertySource("map",
Collections.singletonMap("foo.map.name", (Object) "blah")));
this.factory.setPropertySources(sources);
this.factory.afterPropertiesSet();
Foo foo = this.factory.getObject();
assertThat(foo.map.get("name")).isEqualTo("blah");
}
@Test
public void testBindFromCompositePropertySource() throws Exception {
this.targetName = "foo";
setupFactory();
MutablePropertySources sources = new MutablePropertySources();
CompositePropertySource composite = new CompositePropertySource("composite");
composite.addPropertySource(new MapPropertySource("map",
Collections.singletonMap("foo.map.name", (Object) "blah")));
sources.addFirst(composite);
this.factory.setPropertySources(sources);
this.factory.afterPropertiesSet();
Foo foo = this.factory.getObject();
assertThat(foo.map.get("name")).isEqualTo("blah");
}
private Foo createFoo(final String values) throws Exception {
setupFactory();
return bindFoo(values);
}
private Foo bindFoo(final String values) throws Exception {
Properties properties = PropertiesLoaderUtils
.loadProperties(new ByteArrayResource(values.getBytes()));
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addFirst(new PropertiesPropertySource("test", properties));
this.factory.setPropertySources(propertySources);
this.factory.afterPropertiesSet();
return this.factory.getObject();
}
private void setupFactory() throws IOException {
this.factory = new PropertiesConfigurationFactory<>(Foo.class);
this.factory.setValidator(this.validator);
this.factory.setTargetName(this.targetName);
this.factory.setIgnoreUnknownFields(this.ignoreUnknownFields);
this.factory.setMessageSource(new StaticMessageSource());
}
// Foo needs to be public and to have setters for all properties
public static class Foo {
private Map<String, Object> map = new HashMap<>();
public Map<String, Object> getMap() {
return this.map;
}
public void setMap(Map<String, Object> map) {
this.map = map;
}
}
}
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.bind;
import java.io.IOException;
import java.util.Properties;
import javax.validation.constraints.NotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.springframework.context.support.StaticMessageSource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Parameterized tests for {@link PropertiesConfigurationFactory}
*
* @author Dave Syer
* @author Andy Wilkinson
*/
@RunWith(Parameterized.class)
public class PropertiesConfigurationFactoryParameterizedTests {
private String targetName;
private PropertiesConfigurationFactory<Foo> factory = new PropertiesConfigurationFactory<>(
Foo.class);
@Parameters
public static Object[] parameters() {
return new Object[] { new Object[] { false }, new Object[] { true } };
}
public PropertiesConfigurationFactoryParameterizedTests(boolean ignoreUnknownFields) {
this.factory.setIgnoreUnknownFields(ignoreUnknownFields);
}
@Test
public void testValidPropertiesLoadsWithNoErrors() throws Exception {
Foo foo = createFoo("name: blah\nbar: blah");
assertThat(foo.bar).isEqualTo("blah");
assertThat(foo.name).isEqualTo("blah");
}
@Test
public void testValidPropertiesLoadsWithUpperCase() throws Exception {
Foo foo = createFoo("NAME: blah\nbar: blah");
assertThat(foo.bar).isEqualTo("blah");
assertThat(foo.name).isEqualTo("blah");
}
@Test
public void testUnderscore() throws Exception {
Foo foo = createFoo("spring_foo_baz: blah\nname: blah");
assertThat(foo.spring_foo_baz).isEqualTo("blah");
assertThat(foo.name).isEqualTo("blah");
}
@Test
public void testBindToNamedTarget() throws Exception {
this.targetName = "foo";
Foo foo = createFoo("hi: hello\nfoo.name: foo\nfoo.bar: blah");
assertThat(foo.bar).isEqualTo("blah");
}
@Test
public void testBindToNamedTargetUppercaseUnderscores() throws Exception {
this.targetName = "foo";
Foo foo = createFoo("FOO_NAME: foo\nFOO_BAR: blah");
assertThat(foo.bar).isEqualTo("blah");
}
private Foo createFoo(final String values) throws Exception {
setupFactory();
return bindFoo(values);
}
private Foo bindFoo(final String values) throws Exception {
Properties properties = PropertiesLoaderUtils
.loadProperties(new ByteArrayResource(values.getBytes()));
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addFirst(new PropertiesPropertySource("test", properties));
this.factory.setPropertySources(propertySources);
this.factory.afterPropertiesSet();
return this.factory.getObject();
}
private void setupFactory() throws IOException {
this.factory.setTargetName(this.targetName);
this.factory.setMessageSource(new StaticMessageSource());
}
// Foo needs to be public and to have setters for all properties
public static class Foo {
@NotNull
private String name;
private String bar;
private String spring_foo_baz;
private String fooBar;
public String getSpringFooBaz() {
return this.spring_foo_baz;
}
public void setSpringFooBaz(String spring_foo_baz) {
this.spring_foo_baz = spring_foo_baz;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getBar() {
return this.bar;
}
public void setBar(String bar) {
this.bar = bar;
}
public String getFooBar() {
return this.fooBar;
}
public void setFooBar(String fooBar) {
this.fooBar = fooBar;
}
}
}
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.bind;
import java.io.IOException;
import javax.validation.constraints.NotNull;
import org.junit.BeforeClass;
import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;
import org.springframework.context.support.StaticMessageSource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.test.context.support.TestPropertySourceUtils;
import org.springframework.validation.Validator;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Performance tests for {@link PropertiesConfigurationFactory}.
*
* @author Dave Syer
*/
@RunWith(Theories.class)
public class PropertiesConfigurationFactoryPerformanceTests {
@DataPoints
public static String[] values = new String[1000];
private PropertiesConfigurationFactory<Foo> factory;
private Validator validator;
private boolean ignoreUnknownFields = true;
private String targetName = null;
private static StandardEnvironment environment = new StandardEnvironment();
@BeforeClass
public static void init() {
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(environment,
"name=blah", "bar=blah");
}
@Theory
public void testValidProperties(String value) throws Exception {
Foo foo = createFoo();
assertThat(foo.bar).isEqualTo("blah");
assertThat(foo.name).isEqualTo("blah");
}
private Foo createFoo() throws Exception {
setupFactory();
this.factory.setPropertySources(environment.getPropertySources());
this.factory.afterPropertiesSet();
return this.factory.getObject();
}
private void setupFactory() throws IOException {
this.factory = new PropertiesConfigurationFactory<>(Foo.class);
this.factory.setValidator(this.validator);
this.factory.setTargetName(this.targetName);
this.factory.setIgnoreUnknownFields(this.ignoreUnknownFields);
this.factory.setMessageSource(new StaticMessageSource());
}
// Foo needs to be public and to have setters for all properties
public static class Foo {
@NotNull
private String name;
private String bar;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getBar() {
return this.bar;
}
public void setBar(String bar) {
this.bar = bar;
}
}
}
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.bind;
import java.io.IOException;
import java.util.Collections;
import java.util.Properties;
import javax.validation.Validation;
import javax.validation.constraints.NotNull;
import org.junit.Test;
import org.springframework.beans.NotWritablePropertyException;
import org.springframework.boot.env.RandomValuePropertySource;
import org.springframework.context.support.StaticMessageSource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.env.SystemEnvironmentPropertySource;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.mock.env.MockPropertySource;
import org.springframework.validation.BindException;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.SpringValidatorAdapter;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link PropertiesConfigurationFactory}.
*
* @author Dave Syer
*/
public class PropertiesConfigurationFactoryTests {
private PropertiesConfigurationFactory<Foo> factory;
private Validator validator;
private boolean ignoreUnknownFields = true;
private String targetName = null;
@Test
public void testValidPropertiesLoadsWithDash() throws Exception {
this.ignoreUnknownFields = false;
Foo foo = createFoo("na-me: blah\nbar: blah");
assertThat(foo.bar).isEqualTo("blah");
assertThat(foo.name).isEqualTo("blah");
}
@Test
public void testUnknownPropertyOkByDefault() throws Exception {
Foo foo = createFoo("hi: hello\nname: foo\nbar: blah");
assertThat(foo.bar).isEqualTo("blah");
}
@Test(expected = NotWritablePropertyException.class)
public void testUnknownPropertyCausesLoadFailure() throws Exception {
this.ignoreUnknownFields = false;
createFoo("hi: hello\nname: foo\nbar: blah");
}
@Test(expected = BindException.class)
public void testMissingPropertyCausesValidationError() throws Exception {
this.validator = new SpringValidatorAdapter(
Validation.buildDefaultValidatorFactory().getValidator());
createFoo("bar: blah");
}
@Test
public void systemEnvironmentBindingFailuresAreIgnored() throws Exception {
setupFactory();
MutablePropertySources propertySources = new MutablePropertySources();
MockPropertySource propertySource = new MockPropertySource(
StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME);
propertySource.setProperty("doesNotExist", "foo");
propertySource.setProperty("name", "bar");
propertySources.addFirst(propertySource);
this.factory.setPropertySources(propertySources);
this.factory.setIgnoreUnknownFields(false);
this.factory.afterPropertiesSet();
Foo foo = this.factory.getObject();
assertThat(foo.name).isEqualTo("bar");
}
@Test
public void systemEnvironmentBindingWithDefaults() throws Exception {
setupFactory();
MutablePropertySources propertySources = new MutablePropertySources();
MockPropertySource propertySource = new MockPropertySource(
StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME);
propertySource.setProperty("name", "${foo.name:bar}");
propertySources.addFirst(propertySource);
this.factory.setPropertySources(propertySources);
this.factory.afterPropertiesSet();
Foo foo = this.factory.getObject();
assertThat(foo.name).isEqualTo("bar");
}
@Test
public void systemEnvironmentNoResolvePlaceholders() throws Exception {
setupFactory();
MutablePropertySources propertySources = new MutablePropertySources();
MockPropertySource propertySource = new MockPropertySource(
StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME);
propertySource.setProperty("name", "${foo.name:bar}");
propertySources.addFirst(propertySource);
this.factory.setPropertySources(propertySources);
this.factory.setResolvePlaceholders(false);
this.factory.afterPropertiesSet();
Foo foo = this.factory.getObject();
assertThat(foo.name).isEqualTo("${foo.name:bar}");
}
@Test
public void systemPropertyBindingFailuresAreIgnored() throws Exception {
setupFactory();
MutablePropertySources propertySources = new MutablePropertySources();
MockPropertySource propertySource = new MockPropertySource(
StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME);
propertySource.setProperty("doesNotExist", "foo");
propertySource.setProperty("name", "bar");
propertySources.addFirst(propertySource);
this.factory.setPropertySources(propertySources);
this.factory.setIgnoreUnknownFields(false);
this.factory.afterPropertiesSet();
}
@Test
public void testBindWithDashPrefix() throws Exception {
// gh-4045
this.targetName = "foo-bar";
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addLast(new SystemEnvironmentPropertySource("systemEnvironment",
Collections.<String, Object>singletonMap("FOO_BAR_NAME", "blah")));
propertySources.addLast(new RandomValuePropertySource());
setupFactory();
this.factory.setPropertySources(propertySources);
this.factory.afterPropertiesSet();
Foo foo = this.factory.getObject();
assertThat(foo.name).isEqualTo("blah");
}
@Test
public void testBindWithDelimitedPrefixUsingMatchingDelimiter() throws Exception {
this.targetName = "env_foo";
this.ignoreUnknownFields = false;
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addLast(new SystemEnvironmentPropertySource("systemEnvironment",
Collections.<String, Object>singletonMap("ENV_FOO_NAME", "blah")));
propertySources.addLast(new RandomValuePropertySource("random"));
setupFactory();
this.factory.setPropertySources(propertySources);
this.factory.afterPropertiesSet();
Foo foo = this.factory.getObject();
assertThat(foo.name).isEqualTo("blah");
}
@Test
public void testBindWithDelimitedPrefixUsingDifferentDelimiter() throws Exception {
this.targetName = "env.foo";
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addLast(new SystemEnvironmentPropertySource("systemEnvironment",
Collections.<String, Object>singletonMap("ENV_FOO_NAME", "blah")));
propertySources.addLast(new RandomValuePropertySource("random"));
this.ignoreUnknownFields = false;
setupFactory();
this.factory.setPropertySources(propertySources);
this.factory.afterPropertiesSet();
Foo foo = this.factory.getObject();
assertThat(foo.name).isEqualTo("blah");
}
@Test
public void propertyWithAllUpperCaseSuffixCanBeBound() throws Exception {
Foo foo = createFoo("foo-bar-u-r-i:baz");
assertThat(foo.fooBarURI).isEqualTo("baz");
}
@Test
public void propertyWithAllUpperCaseInTheMiddleCanBeBound() throws Exception {
Foo foo = createFoo("foo-d-l-q-bar:baz");
assertThat(foo.fooDLQBar).isEqualTo(("baz"));
}
private Foo createFoo(final String values) throws Exception {
setupFactory();
return bindFoo(values);
}
private Foo bindFoo(final String values) throws Exception {
Properties properties = PropertiesLoaderUtils
.loadProperties(new ByteArrayResource(values.getBytes()));
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addFirst(new PropertiesPropertySource("test", properties));
this.factory.setPropertySources(propertySources);
this.factory.afterPropertiesSet();
return this.factory.getObject();
}
private void setupFactory() throws IOException {
this.factory = new PropertiesConfigurationFactory<>(Foo.class);
this.factory.setValidator(this.validator);
this.factory.setTargetName(this.targetName);
this.factory.setIgnoreUnknownFields(this.ignoreUnknownFields);
this.factory.setMessageSource(new StaticMessageSource());
}
// Foo needs to be public and to have setters for all properties
public static class Foo {
@NotNull
private String name;
private String bar;
private String spring_foo_baz;
private String fooBar;
private String fooBarURI;
private String fooDLQBar;
public String getSpringFooBaz() {
return this.spring_foo_baz;
}
public void setSpringFooBaz(String spring_foo_baz) {
this.spring_foo_baz = spring_foo_baz;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getBar() {
return this.bar;
}
public void setBar(String bar) {
this.bar = bar;
}
public String getFooBar() {
return this.fooBar;
}
public void setFooBar(String fooBar) {
this.fooBar = fooBar;
}
public String getFooBarURI() {
return this.fooBarURI;
}
public void setFooBarURI(String fooBarURI) {
this.fooBarURI = fooBarURI;
}
public String getFooDLQBar() {
return this.fooDLQBar;
}
public void setFooDLQBar(String fooDLQBar) {
this.fooDLQBar = fooDLQBar;
}
}
}
/*
* Copyright 2012-2016 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.bind;
import java.util.Map;
import org.junit.Test;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.test.context.support.TestPropertySourceUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link PropertySourcesBinder}.
*
* @author Stephane Nicoll
*/
public class PropertySourcesBinderTests {
private StandardEnvironment env = new StandardEnvironment();
@Test
public void extractAllWithPrefix() {
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.env, "foo.first=1",
"foo.second=2");
Map<String, Object> content = new PropertySourcesBinder(this.env)
.extractAll("foo");
assertThat(content.get("first")).isEqualTo("1");
assertThat(content.get("second")).isEqualTo("2");
assertThat(content).hasSize(2);
}
@Test
@SuppressWarnings("unchecked")
public void extractNoPrefix() {
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.env,
"foo.ctx.first=1", "foo.ctx.second=2");
Map<String, Object> content = new PropertySourcesBinder(this.env).extractAll("");
assertThat(content.get("foo")).isInstanceOf(Map.class);
Map<String, Object> foo = (Map<String, Object>) content.get("foo");
assertThat(content.get("foo")).isInstanceOf(Map.class);
Map<String, Object> ctx = (Map<String, Object>) foo.get("ctx");
assertThat(ctx.get("first")).isEqualTo("1");
assertThat(ctx.get("second")).isEqualTo("2");
assertThat(ctx).hasSize(2);
assertThat(foo).hasSize(1);
}
@Test
public void bindToSimplePojo() {
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.env,
"test.name=foo", "test.counter=42");
TestBean bean = new TestBean();
new PropertySourcesBinder(this.env).bindTo("test", bean);
assertThat(bean.getName()).isEqualTo("foo");
assertThat(bean.getCounter()).isEqualTo(42);
}
@SuppressWarnings("unused")
private static class TestBean {
private String name;
private Integer counter;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Integer getCounter() {
return this.counter;
}
public void setCounter(Integer counter) {
this.counter = counter;
}
}
}
/*
* Copyright 2012-2016 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.bind;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.bind.PropertySourcesBindingTests.TestConfig;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link PropertySourcesPropertyValues} binding.
*
* @author Dave Syer
*/
@RunWith(SpringRunner.class)
@DirtiesContext
@ContextConfiguration(classes = TestConfig.class, loader = SpringApplicationBindContextLoader.class)
public class PropertySourcesBindingTests {
@Value("${foo:}")
private String foo;
@Autowired
private Wrapper properties;
@Test
public void overridingOfPropertiesOrderOfAtPropertySources() {
assertThat(this.properties.getBar()).isEqualTo("override");
}
@Test
public void overridingOfPropertiesOrderOfAtPropertySourcesWherePropertyIsCapitalized() {
assertThat(this.properties.getSpam()).isEqualTo("BUCKET");
}
@Test
public void overridingOfPropertiesOrderOfAtPropertySourcesWherePropertyNamesDiffer() {
assertThat(this.properties.getTheName()).isEqualTo("NAME");
}
@Test
public void overridingOfPropertiesAndBindToAtValue() {
assertThat(this.foo).isEqualTo(this.properties.getFoo());
}
@Test
public void overridingOfPropertiesOrderOfApplicationProperties() {
assertThat(this.properties.getFoo()).isEqualTo("bucket");
}
@Import({ SomeConfig.class })
@PropertySources({ @PropertySource("classpath:/some.properties"),
@PropertySource("classpath:/override.properties") })
@Configuration
@EnableConfigurationProperties(Wrapper.class)
public static class TestConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
@Configuration
@PropertySources({ @PropertySource("classpath:/override.properties"),
@PropertySource("classpath:/some.properties") })
public static class SomeConfig {
}
@ConfigurationProperties
public static class Wrapper {
private String foo;
private String bar;
private String spam;
private String theName;
public String getBar() {
return this.bar;
}
public void setBar(String bar) {
this.bar = bar;
}
public String getFoo() {
return this.foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
public String getSpam() {
return this.spam;
}
public void setSpam(String spam) {
this.spam = spam;
}
public String getTheName() {
return this.theName;
}
public void setTheName(String theName) {
this.theName = theName;
}
}
}
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.bind;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.PropertyValue;
import org.springframework.core.env.CompositePropertySource;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.validation.DataBinder;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link PropertySourcesPropertyValues}.
*
* @author Dave Syer
* @author Phillip Webb
* @author Stephane Nicoll
*/
public class PropertySourcesPropertyValuesTests {
private final MutablePropertySources propertySources = new MutablePropertySources();
@Before
public void init() {
this.propertySources.addFirst(new PropertySource<String>("static", "foo") {
@Override
public Object getProperty(String name) {
if (name.equals(getSource())) {
return "bar";
}
return null;
}
});
this.propertySources.addFirst(new MapPropertySource("map",
Collections.<String, Object>singletonMap("name", "${foo}")));
}
@Test
public void testTypesPreserved() {
Map<String, Object> map = Collections.<String, Object>singletonMap("name", 123);
this.propertySources.replace("map", new MapPropertySource("map", map));
PropertySourcesPropertyValues propertyValues = new PropertySourcesPropertyValues(
this.propertySources);
assertThat(propertyValues.getPropertyValues()[0].getValue()).isEqualTo(123);
}
@Test
public void testSize() {
PropertySourcesPropertyValues propertyValues = new PropertySourcesPropertyValues(
this.propertySources);
assertThat(propertyValues.getPropertyValues().length).isEqualTo(1);
}
@Test
public void testOrderPreserved() {
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
map.put("one", 1);
map.put("two", 2);
map.put("three", 3);
map.put("four", 4);
map.put("five", 5);
this.propertySources.addFirst(new MapPropertySource("ordered", map));
PropertySourcesPropertyValues propertyValues = new PropertySourcesPropertyValues(
this.propertySources);
PropertyValue[] values = propertyValues.getPropertyValues();
assertThat(values).hasSize(6);
Collection<String> names = new ArrayList<>();
for (PropertyValue value : values) {
names.add(value.getName());
}
assertThat(names).containsExactly("one", "two", "three", "four", "five", "name");
}
@Test
public void testNonEnumeratedValue() {
PropertySourcesPropertyValues propertyValues = new PropertySourcesPropertyValues(
this.propertySources);
assertThat(propertyValues.getPropertyValue("foo").getValue()).isEqualTo("bar");
}
@Test
public void testCompositeValue() {
PropertySource<?> map = this.propertySources.get("map");
CompositePropertySource composite = new CompositePropertySource("composite");
composite.addPropertySource(map);
this.propertySources.replace("map", composite);
PropertySourcesPropertyValues propertyValues = new PropertySourcesPropertyValues(
this.propertySources);
assertThat(propertyValues.getPropertyValue("foo").getValue()).isEqualTo("bar");
}
@Test
public void testEnumeratedValue() {
PropertySourcesPropertyValues propertyValues = new PropertySourcesPropertyValues(
this.propertySources);
assertThat(propertyValues.getPropertyValue("name").getValue()).isEqualTo("bar");
}
@Test
public void testNonEnumeratedPlaceholder() {
this.propertySources.addFirst(new PropertySource<String>("another", "baz") {
@Override
public Object getProperty(String name) {
if (name.equals(getSource())) {
return "${foo}";
}
return null;
}
});
PropertySourcesPropertyValues propertyValues = new PropertySourcesPropertyValues(
this.propertySources, (Collection<String>) null,
Collections.singleton("baz"));
assertThat(propertyValues.getPropertyValue("baz").getValue()).isEqualTo("bar");
}
@Test
public void testOverriddenValue() {
this.propertySources.addFirst(new MapPropertySource("new",
Collections.<String, Object>singletonMap("name", "spam")));
PropertySourcesPropertyValues propertyValues = new PropertySourcesPropertyValues(
this.propertySources);
assertThat(propertyValues.getPropertyValue("name").getValue()).isEqualTo("spam");
}
@Test
public void testPlaceholdersBinding() {
TestBean target = new TestBean();
DataBinder binder = new DataBinder(target);
binder.bind(new PropertySourcesPropertyValues(this.propertySources));
assertThat(target.getName()).isEqualTo("bar");
}
@Test
public void testPlaceholdersBindingNonEnumerable() {
FooBean target = new FooBean();
DataBinder binder = new DataBinder(target);
binder.bind(new PropertySourcesPropertyValues(this.propertySources,
(Collection<String>) null, Collections.singleton("foo")));
assertThat(target.getFoo()).isEqualTo("bar");
}
@Test
public void testPlaceholdersBindingWithError() {
TestBean target = new TestBean();
DataBinder binder = new DataBinder(target);
this.propertySources.addFirst(new MapPropertySource("another",
Collections.<String, Object>singletonMap("something", "${nonexistent}")));
binder.bind(new PropertySourcesPropertyValues(this.propertySources));
assertThat(target.getName()).isEqualTo("bar");
}
@Test
public void testPlaceholdersErrorInNonEnumerable() {
TestBean target = new TestBean();
DataBinder binder = new DataBinder(target);
this.propertySources.addFirst(new PropertySource<Object>("application", "STUFF") {
@Override
public Object getProperty(String name) {
return new Object();
}
});
binder.bind(new PropertySourcesPropertyValues(this.propertySources,
(Collection<String>) null, Collections.singleton("name")));
assertThat(target.getName()).isNull();
}
@Test
public void testCollectionProperty() throws Exception {
ListBean target = new ListBean();
DataBinder binder = new DataBinder(target);
Map<String, Object> map = new LinkedHashMap<>();
map.put("list[0]", "v0");
map.put("list[1]", "v1");
this.propertySources.addFirst(new MapPropertySource("values", map));
binder.bind(new PropertySourcesPropertyValues(this.propertySources));
assertThat(target.getList()).containsExactly("v0", "v1");
}
@Test
public void testFirstCollectionPropertyWins() throws Exception {
ListBean target = new ListBean();
DataBinder binder = new DataBinder(target);
Map<String, Object> first = new LinkedHashMap<>();
first.put("list[0]", "f0");
Map<String, Object> second = new LinkedHashMap<>();
second.put("list[0]", "s0");
second.put("list[1]", "s1");
this.propertySources.addFirst(new MapPropertySource("s", second));
this.propertySources.addFirst(new MapPropertySource("f", first));
binder.bind(new PropertySourcesPropertyValues(this.propertySources));
assertThat(target.getList()).containsExactly("f0");
}
@Test
public void testFirstCollectionPropertyWinsNestedAttributes() throws Exception {
ListTestBean target = new ListTestBean();
DataBinder binder = new DataBinder(target);
Map<String, Object> first = new LinkedHashMap<>();
first.put("list[0].description", "another description");
Map<String, Object> second = new LinkedHashMap<>();
second.put("list[0].name", "first name");
second.put("list[0].description", "first description");
second.put("list[1].name", "second name");
second.put("list[1].description", "second description");
this.propertySources.addFirst(new MapPropertySource("s", second));
this.propertySources.addFirst(new MapPropertySource("f", first));
binder.bind(new PropertySourcesPropertyValues(this.propertySources));
assertThat(target.getList()).hasSize(1);
assertThat(target.getList().get(0).getDescription())
.isEqualTo("another description");
assertThat(target.getList().get(0).getName()).isNull();
}
public static class TestBean {
private String name;
private String description;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
}
public static class FooBean {
private String foo;
public String getFoo() {
return this.foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
}
public static class ListBean {
private List<String> list = new ArrayList<>();
public List<String> getList() {
return this.list;
}
public void setList(List<String> list) {
this.list = list;
}
}
public static class ListTestBean {
private List<TestBean> list = new ArrayList<>();
public List<TestBean> getList() {
return this.list;
}
public void setList(List<TestBean> list) {
this.list = list;
}
}
}
/*
* Copyright 2012-2016 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.bind;
import java.util.Iterator;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link RelaxedNames}.
*
* @author Phillip Webb
* @author Dave Syer
*/
public class RelaxedNamesTests {
@Test
public void iterator() throws Exception {
Iterator<String> iterator = new RelaxedNames("my-RELAXED-property").iterator();
assertThat(iterator.next()).isEqualTo("my-RELAXED-property");
assertThat(iterator.next()).isEqualTo("my_RELAXED_property");
assertThat(iterator.next()).isEqualTo("myRELAXEDProperty");
assertThat(iterator.next()).isEqualTo("myRelaxedProperty");
assertThat(iterator.next()).isEqualTo("my-relaxed-property");
assertThat(iterator.next()).isEqualTo("my_relaxed_property");
assertThat(iterator.next()).isEqualTo("myrelaxedproperty");
assertThat(iterator.next()).isEqualTo("MY-RELAXED-PROPERTY");
assertThat(iterator.next()).isEqualTo("MY_RELAXED_PROPERTY");
assertThat(iterator.next()).isEqualTo("MYRELAXEDPROPERTY");
assertThat(iterator.hasNext()).isFalse();
}
@Test
public void fromUnderscores() throws Exception {
Iterator<String> iterator = new RelaxedNames("nes_ted").iterator();
assertThat(iterator.next()).isEqualTo("nes_ted");
assertThat(iterator.next()).isEqualTo("nes.ted");
assertThat(iterator.next()).isEqualTo("nesTed");
assertThat(iterator.next()).isEqualTo("nested");
assertThat(iterator.next()).isEqualTo("NES_TED");
assertThat(iterator.next()).isEqualTo("NES.TED");
assertThat(iterator.next()).isEqualTo("NESTED");
assertThat(iterator.hasNext()).isFalse();
}
@Test
public void fromPlain() throws Exception {
Iterator<String> iterator = new RelaxedNames("plain").iterator();
assertThat(iterator.next()).isEqualTo("plain");
assertThat(iterator.next()).isEqualTo("PLAIN");
assertThat(iterator.hasNext()).isFalse();
}
@Test
public void fromCamelCase() throws Exception {
Iterator<String> iterator = new RelaxedNames("caMel").iterator();
assertThat(iterator.next()).isEqualTo("caMel");
assertThat(iterator.next()).isEqualTo("ca_mel");
assertThat(iterator.next()).isEqualTo("ca-mel");
assertThat(iterator.next()).isEqualTo("camel");
assertThat(iterator.next()).isEqualTo("CAMEL");
assertThat(iterator.next()).isEqualTo("CA_MEL");
assertThat(iterator.next()).isEqualTo("CA-MEL");
assertThat(iterator.hasNext()).isFalse();
}
@Test
public void fromCompoundCamelCase() throws Exception {
Iterator<String> iterator = new RelaxedNames("caMelCase").iterator();
assertThat(iterator.next()).isEqualTo("caMelCase");
assertThat(iterator.next()).isEqualTo("ca_mel_case");
assertThat(iterator.next()).isEqualTo("ca-mel-case");
assertThat(iterator.next()).isEqualTo("camelcase");
assertThat(iterator.next()).isEqualTo("CAMELCASE");
assertThat(iterator.next()).isEqualTo("CA_MEL_CASE");
assertThat(iterator.next()).isEqualTo("CA-MEL-CASE");
assertThat(iterator.hasNext()).isFalse();
}
@Test
public void fromPeriods() throws Exception {
Iterator<String> iterator = new RelaxedNames("spring.value").iterator();
assertThat(iterator.next()).isEqualTo("spring.value");
assertThat(iterator.next()).isEqualTo("spring_value");
assertThat(iterator.next()).isEqualTo("springValue");
assertThat(iterator.next()).isEqualTo("springvalue");
assertThat(iterator.next()).isEqualTo("SPRING.VALUE");
assertThat(iterator.next()).isEqualTo("SPRING_VALUE");
assertThat(iterator.next()).isEqualTo("SPRINGVALUE");
assertThat(iterator.hasNext()).isFalse();
}
@Test
public void fromPrefixEndingInPeriod() throws Exception {
Iterator<String> iterator = new RelaxedNames("spring.").iterator();
assertThat(iterator.next()).isEqualTo("spring.");
assertThat(iterator.next()).isEqualTo("spring_");
assertThat(iterator.next()).isEqualTo("SPRING.");
assertThat(iterator.next()).isEqualTo("SPRING_");
assertThat(iterator.hasNext()).isFalse();
}
@Test
public void fromEmpty() throws Exception {
Iterator<String> iterator = new RelaxedNames("").iterator();
assertThat(iterator.next()).isEqualTo("");
assertThat(iterator.hasNext()).isFalse();
}
@Test
public void forCamelCase() throws Exception {
Iterator<String> iterator = RelaxedNames.forCamelCase("camelCase").iterator();
assertThat(iterator.next()).isEqualTo("camel-case");
assertThat(iterator.next()).isEqualTo("camel_case");
assertThat(iterator.next()).isEqualTo("camelCase");
assertThat(iterator.next()).isEqualTo("camelcase");
assertThat(iterator.next()).isEqualTo("CAMEL-CASE");
assertThat(iterator.next()).isEqualTo("CAMEL_CASE");
assertThat(iterator.next()).isEqualTo("CAMELCASE");
}
@Test
public void forCamelCaseWithCaps() throws Exception {
Iterator<String> iterator = RelaxedNames.forCamelCase("camelCASE").iterator();
assertThat(iterator.next()).isEqualTo("camel-c-a-s-e");
assertThat(iterator.next()).isEqualTo("camel_c_a_s_e");
assertThat(iterator.next()).isEqualTo("camelCASE");
assertThat(iterator.next()).isEqualTo("camelcase");
assertThat(iterator.next()).isEqualTo("CAMEL-C-A-S-E");
assertThat(iterator.next()).isEqualTo("CAMEL_C_A_S_E");
assertThat(iterator.next()).isEqualTo("CAMELCASE");
}
}
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.bind;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.StandardEnvironment;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link RelaxedPropertyResolver}.
*
* @author Phillip Webb
* @author Stephane Nicoll
*/
public class RelaxedPropertyResolverTests {
@Rule
public ExpectedException thrown = ExpectedException.none();
private StandardEnvironment environment;
private RelaxedPropertyResolver resolver;
private LinkedHashMap<String, Object> source;
@Before
public void setup() {
this.environment = new StandardEnvironment();
this.source = new LinkedHashMap<>();
this.source.put("myString", "value");
this.source.put("myobject", "object");
this.source.put("myInteger", 123);
this.source.put("myClass", "java.lang.String");
this.environment.getPropertySources()
.addFirst(new MapPropertySource("test", this.source));
this.resolver = new RelaxedPropertyResolver(this.environment);
}
@Test
public void needsPropertyResolver() throws Exception {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("PropertyResolver must not be null");
new RelaxedPropertyResolver(null);
}
@Test
public void getRequiredProperty() throws Exception {
assertThat(this.resolver.getRequiredProperty("my-string")).isEqualTo("value");
this.thrown.expect(IllegalStateException.class);
this.thrown.expectMessage("required key [my-missing] not found");
this.resolver.getRequiredProperty("my-missing");
}
@Test
public void getRequiredPropertyWithType() throws Exception {
assertThat(this.resolver.getRequiredProperty("my-integer", Integer.class))
.isEqualTo(123);
this.thrown.expect(IllegalStateException.class);
this.thrown.expectMessage("required key [my-missing] not found");
this.resolver.getRequiredProperty("my-missing", Integer.class);
}
@Test
public void getProperty() throws Exception {
assertThat(this.resolver.getProperty("my-string")).isEqualTo("value");
assertThat(this.resolver.getProperty("my-missing")).isNull();
}
@Test
public void getPropertyNoSeparator() throws Exception {
assertThat(this.resolver.getProperty("myobject")).isEqualTo("object");
assertThat(this.resolver.getProperty("my-object")).isEqualTo("object");
}
@Test
public void getPropertyWithDefault() throws Exception {
assertThat(this.resolver.getProperty("my-string", "a")).isEqualTo("value");
assertThat(this.resolver.getProperty("my-missing", "a")).isEqualTo("a");
}
@Test
public void getPropertyWithType() throws Exception {
assertThat(this.resolver.getProperty("my-integer", Integer.class)).isEqualTo(123);
assertThat(this.resolver.getProperty("my-missing", Integer.class)).isNull();
}
@Test
public void getPropertyWithTypeAndDefault() throws Exception {
assertThat(this.resolver.getProperty("my-integer", Integer.class, 345))
.isEqualTo(123);
assertThat(this.resolver.getProperty("my-missing", Integer.class, 345))
.isEqualTo(345);
}
@Test
public void containsProperty() throws Exception {
assertThat(this.resolver.containsProperty("my-string")).isTrue();
assertThat(this.resolver.containsProperty("myString")).isTrue();
assertThat(this.resolver.containsProperty("my_string")).isTrue();
assertThat(this.resolver.containsProperty("my-missing")).isFalse();
}
@Test
public void resolverPlaceholder() throws Exception {
this.thrown.expect(UnsupportedOperationException.class);
this.resolver.resolvePlaceholders("test");
}
@Test
public void resolveRequiredPlaceholders() throws Exception {
this.thrown.expect(UnsupportedOperationException.class);
this.resolver.resolveRequiredPlaceholders("test");
}
@Test
public void prefixed() throws Exception {
this.resolver = new RelaxedPropertyResolver(this.environment, "a.b.c.");
this.source.put("a.b.c.d", "test");
assertThat(this.resolver.containsProperty("d")).isTrue();
assertThat(this.resolver.getProperty("d")).isEqualTo("test");
}
@Test
public void prefixedRelaxed() throws Exception {
this.resolver = new RelaxedPropertyResolver(this.environment, "a.");
this.source.put("A_B", "test");
this.source.put("a.foobar", "spam");
assertThat(this.resolver.containsProperty("b")).isTrue();
assertThat(this.resolver.getProperty("b")).isEqualTo("test");
assertThat(this.resolver.getProperty("foo-bar")).isEqualTo("spam");
}
@Test
public void subProperties() throws Exception {
this.source.put("x.y.my-sub.a.b", "1");
this.source.put("x.y.mySub.a.c", "2");
this.source.put("x.y.MY_SUB.a.d", "3");
this.resolver = new RelaxedPropertyResolver(this.environment, "x.y.");
Map<String, Object> subProperties = this.resolver.getSubProperties("my-sub.");
assertThat(subProperties.size()).isEqualTo(3);
assertThat(subProperties.get("a.b")).isEqualTo("1");
assertThat(subProperties.get("a.c")).isEqualTo("2");
assertThat(subProperties.get("a.d")).isEqualTo("3");
}
@Test
public void testPropertySource() throws Exception {
Properties properties;
PropertiesPropertySource propertySource;
String propertyPrefix = "spring.datasource.";
String propertyName = "password";
String fullPropertyName = propertyPrefix + propertyName;
StandardEnvironment environment = new StandardEnvironment();
MutablePropertySources sources = environment.getPropertySources();
properties = new Properties();
properties.put(fullPropertyName, "systemPassword");
propertySource = new PropertiesPropertySource("system", properties);
sources.addLast(propertySource);
properties = new Properties();
properties.put(fullPropertyName, "propertiesPassword");
propertySource = new PropertiesPropertySource("properties", properties);
sources.addLast(propertySource);
RelaxedPropertyResolver propertyResolver = new RelaxedPropertyResolver(
environment, propertyPrefix);
String directProperty = propertyResolver.getProperty(propertyName);
Map<String, Object> subProperties = propertyResolver.getSubProperties("");
String subProperty = (String) subProperties.get(propertyName);
assertThat(subProperty).isEqualTo(directProperty);
}
}
/*
* Copyright 2012-2016 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.bind;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.bind.SimplerPropertySourcesBindingTests.TestConfig;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link PropertySourcesPropertyValues} binding.
*
* @author Dave Syer
*/
@RunWith(SpringRunner.class)
@DirtiesContext
@ContextConfiguration(classes = TestConfig.class, loader = SpringApplicationBindContextLoader.class)
public class SimplerPropertySourcesBindingTests {
@Value("${foo:}")
private String foo;
@Autowired
private Wrapper properties;
@Test
public void overridingOfPropertiesWorksAsExpected() {
assertThat(this.foo).isEqualTo(this.properties.getFoo());
}
@PropertySources({ @PropertySource("classpath:/override.properties"),
@PropertySource("classpath:/some.properties") })
@Configuration
@EnableConfigurationProperties(Wrapper.class)
public static class TestConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
@ConfigurationProperties
public static class Wrapper {
private String foo;
public String getFoo() {
return this.foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment