Optimize property sources pattern matching
Create a PropertyNamePatternsMatcher strategy interface that PropertySourcesPropertyValues can use to determine when a property can be used. PropertiesConfigurationFactory uses DefaultPropertyNamePatternsMatcher which is heavily optimized for frequent calls. Fixes gh-1823
This commit is contained in:
		
							parent
							
								
									adffb7a30f
								
							
						
					
					
						commit
						f5a52ddd5a
					
				| 
						 | 
				
			
			@ -0,0 +1,88 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2012-2014 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;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Default {@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 '.'
 | 
			
		||||
 * or '_'. This implementation is optimized for frequent calls.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Phillip Webb
 | 
			
		||||
 * @since 1.2.0
 | 
			
		||||
 */
 | 
			
		||||
class DefaultPropertyNamePatternsMatcher implements PropertyNamePatternsMatcher {
 | 
			
		||||
 | 
			
		||||
	private final String[] names;
 | 
			
		||||
 | 
			
		||||
	public DefaultPropertyNamePatternsMatcher(String... names) {
 | 
			
		||||
		this(new HashSet<String>(Arrays.asList(names)));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public DefaultPropertyNamePatternsMatcher(Set<String> names) {
 | 
			
		||||
		this.names = names.toArray(new String[names.size()]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean matches(String propertyName) {
 | 
			
		||||
		char[] propertNameChars = 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() <= propertNameChars.length) {
 | 
			
		||||
				match[i] = true;
 | 
			
		||||
				noneMatched = false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (noneMatched) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		for (int charIndex = 0; charIndex < propertNameChars.length; charIndex++) {
 | 
			
		||||
			noneMatched = true;
 | 
			
		||||
			for (int nameIndex = 0; nameIndex < this.names.length; nameIndex++) {
 | 
			
		||||
				if (match[nameIndex]) {
 | 
			
		||||
					if (charIndex < this.names[nameIndex].length()) {
 | 
			
		||||
						if (this.names[nameIndex].charAt(charIndex) == propertNameChars[charIndex]) {
 | 
			
		||||
							match[nameIndex] = true;
 | 
			
		||||
							noneMatched = false;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					else {
 | 
			
		||||
						char charAfter = propertNameChars[this.names[nameIndex].length()];
 | 
			
		||||
						if (charAfter == '.' || 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;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -249,25 +249,20 @@ public class PropertiesConfigurationFactory<T> implements FactoryBean<T>,
 | 
			
		|||
		customizeBinder(dataBinder);
 | 
			
		||||
 | 
			
		||||
		Set<String> names = new HashSet<String>();
 | 
			
		||||
		Set<String> patterns = new HashSet<String>();
 | 
			
		||||
		if (this.target != null) {
 | 
			
		||||
			PropertyDescriptor[] descriptors = BeanUtils
 | 
			
		||||
					.getPropertyDescriptors(this.target.getClass());
 | 
			
		||||
			String prefix = (this.targetName != null ? this.targetName + "." : "");
 | 
			
		||||
			String[] suffixes = new String[] { ".*", "_*" };
 | 
			
		||||
			for (PropertyDescriptor descriptor : descriptors) {
 | 
			
		||||
				String name = descriptor.getName();
 | 
			
		||||
				if (!name.equals("class")) {
 | 
			
		||||
					for (String relaxedName : new RelaxedNames(prefix + name)) {
 | 
			
		||||
						names.add(relaxedName);
 | 
			
		||||
						patterns.add(relaxedName);
 | 
			
		||||
						for (String suffix : suffixes) {
 | 
			
		||||
							patterns.add(relaxedName + suffix);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		PropertyNamePatternsMatcher patterns = new DefaultPropertyNamePatternsMatcher(names);
 | 
			
		||||
 | 
			
		||||
		PropertyValues propertyValues = (this.properties != null ? new MutablePropertyValues(
 | 
			
		||||
				this.properties) : new PropertySourcesPropertyValues(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,43 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2012-2014 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;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Strategy interface used to check if a property name matches specific criteria.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Phillip Webb
 | 
			
		||||
 * @since 1.2.0
 | 
			
		||||
 */
 | 
			
		||||
interface PropertyNamePatternsMatcher {
 | 
			
		||||
 | 
			
		||||
	PropertyNamePatternsMatcher NONE = new PropertyNamePatternsMatcher() {
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		public boolean matches(String propertyName) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return {@code true} of the property name matches.
 | 
			
		||||
	 * @param propertyName the property name
 | 
			
		||||
	 * @return {@code true} if the property name matches
 | 
			
		||||
	 */
 | 
			
		||||
	boolean matches(String propertyName);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -19,6 +19,7 @@ package org.springframework.boot.bind;
 | 
			
		|||
import java.lang.reflect.Field;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.concurrent.ConcurrentHashMap;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -31,7 +32,6 @@ import org.springframework.core.env.PropertySource;
 | 
			
		|||
import org.springframework.core.env.PropertySources;
 | 
			
		||||
import org.springframework.core.env.PropertySourcesPropertyResolver;
 | 
			
		||||
import org.springframework.core.env.StandardEnvironment;
 | 
			
		||||
import org.springframework.util.PatternMatchUtils;
 | 
			
		||||
import org.springframework.util.ReflectionUtils;
 | 
			
		||||
import org.springframework.validation.DataBinder;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -48,7 +48,7 @@ public class PropertySourcesPropertyValues implements PropertyValues {
 | 
			
		|||
 | 
			
		||||
	private final PropertySources propertySources;
 | 
			
		||||
 | 
			
		||||
	private static final Collection<String> NON_ENUMERABLE_ENUMERABLES = Arrays.asList(
 | 
			
		||||
	private static final Collection<String> PATTERN_MATCHED_PROPERTY_SOURCES = Arrays.asList(
 | 
			
		||||
			StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME,
 | 
			
		||||
			StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -57,37 +57,48 @@ public class PropertySourcesPropertyValues implements PropertyValues {
 | 
			
		|||
	 * @param propertySources a PropertySources instance
 | 
			
		||||
	 */
 | 
			
		||||
	public PropertySourcesPropertyValues(PropertySources propertySources) {
 | 
			
		||||
		this(propertySources, null, null);
 | 
			
		||||
		this(propertySources, (PropertyNamePatternsMatcher) null,
 | 
			
		||||
				(Collection<String>) null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new PropertyValues from the given PropertySources
 | 
			
		||||
	 * @param propertySources a PropertySources instance
 | 
			
		||||
	 * @param patterns property name patterns to include from system properties and
 | 
			
		||||
	 * @param includePatterns property name patterns to include from system properties and
 | 
			
		||||
	 * environment variables
 | 
			
		||||
	 * @param names exact property names to include
 | 
			
		||||
	 */
 | 
			
		||||
	public PropertySourcesPropertyValues(PropertySources propertySources,
 | 
			
		||||
			Collection<String> patterns, Collection<String> names) {
 | 
			
		||||
		this.propertySources = propertySources;
 | 
			
		||||
		PropertySourcesPropertyResolver resolver = new PropertySourcesPropertyResolver(
 | 
			
		||||
				propertySources);
 | 
			
		||||
		String[] includes = toArray(patterns);
 | 
			
		||||
		String[] exacts = toArray(names);
 | 
			
		||||
		for (PropertySource<?> source : propertySources) {
 | 
			
		||||
			processPropertySource(source, resolver, includes, exacts);
 | 
			
		||||
		}
 | 
			
		||||
			Collection<String> includePatterns, Collection<String> names) {
 | 
			
		||||
		this(propertySources, new SimplePropertyNamePatternsMatcher(includePatterns), names);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private String[] toArray(Collection<String> strings) {
 | 
			
		||||
		if (strings == null) {
 | 
			
		||||
			return new String[0];
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new PropertyValues from the given PropertySources
 | 
			
		||||
	 * @param propertySources a PropertySources instance
 | 
			
		||||
	 * @param includes property name patterns to include from system properties and
 | 
			
		||||
	 * environment variables
 | 
			
		||||
	 * @param names exact property names to include
 | 
			
		||||
	 */
 | 
			
		||||
	PropertySourcesPropertyValues(PropertySources propertySources,
 | 
			
		||||
			PropertyNamePatternsMatcher includes, Collection<String> names) {
 | 
			
		||||
		this.propertySources = propertySources;
 | 
			
		||||
		if (includes == null) {
 | 
			
		||||
			includes = PropertyNamePatternsMatcher.NONE;
 | 
			
		||||
		}
 | 
			
		||||
		if (names == null) {
 | 
			
		||||
			names = Collections.emptySet();
 | 
			
		||||
		}
 | 
			
		||||
		PropertySourcesPropertyResolver resolver = new PropertySourcesPropertyResolver(
 | 
			
		||||
				propertySources);
 | 
			
		||||
		for (PropertySource<?> source : propertySources) {
 | 
			
		||||
			processPropertySource(source, resolver, includes, names);
 | 
			
		||||
		}
 | 
			
		||||
		return strings.toArray(new String[strings.size()]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void processPropertySource(PropertySource<?> source,
 | 
			
		||||
			PropertySourcesPropertyResolver resolver, String[] includes, String[] exacts) {
 | 
			
		||||
			PropertySourcesPropertyResolver resolver,
 | 
			
		||||
			PropertyNamePatternsMatcher includes, Collection<String> exacts) {
 | 
			
		||||
		if (source instanceof EnumerablePropertySource) {
 | 
			
		||||
			processEnumerablePropertySource((EnumerablePropertySource<?>) source,
 | 
			
		||||
					resolver, includes, exacts);
 | 
			
		||||
| 
						 | 
				
			
			@ -104,12 +115,12 @@ public class PropertySourcesPropertyValues implements PropertyValues {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	private void processEnumerablePropertySource(EnumerablePropertySource<?> source,
 | 
			
		||||
			PropertySourcesPropertyResolver resolver, String[] includes, String[] exacts) {
 | 
			
		||||
			PropertySourcesPropertyResolver resolver,
 | 
			
		||||
			PropertyNamePatternsMatcher includes, Collection<String> exacts) {
 | 
			
		||||
		if (source.getPropertyNames().length > 0) {
 | 
			
		||||
			for (String propertyName : source.getPropertyNames()) {
 | 
			
		||||
				if (PropertySourcesPropertyValues.NON_ENUMERABLE_ENUMERABLES
 | 
			
		||||
						.contains(source.getName())
 | 
			
		||||
						&& !PatternMatchUtils.simpleMatch(includes, propertyName)) {
 | 
			
		||||
				if (PropertySourcesPropertyValues.PATTERN_MATCHED_PROPERTY_SOURCES
 | 
			
		||||
						.contains(source.getName()) && !includes.matches(propertyName)) {
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
				Object value = source.getProperty(propertyName);
 | 
			
		||||
| 
						 | 
				
			
			@ -128,7 +139,8 @@ public class PropertySourcesPropertyValues implements PropertyValues {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	private void processCompositePropertySource(CompositePropertySource source,
 | 
			
		||||
			PropertySourcesPropertyResolver resolver, String[] includes, String[] exacts) {
 | 
			
		||||
			PropertySourcesPropertyResolver resolver,
 | 
			
		||||
			PropertyNamePatternsMatcher includes, Collection<String> exacts) {
 | 
			
		||||
		for (PropertySource<?> nested : extractSources(source)) {
 | 
			
		||||
			processPropertySource(nested, resolver, includes, exacts);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -151,7 +163,8 @@ public class PropertySourcesPropertyValues implements PropertyValues {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	private void processDefaultPropertySource(PropertySource<?> source,
 | 
			
		||||
			PropertySourcesPropertyResolver resolver, String[] includes, String[] exacts) {
 | 
			
		||||
			PropertySourcesPropertyResolver resolver,
 | 
			
		||||
			PropertyNamePatternsMatcher includes, Collection<String> exacts) {
 | 
			
		||||
		for (String propertyName : exacts) {
 | 
			
		||||
			Object value = null;
 | 
			
		||||
			try {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,43 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2012-2014 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.Collection;
 | 
			
		||||
 | 
			
		||||
import org.springframework.util.PatternMatchUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * {@link PropertyNamePatternsMatcher} that delegates to
 | 
			
		||||
 * {@link PatternMatchUtils#simpleMatch(String[], String)}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Phillip Webb
 | 
			
		||||
 * @since 1.2.0
 | 
			
		||||
 */
 | 
			
		||||
class SimplePropertyNamePatternsMatcher implements PropertyNamePatternsMatcher {
 | 
			
		||||
 | 
			
		||||
	private final String[] patterns;
 | 
			
		||||
 | 
			
		||||
	public SimplePropertyNamePatternsMatcher(Collection<String> patterns) {
 | 
			
		||||
		this.patterns = (patterns == null ? new String[] {} : patterns
 | 
			
		||||
				.toArray(new String[patterns.size()]));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean matches(String propertyName) {
 | 
			
		||||
		return PatternMatchUtils.simpleMatch(this.patterns, propertyName);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,69 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2012-2014 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.junit.Assert.assertFalse;
 | 
			
		||||
import static org.junit.Assert.assertTrue;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests for {@link DefaultPropertyNamePatternsMatcher}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Phillip Webb
 | 
			
		||||
 */
 | 
			
		||||
public class DefaultPropertyNamePatternsMatcherTests {
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void namesShorter() {
 | 
			
		||||
		assertFalse(new DefaultPropertyNamePatternsMatcher("aaaa", "bbbb")
 | 
			
		||||
				.matches("zzzzz"));
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void namesExactMatch() {
 | 
			
		||||
		assertTrue(new DefaultPropertyNamePatternsMatcher("aaaa", "bbbb", "cccc")
 | 
			
		||||
				.matches("bbbb"));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void namesLonger() {
 | 
			
		||||
		assertFalse(new DefaultPropertyNamePatternsMatcher("aaaaa", "bbbbb", "ccccc")
 | 
			
		||||
				.matches("bbbb"));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void nameWithDot() throws Exception {
 | 
			
		||||
		assertTrue(new DefaultPropertyNamePatternsMatcher("aaaa", "bbbb", "cccc")
 | 
			
		||||
				.matches("bbbb.anything"));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void nameWithUnderscore() throws Exception {
 | 
			
		||||
		assertTrue(new DefaultPropertyNamePatternsMatcher("aaaa", "bbbb", "cccc")
 | 
			
		||||
				.matches("bbbb_anything"));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void namesMatchWithDifferentLengths() throws Exception {
 | 
			
		||||
		assertTrue(new DefaultPropertyNamePatternsMatcher("aaa", "bbbb", "ccccc")
 | 
			
		||||
				.matches("bbbb"));
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -16,6 +16,7 @@
 | 
			
		|||
 | 
			
		||||
package org.springframework.boot.bind;
 | 
			
		||||
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
 | 
			
		||||
import org.junit.Before;
 | 
			
		||||
| 
						 | 
				
			
			@ -98,7 +99,8 @@ public class PropertySourcesPropertyValuesTests {
 | 
			
		|||
 | 
			
		||||
		});
 | 
			
		||||
		PropertySourcesPropertyValues propertyValues = new PropertySourcesPropertyValues(
 | 
			
		||||
				this.propertySources, null, Collections.singleton("baz"));
 | 
			
		||||
				this.propertySources, (Collection<String>) null,
 | 
			
		||||
				Collections.singleton("baz"));
 | 
			
		||||
		assertEquals("bar", propertyValues.getPropertyValue("baz").getValue());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -123,8 +125,8 @@ public class PropertySourcesPropertyValuesTests {
 | 
			
		|||
	public void testPlaceholdersBindingNonEnumerable() {
 | 
			
		||||
		FooBean target = new FooBean();
 | 
			
		||||
		DataBinder binder = new DataBinder(target);
 | 
			
		||||
		binder.bind(new PropertySourcesPropertyValues(this.propertySources, null,
 | 
			
		||||
				Collections.singleton("foo")));
 | 
			
		||||
		binder.bind(new PropertySourcesPropertyValues(this.propertySources,
 | 
			
		||||
				(Collection<String>) null, Collections.singleton("foo")));
 | 
			
		||||
		assertEquals("bar", target.getFoo());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -148,8 +150,8 @@ public class PropertySourcesPropertyValuesTests {
 | 
			
		|||
				return new Object();
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
		binder.bind(new PropertySourcesPropertyValues(this.propertySources, null,
 | 
			
		||||
				Collections.singleton("name")));
 | 
			
		||||
		binder.bind(new PropertySourcesPropertyValues(this.propertySources,
 | 
			
		||||
				(Collection<String>) null, Collections.singleton("name")));
 | 
			
		||||
		assertEquals(null, target.getName());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue