Format ready for 2.1

git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/lang/trunk@137894 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Stephen Colebourne 2004-08-15 23:18:43 +00:00
parent 131adbbc7c
commit 48e8e7e2e6
1 changed files with 97 additions and 110 deletions

View File

@ -1,125 +1,124 @@
package org.apache.commons.lang;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* Performs basic variable interpolation on a String for variables within
* a Map. Variables of the form, ${var}, are supported.
* <p>Performs basic variable interpolation on a String for variables within a Map.
* Variables of the form, ${var}, are supported.</p>
*
* @author Ken Fitzpatrick
* @author Henri Yandell
* @since 2.1
* @version $Id: Interpolation.java,v 1.2 2004/08/15 23:18:43 scolebourne Exp $
*/
public class Interpolation {
// QUERY: Anyway to escape the ${..} variable so it is not interpolated?
// TODO: Consider making these configurable?
/** The marker used to start a variable. */
private static final String SYMBOLIC_VALUE_MARKER_START = "${";
/** The marker used to end a variable. */
private static final String SYMBOLIC_VALUE_MARKER_END = "}";
/**
* <p>
* Returns a String that is the result of having performed
* variable interpolation on <code>templateString</code>,
* using the value set found in <code>values</code>.
* </p>
* <p>
* The solution is compatible with all JDK versions
* where Jakarta/Commons/Lang also is supported.
* </p>
* <p>
* The expected format of <code>templateString</code> is:
*<code><pre>
* <p>Interpolates a String to replace variables of the form <code>${...}</code>.</p>
*
* <p>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.</p>
*
* <p>The expected format of <code>templateString</code> is:
* <code><pre>
* The ${animal} jumped over the ${target}.
*</pre></code>
* such that the key/value pairs found in <code>values</code>
* are substituted into the string at the <code>${key-name}</code> markers.
* In the above example, <code>valuesMap</code> could have been populated as:
*<code><pre>
* </pre></code>
* such that the key/value pairs found in <code>values</code>
* are substituted into the string at the <code>${key-name}</code> markers.
* In the above example, <code>valuesMap</code> could have been populated as:
* <code><pre>
* Map valuesMap = HashMap();
* valuesMap.put( "animal", "quick brown fox" );
* valuesMap.put( "target", "lazy dog" );
* String resolvedString = StringUtils.interpolate( templateString, valuesMap );
*</pre></code>
* yielding:
*<code><pre>
* </pre></code>
* yielding:
* <code><pre>
* The quick brown fox jumped over the lazy dog.
*</pre></code>
* </p>
* <p>
* The same <code>templateString</code> from the above example could be reused as:
*<code><pre>
* </pre></code></p>
*
* <p>The same <code>templateString</code> from the above example could be reused as:
* <code><pre>
* Map valuesMap = HashMap();
* valuesMap.put( "animal", "cow" );
* valuesMap.put( "target", "moon" );
* String resolvedString = StringUtils.interpolate( templateString, valuesMap );
*</pre></code>
* yielding:
*<code><pre>
* </pre></code>
* yielding:
* <code><pre>
* The cow jumped over the moon.
*</pre></code>
* </p>
* <p>
* The value of <code>templateString</code> is returned in an unaltered if <code>templateString</code>
* is null, empty, or contains no marked variables that can be resolved by the key/value pairs found in
* <code>valuesMap</code>, or if <code>valuesMap</code> is null, empty or has no key/value pairs that can be
* applied to the marked variables within <code>templateString</code>.
* </p>
* @param templateString String containing any mixture of variable and non-variable
* </pre></code></p>
*
* <p>The value of <code>templateString</code> is returned in an unaltered
* if <code>templateString</code> is null, empty, or contains no marked variables
* that can be resolved by the key/value pairs found in <code>valuesMap</code>,
* or if <code>valuesMap</code> is null, empty or has no key/value pairs that can be
* applied to the marked variables within <code>templateString</code>.</p>
*
* <p>If a <code>valuesMap</code> value is null, it will be treated as "".</p>
*
* @param templateString String containing any mixture of variable and non-variable
* content, to be used as a template for the value substitution process
* @param valuesMap Map containing the key/value pairs to be used to resolve
* @param valuesMap Map containing the key/value pairs to be used to resolve
* the values of the marked variables found within <code>templateString</code>
* @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;
}
/**
* <p>
* Returns a String that is the result of having performed variable interpolation on
* <code>templateString</code>, using the value set found in <code>values</code>,
* repeatedly until there are no changes.
* </p>
* <p>
* The expected format of <code>templateString</code> is:
*<code><pre>
* <p>Interpolates a String to replace variables of the form <code>${...}</code>
* where the replace strings may also contain variables to interpolate.</p>
*
* <p>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.</p>
*
* <p>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 <code>valuesMap</code> to contain variables that should also be
* interpolated.</p>
*
* <p>The expected format of <code>templateString</code> is:
* <code><pre>
* The ${animal} jumped over the ${target}.
*</pre></code>
* such that the key/value pairs found in <code>values</code> are substituted into the string at the
* <code>${key-name}</code> markers. In the above example, <code>valuesMap</code>
* could have been populated as:
*<code><pre>
* </pre></code>
* such that the key/value pairs found in <code>values</code> are substituted into the string at the
* <code>${key-name}</code> markers. In the above example, <code>valuesMap</code>
* could have been populated as:
* <code><pre>
* 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 );
*</pre></code>
* yielding:
*<code><pre>
* </pre></code>
* yielding:
* <code><pre>
* The quick brown fox jumped over the lazy dog.
*</pre></code>
* </p>
* yielding:
*<code><pre>
* The cow jumped over the moon.
*</pre></code>
* </p>
* <p>
* The value of <code>templateString</code> is returned in an unaltered form if
* <code>templateString</code> is null, empty, or
* contains no marked variables that can be resolved by the key/value pairs found in
* <code>valuesMap</code>, or if <code>valuesMap</code> is null, empty or has no key/value
* pairs that can be applied to the marked variables within <code>templateString</code>.
* </p>
* @param templateString String containing any mixture of variable and non-variable
* </pre></code></p>
*
* <p>The value of <code>templateString</code> is returned in an unaltered
* if <code>templateString</code> is null, empty, or contains no marked variables
* that can be resolved by the key/value pairs found in <code>valuesMap</code>,
* or if <code>valuesMap</code> is null, empty or has no key/value pairs that can be
* applied to the marked variables within <code>templateString</code>.</p>
*
* <p>If a <code>valuesMap</code> value is null, it will be treated as "".</p>
*
* @param templateString String containing any mixture of variable and non-variable
* content, to be used as a template for the value substitution process
* @param valuesMap Map containing the key/value pairs to be used to resolve
* @param valuesMap Map containing the key/value pairs to be used to resolve
* the values of the marked variables found within <code>templateString</code>
* @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;
}