/*
* Copyright (c) 2012-2015, Luigi R. Viggiano
* All rights reserved.
*
* This software is distributable under the BSD license.
* See the terms of the BSD license in the documentation provided with this software.
*/
package org.aeonbits.owner;
import java.io.Serializable;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static java.util.regex.Pattern.compile;
import static org.aeonbits.owner.Util.fixBackslashForRegex;
/**
* <p>
* Substitutes variables within a string by values.
* </p>
* <p>
* This class takes a piece of text and substitutes all the variables within it. The definition of a variable is
* <code>${variableName}</code>.
* </p>
* <p>
* Typical usage of this class follows the following pattern: First an instance is created and initialized with the
* values that contains the values for the available variables. If a prefix and/or suffix for variables should be used
* other than the default ones, the appropriate settings can be performed. After that the <code>replace()</code> method
* can be called passing in the source text for interpolation. In the returned text all variable references (as long as
* their values are known) will be resolved. The following example demonstrates this:
* </p>
* <pre>
* Map valuesMap = new HashMap();
* valuesMap.put("animal", "quick brown fox");
* valuesMap.put("target", "lazy dog");
* String templateString = "The ${animal} jumped over the ${target}.";
* StrSubstitutor sub = new StrSubstitutor(valuesMap);
* String resolvedString = sub.replace(templateString);
* </pre>
* yielding:
* <pre>
* The quick brown fox jumped over the lazy dog.
* </pre>
*
* @author Luigi R. Viggiano
*/
class StrSubstitutor implements Serializable {
private final Properties values;
private static final Pattern PATTERN = compile("\\$\\{(.+?)\\}");
/**
* Creates a new instance and initializes it. Uses defaults for variable prefix and suffix and the escaping
* character.
*
* @param values the variables' values, may be null
*/
StrSubstitutor(Properties values) {
this.values = values;
}
/**
* Replaces all the occurrences of variables with their matching values from the resolver using the given source
* string as a template.
*
* @param source the string to replace in, null returns null
* @return the result of the replace operation
*/
String replace(String source) {
if (source == null)
return null;
Matcher m = PATTERN.matcher(source);
StringBuffer sb = new StringBuffer();
while (m.find()) {
String var = m.group(1);
String value = values.getProperty(var);
String replacement = (value != null) ? replace(value) : "";
m.appendReplacement(sb, Matcher.quoteReplacement(replacement));
}
m.appendTail(sb);
return sb.toString();
}
}