diff --git a/org.springframework.core/src/main/java/org/springframework/util/PropertyPlaceholderUtils.java b/org.springframework.core/src/main/java/org/springframework/util/PropertyPlaceholderHelper.java
similarity index 55%
rename from org.springframework.core/src/main/java/org/springframework/util/PropertyPlaceholderUtils.java
rename to org.springframework.core/src/main/java/org/springframework/util/PropertyPlaceholderHelper.java
index 51d50f10de1..4e61033f3f3 100644
--- a/org.springframework.core/src/main/java/org/springframework/util/PropertyPlaceholderUtils.java
+++ b/org.springframework.core/src/main/java/org/springframework/util/PropertyPlaceholderHelper.java
@@ -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
* ${name}. Using PropertyPlaceholderUtils 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 {
+
+ private static final Log LOGGER = LogFactory.getLog(PropertyPlaceholderHelper.class);
+
+ private final String placeholderPrefix;
+
+ private final String placeholderSuffix;
- /** Prefix for property placeholders: "${" */
- public static final String PLACEHOLDER_PREFIX = "${";
+ private final boolean ignoreUnresolvablePlaceholders;
- /** Suffix for property placeholders: "}" */
- public static final String PLACEHOLDER_SUFFIX = "}";
+ /**
+ * Creates a new PropertyPlaceholderHelper 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 PropertyPlaceholderHelper 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
+ * (true) or cause an exception (false).
+ */
+ 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 ${name} with the corresponding property from the supplied {@link
@@ -46,7 +79,7 @@ public class PropertyPlaceholderUtils {
* @param properties the Properties 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 PlaceholderResolver 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());
}
- protected static String parseStringValue(String strVal, PlaceholderResolver placeholderResolver, Set visitedPlaceholders) {
+ protected String parseStringValue(String strVal, PlaceholderResolver placeholderResolver,
+ Set 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 {
diff --git a/org.springframework.core/src/main/java/org/springframework/util/SystemPropertyUtils.java b/org.springframework.core/src/main/java/org/springframework/util/SystemPropertyUtils.java
index 9cd11537ac5..1ae56c1c07a 100644
--- a/org.springframework.core/src/main/java/org/springframework/util/SystemPropertyUtils.java
+++ b/org.springframework.core/src/main/java/org/springframework/util/SystemPropertyUtils.java
@@ -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;
diff --git a/org.springframework.core/src/test/java/org/springframework/util/PropertyPlaceholderUtilsTests.java b/org.springframework.core/src/test/java/org/springframework/util/PropertyPlaceholderHelperTests.java
similarity index 66%
rename from org.springframework.core/src/test/java/org/springframework/util/PropertyPlaceholderUtilsTests.java
rename to org.springframework.core/src/test/java/org/springframework/util/PropertyPlaceholderHelperTests.java
index 50ca7f0eed4..c4dd9b77cf0 100644
--- a/org.springframework.core/src/test/java/org/springframework/util/PropertyPlaceholderUtilsTests.java
+++ b/org.springframework.core/src/test/java/org/springframework/util/PropertyPlaceholderHelperTests.java
@@ -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));
}
}
diff --git a/spring-framework.ipr b/spring-framework.ipr
index 7b73466b11a..da8147cc8c8 100644
--- a/spring-framework.ipr
+++ b/spring-framework.ipr
@@ -1,979 +1,961 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
- -
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+