Skip to content

Commit cbe8ccf

Browse files
Copilotslachiewicz
andcommitted
Fix RegexBasedInterpolator cache - populate existingAnswers map when cacheAnswers is true
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
1 parent dabd0db commit cbe8ccf

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

src/main/java/org/codehaus/plexus/interpolation/RegexBasedInterpolator.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,10 @@ private String interpolate(
301301
// but this could result in multiple lookups of stringValue, and replaceAll is not correct behaviour
302302
result = StringUtils.replace(result, wholeExpr, String.valueOf(value));
303303

304+
if (cacheAnswers) {
305+
existingAnswers.put(realExpr, value);
306+
}
307+
304308
matcher.reset(result);
305309
}
306310
} finally {

src/test/java/org/codehaus/plexus/interpolation/RegexBasedInterpolatorTest.java

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,4 +223,73 @@ public Object execute(String expression, Object value) {
223223

224224
System.out.println("time with pattern reuse and RegexBasedInterpolator instance reuse " + (end - start));
225225
}
226+
227+
@Test
228+
public void testCacheAnswersTrue() throws InterpolationException {
229+
Map ctx = new HashMap();
230+
ctx.put("key", "value");
231+
232+
final int[] valueSourceCallCount = {0};
233+
234+
ValueSource vs = new AbstractValueSource(false) {
235+
@Override
236+
public Object getValue(String expression) {
237+
valueSourceCallCount[0]++;
238+
return ctx.get(expression);
239+
}
240+
};
241+
242+
RegexBasedInterpolator interpolator = new RegexBasedInterpolator();
243+
interpolator.setCacheAnswers(true);
244+
interpolator.addValueSource(vs);
245+
246+
// First interpolation
247+
String result = interpolator.interpolate("${key}-${key}-${key}-${key}");
248+
assertEquals("value-value-value-value", result);
249+
assertEquals(1, valueSourceCallCount[0]);
250+
251+
// Second interpolation - cache should be used, no new ValueSource calls
252+
result = interpolator.interpolate("${key}-${key}-${key}-${key}");
253+
assertEquals("value-value-value-value", result);
254+
assertEquals(1, valueSourceCallCount[0]); // still 1, cache was used
255+
256+
// Third interpolation with different expression that also uses cached value
257+
result = interpolator.interpolate("The value is ${key}");
258+
assertEquals("The value is value", result);
259+
assertEquals(1, valueSourceCallCount[0]); // still 1, cache was used
260+
}
261+
262+
@Test
263+
public void testCacheAnswersFalse() throws InterpolationException {
264+
Map ctx = new HashMap();
265+
ctx.put("key", "value");
266+
267+
final int[] valueSourceCallCount = {0};
268+
269+
ValueSource vs = new AbstractValueSource(false) {
270+
@Override
271+
public Object getValue(String expression) {
272+
valueSourceCallCount[0]++;
273+
return ctx.get(expression);
274+
}
275+
};
276+
277+
RegexBasedInterpolator interpolator = new RegexBasedInterpolator();
278+
interpolator.addValueSource(vs);
279+
280+
// First interpolation
281+
String result = interpolator.interpolate("${key}-${key}-${key}-${key}");
282+
assertEquals("value-value-value-value", result);
283+
assertEquals(1, valueSourceCallCount[0]);
284+
285+
// Second interpolation - without caching, ValueSource is called again
286+
result = interpolator.interpolate("${key}-${key}-${key}-${key}");
287+
assertEquals("value-value-value-value", result);
288+
assertEquals(2, valueSourceCallCount[0]); // incremented to 2
289+
290+
// Third interpolation
291+
result = interpolator.interpolate("The value is ${key}");
292+
assertEquals("The value is value", result);
293+
assertEquals(3, valueSourceCallCount[0]); // incremented to 3
294+
}
226295
}

0 commit comments

Comments
 (0)