[lang-482] Added support for substitution in variable names.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1005974 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
790140111d
commit
6f6eddbf3a
|
@ -86,6 +86,16 @@
|
||||||
* <pre>
|
* <pre>
|
||||||
* The variable $${${name}} must be used.
|
* The variable $${${name}} must be used.
|
||||||
* </pre>
|
* </pre>
|
||||||
|
* <p>
|
||||||
|
* In some complex scenarios you might even want to perform substitution in the
|
||||||
|
* names of variables, for instance
|
||||||
|
* <pre>
|
||||||
|
* ${jre-${java.specification.version}}
|
||||||
|
* </pre>
|
||||||
|
* <code>StrSubstitutor</code> supports this recursive substitution in variable
|
||||||
|
* names, but it has to be enabled explicitly by setting the
|
||||||
|
* {@link #setEnableSubstitutionInVariables(boolean) enableSubstitutionInVariables}
|
||||||
|
* property to <b>true</b>.
|
||||||
*
|
*
|
||||||
* @author Apache Software Foundation
|
* @author Apache Software Foundation
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
|
@ -122,6 +132,10 @@ public class StrSubstitutor {
|
||||||
* Variable resolution is delegated to an implementor of VariableResolver.
|
* Variable resolution is delegated to an implementor of VariableResolver.
|
||||||
*/
|
*/
|
||||||
private StrLookup<?> variableResolver;
|
private StrLookup<?> variableResolver;
|
||||||
|
/**
|
||||||
|
* The flag whether substitution in variable names is enabled.
|
||||||
|
*/
|
||||||
|
private boolean enableSubstitutionInVariables;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
|
@ -571,7 +585,8 @@ private int substitute(StrBuilder buf, int offset, int length, List<String> prio
|
||||||
int bufEnd = offset + length;
|
int bufEnd = offset + length;
|
||||||
int pos = offset;
|
int pos = offset;
|
||||||
while (pos < bufEnd) {
|
while (pos < bufEnd) {
|
||||||
int startMatchLen = prefixMatcher.isMatch(chars, pos, offset, bufEnd);
|
int startMatchLen = prefixMatcher.isMatch(chars, pos, offset,
|
||||||
|
bufEnd);
|
||||||
if (startMatchLen == 0) {
|
if (startMatchLen == 0) {
|
||||||
pos++;
|
pos++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -579,7 +594,7 @@ private int substitute(StrBuilder buf, int offset, int length, List<String> prio
|
||||||
if (pos > offset && chars[pos - 1] == escape) {
|
if (pos > offset && chars[pos - 1] == escape) {
|
||||||
// escaped
|
// escaped
|
||||||
buf.deleteCharAt(pos - 1);
|
buf.deleteCharAt(pos - 1);
|
||||||
chars = buf.buffer; // in case buffer was altered
|
chars = buf.buffer; // in case buffer was altered
|
||||||
lengthChange--;
|
lengthChange--;
|
||||||
altered = true;
|
altered = true;
|
||||||
bufEnd--;
|
bufEnd--;
|
||||||
|
@ -588,45 +603,73 @@ private int substitute(StrBuilder buf, int offset, int length, List<String> prio
|
||||||
int startPos = pos;
|
int startPos = pos;
|
||||||
pos += startMatchLen;
|
pos += startMatchLen;
|
||||||
int endMatchLen = 0;
|
int endMatchLen = 0;
|
||||||
|
int nestedVarCount = 0;
|
||||||
while (pos < bufEnd) {
|
while (pos < bufEnd) {
|
||||||
endMatchLen = suffixMatcher.isMatch(chars, pos, offset, bufEnd);
|
if (isEnableSubstitutionInVariables()
|
||||||
|
&& (endMatchLen = prefixMatcher.isMatch(chars,
|
||||||
|
pos, offset, bufEnd)) != 0) {
|
||||||
|
// found a nested variable start
|
||||||
|
nestedVarCount++;
|
||||||
|
pos += endMatchLen;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
endMatchLen = suffixMatcher.isMatch(chars, pos, offset,
|
||||||
|
bufEnd);
|
||||||
if (endMatchLen == 0) {
|
if (endMatchLen == 0) {
|
||||||
pos++;
|
pos++;
|
||||||
} else {
|
} else {
|
||||||
// found variable end marker
|
// found variable end marker
|
||||||
String varName = new String(chars, startPos + startMatchLen,
|
if (nestedVarCount == 0) {
|
||||||
pos - startPos - startMatchLen);
|
String varName = new String(chars, startPos
|
||||||
pos += endMatchLen;
|
+ startMatchLen, pos - startPos
|
||||||
int endPos = pos;
|
- startMatchLen);
|
||||||
|
if (isEnableSubstitutionInVariables()) {
|
||||||
|
StrBuilder bufName = new StrBuilder(varName);
|
||||||
|
substitute(bufName, 0, bufName.length());
|
||||||
|
varName = bufName.toString();
|
||||||
|
}
|
||||||
|
pos += endMatchLen;
|
||||||
|
int endPos = pos;
|
||||||
|
|
||||||
// on the first call initialize priorVariables
|
// on the first call initialize priorVariables
|
||||||
if (priorVariables == null) {
|
if (priorVariables == null) {
|
||||||
priorVariables = new ArrayList<String>();
|
priorVariables = new ArrayList<String>();
|
||||||
priorVariables.add(new String(chars, offset, length));
|
priorVariables.add(new String(chars,
|
||||||
|
offset, length));
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle cyclic substitution
|
||||||
|
checkCyclicSubstitution(varName, priorVariables);
|
||||||
|
priorVariables.add(varName);
|
||||||
|
|
||||||
|
// resolve the variable
|
||||||
|
String varValue = resolveVariable(varName, buf,
|
||||||
|
startPos, endPos);
|
||||||
|
if (varValue != null) {
|
||||||
|
// recursive replace
|
||||||
|
int varLen = varValue.length();
|
||||||
|
buf.replace(startPos, endPos, varValue);
|
||||||
|
altered = true;
|
||||||
|
int change = substitute(buf, startPos,
|
||||||
|
varLen, priorVariables);
|
||||||
|
change = change
|
||||||
|
+ (varLen - (endPos - startPos));
|
||||||
|
pos += change;
|
||||||
|
bufEnd += change;
|
||||||
|
lengthChange += change;
|
||||||
|
chars = buf.buffer; // in case buffer was
|
||||||
|
// altered
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove variable from the cyclic stack
|
||||||
|
priorVariables
|
||||||
|
.remove(priorVariables.size() - 1);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
nestedVarCount--;
|
||||||
|
pos += endMatchLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle cyclic substitution
|
|
||||||
checkCyclicSubstitution(varName, priorVariables);
|
|
||||||
priorVariables.add(varName);
|
|
||||||
|
|
||||||
// resolve the variable
|
|
||||||
String varValue = resolveVariable(varName, buf, startPos, endPos);
|
|
||||||
if (varValue != null) {
|
|
||||||
// recursive replace
|
|
||||||
int varLen = varValue.length();
|
|
||||||
buf.replace(startPos, endPos, varValue);
|
|
||||||
altered = true;
|
|
||||||
int change = substitute(buf, startPos, varLen, priorVariables);
|
|
||||||
change = change + (varLen - (endPos - startPos));
|
|
||||||
pos += change;
|
|
||||||
bufEnd += change;
|
|
||||||
lengthChange += change;
|
|
||||||
chars = buf.buffer; // in case buffer was altered
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove variable from the cyclic stack
|
|
||||||
priorVariables.remove(priorVariables.size() - 1);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -740,7 +783,7 @@ public StrSubstitutor setVariablePrefixMatcher(StrMatcher prefixMatcher) {
|
||||||
/**
|
/**
|
||||||
* Sets the variable prefix to use.
|
* Sets the variable prefix to use.
|
||||||
* <p>
|
* <p>
|
||||||
* The variable prefix is the characer or characters that identify the
|
* The variable prefix is the character or characters that identify the
|
||||||
* start of a variable. This method allows a single character prefix to
|
* start of a variable. This method allows a single character prefix to
|
||||||
* be easily set.
|
* be easily set.
|
||||||
*
|
*
|
||||||
|
@ -819,7 +862,7 @@ public StrSubstitutor setVariableSuffix(char suffix) {
|
||||||
/**
|
/**
|
||||||
* Sets the variable suffix to use.
|
* Sets the variable suffix to use.
|
||||||
* <p>
|
* <p>
|
||||||
* The variable suffix is the characer or characters that identify the
|
* 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.
|
* 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
|
||||||
|
@ -853,4 +896,29 @@ public void setVariableResolver(StrLookup<?> variableResolver) {
|
||||||
this.variableResolver = variableResolver;
|
this.variableResolver = variableResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Substitution support in variable names
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* Returns a flag whether substitution is done in variable names.
|
||||||
|
*
|
||||||
|
* @return the substitution in variable names flag
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
public boolean isEnableSubstitutionInVariables() {
|
||||||
|
return enableSubstitutionInVariables;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a flag whether substitution is done in variable names. If set to
|
||||||
|
* <b>true</b>, the names of variables can 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
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
public void setEnableSubstitutionInVariables(
|
||||||
|
boolean enableSubstitutionInVariables) {
|
||||||
|
this.enableSubstitutionInVariables = enableSubstitutionInVariables;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
* (the "License"); you may not use this file except in compliance with
|
* (the "License"); you may not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
* the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test class for StrSubstitutor.
|
* Test class for StrSubstitutor.
|
||||||
*
|
*
|
||||||
* @author Oliver Heger
|
* @author Oliver Heger
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
@ -255,6 +255,57 @@ public void testReplacePartialString_noReplace() {
|
||||||
assertEquals("${animal} jumps", sub.replace("The ${animal} jumps over the ${target}.", 4, 15));
|
assertEquals("${animal} jumps", sub.replace("The ${animal} jumps over the ${target}.", 4, 15));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether a variable can be replaced in a variable name.
|
||||||
|
*/
|
||||||
|
public void testReplaceInVariable() {
|
||||||
|
values.put("animal.1", "fox");
|
||||||
|
values.put("animal.2", "mouse");
|
||||||
|
values.put("species", "2");
|
||||||
|
StrSubstitutor sub = new StrSubstitutor(values);
|
||||||
|
sub.setEnableSubstitutionInVariables(true);
|
||||||
|
assertEquals(
|
||||||
|
"Wrong result (1)",
|
||||||
|
"The mouse jumps over the lazy dog.",
|
||||||
|
sub.replace("The ${animal.${species}} jumps over the ${target}."));
|
||||||
|
values.put("species", "1");
|
||||||
|
assertEquals(
|
||||||
|
"Wrong result (2)",
|
||||||
|
"The fox jumps over the lazy dog.",
|
||||||
|
sub.replace("The ${animal.${species}} jumps over the ${target}."));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether substitution in variable names is disabled per default.
|
||||||
|
*/
|
||||||
|
public void testReplaceInVariableDisabled() {
|
||||||
|
values.put("animal.1", "fox");
|
||||||
|
values.put("animal.2", "mouse");
|
||||||
|
values.put("species", "2");
|
||||||
|
StrSubstitutor sub = new StrSubstitutor(values);
|
||||||
|
assertEquals(
|
||||||
|
"Wrong result",
|
||||||
|
"The ${animal.${species}} jumps over the lazy dog.",
|
||||||
|
sub.replace("The ${animal.${species}} jumps over the ${target}."));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests complex and recursive substitution in variable names.
|
||||||
|
*/
|
||||||
|
public void testReplaceInVariableRecursive() {
|
||||||
|
values.put("animal.2", "brown fox");
|
||||||
|
values.put("animal.1", "white mouse");
|
||||||
|
values.put("color", "white");
|
||||||
|
values.put("species.white", "1");
|
||||||
|
values.put("species.brown", "2");
|
||||||
|
StrSubstitutor sub = new StrSubstitutor(values);
|
||||||
|
sub.setEnableSubstitutionInVariables(true);
|
||||||
|
assertEquals(
|
||||||
|
"Wrong result",
|
||||||
|
"The white mouse jumps over the lazy dog.",
|
||||||
|
sub.replace("The ${animal.${species.${color}}} jumps over the ${target}."));
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Tests protected.
|
* Tests protected.
|
||||||
|
@ -325,7 +376,7 @@ public void testGetSetPrefix() {
|
||||||
assertEquals(true, sub.getVariablePrefixMatcher() instanceof StrMatcher.StringMatcher);
|
assertEquals(true, sub.getVariablePrefixMatcher() instanceof StrMatcher.StringMatcher);
|
||||||
sub.setVariablePrefix('<');
|
sub.setVariablePrefix('<');
|
||||||
assertEquals(true, sub.getVariablePrefixMatcher() instanceof StrMatcher.CharMatcher);
|
assertEquals(true, sub.getVariablePrefixMatcher() instanceof StrMatcher.CharMatcher);
|
||||||
|
|
||||||
sub.setVariablePrefix("<<");
|
sub.setVariablePrefix("<<");
|
||||||
assertEquals(true, sub.getVariablePrefixMatcher() instanceof StrMatcher.StringMatcher);
|
assertEquals(true, sub.getVariablePrefixMatcher() instanceof StrMatcher.StringMatcher);
|
||||||
try {
|
try {
|
||||||
|
@ -335,7 +386,7 @@ public void testGetSetPrefix() {
|
||||||
// expected
|
// expected
|
||||||
}
|
}
|
||||||
assertEquals(true, sub.getVariablePrefixMatcher() instanceof StrMatcher.StringMatcher);
|
assertEquals(true, sub.getVariablePrefixMatcher() instanceof StrMatcher.StringMatcher);
|
||||||
|
|
||||||
StrMatcher matcher = StrMatcher.commaMatcher();
|
StrMatcher matcher = StrMatcher.commaMatcher();
|
||||||
sub.setVariablePrefixMatcher(matcher);
|
sub.setVariablePrefixMatcher(matcher);
|
||||||
assertSame(matcher, sub.getVariablePrefixMatcher());
|
assertSame(matcher, sub.getVariablePrefixMatcher());
|
||||||
|
@ -356,7 +407,7 @@ public void testGetSetSuffix() {
|
||||||
assertEquals(true, sub.getVariableSuffixMatcher() instanceof StrMatcher.StringMatcher);
|
assertEquals(true, sub.getVariableSuffixMatcher() instanceof StrMatcher.StringMatcher);
|
||||||
sub.setVariableSuffix('<');
|
sub.setVariableSuffix('<');
|
||||||
assertEquals(true, sub.getVariableSuffixMatcher() instanceof StrMatcher.CharMatcher);
|
assertEquals(true, sub.getVariableSuffixMatcher() instanceof StrMatcher.CharMatcher);
|
||||||
|
|
||||||
sub.setVariableSuffix("<<");
|
sub.setVariableSuffix("<<");
|
||||||
assertEquals(true, sub.getVariableSuffixMatcher() instanceof StrMatcher.StringMatcher);
|
assertEquals(true, sub.getVariableSuffixMatcher() instanceof StrMatcher.StringMatcher);
|
||||||
try {
|
try {
|
||||||
|
@ -366,7 +417,7 @@ public void testGetSetSuffix() {
|
||||||
// expected
|
// expected
|
||||||
}
|
}
|
||||||
assertEquals(true, sub.getVariableSuffixMatcher() instanceof StrMatcher.StringMatcher);
|
assertEquals(true, sub.getVariableSuffixMatcher() instanceof StrMatcher.StringMatcher);
|
||||||
|
|
||||||
StrMatcher matcher = StrMatcher.commaMatcher();
|
StrMatcher matcher = StrMatcher.commaMatcher();
|
||||||
sub.setVariableSuffixMatcher(matcher);
|
sub.setVariableSuffixMatcher(matcher);
|
||||||
assertSame(matcher, sub.getVariableSuffixMatcher());
|
assertSame(matcher, sub.getVariableSuffixMatcher());
|
||||||
|
@ -412,7 +463,7 @@ public void testStaticReplaceSystemProperties() {
|
||||||
+ "working with ${os.name}, your home "
|
+ "working with ${os.name}, your home "
|
||||||
+ "directory is ${user.home}."));
|
+ "directory is ${user.home}."));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the replace of a properties object
|
* Test the replace of a properties object
|
||||||
*/
|
*/
|
||||||
|
@ -430,38 +481,38 @@ public void testSubstitutetDefaultProperties(){
|
||||||
private void doTestReplace(String expectedResult, String replaceTemplate, boolean substring) {
|
private void doTestReplace(String expectedResult, String replaceTemplate, boolean substring) {
|
||||||
String expectedShortResult = expectedResult.substring(1, expectedResult.length() - 1);
|
String expectedShortResult = expectedResult.substring(1, expectedResult.length() - 1);
|
||||||
StrSubstitutor sub = new StrSubstitutor(values);
|
StrSubstitutor sub = new StrSubstitutor(values);
|
||||||
|
|
||||||
// replace using String
|
// replace using String
|
||||||
assertEquals(expectedResult, sub.replace(replaceTemplate));
|
assertEquals(expectedResult, sub.replace(replaceTemplate));
|
||||||
if (substring) {
|
if (substring) {
|
||||||
assertEquals(expectedShortResult, sub.replace(replaceTemplate, 1, replaceTemplate.length() - 2));
|
assertEquals(expectedShortResult, sub.replace(replaceTemplate, 1, replaceTemplate.length() - 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
// replace using char[]
|
// replace using char[]
|
||||||
char[] chars = replaceTemplate.toCharArray();
|
char[] chars = replaceTemplate.toCharArray();
|
||||||
assertEquals(expectedResult, sub.replace(chars));
|
assertEquals(expectedResult, sub.replace(chars));
|
||||||
if (substring) {
|
if (substring) {
|
||||||
assertEquals(expectedShortResult, sub.replace(chars, 1, chars.length - 2));
|
assertEquals(expectedShortResult, sub.replace(chars, 1, chars.length - 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
// replace using StringBuffer
|
// replace using StringBuffer
|
||||||
StringBuffer buf = new StringBuffer(replaceTemplate);
|
StringBuffer buf = new StringBuffer(replaceTemplate);
|
||||||
assertEquals(expectedResult, sub.replace(buf));
|
assertEquals(expectedResult, sub.replace(buf));
|
||||||
if (substring) {
|
if (substring) {
|
||||||
assertEquals(expectedShortResult, sub.replace(buf, 1, buf.length() - 2));
|
assertEquals(expectedShortResult, sub.replace(buf, 1, buf.length() - 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
// replace using StrBuilder
|
// replace using StrBuilder
|
||||||
StrBuilder bld = new StrBuilder(replaceTemplate);
|
StrBuilder bld = new StrBuilder(replaceTemplate);
|
||||||
assertEquals(expectedResult, sub.replace(bld));
|
assertEquals(expectedResult, sub.replace(bld));
|
||||||
if (substring) {
|
if (substring) {
|
||||||
assertEquals(expectedShortResult, sub.replace(bld, 1, bld.length() - 2));
|
assertEquals(expectedShortResult, sub.replace(bld, 1, bld.length() - 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
// replace using object
|
// replace using object
|
||||||
MutableObject<String> obj = new MutableObject<String>(replaceTemplate); // toString returns template
|
MutableObject<String> obj = new MutableObject<String>(replaceTemplate); // toString returns template
|
||||||
assertEquals(expectedResult, sub.replace(obj));
|
assertEquals(expectedResult, sub.replace(obj));
|
||||||
|
|
||||||
// replace in StringBuffer
|
// replace in StringBuffer
|
||||||
buf = new StringBuffer(replaceTemplate);
|
buf = new StringBuffer(replaceTemplate);
|
||||||
assertEquals(true, sub.replaceIn(buf));
|
assertEquals(true, sub.replaceIn(buf));
|
||||||
|
@ -471,7 +522,7 @@ private void doTestReplace(String expectedResult, String replaceTemplate, boolea
|
||||||
assertEquals(true, sub.replaceIn(buf, 1, buf.length() - 2));
|
assertEquals(true, sub.replaceIn(buf, 1, buf.length() - 2));
|
||||||
assertEquals(expectedResult, buf.toString()); // expect full result as remainder is untouched
|
assertEquals(expectedResult, buf.toString()); // expect full result as remainder is untouched
|
||||||
}
|
}
|
||||||
|
|
||||||
// replace in StrBuilder
|
// replace in StrBuilder
|
||||||
bld = new StrBuilder(replaceTemplate);
|
bld = new StrBuilder(replaceTemplate);
|
||||||
assertEquals(true, sub.replaceIn(bld));
|
assertEquals(true, sub.replaceIn(bld));
|
||||||
|
@ -485,7 +536,7 @@ private void doTestReplace(String expectedResult, String replaceTemplate, boolea
|
||||||
|
|
||||||
private void doTestNoReplace(String replaceTemplate) {
|
private void doTestNoReplace(String replaceTemplate) {
|
||||||
StrSubstitutor sub = new StrSubstitutor(values);
|
StrSubstitutor sub = new StrSubstitutor(values);
|
||||||
|
|
||||||
if (replaceTemplate == null) {
|
if (replaceTemplate == null) {
|
||||||
assertEquals(null, sub.replace((String) null));
|
assertEquals(null, sub.replace((String) null));
|
||||||
assertEquals(null, sub.replace((String) null, 0, 100));
|
assertEquals(null, sub.replace((String) null, 0, 100));
|
||||||
|
|
Loading…
Reference in New Issue