Commit 26a90c1d authored by Dave Syer's avatar Dave Syer

Add flag to PropertiesConfigurationFactory to switch off placeholder resolution

The default behaviour is unchanged, but it is useful for some applications to be
able to bind without placeholder resolution (e.g. to prevent exposing system
environment variables, if the bound object is being sent over the wire).
parent d1fd79cf
......@@ -86,6 +86,8 @@ public class PropertiesConfigurationFactory<T>
private ConversionService conversionService;
private boolean resolvePlaceholders = true;
/**
* Create a new {@link PropertiesConfigurationFactory} instance.
* @param target the target object to bind too
......@@ -203,6 +205,16 @@ public class PropertiesConfigurationFactory<T>
this.exceptionIfInvalid = exceptionIfInvalid;
}
/**
* Flag to indicate that placeholders should be replaced during binding. Default is
* true.
*
* @param resolvePlaceholders flag value
*/
public void setResolvePlaceholders(boolean resolvePlaceholders) {
this.resolvePlaceholders = resolvePlaceholders;
}
@Override
public void afterPropertiesSet() throws Exception {
bindPropertiesToTarget();
......@@ -322,7 +334,8 @@ public class PropertiesConfigurationFactory<T>
Iterable<String> relaxedTargetNames) {
PropertyNamePatternsMatcher includes = getPropertyNamePatternsMatcher(names,
relaxedTargetNames);
return new PropertySourcesPropertyValues(this.propertySources, names, includes);
return new PropertySourcesPropertyValues(this.propertySources, names, includes,
this.resolvePlaceholders);
}
private PropertyNamePatternsMatcher getPropertyNamePatternsMatcher(Set<String> names,
......
......@@ -56,12 +56,15 @@ public class PropertySourcesPropertyValues implements PropertyValues {
private final ConcurrentHashMap<String, PropertySource<?>> collectionOwners = new ConcurrentHashMap<String, PropertySource<?>>();
private boolean resolvePlaceholders = true;
/**
* Create a new PropertyValues from the given PropertySources.
* @param propertySources a PropertySources instance
*/
public PropertySourcesPropertyValues(PropertySources propertySources) {
this(propertySources, (Collection<String>) null, PropertyNamePatternsMatcher.ALL);
this(propertySources, (Collection<String>) null, PropertyNamePatternsMatcher.ALL,
true);
}
/**
......@@ -76,7 +79,7 @@ public class PropertySourcesPropertyValues implements PropertyValues {
Collection<String> includePatterns,
Collection<String> nonEnumerableFallbackNames) {
this(propertySources, nonEnumerableFallbackNames,
new PatternPropertyNamePatternsMatcher(includePatterns));
new PatternPropertyNamePatternsMatcher(includePatterns), true);
}
/**
......@@ -85,15 +88,17 @@ public class PropertySourcesPropertyValues implements PropertyValues {
* @param nonEnumerableFallbackNames the property names to try in lieu of an
* {@link EnumerablePropertySource}.
* @param includes the property name patterns to include
* @param resolvePlaceholders flag to indicate the placeholders should be resolved
*/
PropertySourcesPropertyValues(PropertySources propertySources,
Collection<String> nonEnumerableFallbackNames,
PropertyNamePatternsMatcher includes) {
PropertyNamePatternsMatcher includes, boolean resolvePlaceholders) {
Assert.notNull(propertySources, "PropertySources must not be null");
Assert.notNull(includes, "Includes must not be null");
this.propertySources = propertySources;
this.nonEnumerableFallbackNames = nonEnumerableFallbackNames;
this.includes = includes;
this.resolvePlaceholders = resolvePlaceholders;
PropertySourcesPropertyResolver resolver = new PropertySourcesPropertyResolver(
propertySources);
for (PropertySource<?> source : propertySources) {
......@@ -101,6 +106,16 @@ public class PropertySourcesPropertyValues implements PropertyValues {
}
}
/**
* Flag to indicate that placeholders should be replaced during binding. Default is
* true.
*
* @param resolvePlaceholders flag value
*/
public void setResolvePlaceholders(boolean resolvePlaceholders) {
this.resolvePlaceholders = resolvePlaceholders;
}
private void processPropertySource(PropertySource<?> source,
PropertySourcesPropertyResolver resolver) {
if (source instanceof CompositePropertySource) {
......@@ -138,12 +153,14 @@ public class PropertySourcesPropertyValues implements PropertyValues {
private Object getEnumerableProperty(EnumerablePropertySource<?> source,
PropertySourcesPropertyResolver resolver, String propertyName) {
try {
return resolver.getProperty(propertyName, Object.class);
if (this.resolvePlaceholders) {
return resolver.getProperty(propertyName, Object.class);
}
}
catch (RuntimeException ex) {
// Probably could not resolve placeholders, ignore it here
return source.getProperty(propertyName);
}
return source.getProperty(propertyName);
}
private void processNonEnumerablePropertySource(PropertySource<?> source,
......
......@@ -105,6 +105,35 @@ public class PropertiesConfigurationFactoryTests {
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();
......
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