PropertyPlaceholderConfigurer supports "${myKey:myDefaultValue}" defaulting syntax
This commit is contained in:
parent
8eca898d44
commit
0f43d6c592
|
|
@ -99,6 +99,9 @@ public class PropertyPlaceholderConfigurer extends PropertyResourceConfigurer
|
|||
/** Default placeholder suffix: "}" */
|
||||
public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}";
|
||||
|
||||
/** Default value separator: ":" */
|
||||
public static final String DEFAULT_VALUE_SEPARATOR = ":";
|
||||
|
||||
|
||||
/** Never check system properties. */
|
||||
public static final int SYSTEM_PROPERTIES_MODE_NEVER = 0;
|
||||
|
|
@ -122,6 +125,8 @@ public class PropertyPlaceholderConfigurer extends PropertyResourceConfigurer
|
|||
|
||||
private String placeholderSuffix = DEFAULT_PLACEHOLDER_SUFFIX;
|
||||
|
||||
private String valueSeparator = DEFAULT_VALUE_SEPARATOR;
|
||||
|
||||
private int systemPropertiesMode = SYSTEM_PROPERTIES_MODE_FALLBACK;
|
||||
|
||||
private boolean searchSystemEnvironment = true;
|
||||
|
|
@ -360,7 +365,8 @@ public class PropertyPlaceholderConfigurer extends PropertyResourceConfigurer
|
|||
private final PlaceholderResolver resolver;
|
||||
|
||||
public PlaceholderResolvingStringValueResolver(Properties props) {
|
||||
this.helper = new PropertyPlaceholderHelper(placeholderPrefix, placeholderSuffix, ignoreUnresolvablePlaceholders);
|
||||
this.helper = new PropertyPlaceholderHelper(
|
||||
placeholderPrefix, placeholderSuffix, valueSeparator, ignoreUnresolvablePlaceholders);
|
||||
this.resolver = new PropertyPlaceholderConfigurerResolver(props);
|
||||
}
|
||||
|
||||
|
|
@ -370,6 +376,7 @@ public class PropertyPlaceholderConfigurer extends PropertyResourceConfigurer
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private class PropertyPlaceholderConfigurerResolver implements PlaceholderResolver {
|
||||
|
||||
private final Properties props;
|
||||
|
|
|
|||
|
|
@ -662,6 +662,19 @@ public final class PropertyResourceConfigurerTests {
|
|||
assertEquals("mytest", tb.getTouchy());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyPlaceholderConfigurerWithInlineDefault() {
|
||||
factory.registerBeanDefinition("tb",
|
||||
genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("touchy", "${test:mytest}").getBeanDefinition());
|
||||
|
||||
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
|
||||
ppc.postProcessBeanFactory(factory);
|
||||
|
||||
TestBean tb = (TestBean) factory.getBean("tb");
|
||||
assertEquals("mytest", tb.getTouchy());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyPlaceholderConfigurerWithAliases() {
|
||||
factory.registerBeanDefinition("tb",
|
||||
|
|
|
|||
|
|
@ -16,18 +16,18 @@
|
|||
|
||||
package org.springframework.util;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Utility class for working with Strings that have placeholder values in them. A placeholder takes the form
|
||||
* <code>${name}</code>. Using <code>PropertyPlaceholderUtils</code> these placeholders can be substituted for
|
||||
* user-supplied values. <p> Values for substitution can be supplied using a {@link Properties} instance or using a
|
||||
* {@link PlaceholderResolver}.
|
||||
* <code>${name}</code>. Using <code>PropertyPlaceholderHelper</code> these placeholders can be substituted for
|
||||
* user-supplied values. <p> Values for substitution can be supplied using a {@link Properties} instance or
|
||||
* using a {@link PlaceholderResolver}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rob Harrop
|
||||
|
|
@ -35,46 +35,49 @@ import org.apache.commons.logging.LogFactory;
|
|||
*/
|
||||
public class PropertyPlaceholderHelper {
|
||||
|
||||
private static final Log LOGGER = LogFactory.getLog(PropertyPlaceholderHelper.class);
|
||||
private static final Log logger = LogFactory.getLog(PropertyPlaceholderHelper.class);
|
||||
|
||||
private final String placeholderPrefix;
|
||||
|
||||
private final String placeholderSuffix;
|
||||
|
||||
private final String valueSeparator;
|
||||
|
||||
private final boolean ignoreUnresolvablePlaceholders;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>PropertyPlaceholderHelper</code> that uses the supplied prefix and suffix. Unresolvable
|
||||
* placeholders are ignored.
|
||||
*
|
||||
* Creates a new <code>PropertyPlaceholderHelper</code> that uses the supplied prefix and suffix.
|
||||
* Unresolvable placeholders are ignored.
|
||||
* @param placeholderPrefix the prefix that denotes the start of a placeholder.
|
||||
* @param placeholderSuffix the suffix that denotes the end of a placeholder.
|
||||
*/
|
||||
public PropertyPlaceholderHelper(String placeholderPrefix, String placeholderSuffix) {
|
||||
this(placeholderPrefix, placeholderSuffix, true);
|
||||
this(placeholderPrefix, placeholderSuffix, null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>PropertyPlaceholderHelper</code> that uses the supplied prefix and suffix.
|
||||
*
|
||||
* @param placeholderPrefix the prefix that denotes the start of a placeholder.
|
||||
* @param placeholderSuffix the suffix that denotes the end of a placeholder.
|
||||
* @param ignoreUnresolvablePlaceholders indicates whether unresolvable placeholders should be ignored
|
||||
* (<code>true</code>) or cause an exception (<code>false</code>).
|
||||
*/
|
||||
public PropertyPlaceholderHelper(String placeholderPrefix, String placeholderSuffix,
|
||||
boolean ignoreUnresolvablePlaceholders) {
|
||||
Assert.notNull(placeholderPrefix, "Argument 'placeholderPrefix' must not be null.");
|
||||
Assert.notNull(placeholderSuffix, "Argument 'placeholderSuffix' must not be null.");
|
||||
String valueSeparator, boolean ignoreUnresolvablePlaceholders) {
|
||||
|
||||
Assert.notNull(placeholderPrefix, "placeholderPrefix must not be null");
|
||||
Assert.notNull(placeholderSuffix, "placeholderSuffix must not be null");
|
||||
this.placeholderPrefix = placeholderPrefix;
|
||||
this.placeholderSuffix = placeholderSuffix;
|
||||
this.valueSeparator = valueSeparator;
|
||||
this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replaces all placeholders of format <code>${name}</code> with the corresponding property from the supplied {@link
|
||||
* Properties}.
|
||||
*
|
||||
* Replaces all placeholders of format <code>${name}</code> with the corresponding property
|
||||
* from the supplied {@link Properties}.
|
||||
* @param value the value containing the placeholders to be replaced.
|
||||
* @param properties the <code>Properties</code> to use for replacement.
|
||||
* @return the supplied value with placeholders replaced inline.
|
||||
|
|
@ -82,7 +85,6 @@ public class PropertyPlaceholderHelper {
|
|||
public String replacePlaceholders(String value, final Properties properties) {
|
||||
Assert.notNull(properties, "Argument 'properties' must not be null.");
|
||||
return replacePlaceholders(value, new PlaceholderResolver() {
|
||||
|
||||
public String resolvePlaceholder(String placeholderName) {
|
||||
return properties.getProperty(placeholderName);
|
||||
}
|
||||
|
|
@ -90,9 +92,8 @@ public class PropertyPlaceholderHelper {
|
|||
}
|
||||
|
||||
/**
|
||||
* Replaces all placeholders of format <code>${name}</code> with the value returned from the supplied {@link
|
||||
* PlaceholderResolver}.
|
||||
*
|
||||
* Replaces all placeholders of format <code>${name}</code> with the value returned from the supplied
|
||||
* {@link PlaceholderResolver}.
|
||||
* @param value the value containing the placeholders to be replaced.
|
||||
* @param placeholderResolver the <code>PlaceholderResolver</code> to use for replacement.
|
||||
* @return the supplied value with placeholders replaced inline.
|
||||
|
|
@ -102,8 +103,9 @@ public class PropertyPlaceholderHelper {
|
|||
return parseStringValue(value, placeholderResolver, new HashSet<String>());
|
||||
}
|
||||
|
||||
protected String parseStringValue(String strVal, PlaceholderResolver placeholderResolver,
|
||||
Set<String> visitedPlaceholders) {
|
||||
protected String parseStringValue(
|
||||
String strVal, PlaceholderResolver placeholderResolver, Set<String> visitedPlaceholders) {
|
||||
|
||||
StringBuilder buf = new StringBuilder(strVal);
|
||||
|
||||
int startIndex = strVal.indexOf(this.placeholderPrefix);
|
||||
|
|
@ -120,14 +122,25 @@ public class PropertyPlaceholderHelper {
|
|||
|
||||
// Now obtain the value for the fully resolved key...
|
||||
String propVal = placeholderResolver.resolvePlaceholder(placeholder);
|
||||
if (propVal == null && this.valueSeparator != null) {
|
||||
int separatorIndex = placeholder.indexOf(this.valueSeparator);
|
||||
if (separatorIndex != -1) {
|
||||
String actualPlaceholder = placeholder.substring(0, separatorIndex);
|
||||
String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length());
|
||||
propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder);
|
||||
if (propVal == null) {
|
||||
propVal = defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (propVal != null) {
|
||||
// Recursive invocation, parsing placeholders contained in the
|
||||
// previously resolved placeholder value.
|
||||
propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
|
||||
buf.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
|
||||
|
||||
if (LOGGER.isTraceEnabled()) {
|
||||
LOGGER.trace("Resolved placeholder '" + placeholder + "'");
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Resolved placeholder '" + placeholder + "'");
|
||||
}
|
||||
|
||||
startIndex = buf.indexOf(this.placeholderPrefix, startIndex + propVal.length());
|
||||
|
|
@ -174,19 +187,19 @@ public class PropertyPlaceholderHelper {
|
|||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Strategy interface used to resolve replacement values for placeholders contained in Strings.
|
||||
*
|
||||
* @see PropertyPlaceholderHelper
|
||||
*/
|
||||
public static interface PlaceholderResolver {
|
||||
|
||||
/**
|
||||
* Resolves the supplied placeholder name into the replacement value.
|
||||
*
|
||||
* @param placeholderName the name of the placeholder to resolve.
|
||||
* @return the replacement value or <code>null</code> if no replacement is to be made.
|
||||
*/
|
||||
String resolvePlaceholder(String placeholderName);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
|
|
@ -38,18 +38,22 @@ public abstract class SystemPropertyUtils {
|
|||
/** Suffix for system property placeholders: "}" */
|
||||
public static final String PLACEHOLDER_SUFFIX = "}";
|
||||
|
||||
private static final PropertyPlaceholderHelper HELPER = new PropertyPlaceholderHelper(PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX);
|
||||
/** Value separator for system property placeholders: "}" */
|
||||
public static final String VALUE_SEPARATOR = ":";
|
||||
|
||||
private static final PropertyPlaceholderHelper helper =
|
||||
new PropertyPlaceholderHelper(PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, VALUE_SEPARATOR, false);
|
||||
|
||||
|
||||
/**
|
||||
* Resolve ${...} placeholders in the given text, replacing them with corresponding system property values.
|
||||
*
|
||||
* @param text the String to resolve
|
||||
* @return the resolved String
|
||||
* @see #PLACEHOLDER_PREFIX
|
||||
* @see #PLACEHOLDER_SUFFIX
|
||||
*/
|
||||
public static String resolvePlaceholders(final String text) {
|
||||
return HELPER.replacePlaceholders(text, new PlaceholderResolver() {
|
||||
|
||||
return helper.replacePlaceholders(text, new PlaceholderResolver() {
|
||||
public String resolvePlaceholder(String placeholderName) {
|
||||
String propVal = null;
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -18,10 +18,12 @@ package org.springframework.util;
|
|||
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/** @author Rob Harrop */
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
public class PropertyPlaceholderHelperTests {
|
||||
|
||||
private final PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}");
|
||||
|
|
@ -98,7 +100,8 @@ public class PropertyPlaceholderHelperTests {
|
|||
Properties props = new Properties();
|
||||
props.setProperty("foo", "bar");
|
||||
|
||||
PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}", false);
|
||||
PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}", null, false);
|
||||
assertEquals("foo=bar,bar=${bar}", helper.replacePlaceholders(text, props));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,33 +18,54 @@ package org.springframework.util;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/** @author Rob Harrop */
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class SystemPropertyUtilsTests {
|
||||
|
||||
@Test
|
||||
public void testReplaceFromSystemProperty() {
|
||||
System.setProperty("test.prop", "bar");
|
||||
try {
|
||||
String resolved = SystemPropertyUtils.resolvePlaceholders("${test.prop}");
|
||||
assertEquals("bar", resolved);
|
||||
}
|
||||
finally {
|
||||
System.getProperties().remove("test.prop");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplaceWithDefault() {
|
||||
String resolved = SystemPropertyUtils.resolvePlaceholders("${test.prop:foo}");
|
||||
assertEquals("foo", resolved);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecursiveFromSystemProperty() {
|
||||
System.setProperty("test.prop", "foo=${bar}");
|
||||
System.setProperty("bar", "baz");
|
||||
try {
|
||||
String resolved = SystemPropertyUtils.resolvePlaceholders("${test.prop}");
|
||||
assertEquals("foo=baz", resolved);
|
||||
}
|
||||
finally {
|
||||
System.getProperties().remove("test.prop");
|
||||
System.getProperties().remove("bar");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplaceFromEnv() {
|
||||
Map<String,String> env = System.getenv();
|
||||
if(env.containsKey("PATH")) {
|
||||
if (env.containsKey("PATH")) {
|
||||
String text = "${PATH}";
|
||||
assertEquals(env.get("PATH"), SystemPropertyUtils.resolvePlaceholders(text));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue