From 48e8e7e2e66a1726801d9e7a198bf411e0d8d269 Mon Sep 17 00:00:00 2001
From: Stephen Colebourne Performs basic variable interpolation on a String for variables within a Map.
+ * Variables of the form, ${var}, are supported.
- * Returns a String that is the result of having performed
- * variable interpolation on
- * The solution is compatible with all JDK versions
- * where Jakarta/Commons/Lang also is supported.
- *
- * The expected format of Interpolates a String to replace variables of the form This method is useful for enabling simple strings to be modified based
+ * on a map of data. A typical use case might be to add data from configuration
+ * to an error message. This method, and this class, does not seek to replace
+ * full interpolation mechanisms, for example Velocity. The expected format of
- * The same The same
- * The value of The value of If a
- * Returns a String that is the result of having performed variable interpolation on
- *
- * The expected format of Interpolates a String to replace variables of the form This method is useful for enabling simple strings to be modified based
+ * on a map of data. A typical use case might be to add data from configuration
+ * to an error message. This method, and this class, does not seek to replace
+ * full interpolation mechanisms, for example Velocity. This method calls {@link #interpolate(String, Map)} repeatedly until the
+ * returned string does not change. This has the effect of allowing the replace
+ * strings in The expected format of
- * The value of templateString
,
- * using the value set found in values
.
- * templateString
is:
- *
+ *
${...}
.templateString
is:
+ *
- * such that the key/value pairs found in
* The ${animal} jumped over the ${target}.
- *
values
- * are substituted into the string at the ${key-name}
markers.
- * In the above example, valuesMap
could have been populated as:
- *
+ * such that the key/value pairs found in
+ *
values
+ * are substituted into the string at the ${key-name}
markers.
+ * In the above example, valuesMap
could have been populated as:
+ *
- * yielding:
- *
* Map valuesMap = HashMap();
* valuesMap.put( "animal", "quick brown fox" );
* valuesMap.put( "target", "lazy dog" );
* String resolvedString = StringUtils.interpolate( templateString, valuesMap );
- *
+ * yielding:
+ *
+ *
- *
* The quick brown fox jumped over the lazy dog.
- *
templateString
from the above example could be reused as:
- *
+ *
templateString
from the above example could be reused as:
+ *
- * yielding:
- *
* Map valuesMap = HashMap();
* valuesMap.put( "animal", "cow" );
* valuesMap.put( "target", "moon" );
* String resolvedString = StringUtils.interpolate( templateString, valuesMap );
- *
+ * yielding:
+ *
+ *
- *
* The cow jumped over the moon.
- *
templateString
is returned in an unaltered if templateString
- * is null, empty, or contains no marked variables that can be resolved by the key/value pairs found in
- * valuesMap
, or if valuesMap
is null, empty or has no key/value pairs that can be
- * applied to the marked variables within templateString
.
- * templateString
is returned in an unaltered
+ * if templateString
is null, empty, or contains no marked variables
+ * that can be resolved by the key/value pairs found in valuesMap
,
+ * or if valuesMap
is null, empty or has no key/value pairs that can be
+ * applied to the marked variables within templateString
.valuesMap
value is null, it will be treated as "".templateString
- * @return String
+ * @return the interpolated String
*/
- public static String interpolate( String templateString, Map valuesMap ) {
+ public static String interpolate(String templateString, Map valuesMap) {
// pre-conditions
- if ( valuesMap == null )
+ if (templateString == null || valuesMap == null ||
+ templateString.length() == 0 || valuesMap.isEmpty()) {
return templateString;
- if ( templateString == null )
- return templateString;
- if ( templateString.length() < 1 )
- return templateString;
- if ( valuesMap.isEmpty() )
- return templateString;
-
+ }
+
// default the returned String to the templateString
String returnString = templateString;
String nextKey = null;
Object substitutionBean = null;
String substitutionValue = null;
String nextValueToBeSubstituted = null;
-
+
// get a list of substitution valuesMap
Iterator keys = valuesMap.keySet().iterator();
-
- while( keys.hasNext() ) {
- nextKey = ( String ) keys.next();
- substitutionValue = StringUtils.defaultString( ( String ) valuesMap.get( nextKey ) );
+ while (keys.hasNext()) {
+ nextKey = (String) keys.next();
+ substitutionValue = StringUtils.defaultString((String) valuesMap.get(nextKey));
nextValueToBeSubstituted = SYMBOLIC_VALUE_MARKER_START + nextKey + SYMBOLIC_VALUE_MARKER_END;
- returnString = StringUtils.replace( returnString, nextValueToBeSubstituted, substitutionValue );
+ returnString = StringUtils.replace(returnString, nextValueToBeSubstituted, substitutionValue);
}
return returnString;
}
-
/**
- * templateString
, using the value set found in values
,
- * repeatedly until there are no changes.
- * templateString
is:
- *
+ *
${...}
+ * where the replace strings may also contain variables to interpolate.valuesMap
to contain variables that should also be
+ * interpolated.templateString
is:
+ *
- * such that the key/value pairs found in
* The ${animal} jumped over the ${target}.
- *
values
are substituted into the string at the
- * ${key-name}
markers. In the above example, valuesMap
- * could have been populated as:
- *
+ * such that the key/value pairs found in
+ *
values
are substituted into the string at the
+ * ${key-name}
markers. In the above example, valuesMap
+ * could have been populated as:
+ *
- * yielding:
- *
* Map valuesMap = HashMap();
* valuesMap.put( "animal", "${critter}" );
* valuesMap.put( "target", "${pet}" );
@@ -130,52 +129,40 @@ public class Interpolation {
* valuesMap.put( "critterColor", "brown" );
* valuesMap.put( "critterType", "fox" );
* String resolvedString = StringUtils.interpolate( templateString, valuesMap, true );
- *
+ * yielding:
+ *
+ *
- *
* The quick brown fox jumped over the lazy dog.
- *
- *
- * The cow jumped over the moon.
- *
templateString
is returned in an unaltered form if
- * templateString
is null, empty, or
- * contains no marked variables that can be resolved by the key/value pairs found in
- * valuesMap
, or if valuesMap
is null, empty or has no key/value
- * pairs that can be applied to the marked variables within templateString
.
- *
The value of templateString
is returned in an unaltered
+ * if templateString
is null, empty, or contains no marked variables
+ * that can be resolved by the key/value pairs found in valuesMap
,
+ * or if valuesMap
is null, empty or has no key/value pairs that can be
+ * applied to the marked variables within templateString
.
If a valuesMap
value is null, it will be treated as "".
templateString
- * @return String
+ * @return the interpolated String
*/
- public static String interpolateRepeatedly(
- String templateString,
- Map valuesMap)
- {
+ public static String interpolateRepeatedly(String templateString, Map valuesMap) {
// pre-conditions
- if ( valuesMap == null )
+ if (templateString == null || valuesMap == null ||
+ templateString.length() == 0 || valuesMap.isEmpty()) {
return templateString;
- if ( templateString == null )
- return templateString;
- if ( templateString.length() < 1 )
- return templateString;
- if ( valuesMap.isEmpty() )
- return templateString;
-
+ }
+
String currentResult = templateString;
String previousResult = null;
- while( ! StringUtils.equals( currentResult, previousResult ) )
- {
+ while (!StringUtils.equals(currentResult, previousResult)) {
previousResult = currentResult;
- currentResult = Interpolation.interpolate( previousResult, valuesMap );
+ currentResult = Interpolation.interpolate(previousResult, valuesMap);
}
-
+
return currentResult;
}