You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2019/08/04 21:41:47 UTC
[commons-text] 02/02: [TEXT-171]
StringLookupFactory.addDefaultStringLookups(Map) does not convert keys to
lower case.
This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-text.git
commit bc1b2049f171050385678905a4359287052168d1
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Sun Aug 4 17:41:41 2019 -0400
[TEXT-171] StringLookupFactory.addDefaultStringLookups(Map) does not
convert keys to lower case.
Also, better Javadoc.
---
src/changes/changes.xml | 1 +
.../org/apache/commons/text/StringSubstitutor.java | 515 +++++++++------------
.../text/lookup/InterpolatorStringLookup.java | 8 +-
.../commons/text/lookup/StringLookupFactory.java | 29 +-
src/site/xdoc/userguide.xml | 26 ++
.../org/apache/commons/text/StrLookupTest.java | 2 +-
...ubstitutorWithInterpolatorStringLookupTest.java | 39 +-
.../lookup/ResourceBundleStringLookupTest.java | 2 +-
.../text/lookup/StringLookupFactoryTest.java | 34 +-
.../commons/text/lookup/UrlStringLookupTest.java | 3 +-
.../example}/testResourceBundleLookup.properties | 1 +
11 files changed, 325 insertions(+), 335 deletions(-)
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 8d1527e..7f41562 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -50,6 +50,7 @@ The <action> type attribute can be add,update,fix,remove.
<action issue="TEXT-168" type="fix" dev="ggregory" due-to="luksan47">(doc) Fixed wrong value for Jaro-Winkler example #117</action>
<action issue="TEXT-169" type="add" dev="ggregory" due-to="Gary Gregory">Add helper factory method org.apache.commons.text.StringSubstitutor.createInterpolator().</action>
<action issue="TEXT-170" type="add" dev="ggregory" due-to="Gary Gregory">Add String lookup for host names and IP addresses (DnsStringLookup).</action>
+ <action issue="TEXT-171" type="fix" dev="ggregory" due-to="Gary Gregory">StringLookupFactory.addDefaultStringLookups(Map) does not convert keys to lower case.</action>
<action type="update" dev="ggregory" due-to="Gary Gregory">Expand Javadoc for StringSubstitutor and friends.</action>
</release>
diff --git a/src/main/java/org/apache/commons/text/StringSubstitutor.java b/src/main/java/org/apache/commons/text/StringSubstitutor.java
index 99b9c7a..07f8507 100644
--- a/src/main/java/org/apache/commons/text/StringSubstitutor.java
+++ b/src/main/java/org/apache/commons/text/StringSubstitutor.java
@@ -34,22 +34,27 @@ import org.apache.commons.text.matcher.StringMatcherFactory;
* <p>
* This class takes a piece of text and substitutes all the variables within it. The default definition of a variable is
* <code>${variableName}</code>. The prefix and suffix can be changed via constructors and set methods.
+ * </p>
* <p>
* Variable values are typically resolved from a map, but could also be resolved from system properties, or by supplying
* a custom variable resolver.
* <p>
* The simplest example is to use this class to replace Java System properties. For example:
+ * </p>
*
* <pre>
* StringSubstitutor
* .replaceSystemProperties("You are running with java.version = ${java.version} and os.name = ${os.name}.");
* </pre>
+ *
+ * <h1>Using a Custom Map</h1>
* <p>
* Typical usage of this class follows the following pattern: First an instance is created and initialized with the map
* 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()} 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 = HashMap();
@@ -60,18 +65,23 @@ import org.apache.commons.text.matcher.StringMatcherFactory;
* String resolvedString = sub.replace(templateString);
* </pre>
*
+ * <p>
* yielding:
+ * </p>
*
* <pre>
* The quick brown fox jumped over the lazy dog.
* </pre>
+ *
+ * <h1>Providing Default Values</h1>
* <p>
- * Also, this class allows to set a default value for unresolved variables. The default value for a variable can be
- * appended to the variable name after the variable default value delimiter. The default value of the variable default
- * value delimiter is ':-', as in bash and other *nix shells, as those are arguably where the default ${} delimiter set
+ * This class lets you set a default value for unresolved variables. The default value for a variable can be appended to
+ * the variable name after the variable default value delimiter. The default value of the variable default value
+ * delimiter is ':-', as in bash and other *nix shells, as those are arguably where the default ${} delimiter set
* originated. The variable default value delimiter can be manually set by calling
* {@link #setValueDelimiterMatcher(StringMatcher)}, {@link #setValueDelimiter(char)} or
* {@link #setValueDelimiter(String)}. The following shows an example with variable default value settings:
+ * </p>
*
* <pre>
* Map valuesMap = HashMap();
@@ -82,57 +92,106 @@ import org.apache.commons.text.matcher.StringMatcherFactory;
* String resolvedString = sub.replace(templateString);
* </pre>
*
+ * <p>
* yielding:
+ * </p>
*
* <pre>
* The quick brown fox jumped over the lazy dog. 1234567890.
* </pre>
+ *
+ * <p>
+ * {@code StringSubstitutor} supports throwing exceptions for unresolved variables, you enable this by setting calling
+ * {@link #setEnableUndefinedVariableException(boolean)} with {@code true}.
+ * </p>
+ *
+ * <h1>Reusing Instances</h1>
* <p>
* In addition to this usage pattern there are some static convenience methods that cover the most common use cases.
* These methods can be used without the need of manually creating an instance. However if multiple replace operations
* are to be performed, creating and reusing an instance of this class will be more efficient.
+ * </p>
+ * <p>
+ * This class is <b>not</b> thread safe.
+ * </p>
+ *
+ * <h1>Using Interpolation</h1>
+ * <p>
+ * The default interpolator let's you use string lookups like:
+ * </p>
+ *
+ * <pre>
+final StringSubstitutor interpolator = StringSubstitutor.createInterpolator();
+interpolator.setEnableSubstitutionInVariables(true); // Allows for nested $'s.
+final String text = interpolator.replace(
+ "Base64 Decoder: ${base64Decoder:SGVsbG9Xb3JsZCE=}\n" +
+ "Base64 Encoder: ${base64Encoder:HelloWorld!}\n" +
+ "Java Constant: ${const:java.awt.event.KeyEvent.VK_ESCAPE}\n" +
+ "Date: ${date:yyyy-MM-dd}\n" +
+ "DNS: ${dns:address|apache.org}\n" +
+ "Environment Variable: ${env:USERNAME}\n" +
+ "File Content: ${file:UTF-8:src/test/resources/document.properties}\n" +
+ "Java: ${java:version}\n" +
+ "Localhost: ${localhost:canonical-name}\n" +
+ "Properties File: ${properties:src/test/resources/document.properties::mykey}\n" +
+ "Resource Bundle: ${resourceBundle:org.example.testResourceBundleLookup:mykey}\n" +
+ "Script: ${script:javascript:3 + 4}\n" +
+ "System Property: ${sys:user.dir}\n" +
+ "URL Decoder: ${urlDecoder:Hello%20World%21}\n" +
+ "URL Encoder: ${urlEncoder:Hello World!}\n" +
+ "URL Content (HTTP): ${url:UTF-8:http://www.apache.org}\n" +
+ "URL Content (HTTPS): ${url:UTF-8:https://www.apache.org}\n" +
+ "URL Content (File): ${url:UTF-8:file:///${sys:user.dir}/src/test/resources/document.properties}\n" +
+ "XML XPath: ${xml:src/test/resources/document.xml:/root/path/to/node}\n"
+);
+ * </pre>
+ * <p>
+ * For documentation of each lookup, see {@link StringLookupFactory}.
+ * </p>
+ *
+ * <h1>Using Recursive Variable Replacement</h1>
* <p>
* Variable replacement works in a recursive way. Thus, if a variable value contains a variable then that variable will
* also be replaced. Cyclic replacements are detected and will cause an exception to be thrown.
+ * </p>
* <p>
* Sometimes the interpolation's result must contain a variable prefix. As an example take the following source text:
+ * </p>
*
* <pre>
* The variable ${${name}} must be used.
* </pre>
*
+ * <p>
* Here only the variable's name referred to in the text should be replaced resulting in the text (assuming that the
* value of the {@code name} variable is {@code x}):
+ * </p>
*
* <pre>
* The variable ${x} must be used.
* </pre>
*
+ * <p>
* To achieve this effect there are two possibilities: Either set a different prefix and suffix for variables which do
* not conflict with the result text you want to produce. The other possibility is to use the escape character, by
* default '$'. If this character is placed before a variable reference, this reference is ignored and won't be
* replaced. For example:
+ * </p>
*
* <pre>
* The variable $${${name}} must be used.
* </pre>
* <p>
* In some complex scenarios you might even want to perform substitution in the names of variables, for instance
+ * </p>
*
* <pre>
* ${jre-${java.specification.version}}
* </pre>
*
* <p>
- * {@code StringSubstitutor} supports this recursive substitution in variable names, but it has to be enabled
- * explicitly by calling {@link #setEnableSubstitutionInVariables(boolean)} with {@code true}.
- * </p>
- * <p>
- * {@code StringSubstitutor} supports throwing exceptions for unresolved variables, you enable this by setting
- * calling {@link #setEnableUndefinedVariableException(boolean)} with {@code true}.
- * </p>
- * <p>
- * This class is <b>not</b> thread safe.
+ * {@code StringSubstitutor} supports this recursive substitution in variable names, but it has to be enabled explicitly
+ * by calling {@link #setEnableSubstitutionInVariables(boolean)} with {@code true}.
* </p>
*
* @since 1.3
@@ -178,8 +237,8 @@ public class StringSubstitutor {
/**
* Constant for the default value delimiter of a variable.
*/
- public static final StringMatcher DEFAULT_VALUE_DELIMITER =
- StringMatcherFactory.INSTANCE.stringMatcher(DEFAULT_VAR_DEFAULT);
+ public static final StringMatcher DEFAULT_VALUE_DELIMITER = StringMatcherFactory.INSTANCE
+ .stringMatcher(DEFAULT_VAR_DEFAULT);
/**
* Creates a new instance using the interpolator string lookup
@@ -187,10 +246,9 @@ public class StringSubstitutor {
* <p>
* This StringSubstitutor lets you perform substituions like:
* </p>
+ *
* <pre>
- * StringSubstitutor.createInterpolator().replace(
- * "OS name: ${sys:os.name}, " +
- * "3 + 4 = ${script:javascript:3 + 4}");
+ * StringSubstitutor.createInterpolator().replace("OS name: ${sys:os.name}, " + "3 + 4 = ${script:javascript:3 + 4}");
* </pre>
*
* @return a new instance using the interpolator string lookup.
@@ -204,15 +262,11 @@ public class StringSubstitutor {
/**
* Replaces all the occurrences of variables in the given source object with their matching values from the map.
*
- * @param <V>
- * the type of the values in the map
- * @param source
- * the source text containing the variables to substitute, null returns null
- * @param valueMap
- * the map with the values, may be null
+ * @param <V> the type of the values in the map
+ * @param source the source text containing the variables to substitute, null returns null
+ * @param valueMap the map with the values, may be null
* @return The result of the replace operation
- * @throws IllegalArgumentException
- * if a variable is not found and enableUndefinedVariableException is true
+ * @throws IllegalArgumentException if a variable is not found and enableUndefinedVariableException is true
*/
public static <V> String replace(final Object source, final Map<String, V> valueMap) {
return new StringSubstitutor(valueMap).replace(source);
@@ -222,21 +276,14 @@ public class StringSubstitutor {
* Replaces all the occurrences of variables in the given source object with their matching values from the map.
* This method allows to specify a custom variable prefix and suffix
*
- * @param <V>
- * the type of the values in the map
- * @param source
- * the source text containing the variables to substitute, null returns null
- * @param valueMap
- * the map with the values, may be null
- * @param prefix
- * the prefix of variables, not null
- * @param suffix
- * the suffix of variables, not null
+ * @param <V> the type of the values in the map
+ * @param source the source text containing the variables to substitute, null returns null
+ * @param valueMap the map with the values, may be null
+ * @param prefix the prefix of variables, not null
+ * @param suffix the suffix of variables, not null
* @return The result of the replace operation
- * @throws IllegalArgumentException
- * if the prefix or suffix is null
- * @throws IllegalArgumentException
- * if a variable is not found and enableUndefinedVariableException is true
+ * @throws IllegalArgumentException if the prefix or suffix is null
+ * @throws IllegalArgumentException if a variable is not found and enableUndefinedVariableException is true
*/
public static <V> String replace(final Object source, final Map<String, V> valueMap, final String prefix,
final String suffix) {
@@ -247,13 +294,10 @@ public class StringSubstitutor {
* Replaces all the occurrences of variables in the given source object with their matching values from the
* properties.
*
- * @param source
- * the source text containing the variables to substitute, null returns null
- * @param valueProperties
- * the properties with values, may be null
+ * @param source the source text containing the variables to substitute, null returns null
+ * @param valueProperties the properties with values, may be null
* @return The result of the replace operation
- * @throws IllegalArgumentException
- * if a variable is not found and enableUndefinedVariableException is true
+ * @throws IllegalArgumentException if a variable is not found and enableUndefinedVariableException is true
*/
public static String replace(final Object source, final Properties valueProperties) {
if (valueProperties == null) {
@@ -273,11 +317,9 @@ public class StringSubstitutor {
* Replaces all the occurrences of variables in the given source object with their matching values from the system
* properties.
*
- * @param source
- * the source text containing the variables to substitute, null returns null
+ * @param source the source text containing the variables to substitute, null returns null
* @return The result of the replace operation
- * @throws IllegalArgumentException
- * if a variable is not found and enableUndefinedVariableException is true
+ * @throws IllegalArgumentException if a variable is not found and enableUndefinedVariableException is true
*/
public static String replaceSystemProperties(final Object source) {
return new StringSubstitutor(StringLookupFactory.INSTANCE.systemPropertyStringLookup()).replace(source);
@@ -340,10 +382,8 @@ public class StringSubstitutor {
* Creates a new instance and initializes it. Uses defaults for variable prefix and suffix and the escaping
* character.
*
- * @param <V>
- * the type of the values in the map
- * @param valueMap
- * the map with the variables' values, may be null
+ * @param <V> the type of the values in the map
+ * @param valueMap the map with the variables' values, may be null
*/
public <V> StringSubstitutor(final Map<String, V> valueMap) {
this(StringLookupFactory.INSTANCE.mapStringLookup(valueMap), DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_ESCAPE);
@@ -352,16 +392,11 @@ public class StringSubstitutor {
/**
* Creates a new instance and initializes it. Uses a default escaping character.
*
- * @param <V>
- * the type of the values in the map
- * @param valueMap
- * the map with the variables' values, may be null
- * @param prefix
- * the prefix for variables, not null
- * @param suffix
- * the suffix for variables, not null
- * @throws IllegalArgumentException
- * if the prefix or suffix is null
+ * @param <V> the type of the values in the map
+ * @param valueMap the map with the variables' values, may be null
+ * @param prefix the prefix for variables, not null
+ * @param suffix the suffix for variables, not null
+ * @throws IllegalArgumentException if the prefix or suffix is null
*/
public <V> StringSubstitutor(final Map<String, V> valueMap, final String prefix, final String suffix) {
this(StringLookupFactory.INSTANCE.mapStringLookup(valueMap), prefix, suffix, DEFAULT_ESCAPE);
@@ -370,18 +405,12 @@ public class StringSubstitutor {
/**
* Creates a new instance and initializes it.
*
- * @param <V>
- * the type of the values in the map
- * @param valueMap
- * the map with the variables' values, may be null
- * @param prefix
- * the prefix for variables, not null
- * @param suffix
- * the suffix for variables, not null
- * @param escape
- * the escape character
- * @throws IllegalArgumentException
- * if the prefix or suffix is null
+ * @param <V> the type of the values in the map
+ * @param valueMap the map with the variables' values, may be null
+ * @param prefix the prefix for variables, not null
+ * @param suffix the suffix for variables, not null
+ * @param escape the escape character
+ * @throws IllegalArgumentException if the prefix or suffix is null
*/
public <V> StringSubstitutor(final Map<String, V> valueMap, final String prefix, final String suffix,
final char escape) {
@@ -391,20 +420,13 @@ public class StringSubstitutor {
/**
* Creates a new instance and initializes it.
*
- * @param <V>
- * the type of the values in the map
- * @param valueMap
- * the map with the variables' values, may be null
- * @param prefix
- * the prefix for variables, not null
- * @param suffix
- * the suffix for variables, not null
- * @param escape
- * the escape character
- * @param valueDelimiter
- * the variable default value delimiter, may be null
- * @throws IllegalArgumentException
- * if the prefix or suffix is null
+ * @param <V> the type of the values in the map
+ * @param valueMap the map with the variables' values, may be null
+ * @param prefix the prefix for variables, not null
+ * @param suffix the suffix for variables, not null
+ * @param escape the escape character
+ * @param valueDelimiter the variable default value delimiter, may be null
+ * @throws IllegalArgumentException if the prefix or suffix is null
*/
public <V> StringSubstitutor(final Map<String, V> valueMap, final String prefix, final String suffix,
final char escape, final String valueDelimiter) {
@@ -414,8 +436,7 @@ public class StringSubstitutor {
/**
* Creates a new instance and initializes it.
*
- * @param variableResolver
- * the variable resolver, may be null
+ * @param variableResolver the variable resolver, may be null
*/
public StringSubstitutor(final StringLookup variableResolver) {
this(variableResolver, DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_ESCAPE);
@@ -424,16 +445,11 @@ public class StringSubstitutor {
/**
* Creates a new instance and initializes it.
*
- * @param variableResolver
- * the variable resolver, may be null
- * @param prefix
- * the prefix for variables, not null
- * @param suffix
- * the suffix for variables, not null
- * @param escape
- * the escape character
- * @throws IllegalArgumentException
- * if the prefix or suffix is null
+ * @param variableResolver the variable resolver, may be null
+ * @param prefix the prefix for variables, not null
+ * @param suffix the suffix for variables, not null
+ * @param escape the escape character
+ * @throws IllegalArgumentException if the prefix or suffix is null
*/
public StringSubstitutor(final StringLookup variableResolver, final String prefix, final String suffix,
final char escape) {
@@ -447,18 +463,12 @@ public class StringSubstitutor {
/**
* Creates a new instance and initializes it.
*
- * @param variableResolver
- * the variable resolver, may be null
- * @param prefix
- * the prefix for variables, not null
- * @param suffix
- * the suffix for variables, not null
- * @param escape
- * the escape character
- * @param valueDelimiter
- * the variable default value delimiter string, may be null
- * @throws IllegalArgumentException
- * if the prefix or suffix is null
+ * @param variableResolver the variable resolver, may be null
+ * @param prefix the prefix for variables, not null
+ * @param suffix the suffix for variables, not null
+ * @param escape the escape character
+ * @param valueDelimiter the variable default value delimiter string, may be null
+ * @throws IllegalArgumentException if the prefix or suffix is null
*/
public StringSubstitutor(final StringLookup variableResolver, final String prefix, final String suffix,
final char escape, final String valueDelimiter) {
@@ -472,16 +482,11 @@ public class StringSubstitutor {
/**
* Creates a new instance and initializes it.
*
- * @param variableResolver
- * the variable resolver, may be null
- * @param prefixMatcher
- * the prefix for variables, not null
- * @param suffixMatcher
- * the suffix for variables, not null
- * @param escape
- * the escape character
- * @throws IllegalArgumentException
- * if the prefix or suffix is null
+ * @param variableResolver the variable resolver, may be null
+ * @param prefixMatcher the prefix for variables, not null
+ * @param suffixMatcher the suffix for variables, not null
+ * @param escape the escape character
+ * @throws IllegalArgumentException if the prefix or suffix is null
*/
public StringSubstitutor(final StringLookup variableResolver, final StringMatcher prefixMatcher,
final StringMatcher suffixMatcher, final char escape) {
@@ -491,18 +496,12 @@ public class StringSubstitutor {
/**
* Creates a new instance and initializes it.
*
- * @param variableResolver
- * the variable resolver, may be null
- * @param prefixMatcher
- * the prefix for variables, not null
- * @param suffixMatcher
- * the suffix for variables, not null
- * @param escape
- * the escape character
- * @param valueDelimiterMatcher
- * the variable default value delimiter matcher, may be null
- * @throws IllegalArgumentException
- * if the prefix or suffix is null
+ * @param variableResolver the variable resolver, may be null
+ * @param prefixMatcher the prefix for variables, not null
+ * @param suffixMatcher the suffix for variables, not null
+ * @param escape the escape character
+ * @param valueDelimiterMatcher the variable default value delimiter matcher, may be null
+ * @throws IllegalArgumentException if the prefix or suffix is null
*/
public StringSubstitutor(final StringLookup variableResolver, final StringMatcher prefixMatcher,
final StringMatcher suffixMatcher, final char escape, final StringMatcher valueDelimiterMatcher) {
@@ -516,10 +515,8 @@ public class StringSubstitutor {
/**
* Checks if the specified variable is already in the stack (list) of variables.
*
- * @param varName
- * the variable name to check
- * @param priorVariables
- * the list of prior variables
+ * @param varName the variable name to check
+ * @param priorVariables the list of prior variables
*/
private void checkCyclicSubstitution(final String varName, final List<String> priorVariables) {
if (!priorVariables.contains(varName)) {
@@ -637,8 +634,7 @@ public class StringSubstitutor {
}
/**
- * Returns a flag whether exception can be thrown upon undefined
- * variable.
+ * Returns a flag whether exception can be thrown upon undefined variable.
*
* @return The fail on undefined variable flag
*/
@@ -660,11 +656,9 @@ public class StringSubstitutor {
* Replaces all the occurrences of variables with their matching values from the resolver using the given source
* array as a template. The array is not altered by this method.
*
- * @param source
- * the character array to replace in, not altered, null returns null
+ * @param source the character array to replace in, not altered, null returns null
* @return The result of the replace operation
- * @throws IllegalArgumentException
- * if variable is not found when its allowed to throw exception
+ * @throws IllegalArgumentException if variable is not found when its allowed to throw exception
*/
public String replace(final char[] source) {
if (source == null) {
@@ -682,15 +676,11 @@ public class StringSubstitutor {
* Only the specified portion of the array will be processed. The rest of the array is not processed, and is not
* returned.
*
- * @param source
- * the character array to replace in, not altered, null returns null
- * @param offset
- * the start offset within the array, must be valid
- * @param length
- * the length within the array to be processed, must be valid
+ * @param source the character array to replace in, not altered, null returns null
+ * @param offset the start offset within the array, must be valid
+ * @param length the length within the array to be processed, must be valid
* @return The result of the replace operation
- * @throws IllegalArgumentException
- * if variable is not found when its allowed to throw exception
+ * @throws IllegalArgumentException if variable is not found when its allowed to throw exception
*/
public String replace(final char[] source, final int offset, final int length) {
if (source == null) {
@@ -705,11 +695,9 @@ public class StringSubstitutor {
* Replaces all the occurrences of variables with their matching values from the resolver using the given source as
* a template. The source is not altered by this method.
*
- * @param source
- * the buffer to use as a template, not changed, null returns null
+ * @param source the buffer to use as a template, not changed, null returns null
* @return The result of the replace operation
- * @throws IllegalArgumentException
- * if variable is not found when its allowed to throw exception
+ * @throws IllegalArgumentException if variable is not found when its allowed to throw exception
*/
public String replace(final CharSequence source) {
if (source == null) {
@@ -725,15 +713,11 @@ public class StringSubstitutor {
* Only the specified portion of the buffer will be processed. The rest of the buffer is not processed, and is not
* returned.
*
- * @param source
- * the buffer to use as a template, not changed, null returns null
- * @param offset
- * the start offset within the array, must be valid
- * @param length
- * the length within the array to be processed, must be valid
+ * @param source the buffer to use as a template, not changed, null returns null
+ * @param offset the start offset within the array, must be valid
+ * @param length the length within the array to be processed, must be valid
* @return The result of the replace operation
- * @throws IllegalArgumentException
- * if variable is not found when its allowed to throw exception
+ * @throws IllegalArgumentException if variable is not found when its allowed to throw exception
*/
public String replace(final CharSequence source, final int offset, final int length) {
if (source == null) {
@@ -749,11 +733,9 @@ public class StringSubstitutor {
* Replaces all the occurrences of variables in the given source object with their matching values from the
* resolver. The input source object is converted to a string using <code>toString</code> and is not altered.
*
- * @param source
- * the source to replace in, null returns null
+ * @param source the source to replace in, null returns null
* @return The result of the replace operation
- * @throws IllegalArgumentException
- * if a variable is not found and enableUndefinedVariableException is true
+ * @throws IllegalArgumentException if a variable is not found and enableUndefinedVariableException is true
*/
public String replace(final Object source) {
if (source == null) {
@@ -769,11 +751,9 @@ public class StringSubstitutor {
* 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
+ * @param source the string to replace in, null returns null
* @return The result of the replace operation
- * @throws IllegalArgumentException
- * if variable is not found when its allowed to throw exception
+ * @throws IllegalArgumentException if variable is not found when its allowed to throw exception
*/
public String replace(final String source) {
if (source == null) {
@@ -793,15 +773,11 @@ public class StringSubstitutor {
* Only the specified portion of the string will be processed. The rest of the string is not processed, and is not
* returned.
*
- * @param source
- * the string to replace in, null returns null
- * @param offset
- * the start offset within the array, must be valid
- * @param length
- * the length within the array to be processed, must be valid
+ * @param source the string to replace in, null returns null
+ * @param offset the start offset within the array, must be valid
+ * @param length the length within the array to be processed, must be valid
* @return The result of the replace operation
- * @throws IllegalArgumentException
- * if variable is not found when its allowed to throw exception
+ * @throws IllegalArgumentException if variable is not found when its allowed to throw exception
*/
public String replace(final String source, final int offset, final int length) {
if (source == null) {
@@ -819,11 +795,9 @@ public class StringSubstitutor {
* Replaces all the occurrences of variables with their matching values from the resolver using the given source
* buffer as a template. The buffer is not altered by this method.
*
- * @param source
- * the buffer to use as a template, not changed, null returns null
+ * @param source the buffer to use as a template, not changed, null returns null
* @return The result of the replace operation
- * @throws IllegalArgumentException
- * if variable is not found when its allowed to throw exception
+ * @throws IllegalArgumentException if variable is not found when its allowed to throw exception
*/
public String replace(final StringBuffer source) {
if (source == null) {
@@ -841,15 +815,11 @@ public class StringSubstitutor {
* Only the specified portion of the buffer will be processed. The rest of the buffer is not processed, and is not
* returned.
*
- * @param source
- * the buffer to use as a template, not changed, null returns null
- * @param offset
- * the start offset within the array, must be valid
- * @param length
- * the length within the array to be processed, must be valid
+ * @param source the buffer to use as a template, not changed, null returns null
+ * @param offset the start offset within the array, must be valid
+ * @param length the length within the array to be processed, must be valid
* @return The result of the replace operation
- * @throws IllegalArgumentException
- * if variable is not found when its allowed to throw exception
+ * @throws IllegalArgumentException if variable is not found when its allowed to throw exception
*/
public String replace(final StringBuffer source, final int offset, final int length) {
if (source == null) {
@@ -865,11 +835,9 @@ public class StringSubstitutor {
* Replaces all the occurrences of variables with their matching values from the resolver using the given source
* builder as a template. The builder is not altered by this method.
*
- * @param source
- * the builder to use as a template, not changed, null returns null
+ * @param source the builder to use as a template, not changed, null returns null
* @return The result of the replace operation
- * @throws IllegalArgumentException
- * if variable is not found when its allowed to throw exception
+ * @throws IllegalArgumentException if variable is not found when its allowed to throw exception
*/
public String replace(final TextStringBuilder source) {
if (source == null) {
@@ -887,15 +855,11 @@ public class StringSubstitutor {
* Only the specified portion of the builder will be processed. The rest of the builder is not processed, and is not
* returned.
*
- * @param source
- * the builder to use as a template, not changed, null returns null
- * @param offset
- * the start offset within the array, must be valid
- * @param length
- * the length within the array to be processed, must be valid
+ * @param source the builder to use as a template, not changed, null returns null
+ * @param offset the start offset within the array, must be valid
+ * @param length the length within the array to be processed, must be valid
* @return The result of the replace operation
- * @throws IllegalArgumentException
- * if variable is not found when its allowed to throw exception
+ * @throws IllegalArgumentException if variable is not found when its allowed to throw exception
*/
public String replace(final TextStringBuilder source, final int offset, final int length) {
if (source == null) {
@@ -911,8 +875,7 @@ public class StringSubstitutor {
* Replaces all the occurrences of variables within the given source buffer with their matching values from the
* resolver. The buffer is updated with the result.
*
- * @param source
- * the buffer to replace in, updated, null returns zero
+ * @param source the buffer to replace in, updated, null returns zero
* @return true if altered
*/
public boolean replaceIn(final StringBuffer source) {
@@ -929,15 +892,11 @@ public class StringSubstitutor {
* Only the specified portion of the buffer will be processed. The rest of the buffer is not processed, but it is
* not deleted.
*
- * @param source
- * the buffer to replace in, updated, null returns zero
- * @param offset
- * the start offset within the array, must be valid
- * @param length
- * the length within the buffer to be processed, must be valid
+ * @param source the buffer to replace in, updated, null returns zero
+ * @param offset the start offset within the array, must be valid
+ * @param length the length within the buffer to be processed, must be valid
* @return true if altered
- * @throws IllegalArgumentException
- * if variable is not found when its allowed to throw exception
+ * @throws IllegalArgumentException if variable is not found when its allowed to throw exception
*/
public boolean replaceIn(final StringBuffer source, final int offset, final int length) {
if (source == null) {
@@ -956,8 +915,7 @@ public class StringSubstitutor {
* Replaces all the occurrences of variables within the given source buffer with their matching values from the
* resolver. The buffer is updated with the result.
*
- * @param source
- * the buffer to replace in, updated, null returns zero
+ * @param source the buffer to replace in, updated, null returns zero
* @return true if altered
*/
public boolean replaceIn(final StringBuilder source) {
@@ -974,15 +932,11 @@ public class StringSubstitutor {
* Only the specified portion of the buffer will be processed. The rest of the buffer is not processed, but it is
* not deleted.
*
- * @param source
- * the buffer to replace in, updated, null returns zero
- * @param offset
- * the start offset within the array, must be valid
- * @param length
- * the length within the buffer to be processed, must be valid
+ * @param source the buffer to replace in, updated, null returns zero
+ * @param offset the start offset within the array, must be valid
+ * @param length the length within the buffer to be processed, must be valid
* @return true if altered
- * @throws IllegalArgumentException
- * if variable is not found when its allowed to throw exception
+ * @throws IllegalArgumentException if variable is not found when its allowed to throw exception
*/
public boolean replaceIn(final StringBuilder source, final int offset, final int length) {
if (source == null) {
@@ -1001,11 +955,9 @@ public class StringSubstitutor {
* Replaces all the occurrences of variables within the given source builder with their matching values from the
* resolver.
*
- * @param source
- * the builder to replace in, updated, null returns zero
+ * @param source the builder to replace in, updated, null returns zero
* @return true if altered
- * @throws IllegalArgumentException
- * if variable is not found when its allowed to throw exception
+ * @throws IllegalArgumentException if variable is not found when its allowed to throw exception
*/
public boolean replaceIn(final TextStringBuilder source) {
if (source == null) {
@@ -1021,15 +973,11 @@ public class StringSubstitutor {
* Only the specified portion of the builder will be processed. The rest of the builder is not processed, but it is
* not deleted.
*
- * @param source
- * the builder to replace in, null returns zero
- * @param offset
- * the start offset within the array, must be valid
- * @param length
- * the length within the builder to be processed, must be valid
+ * @param source the builder to replace in, null returns zero
+ * @param offset the start offset within the array, must be valid
+ * @param length the length within the builder to be processed, must be valid
* @return true if altered
- * @throws IllegalArgumentException
- * if variable is not found when its allowed to throw exception
+ * @throws IllegalArgumentException if variable is not found when its allowed to throw exception
*/
public boolean replaceIn(final TextStringBuilder source, final int offset, final int length) {
if (source == null) {
@@ -1048,14 +996,10 @@ public class StringSubstitutor {
* passed the variable's name and must return the corresponding value. This implementation uses the
* {@link #getStringLookup()} with the variable's name as the key.
*
- * @param variableName
- * the name of the variable, not null
- * @param buf
- * the buffer where the substitution is occurring, not null
- * @param startPos
- * the start position of the variable including the prefix, valid
- * @param endPos
- * the end position of the variable including the suffix, valid
+ * @param variableName the name of the variable, not null
+ * @param buf the buffer where the substitution is occurring, not null
+ * @param startPos the start position of the variable including the prefix, valid
+ * @param endPos the end position of the variable including the suffix, valid
* @return The variable's value or <b>null</b> if the variable is unknown
*/
protected String resolveVariable(final String variableName, final TextStringBuilder buf, final int startPos,
@@ -1070,8 +1014,7 @@ public class StringSubstitutor {
/**
* Sets a flag whether substitution is done in variable values (recursive).
*
- * @param disableSubstitutionInValues
- * true if substitution in variable value are disabled
+ * @param disableSubstitutionInValues true if substitution in variable value are disabled
* @return this, to enable chaining
*/
public StringSubstitutor setDisableSubstitutionInValues(final boolean disableSubstitutionInValues) {
@@ -1084,8 +1027,7 @@ public class StringSubstitutor {
* contain other variables which are processed first before the original variable is evaluated, e.g.
* <code>${jre-${java.version}}</code>. The default value is <b>false</b>.
*
- * @param enableSubstitutionInVariables
- * the new value of the flag
+ * @param enableSubstitutionInVariables the new value of the flag
* @return this, to enable chaining
*/
public StringSubstitutor setEnableSubstitutionInVariables(final boolean enableSubstitutionInVariables) {
@@ -1096,8 +1038,7 @@ public class StringSubstitutor {
/**
* Sets a flag whether exception should be thrown if any variable is undefined.
*
- * @param failOnUndefinedVariable
- * true if exception should be thrown on undefined variable
+ * @param failOnUndefinedVariable true if exception should be thrown on undefined variable
* @return this, to enable chaining
*/
public StringSubstitutor setEnableUndefinedVariableException(final boolean failOnUndefinedVariable) {
@@ -1109,8 +1050,7 @@ public class StringSubstitutor {
* Sets the escape character. If this character is placed before a variable reference in the source text, this
* variable will be ignored.
*
- * @param escapeCharacter
- * the escape character (0 for disabling escaping)
+ * @param escapeCharacter the escape character (0 for disabling escaping)
* @return this, to enable chaining
*/
public StringSubstitutor setEscapeChar(final char escapeCharacter) {
@@ -1125,8 +1065,7 @@ public class StringSubstitutor {
* (e.g. <code>$${this-is-escaped}</code> becomes <code>${this-is-escaped}</code>). The default value is
* <b>false</b>
*
- * @param preserveEscapes
- * true if escapes are to be preserved
+ * @param preserveEscapes true if escapes are to be preserved
* @return this, to enable chaining
*/
public StringSubstitutor setPreserveEscapes(final boolean preserveEscapes) {
@@ -1140,8 +1079,7 @@ public class StringSubstitutor {
* The variable default value delimiter is the character or characters that delimite the variable name and the
* variable default value. This method allows a single character variable default value delimiter to be easily set.
*
- * @param valueDelimiter
- * the variable default value delimiter character to use
+ * @param valueDelimiter the variable default value delimiter character to use
* @return this, to enable chaining
*/
public StringSubstitutor setValueDelimiter(final char valueDelimiter) {
@@ -1157,8 +1095,7 @@ public class StringSubstitutor {
* If the <code>valueDelimiter</code> is null or empty string, then the variable default value resolution becomes
* disabled.
*
- * @param valueDelimiter
- * the variable default value delimiter string to use, may be null or empty
+ * @param valueDelimiter the variable default value delimiter string to use, may be null or empty
* @return this, to enable chaining
*/
public StringSubstitutor setValueDelimiter(final String valueDelimiter) {
@@ -1178,8 +1115,7 @@ public class StringSubstitutor {
* <p>
* If the <code>valueDelimiterMatcher</code> is null, then the variable default value resolution becomes disabled.
*
- * @param valueDelimiterMatcher
- * variable default value delimiter matcher to use, may be null
+ * @param valueDelimiterMatcher variable default value delimiter matcher to use, may be null
* @return this, to enable chaining
*/
public StringSubstitutor setValueDelimiterMatcher(final StringMatcher valueDelimiterMatcher) {
@@ -1193,8 +1129,7 @@ public class StringSubstitutor {
* The variable prefix is the character or characters that identify the start of a variable. This method allows a
* single character prefix to be easily set.
*
- * @param prefix
- * the prefix character to use
+ * @param prefix the prefix character to use
* @return this, to enable chaining
*/
public StringSubstitutor setVariablePrefix(final char prefix) {
@@ -1207,11 +1142,9 @@ public class StringSubstitutor {
* The variable prefix is the character or characters that identify the start of a variable. This method allows a
* string prefix to be easily set.
*
- * @param prefix
- * the prefix for variables, not null
+ * @param prefix the prefix for variables, not null
* @return this, to enable chaining
- * @throws IllegalArgumentException
- * if the prefix is null
+ * @throws IllegalArgumentException if the prefix is null
*/
public StringSubstitutor setVariablePrefix(final String prefix) {
Validate.isTrue(prefix != null, "Variable prefix must not be null!");
@@ -1224,11 +1157,9 @@ public class StringSubstitutor {
* The variable prefix is the character or characters that identify the start of a variable. This prefix is
* expressed in terms of a matcher allowing advanced prefix matches.
*
- * @param prefixMatcher
- * the prefix matcher to use, null ignored
+ * @param prefixMatcher the prefix matcher to use, null ignored
* @return this, to enable chaining
- * @throws IllegalArgumentException
- * if the prefix matcher is null
+ * @throws IllegalArgumentException if the prefix matcher is null
*/
public StringSubstitutor setVariablePrefixMatcher(final StringMatcher prefixMatcher) {
Validate.isTrue(prefixMatcher != null, "Variable prefix matcher must not be null!");
@@ -1239,8 +1170,7 @@ public class StringSubstitutor {
/**
* Sets the VariableResolver that is used to lookup variables.
*
- * @param variableResolver
- * the VariableResolver
+ * @param variableResolver the VariableResolver
* @return this, to enable chaining
*/
public StringSubstitutor setVariableResolver(final StringLookup variableResolver) {
@@ -1254,8 +1184,7 @@ public class StringSubstitutor {
* The variable suffix is the character or characters that identify the end of a variable. This method allows a
* single character suffix to be easily set.
*
- * @param suffix
- * the suffix character to use
+ * @param suffix the suffix character to use
* @return this, to enable chaining
*/
public StringSubstitutor setVariableSuffix(final char suffix) {
@@ -1268,11 +1197,9 @@ public class StringSubstitutor {
* The variable suffix is the character or characters that identify the end of a variable. This method allows a
* string suffix to be easily set.
*
- * @param suffix
- * the suffix for variables, not null
+ * @param suffix the suffix for variables, not null
* @return this, to enable chaining
- * @throws IllegalArgumentException
- * if the suffix is null
+ * @throws IllegalArgumentException if the suffix is null
*/
public StringSubstitutor setVariableSuffix(final String suffix) {
Validate.isTrue(suffix != null, "Variable suffix must not be null!");
@@ -1285,11 +1212,9 @@ public class StringSubstitutor {
* The variable suffix is the character or characters that identify the end of a variable. This suffix is expressed
* in terms of a matcher allowing advanced suffix matches.
*
- * @param suffixMatcher
- * the suffix matcher to use, null ignored
+ * @param suffixMatcher the suffix matcher to use, null ignored
* @return this, to enable chaining
- * @throws IllegalArgumentException
- * if the suffix matcher is null
+ * @throws IllegalArgumentException if the suffix matcher is null
*/
public StringSubstitutor setVariableSuffixMatcher(final StringMatcher suffixMatcher) {
Validate.isTrue(suffixMatcher != null, "Variable suffix matcher must not be null!");
@@ -1307,12 +1232,9 @@ public class StringSubstitutor {
* Writers of subclasses can override this method if they need access to the substitution process at the start or
* end.
*
- * @param buf
- * the string builder to substitute into, not null
- * @param offset
- * the start offset within the builder, must be valid
- * @param length
- * the length within the builder to be processed, must be valid
+ * @param buf the string builder to substitute into, not null
+ * @param offset the start offset within the builder, must be valid
+ * @param length the length within the builder to be processed, must be valid
* @return true if altered
*/
protected boolean substitute(final TextStringBuilder buf, final int offset, final int length) {
@@ -1323,18 +1245,13 @@ public class StringSubstitutor {
* Recursive handler for multiple levels of interpolation. This is the main interpolation method, which resolves the
* values of all variable references contained in the passed in text.
*
- * @param buf
- * the string builder to substitute into, not null
- * @param offset
- * the start offset within the builder, must be valid
- * @param length
- * the length within the builder to be processed, must be valid
- * @param priorVariables
- * the stack keeping track of the replaced variables, may be null
+ * @param buf the string builder to substitute into, not null
+ * @param offset the start offset within the builder, must be valid
+ * @param length the length within the builder to be processed, must be valid
+ * @param priorVariables the stack keeping track of the replaced variables, may be null
* @return The length change that occurs, unless priorVariables is null when the int represents a boolean flag as to
* whether any change occurred.
- * @throws IllegalArgumentException
- * if variable is not found when its allowed to throw exception
+ * @throws IllegalArgumentException if variable is not found when its allowed to throw exception
*/
private int substitute(final TextStringBuilder buf, final int offset, final int length,
List<String> priorVariables) {
diff --git a/src/main/java/org/apache/commons/text/lookup/InterpolatorStringLookup.java b/src/main/java/org/apache/commons/text/lookup/InterpolatorStringLookup.java
index ce6d63c..3b44447 100644
--- a/src/main/java/org/apache/commons/text/lookup/InterpolatorStringLookup.java
+++ b/src/main/java/org/apache/commons/text/lookup/InterpolatorStringLookup.java
@@ -96,7 +96,7 @@ class InterpolatorStringLookup extends AbstractStringLookup {
this.defaultStringLookup = defaultStringLookup;
this.stringLookupMap = new HashMap<>(stringLookupMap.size());
for (final Entry<String, StringLookup> entry : stringLookupMap.entrySet()) {
- this.stringLookupMap.put(entry.getKey().toLowerCase(Locale.ROOT), entry.getValue());
+ this.stringLookupMap.put(toKey(entry.getKey()), entry.getValue());
}
if (addDefaultLookups) {
StringLookupFactory.INSTANCE.addDefaultStringLookups(this.stringLookupMap);
@@ -112,6 +112,10 @@ class InterpolatorStringLookup extends AbstractStringLookup {
return stringLookupMap;
}
+ static String toKey(final String key) {
+ return key.toLowerCase(Locale.ROOT);
+ }
+
/**
* Resolves the specified variable. This implementation will try to extract a variable prefix from the given
* variable name (the first colon (':') is used as prefix separator). It then passes the name of the variable with
@@ -130,7 +134,7 @@ class InterpolatorStringLookup extends AbstractStringLookup {
final int prefixPos = var.indexOf(PREFIX_SEPARATOR);
if (prefixPos >= 0) {
- final String prefix = var.substring(0, prefixPos).toLowerCase(Locale.ROOT);
+ final String prefix = toKey(var.substring(0, prefixPos));
final String name = var.substring(prefixPos + 1);
final StringLookup lookup = stringLookupMap.get(prefix);
String value = null;
diff --git a/src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java b/src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java
index 443f808..ebda233 100644
--- a/src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java
+++ b/src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java
@@ -293,7 +293,7 @@ public final class StringLookupFactory {
// "base64" is deprecated in favor of KEY_BASE64_DECODER.
stringLookupMap.put("base64", Base64DecoderStringLookup.INSTANCE);
for (final DefaultStringLookup stringLookup : DefaultStringLookup.values()) {
- stringLookupMap.put(stringLookup.getKey(), stringLookup.getStringLookup());
+ stringLookupMap.put(InterpolatorStringLookup.toKey(stringLookup.getKey()), stringLookup.getStringLookup());
}
}
}
@@ -698,10 +698,13 @@ public final class StringLookupFactory {
/**
* Returns the PropertiesStringLookup singleton instance.
* <p>
- * Looks up the value for the key in the format "DocumentPath:MyKey".
+ * Looks up the value for the key in the format "DocumentPath::MyKey".
* </p>
* <p>
- * For example: "com/domain/document.properties:MyKey".
+ * Note the use of "::" instead of ":" to allow for "C:" drive letters in paths.
+ * </p>
+ * <p>
+ * For example: "com/domain/document.properties::MyKey".
* </p>
*
* <p>
@@ -709,18 +712,18 @@ public final class StringLookupFactory {
* </p>
*
* <pre>
- * StringLookupFactory.INSTANCE.propertiesStringLookup().lookup("com/domain/document.properties:MyKey");
+ * StringLookupFactory.INSTANCE.propertiesStringLookup().lookup("com/domain/document.properties::MyKey");
* </pre>
* <p>
* Using a {@link StringSubstitutor}:
* </p>
*
* <pre>
- * StringSubstitutor.createInterpolator().replace("... ${properties:com/domain/document.properties:MyKey} ..."));
+ * StringSubstitutor.createInterpolator().replace("... ${properties:com/domain/document.properties::MyKey} ..."));
* </pre>
* <p>
- * The above examples convert {@code "com/domain/document.properties:MyKey"} to the key value in the properties file
- * at the path "com/domain/document.properties".
+ * The above examples convert {@code "com/domain/document.properties::MyKey"} to the key value in the properties
+ * file at the path "com/domain/document.properties".
* </p>
*
* @return The PropertiesStringLookup singleton instance.
@@ -832,17 +835,17 @@ public final class StringLookupFactory {
* </p>
*
* <pre>
- * StringLookupFactory.INSTANCE.systemPropertyStringLookup().lookup("USER");
+ * StringLookupFactory.INSTANCE.systemPropertyStringLookup().lookup("os.name");
* </pre>
* <p>
* Using a {@link StringSubstitutor}:
* </p>
*
* <pre>
- * StringSubstitutor.createInterpolator().replace("... ${env:USER} ..."));
+ * StringSubstitutor.createInterpolator().replace("... ${sys:os.name} ..."));
* </pre>
* <p>
- * The above examples convert {@code "USER"} to the current Linux user.
+ * The above examples convert {@code "os.name"} to the operating system name.
* </p>
*
* @return The SystemPropertyStringLookup singleton instance.
@@ -934,17 +937,17 @@ public final class StringLookupFactory {
* </p>
*
* <pre>
- * StringLookupFactory.INSTANCE.urlStringLookup().lookup("UTF-8:http://www.google.com");
+ * StringLookupFactory.INSTANCE.urlStringLookup().lookup("UTF-8:https://www.apache.org");
* </pre>
* <p>
* Using a {@link StringSubstitutor}:
* </p>
*
* <pre>
- * StringSubstitutor.createInterpolator().replace("... ${url:UTF-8:http://www.google.com} ..."));
+ * StringSubstitutor.createInterpolator().replace("... ${url:UTF-8:https://www.apache.org} ..."));
* </pre>
* <p>
- * The above examples convert {@code "UTF-8:http://www.google.com"} to the contents of that page.
+ * The above examples convert {@code "UTF-8:https://www.apache.org"} to the contents of that page.
* </p>
*
* @return The UrlStringLookup singleton instance.
diff --git a/src/site/xdoc/userguide.xml b/src/site/xdoc/userguide.xml
index 9784950..56438cd 100644
--- a/src/site/xdoc/userguide.xml
+++ b/src/site/xdoc/userguide.xml
@@ -181,7 +181,33 @@ limitations under the License.
where you can select which lookup are used from
<a href="http://commons.apache.org/proper/commons-text/apidocs/org/apache/commons/text/lookup/StringLookupFactory.html">StringLookupFactory</a>.</p>
<p>
+ The SS lets you build complex strings:
</p>
+ <code>
+final StringSubstitutor interpolator = StringSubstitutor.createInterpolator();
+interpolator.setEnableSubstitutionInVariables(true); // Allows for nested $'s.
+final String text = interpolator.replace(
+ "Base64 Decoder: ${base64Decoder:SGVsbG9Xb3JsZCE=}\n" +
+ "Base64 Encoder: ${base64Encoder:HelloWorld!}\n" +
+ "Java Constant: ${const:java.awt.event.KeyEvent.VK_ESCAPE}\n" +
+ "Date: ${date:yyyy-MM-dd}\n" +
+ "DNS: ${dns:address|apache.org}\n" +
+ "Environment Variable: ${env:USERNAME}\n" +
+ "File Content: ${file:UTF-8:src/test/resources/document.properties}\n" +
+ "Java: ${java:version}\n" +
+ "Localhost: ${localhost:canonical-name}\n" +
+ "Properties File: ${properties:src/test/resources/document.properties::mykey}\n" +
+ "Resource Bundle: ${resourceBundle:org.example.testResourceBundleLookup:mykey}\n" +
+ "Script: ${script:javascript:3 + 4}\n" +
+ "System Property: ${sys:user.dir}\n" +
+ "URL Decoder: ${urlDecoder:Hello%20World%21}\n" +
+ "URL Encoder: ${urlEncoder:Hello World!}\n" +
+ "URL Content (HTTP): ${url:UTF-8:http://www.apache.org}\n" +
+ "URL Content (HTTPS): ${url:UTF-8:https://www.apache.org}\n" +
+ "URL Content (File): ${url:UTF-8:file:///${sys:user.dir}/src/test/resources/document.properties}\n" +
+ "XML XPath: ${xml:src/test/resources/document.xml:/root/path/to/node}\n"
+);
+ </code>
</section>
<section name="text.similarity">
diff --git a/src/test/java/org/apache/commons/text/StrLookupTest.java b/src/test/java/org/apache/commons/text/StrLookupTest.java
index 876bfc4..1ebd0be 100644
--- a/src/test/java/org/apache/commons/text/StrLookupTest.java
+++ b/src/test/java/org/apache/commons/text/StrLookupTest.java
@@ -106,7 +106,7 @@ public class StrLookupTest {
@Test
public void testResourceBundleLookup() {
- final ResourceBundle map = ResourceBundle.getBundle("testResourceBundleLookup");
+ final ResourceBundle map = ResourceBundle.getBundle("org.example.testResourceBundleLookup");
assertEquals("value", StrLookup.resourceBundleLookup(map).lookup("key"));
assertEquals("2", StrLookup.resourceBundleLookup(map).lookup("number"));
assertNull(StrLookup.resourceBundleLookup(map).lookup(null));
diff --git a/src/test/java/org/apache/commons/text/StringSubstitutorWithInterpolatorStringLookupTest.java b/src/test/java/org/apache/commons/text/StringSubstitutorWithInterpolatorStringLookupTest.java
index feb73eb..8fac019 100644
--- a/src/test/java/org/apache/commons/text/StringSubstitutorWithInterpolatorStringLookupTest.java
+++ b/src/test/java/org/apache/commons/text/StringSubstitutorWithInterpolatorStringLookupTest.java
@@ -59,9 +59,46 @@ public class StringSubstitutorWithInterpolatorStringLookupTest {
}
@Test
+ public void testDefaultInterpolator() {
+ // Used to cut and paste into the docs.
+ // @formatter:off
+ final StringSubstitutor interpolator = StringSubstitutor.createInterpolator();
+ interpolator.setEnableSubstitutionInVariables(true); // Allows for nested $'s.
+ final String text = interpolator.replace(
+ "Base64 Decoder: ${base64Decoder:SGVsbG9Xb3JsZCE=}\n" +
+ "Base64 Encoder: ${base64Encoder:HelloWorld!}\n" +
+ "Java Constant: ${const:java.awt.event.KeyEvent.VK_ESCAPE}\n" +
+ "Date: ${date:yyyy-MM-dd}\n" +
+ "DNS: ${dns:address|apache.org}\n" +
+ "Environment Variable: ${env:USERNAME}\n" +
+ "File Content: ${file:UTF-8:src/test/resources/document.properties}\n" +
+ "Java: ${java:version}\n" +
+ "Localhost: ${localhost:canonical-name}\n" +
+ "Properties File: ${properties:src/test/resources/document.properties::mykey}\n" +
+ "Resource Bundle: ${resourceBundle:org.example.testResourceBundleLookup:mykey}\n" +
+ "Script: ${script:javascript:3 + 4}\n" +
+ "System Property: ${sys:user.dir}\n" +
+ "URL Decoder: ${urlDecoder:Hello%20World%21}\n" +
+ "URL Encoder: ${urlEncoder:Hello World!}\n" +
+ "URL Content (HTTP): ${url:UTF-8:http://www.apache.org}\n" +
+ "URL Content (HTTPS): ${url:UTF-8:https://www.apache.org}\n" +
+ "URL Content (File): ${url:UTF-8:file:///${sys:user.dir}/src/test/resources/document.properties}\n" +
+ "XML XPath: ${xml:src/test/resources/document.xml:/root/path/to/node}\n"
+ );
+ // @formatter:on
+ Assertions.assertNotNull(text);
+ // TEXT-171:
+ Assertions.assertFalse(text.contains("${base64Decoder:SGVsbG9Xb3JsZCE=}"));
+ Assertions.assertFalse(text.contains("${base64Encoder:HelloWorld!}"));
+ Assertions.assertFalse(text.contains("${urlDecoder:Hello%20World%21}"));
+ Assertions.assertFalse(text.contains("${urlEncoder:Hello World!}"));
+ Assertions.assertFalse(text.contains("${resourceBundle:org.example.testResourceBundleLookup:mykey}"));
+ // System.out.println(text);
+ }
+ @Test
public void testDefaultValueForMissingKeyInResourceBundle() {
final StringLookup interpolatorStringLookup = StringLookupFactory.INSTANCE.interpolatorStringLookup(
- StringLookupFactory.INSTANCE.resourceBundleStringLookup("testResourceBundleLookup"));
+ StringLookupFactory.INSTANCE.resourceBundleStringLookup("org.example.testResourceBundleLookup"));
assertEquals("${missingKey:-defaultValue}", interpolatorStringLookup.lookup("keyWithMissingKey"));
final StringSubstitutor stringSubstitutor = new StringSubstitutor(interpolatorStringLookup);
// The following would throw a MissingResourceException before TEXT-165.
diff --git a/src/test/java/org/apache/commons/text/lookup/ResourceBundleStringLookupTest.java b/src/test/java/org/apache/commons/text/lookup/ResourceBundleStringLookupTest.java
index c6dbd13..3977fbc 100644
--- a/src/test/java/org/apache/commons/text/lookup/ResourceBundleStringLookupTest.java
+++ b/src/test/java/org/apache/commons/text/lookup/ResourceBundleStringLookupTest.java
@@ -30,7 +30,7 @@ import org.junit.jupiter.api.Test;
*/
public class ResourceBundleStringLookupTest {
- private static final String TEST_RESOURCE_BUNDLE = "testResourceBundleLookup";
+ private static final String TEST_RESOURCE_BUNDLE = "org.example.testResourceBundleLookup";
@Test
public void testAny() {
diff --git a/src/test/java/org/apache/commons/text/lookup/StringLookupFactoryTest.java b/src/test/java/org/apache/commons/text/lookup/StringLookupFactoryTest.java
index e7731e7..527959c 100644
--- a/src/test/java/org/apache/commons/text/lookup/StringLookupFactoryTest.java
+++ b/src/test/java/org/apache/commons/text/lookup/StringLookupFactoryTest.java
@@ -30,23 +30,23 @@ import org.junit.jupiter.api.Test;
public class StringLookupFactoryTest {
public static void assertDefaultKeys(final Map<String, StringLookup> stringLookupMap) {
- assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_BASE64_DECODER));
- assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_BASE64_ENCODER));
- assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_CONST));
- assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_DATE));
- assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_DNS));
- assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_ENV));
- assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_FILE));
- assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_JAVA));
- assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_LOCALHOST));
- assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_PROPERTIES));
- assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_RESOURCE_BUNDLE));
- assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_SCRIPT));
- assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_SYS));
- assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_URL));
- assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_URL_DECODER));
- assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_URL_ENCODER));
- assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_XML));
+ assertTrue(stringLookupMap.containsKey(InterpolatorStringLookup.toKey(StringLookupFactory.KEY_BASE64_DECODER)));
+ assertTrue(stringLookupMap.containsKey(InterpolatorStringLookup.toKey(StringLookupFactory.KEY_BASE64_ENCODER)));
+ assertTrue(stringLookupMap.containsKey(InterpolatorStringLookup.toKey(StringLookupFactory.KEY_CONST)));
+ assertTrue(stringLookupMap.containsKey(InterpolatorStringLookup.toKey(StringLookupFactory.KEY_DATE)));
+ assertTrue(stringLookupMap.containsKey(InterpolatorStringLookup.toKey(StringLookupFactory.KEY_DNS)));
+ assertTrue(stringLookupMap.containsKey(InterpolatorStringLookup.toKey(StringLookupFactory.KEY_ENV)));
+ assertTrue(stringLookupMap.containsKey(InterpolatorStringLookup.toKey(StringLookupFactory.KEY_FILE)));
+ assertTrue(stringLookupMap.containsKey(InterpolatorStringLookup.toKey(StringLookupFactory.KEY_JAVA)));
+ assertTrue(stringLookupMap.containsKey(InterpolatorStringLookup.toKey(StringLookupFactory.KEY_LOCALHOST)));
+ assertTrue(stringLookupMap.containsKey(InterpolatorStringLookup.toKey(StringLookupFactory.KEY_PROPERTIES)));
+ assertTrue(stringLookupMap.containsKey(InterpolatorStringLookup.toKey(StringLookupFactory.KEY_RESOURCE_BUNDLE)));
+ assertTrue(stringLookupMap.containsKey(InterpolatorStringLookup.toKey(StringLookupFactory.KEY_SCRIPT)));
+ assertTrue(stringLookupMap.containsKey(InterpolatorStringLookup.toKey(StringLookupFactory.KEY_SYS)));
+ assertTrue(stringLookupMap.containsKey(InterpolatorStringLookup.toKey(StringLookupFactory.KEY_URL)));
+ assertTrue(stringLookupMap.containsKey(InterpolatorStringLookup.toKey(StringLookupFactory.KEY_URL_DECODER)));
+ assertTrue(stringLookupMap.containsKey(InterpolatorStringLookup.toKey(StringLookupFactory.KEY_URL_ENCODER)));
+ assertTrue(stringLookupMap.containsKey(InterpolatorStringLookup.toKey(StringLookupFactory.KEY_XML)));
}
@Test
diff --git a/src/test/java/org/apache/commons/text/lookup/UrlStringLookupTest.java b/src/test/java/org/apache/commons/text/lookup/UrlStringLookupTest.java
index 13be021..cf7444c 100644
--- a/src/test/java/org/apache/commons/text/lookup/UrlStringLookupTest.java
+++ b/src/test/java/org/apache/commons/text/lookup/UrlStringLookupTest.java
@@ -59,7 +59,8 @@ public class UrlStringLookupTest {
@Test
public void testHttpScheme() throws Exception {
- Assertions.assertNotNull(UrlStringLookup.INSTANCE.lookup("UTF-8:http://www.google.com"));
+ Assertions.assertNotNull(UrlStringLookup.INSTANCE.lookup("UTF-8:https://www.apache.org"));
+ Assertions.assertNotNull(UrlStringLookup.INSTANCE.lookup("UTF-8:https://www.google.com"));
}
@Test
diff --git a/src/test/resources/testResourceBundleLookup.properties b/src/test/resources/org/example/testResourceBundleLookup.properties
similarity index 97%
rename from src/test/resources/testResourceBundleLookup.properties
rename to src/test/resources/org/example/testResourceBundleLookup.properties
index ffc5e13..822001e 100644
--- a/src/test/resources/testResourceBundleLookup.properties
+++ b/src/test/resources/org/example/testResourceBundleLookup.properties
@@ -16,3 +16,4 @@
key = value
number = 2
keyWithMissingKey = ${missingKey:-defaultValue}
+mykey = Hello World!