diff --git a/src/main/java/org/codehaus/plexus/interpolation/AbstractDelegatingValueSource.java b/src/main/java/org/codehaus/plexus/interpolation/AbstractDelegatingValueSource.java
index 836c6b3..bd0c7aa 100644
--- a/src/main/java/org/codehaus/plexus/interpolation/AbstractDelegatingValueSource.java
+++ b/src/main/java/org/codehaus/plexus/interpolation/AbstractDelegatingValueSource.java
@@ -34,14 +34,22 @@ protected ValueSource getDelegate() {
return delegate;
}
+ @Override
+ public Object getValue(String expression, String delimiterStart, String delimiterEnd) {
+ return getDelegate().getValue(expression, delimiterStart, delimiterEnd);
+ }
+
+ @Override
public Object getValue(String expression) {
return getDelegate().getValue(expression);
}
+ @Override
public void clearFeedback() {
delegate.clearFeedback();
}
+ @Override
public List getFeedback() {
return delegate.getFeedback();
}
diff --git a/src/main/java/org/codehaus/plexus/interpolation/RegexBasedInterpolator.java b/src/main/java/org/codehaus/plexus/interpolation/RegexBasedInterpolator.java
index b286bb8..d940aaa 100644
--- a/src/main/java/org/codehaus/plexus/interpolation/RegexBasedInterpolator.java
+++ b/src/main/java/org/codehaus/plexus/interpolation/RegexBasedInterpolator.java
@@ -177,6 +177,8 @@ public String interpolate(String input, String thisPrefixPattern, RecursionInter
int realExprGroup = 2;
Pattern expressionPattern;
+ final String expressionDelimiterStart;
+ final String expressionDelimiterEnd;
if (startRegex != null || endRegex != null) {
if (thisPrefixPattern == null) {
expressionPattern = getPattern(startRegex + endRegex);
@@ -184,16 +186,27 @@ public String interpolate(String input, String thisPrefixPattern, RecursionInter
} else {
expressionPattern = getPattern(startRegex + thisPrefixPattern + endRegex);
}
+ expressionDelimiterStart = startRegex;
+ expressionDelimiterEnd = endRegex;
- } else if (thisPrefixPattern != null) {
- expressionPattern = getPattern("\\$\\{(" + thisPrefixPattern + ")?(.+?)\\}");
} else {
- expressionPattern = getPattern(DEFAULT_REGEXP);
- realExprGroup = 1;
+ expressionDelimiterStart = "${";
+ expressionDelimiterEnd = "}";
+ if (thisPrefixPattern != null) {
+ expressionPattern = getPattern("\\$\\{(" + thisPrefixPattern + ")?(.+?)\\}");
+ } else {
+ expressionPattern = getPattern(DEFAULT_REGEXP);
+ realExprGroup = 1;
+ }
}
-
try {
- return interpolate(input, recursionInterceptor, expressionPattern, realExprGroup);
+ return interpolate(
+ input,
+ recursionInterceptor,
+ expressionPattern,
+ expressionDelimiterStart,
+ expressionDelimiterEnd,
+ realExprGroup);
} finally {
if (!cacheAnswers) {
clearAnswers();
@@ -228,7 +241,12 @@ private Pattern getPattern(String regExp) {
* @todo Ensure unresolvable expressions don't trigger infinite recursion.
*/
private String interpolate(
- String input, RecursionInterceptor recursionInterceptor, Pattern expressionPattern, int realExprGroup)
+ String input,
+ RecursionInterceptor recursionInterceptor,
+ Pattern expressionPattern,
+ String expressionDelimiterStart,
+ String expressionDelimiterEnd,
+ int realExprGroup)
throws InterpolationException {
if (input == null) {
// return empty String to prevent NPE too
@@ -256,11 +274,17 @@ private String interpolate(
for (ValueSource vs : valueSources) {
if (value != null) break;
- value = vs.getValue(realExpr);
+ value = vs.getValue(realExpr, expressionDelimiterStart, expressionDelimiterEnd);
}
if (value != null) {
- value = interpolate(String.valueOf(value), recursionInterceptor, expressionPattern, realExprGroup);
+ value = interpolate(
+ String.valueOf(value),
+ recursionInterceptor,
+ expressionPattern,
+ expressionDelimiterStart,
+ expressionDelimiterEnd,
+ realExprGroup);
if (postProcessors != null && !postProcessors.isEmpty()) {
for (InterpolationPostProcessor postProcessor : postProcessors) {
diff --git a/src/main/java/org/codehaus/plexus/interpolation/StringSearchInterpolator.java b/src/main/java/org/codehaus/plexus/interpolation/StringSearchInterpolator.java
index 04cba3d..28e2189 100644
--- a/src/main/java/org/codehaus/plexus/interpolation/StringSearchInterpolator.java
+++ b/src/main/java/org/codehaus/plexus/interpolation/StringSearchInterpolator.java
@@ -163,7 +163,7 @@ private String interpolate(String input, RecursionInterceptor recursionIntercept
if (value != null) {
break;
}
- value = valueSource.getValue(realExpr);
+ value = valueSource.getValue(realExpr, startExpr, endExpr);
if (value != null && value.toString().contains(wholeExpr)) {
bestAnswer = value;
diff --git a/src/main/java/org/codehaus/plexus/interpolation/ValueSource.java b/src/main/java/org/codehaus/plexus/interpolation/ValueSource.java
index 347b738..005822b 100644
--- a/src/main/java/org/codehaus/plexus/interpolation/ValueSource.java
+++ b/src/main/java/org/codehaus/plexus/interpolation/ValueSource.java
@@ -25,8 +25,21 @@
public interface ValueSource {
/**
+ * Returns a value resolved from an expression. The return value is recursively resolved via {@link Interpolator#interpolate(String)}, i.e. might contain expressions as well.
* @param expression The string expression.
- * @return the value related to the expression, or null if not found.
+ * @param expressionStartDelimiter A valid start delimiter of the expression to be used with the calling {@link Interpolator} (by default ${
).
+ * @param expressionEndDelimiter A valid end delimiter of the expression to be used with the calling {@link Interpolator} (by default }
).
+ * @return the value related to the expression, or {@code null} if not found. This value might contain other expressions separated by {@code expressionStartDelimiter} and {@code expressionEndDelimiter}
+ * @since 1.28
+ */
+ default Object getValue(String expression, String expressionStartDelimiter, String expressionEndDelimiter) {
+ return getValue(expression);
+ }
+
+ /**
+ * @param expression The string expression.
+ * @return the value related to the expression, or {@code null} if not found.
+ * @see #getValue(String, String, String)
*/
public Object getValue(String expression);
diff --git a/src/main/java/org/codehaus/plexus/interpolation/multi/MultiDelimiterStringSearchInterpolator.java b/src/main/java/org/codehaus/plexus/interpolation/multi/MultiDelimiterStringSearchInterpolator.java
index fc472e2..ba658e5 100644
--- a/src/main/java/org/codehaus/plexus/interpolation/multi/MultiDelimiterStringSearchInterpolator.java
+++ b/src/main/java/org/codehaus/plexus/interpolation/multi/MultiDelimiterStringSearchInterpolator.java
@@ -201,7 +201,7 @@ private String interpolate(String input, RecursionInterceptor recursionIntercept
for (ValueSource vs : valueSources) {
if (value != null) break;
- value = vs.getValue(realExpr);
+ value = vs.getValue(realExpr, startExpr, endExpr);
if (value != null && value.toString().contains(wholeExpr)) {
bestAnswer = value;
diff --git a/src/test/java/org/codehaus/plexus/interpolation/RegexBasedInterpolatorTest.java b/src/test/java/org/codehaus/plexus/interpolation/RegexBasedInterpolatorTest.java
index d3c31f6..61a25c2 100644
--- a/src/test/java/org/codehaus/plexus/interpolation/RegexBasedInterpolatorTest.java
+++ b/src/test/java/org/codehaus/plexus/interpolation/RegexBasedInterpolatorTest.java
@@ -80,6 +80,28 @@ public void testShouldResolveByContextValue() throws InterpolationException {
assertEquals("this is a testVar", result);
}
+ @Test
+ public void testDelimitersPassedToValueSource() throws InterpolationException {
+ RegexBasedInterpolator interpolator = new RegexBasedInterpolator();
+ interpolator.addValueSource(new AbstractValueSource(false) {
+
+ @Override
+ public Object getValue(String expression, String expressionStartDelimiter, String expressionEndDelimiter) {
+ assertEquals("${", expressionStartDelimiter);
+ assertEquals("}", expressionEndDelimiter);
+ return expression;
+ }
+
+ @Override
+ public Object getValue(String expression) {
+ fail("This method is not supposed to be called");
+ return null;
+ }
+ });
+
+ assertEquals("test", interpolator.interpolate("${test}"));
+ }
+
@Test
public void testShouldResolveByEnvar() throws IOException, InterpolationException {
OperatingSystemUtils.setEnvVarSource(new OperatingSystemUtils.EnvVarSource() {
diff --git a/src/test/java/org/codehaus/plexus/interpolation/StringSearchInterpolatorTest.java b/src/test/java/org/codehaus/plexus/interpolation/StringSearchInterpolatorTest.java
index 41de806..e1fa00a 100644
--- a/src/test/java/org/codehaus/plexus/interpolation/StringSearchInterpolatorTest.java
+++ b/src/test/java/org/codehaus/plexus/interpolation/StringSearchInterpolatorTest.java
@@ -94,6 +94,30 @@ public void testLongDelimitersWithNoContext() throws InterpolationException {
assertEquals(result, interpolator.interpolate(src));
}
+ @Test
+ public void testLongDelimitersPassedToValueSource() throws InterpolationException {
+ String src = "test";
+
+ StringSearchInterpolator interpolator = new StringSearchInterpolator("", "");
+ interpolator.addValueSource(new AbstractValueSource(false) {
+
+ @Override
+ public Object getValue(String expression, String expressionStartDelimiter, String expressionEndDelimiter) {
+ assertEquals("", expressionStartDelimiter);
+ assertEquals("", expressionEndDelimiter);
+ return expression;
+ }
+
+ @Override
+ public Object getValue(String expression) {
+ fail("This method is not supposed to be called");
+ return null;
+ }
+ });
+
+ assertEquals("test", interpolator.interpolate(src));
+ }
+
@Test
public void testSimpleSubstitution() throws InterpolationException {
Properties p = new Properties();
diff --git a/src/test/java/org/codehaus/plexus/interpolation/multi/MultiDelimiterStringSearchInterpolatorTest.java b/src/test/java/org/codehaus/plexus/interpolation/multi/MultiDelimiterStringSearchInterpolatorTest.java
index 2c5fe2f..8b3b724 100644
--- a/src/test/java/org/codehaus/plexus/interpolation/multi/MultiDelimiterStringSearchInterpolatorTest.java
+++ b/src/test/java/org/codehaus/plexus/interpolation/multi/MultiDelimiterStringSearchInterpolatorTest.java
@@ -19,12 +19,14 @@
import java.util.HashMap;
import java.util.Map;
+import org.codehaus.plexus.interpolation.AbstractValueSource;
import org.codehaus.plexus.interpolation.InterpolationException;
import org.codehaus.plexus.interpolation.MapBasedValueSource;
import org.codehaus.plexus.interpolation.ValueSource;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
public class MultiDelimiterStringSearchInterpolatorTest {
@@ -119,4 +121,29 @@ public void testInterpolationWithMultipleEscapes3() throws InterpolationExceptio
assertEquals("##${first} and #${second} and beer", result);
}
+
+ @Test
+ public void testDelimitersPassedToValueSource() throws InterpolationException {
+ ValueSource vs = new AbstractValueSource(false) {
+
+ @Override
+ public Object getValue(String expression, String expressionStartDelimiter, String expressionEndDelimiter) {
+ assertEquals("#(", expressionStartDelimiter);
+ assertEquals(")", expressionEndDelimiter);
+ return expression;
+ }
+
+ @Override
+ public Object getValue(String expression) {
+ fail("This method is not supposed to be called");
+ return null;
+ }
+ };
+ MultiDelimiterStringSearchInterpolator interpolator = new MultiDelimiterStringSearchInterpolator() //
+ .withValueSource(vs) //
+ .escapeString("#");
+ interpolator.addDelimiterSpec("#(*)");
+
+ assertEquals("test", interpolator.interpolate("#(test)"));
+ }
}