Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions src/main/java/org/codehaus/plexus/interpolation/Interpolator.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,62 @@ public interface Interpolator extends BasicInterpolator {
String interpolate(String input, String thisPrefixPattern, RecursionInterceptor recursionInterceptor)
throws InterpolationException;

/**
* Attempt to resolve all expressions in the given input string, using the
* provided lists of value sources and post processors. This method allows
* for efficient interpolation without the need to repeatedly add and remove
* value sources and post processors from the interpolator instance.
* <p>
* This method triggers the use of a {@link SimpleRecursionInterceptor}
* instance for protection against expression cycles.</p>
* <p>
* <b>return an empty String if input is null</b>
*
* @param input The input string to interpolate
* @param valueSources The list of value sources to use for resolving expressions.
* If null or empty, no value sources will be used.
* @param postProcessors The list of post processors to apply after interpolation.
* If null or empty, no post processors will be used.
* @return interpolated string.
* @throws InterpolationException in case of an error.
* @since 1.29
*/
default String interpolate(
String input, List<ValueSource> valueSources, List<InterpolationPostProcessor> postProcessors)
throws InterpolationException {
return interpolate(input, valueSources, postProcessors, new SimpleRecursionInterceptor());
}

/**
* Attempt to resolve all expressions in the given input string, using the
* provided lists of value sources and post processors. This method allows
* for efficient interpolation without the need to repeatedly add and remove
* value sources and post processors from the interpolator instance.
* <p>
* The supplied recursion interceptor will provide protection from expression
* cycles, ensuring that the input can be resolved or an exception is thrown.
* <p>
* <b>return an empty String if input is null</b>
*
* @param input The input string to interpolate
* @param valueSources The list of value sources to use for resolving expressions.
* If null or empty, no value sources will be used.
* @param postProcessors The list of post processors to apply after interpolation.
* If null or empty, no post processors will be used.
* @param recursionInterceptor Used to protect the interpolation process
* from expression cycles, and throw an
* exception if one is detected.
* @return interpolated string.
* @throws InterpolationException in case of an error.
* @since 1.29
*/
String interpolate(
String input,
List<ValueSource> valueSources,
List<InterpolationPostProcessor> postProcessors,
RecursionInterceptor recursionInterceptor)
throws InterpolationException;

/**
* Return any feedback messages and errors that were generated - but
* suppressed - during the interpolation process. Since unresolvable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,10 +248,39 @@ private String interpolate(
String expressionDelimiterEnd,
int realExprGroup)
throws InterpolationException {
return interpolate(
input,
recursionInterceptor,
expressionPattern,
expressionDelimiterStart,
expressionDelimiterEnd,
realExprGroup,
this.valueSources,
this.postProcessors);
}

private String interpolate(
String input,
RecursionInterceptor recursionInterceptor,
Pattern expressionPattern,
String expressionDelimiterStart,
String expressionDelimiterEnd,
int realExprGroup,
List<ValueSource> valueSources,
List<InterpolationPostProcessor> postProcessors)
throws InterpolationException {
if (input == null) {
// return empty String to prevent NPE too
return "";
}

// Use instance value sources if provided list is null or empty
List<ValueSource> effectiveValueSources =
(valueSources != null && !valueSources.isEmpty()) ? valueSources : this.valueSources;
// Use instance post processors if provided list is null or empty
List<InterpolationPostProcessor> effectivePostProcessors =
(postProcessors != null && !postProcessors.isEmpty()) ? postProcessors : this.postProcessors;

String result = input;

Matcher matcher = expressionPattern.matcher(result);
Expand All @@ -271,7 +300,7 @@ private String interpolate(
recursionInterceptor.expressionResolutionStarted(realExpr);
try {
Object value = existingAnswers.get(realExpr);
for (ValueSource vs : valueSources) {
for (ValueSource vs : effectiveValueSources) {
if (value != null) break;

value = vs.getValue(realExpr, expressionDelimiterStart, expressionDelimiterEnd);
Expand All @@ -284,10 +313,12 @@ private String interpolate(
expressionPattern,
expressionDelimiterStart,
expressionDelimiterEnd,
realExprGroup);
realExprGroup,
effectiveValueSources,
effectivePostProcessors);

if (postProcessors != null && !postProcessors.isEmpty()) {
for (InterpolationPostProcessor postProcessor : postProcessors) {
if (effectivePostProcessors != null && !effectivePostProcessors.isEmpty()) {
for (InterpolationPostProcessor postProcessor : effectivePostProcessors) {
Object newVal = postProcessor.execute(realExpr, value);
if (newVal != null) {
value = newVal;
Expand Down Expand Up @@ -373,7 +404,7 @@ public String interpolate(String input, String thisPrefixPattern) throws Interpo
* @param input The input string to interpolate
*/
public String interpolate(String input) throws InterpolationException {
return interpolate(input, null, null);
return interpolate(input, (String) null, (RecursionInterceptor) null);
}

/**
Expand All @@ -393,6 +424,65 @@ public String interpolate(String input, RecursionInterceptor recursionIntercepto
return interpolate(input, null, recursionInterceptor);
}

/**
* {@inheritDoc}
*/
public String interpolate(
String input,
List<ValueSource> valueSources,
List<InterpolationPostProcessor> postProcessors,
RecursionInterceptor recursionInterceptor)
throws InterpolationException {
if (input == null) {
// return empty String to prevent NPE too
return "";
}
if (recursionInterceptor == null) {
recursionInterceptor = new SimpleRecursionInterceptor();
}

String thisPrefixPattern = null;
int realExprGroup = 2;
Pattern expressionPattern;
final String expressionDelimiterStart;
final String expressionDelimiterEnd;
if (startRegex != null || endRegex != null) {
if (thisPrefixPattern == null) {
expressionPattern = getPattern(startRegex + endRegex);
realExprGroup = 1;
} else {
expressionPattern = getPattern(startRegex + thisPrefixPattern + endRegex);
}
expressionDelimiterStart = startRegex;
expressionDelimiterEnd = endRegex;

} else {
expressionDelimiterStart = "${";
expressionDelimiterEnd = "}";
if (thisPrefixPattern != null) {
expressionPattern = getPattern("\\$\\{(" + thisPrefixPattern + ")?(.+?)\\}");
} else {
expressionPattern = getPattern(DEFAULT_REGEXP);
realExprGroup = 1;
}
}
try {
return interpolate(
input,
recursionInterceptor,
expressionPattern,
expressionDelimiterStart,
expressionDelimiterEnd,
realExprGroup,
valueSources,
postProcessors);
} finally {
if (!cacheAnswers) {
clearAnswers();
}
}
}

public boolean isReusePatterns() {
return reusePatterns;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,48 @@ public String interpolate(String input, RecursionInterceptor recursionIntercepto
}
}

/**
* {@inheritDoc}
*/
public String interpolate(
String input,
List<ValueSource> valueSources,
List<InterpolationPostProcessor> postProcessors,
RecursionInterceptor recursionInterceptor)
throws InterpolationException {
try {
return interpolate(input, recursionInterceptor, new HashSet<String>(), valueSources, postProcessors);
} finally {
if (!cacheAnswers) {
existingAnswers.clear();
}
}
}

private String interpolate(String input, RecursionInterceptor recursionInterceptor, Set<String> unresolvable)
throws InterpolationException {
return interpolate(input, recursionInterceptor, unresolvable, this.valueSources, this.postProcessors);
}

private String interpolate(
String input,
RecursionInterceptor recursionInterceptor,
Set<String> unresolvable,
List<ValueSource> valueSources,
List<InterpolationPostProcessor> postProcessors)
throws InterpolationException {
if (input == null) {
// return empty String to prevent NPE too
return "";
}

// Use instance value sources if provided list is null or empty
List<ValueSource> effectiveValueSources =
(valueSources != null && !valueSources.isEmpty()) ? valueSources : this.valueSources;
// Use instance post processors if provided list is null or empty
List<InterpolationPostProcessor> effectivePostProcessors =
(postProcessors != null && !postProcessors.isEmpty()) ? postProcessors : this.postProcessors;

int startIdx;
int endIdx = -1;
if ((startIdx = input.indexOf(startExpr, endIdx + 1)) > -1) {
Expand Down Expand Up @@ -159,7 +194,7 @@ private String interpolate(String input, RecursionInterceptor recursionIntercept
Object value = getExistingAnswer(realExpr);
Object bestAnswer = null;

for (ValueSource valueSource : valueSources) {
for (ValueSource valueSource : effectiveValueSources) {
if (value != null) {
break;
}
Expand All @@ -179,10 +214,15 @@ private String interpolate(String input, RecursionInterceptor recursionIntercept
}

if (value != null) {
value = interpolate(String.valueOf(value), recursionInterceptor, unresolvable);

if (postProcessors != null && !postProcessors.isEmpty()) {
for (InterpolationPostProcessor postProcessor : postProcessors) {
value = interpolate(
String.valueOf(value),
recursionInterceptor,
unresolvable,
effectiveValueSources,
effectivePostProcessors);

if (effectivePostProcessors != null && !effectivePostProcessors.isEmpty()) {
for (InterpolationPostProcessor postProcessor : effectivePostProcessors) {
Object newVal = postProcessor.execute(realExpr, value);
if (newVal != null) {
value = newVal;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,48 @@ public String interpolate(String input, RecursionInterceptor recursionIntercepto
}
}

/**
* {@inheritDoc}
*/
public String interpolate(
String input,
List<ValueSource> valueSources,
List<InterpolationPostProcessor> postProcessors,
RecursionInterceptor recursionInterceptor)
throws InterpolationException {
try {
return interpolate(input, recursionInterceptor, new HashSet(), valueSources, postProcessors);
} finally {
if (!cacheAnswers) {
existingAnswers.clear();
}
}
}

private String interpolate(String input, RecursionInterceptor recursionInterceptor, Set<String> unresolvable)
throws InterpolationException {
return interpolate(input, recursionInterceptor, unresolvable, this.valueSources, this.postProcessors);
}

private String interpolate(
String input,
RecursionInterceptor recursionInterceptor,
Set<String> unresolvable,
List<ValueSource> valueSources,
List postProcessors)
throws InterpolationException {
if (input == null) {
// return empty String to prevent NPE too
return "";
}

// Use instance value sources if provided list is null or empty
List<ValueSource> effectiveValueSources =
(valueSources != null && !valueSources.isEmpty()) ? valueSources : this.valueSources;
// Use instance post processors if provided list is null or empty
List effectivePostProcessors =
(postProcessors != null && !postProcessors.isEmpty()) ? postProcessors : this.postProcessors;

StringBuilder result = new StringBuilder(input.length() * 2);

String lastResult = input;
Expand Down Expand Up @@ -198,7 +234,7 @@ private String interpolate(String input, RecursionInterceptor recursionIntercept

Object value = existingAnswers.get(realExpr);
Object bestAnswer = null;
for (ValueSource vs : valueSources) {
for (ValueSource vs : effectiveValueSources) {
if (value != null) break;

value = vs.getValue(realExpr, startExpr, endExpr);
Expand All @@ -217,10 +253,15 @@ private String interpolate(String input, RecursionInterceptor recursionIntercept
}

if (value != null) {
value = interpolate(String.valueOf(value), recursionInterceptor, unresolvable);

if (postProcessors != null && !postProcessors.isEmpty()) {
for (Object postProcessor1 : postProcessors) {
value = interpolate(
String.valueOf(value),
recursionInterceptor,
unresolvable,
effectiveValueSources,
effectivePostProcessors);

if (effectivePostProcessors != null && !effectivePostProcessors.isEmpty()) {
for (Object postProcessor1 : effectivePostProcessors) {
InterpolationPostProcessor postProcessor = (InterpolationPostProcessor) postProcessor1;
Object newVal = postProcessor.execute(realExpr, value);
if (newVal != null) {
Expand Down
Loading