reworked PropertyPlaceholderHelper
This commit is contained in:
parent
d16faafc4f
commit
f20c074ff4
|
|
@ -20,6 +20,9 @@ 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
|
||||
|
|
@ -30,13 +33,43 @@ import java.util.HashSet;
|
|||
* @author Rob Harrop
|
||||
* @since 3.0
|
||||
*/
|
||||
public class PropertyPlaceholderUtils {
|
||||
public class PropertyPlaceholderHelper {
|
||||
|
||||
/** Prefix for property placeholders: "${" */
|
||||
public static final String PLACEHOLDER_PREFIX = "${";
|
||||
private static final Log LOGGER = LogFactory.getLog(PropertyPlaceholderHelper.class);
|
||||
|
||||
/** Suffix for property placeholders: "}" */
|
||||
public static final String PLACEHOLDER_SUFFIX = "}";
|
||||
private final String placeholderPrefix;
|
||||
|
||||
private final String placeholderSuffix;
|
||||
|
||||
private final boolean ignoreUnresolvablePlaceholders;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.");
|
||||
this.placeholderPrefix = placeholderPrefix;
|
||||
this.placeholderSuffix = placeholderSuffix;
|
||||
this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces all placeholders of format <code>${name}</code> with the corresponding property from the supplied {@link
|
||||
|
|
@ -46,7 +79,7 @@ public class PropertyPlaceholderUtils {
|
|||
* @param properties the <code>Properties</code> to use for replacement.
|
||||
* @return the supplied value with placeholders replaced inline.
|
||||
*/
|
||||
public static String replacePlaceholders(String value, final Properties properties) {
|
||||
public String replacePlaceholders(String value, final Properties properties) {
|
||||
Assert.notNull(properties, "Argument 'properties' must not be null.");
|
||||
return replacePlaceholders(value, new PlaceholderResolver() {
|
||||
|
||||
|
|
@ -64,18 +97,20 @@ public class PropertyPlaceholderUtils {
|
|||
* @param placeholderResolver the <code>PlaceholderResolver</code> to use for replacement.
|
||||
* @return the supplied value with placeholders replaced inline.
|
||||
*/
|
||||
public static String replacePlaceholders(String value, PlaceholderResolver placeholderResolver) {
|
||||
public String replacePlaceholders(String value, PlaceholderResolver placeholderResolver) {
|
||||
Assert.notNull(value, "Argument 'value' must not be null.");
|
||||
return parseStringValue(value, placeholderResolver, new HashSet<String>());
|
||||
}
|
||||
|
||||
protected static 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(PLACEHOLDER_PREFIX);
|
||||
int startIndex = strVal.indexOf(this.placeholderPrefix);
|
||||
while (startIndex != -1) {
|
||||
int endIndex = findPlaceholderEndIndex(buf, startIndex);
|
||||
if (endIndex != -1) {
|
||||
String placeholder = buf.substring(startIndex + PLACEHOLDER_PREFIX.length(), endIndex);
|
||||
String placeholder = buf.substring(startIndex + this.placeholderPrefix.length(), endIndex);
|
||||
if (!visitedPlaceholders.add(placeholder)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Circular placeholder reference '" + placeholder + "' in property definitions");
|
||||
|
|
@ -89,17 +124,20 @@ public class PropertyPlaceholderUtils {
|
|||
// Recursive invocation, parsing placeholders contained in the
|
||||
// previously resolved placeholder value.
|
||||
propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
|
||||
buf.replace(startIndex, endIndex + PLACEHOLDER_SUFFIX.length(), propVal);
|
||||
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(PLACEHOLDER_PREFIX, startIndex + propVal.length());
|
||||
startIndex = buf.indexOf(this.placeholderPrefix, startIndex + propVal.length());
|
||||
}
|
||||
else {
|
||||
else if (this.ignoreUnresolvablePlaceholders) {
|
||||
// Proceed with unprocessed value.
|
||||
startIndex = buf.indexOf(PLACEHOLDER_PREFIX, endIndex + PLACEHOLDER_SUFFIX.length());
|
||||
startIndex = buf.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Could not resolve placeholder '" + placeholder + "'");
|
||||
}
|
||||
|
||||
visitedPlaceholders.remove(placeholder);
|
||||
|
|
@ -112,22 +150,22 @@ public class PropertyPlaceholderUtils {
|
|||
return buf.toString();
|
||||
}
|
||||
|
||||
private static int findPlaceholderEndIndex(CharSequence buf, int startIndex) {
|
||||
int index = startIndex + PLACEHOLDER_PREFIX.length();
|
||||
private int findPlaceholderEndIndex(CharSequence buf, int startIndex) {
|
||||
int index = startIndex + this.placeholderPrefix.length();
|
||||
int withinNestedPlaceholder = 0;
|
||||
while (index < buf.length()) {
|
||||
if (StringUtils.substringMatch(buf, index, PLACEHOLDER_SUFFIX)) {
|
||||
if (StringUtils.substringMatch(buf, index, this.placeholderSuffix)) {
|
||||
if (withinNestedPlaceholder > 0) {
|
||||
withinNestedPlaceholder--;
|
||||
index = index + PLACEHOLDER_PREFIX.length() - 1;
|
||||
index = index + this.placeholderPrefix.length() - 1;
|
||||
}
|
||||
else {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
else if (StringUtils.substringMatch(buf, index, PLACEHOLDER_PREFIX)) {
|
||||
else if (StringUtils.substringMatch(buf, index, this.placeholderPrefix)) {
|
||||
withinNestedPlaceholder++;
|
||||
index = index + PLACEHOLDER_PREFIX.length();
|
||||
index = index + this.placeholderPrefix.length();
|
||||
}
|
||||
else {
|
||||
index++;
|
||||
|
|
@ -139,7 +177,7 @@ public class PropertyPlaceholderUtils {
|
|||
/**
|
||||
* Strategy interface used to resolve replacement values for placeholders contained in Strings.
|
||||
*
|
||||
* @see org.springframework.util.PropertyPlaceholderUtils
|
||||
* @see PropertyPlaceholderHelper
|
||||
*/
|
||||
public static interface PlaceholderResolver {
|
||||
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
package org.springframework.util;
|
||||
|
||||
import org.springframework.util.PropertyPlaceholderUtils.PlaceholderResolver;
|
||||
import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver;
|
||||
|
||||
/**
|
||||
* Helper class for resolving placeholders in texts. Usually applied to file paths.
|
||||
|
|
@ -38,6 +38,7 @@ 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);
|
||||
/**
|
||||
* Resolve ${...} placeholders in the given text, replacing them with corresponding system property values.
|
||||
*
|
||||
|
|
@ -47,7 +48,7 @@ public abstract class SystemPropertyUtils {
|
|||
* @see #PLACEHOLDER_SUFFIX
|
||||
*/
|
||||
public static String resolvePlaceholders(final String text) {
|
||||
return PropertyPlaceholderUtils.replacePlaceholders(text, new PlaceholderResolver() {
|
||||
return HELPER.replacePlaceholders(text, new PlaceholderResolver() {
|
||||
|
||||
public String resolvePlaceholder(String placeholderName) {
|
||||
String propVal = null;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,9 @@ import org.junit.Test;
|
|||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/** @author Rob Harrop */
|
||||
public class PropertyPlaceholderUtilsTests {
|
||||
public class PropertyPlaceholderHelperTests {
|
||||
|
||||
private final PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}");
|
||||
|
||||
@Test
|
||||
public void testWithProperties() {
|
||||
|
|
@ -30,7 +32,7 @@ public class PropertyPlaceholderUtilsTests {
|
|||
Properties props = new Properties();
|
||||
props.setProperty("foo", "bar");
|
||||
|
||||
assertEquals("foo=bar", PropertyPlaceholderUtils.replacePlaceholders(text, props));
|
||||
assertEquals("foo=bar", this.helper.replacePlaceholders(text, props));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -40,7 +42,7 @@ public class PropertyPlaceholderUtilsTests {
|
|||
props.setProperty("foo", "bar");
|
||||
props.setProperty("bar", "baz");
|
||||
|
||||
assertEquals("foo=bar,bar=baz", PropertyPlaceholderUtils.replacePlaceholders(text, props));
|
||||
assertEquals("foo=bar,bar=baz", this.helper.replacePlaceholders(text, props));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -50,7 +52,7 @@ public class PropertyPlaceholderUtilsTests {
|
|||
props.setProperty("bar", "${baz}");
|
||||
props.setProperty("baz", "bar");
|
||||
|
||||
assertEquals("foo=bar", PropertyPlaceholderUtils.replacePlaceholders(text, props));
|
||||
assertEquals("foo=bar", this.helper.replacePlaceholders(text, props));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -60,7 +62,7 @@ public class PropertyPlaceholderUtilsTests {
|
|||
props.setProperty("bar", "bar");
|
||||
props.setProperty("inner", "ar");
|
||||
|
||||
assertEquals("foo=bar", PropertyPlaceholderUtils.replacePlaceholders(text, props));
|
||||
assertEquals("foo=bar", this.helper.replacePlaceholders(text, props));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -68,7 +70,7 @@ public class PropertyPlaceholderUtilsTests {
|
|||
String text = "foo=${foo}";
|
||||
|
||||
assertEquals("foo=bar",
|
||||
PropertyPlaceholderUtils.replacePlaceholders(text, new PropertyPlaceholderUtils.PlaceholderResolver() {
|
||||
this.helper.replacePlaceholders(text, new PropertyPlaceholderHelper.PlaceholderResolver() {
|
||||
|
||||
public String resolvePlaceholder(String placeholderName) {
|
||||
if ("foo".equals(placeholderName)) {
|
||||
|
|
@ -87,6 +89,16 @@ public class PropertyPlaceholderUtilsTests {
|
|||
Properties props = new Properties();
|
||||
props.setProperty("foo", "bar");
|
||||
|
||||
assertEquals("foo=bar,bar=${bar}", PropertyPlaceholderUtils.replacePlaceholders(text, props));
|
||||
assertEquals("foo=bar,bar=${bar}", this.helper.replacePlaceholders(text, props));
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testUnresolvedPlaceholderAsError() {
|
||||
String text = "foo=${foo},bar=${bar}";
|
||||
Properties props = new Properties();
|
||||
props.setProperty("foo", "bar");
|
||||
|
||||
PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}", false);
|
||||
assertEquals("foo=bar,bar=${bar}", helper.replacePlaceholders(text, props));
|
||||
}
|
||||
}
|
||||
1940
spring-framework.ipr
1940
spring-framework.ipr
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue