@@ -138,141 +138,149 @@ private String interpolate( String input, RecursionInterceptor recursionIntercep
138
138
// return empty String to prevent NPE too
139
139
return "" ;
140
140
}
141
- StringBuilder result = new StringBuilder ( input .length () * 2 );
142
141
143
142
int startIdx ;
144
143
int endIdx = -1 ;
145
- while ( ( startIdx = input .indexOf ( startExpr , endIdx + 1 ) ) > -1 )
144
+ if ( ( startIdx = input .indexOf ( startExpr , endIdx + 1 ) ) > -1 )
146
145
{
147
- result .append ( input , endIdx + 1 , startIdx );
148
-
149
- endIdx = input .indexOf ( endExpr , startIdx + 1 );
150
- if ( endIdx < 0 )
151
- {
152
- break ;
153
- }
154
-
155
- final String wholeExpr = input .substring ( startIdx , endIdx + endExpr .length () );
156
- String realExpr = wholeExpr .substring ( startExpr .length (), wholeExpr .length () - endExpr .length () );
157
-
158
- if ( startIdx >= 0 && escapeString != null && escapeString .length () > 0 )
159
- {
160
- int startEscapeIdx = startIdx == 0 ? 0 : startIdx - escapeString .length ();
161
- if ( startEscapeIdx >= 0 )
146
+ StringBuilder result = new StringBuilder ( input .length () * 2 );
147
+ do
162
148
{
163
- String escape = input .substring ( startEscapeIdx , startIdx );
164
- if ( escapeString .equals ( escape ) )
165
- {
166
- result .append ( wholeExpr );
167
- result .replace ( startEscapeIdx , startEscapeIdx + escapeString .length (), "" );
168
- continue ;
169
- }
170
- }
171
- }
149
+ result .append ( input , endIdx + 1 , startIdx );
172
150
173
- boolean resolved = false ;
174
- if ( !unresolvable .contains ( wholeExpr ) )
175
- {
176
- if ( realExpr .startsWith ( "." ) )
151
+ endIdx = input .indexOf ( endExpr , startIdx + 1 );
152
+ if ( endIdx < 0 )
177
153
{
178
- realExpr = realExpr . substring ( 1 ) ;
154
+ break ;
179
155
}
180
156
181
- if ( recursionInterceptor .hasRecursiveExpression ( realExpr ) )
182
- {
183
- throw new InterpolationCycleException ( recursionInterceptor , realExpr , wholeExpr );
184
- }
157
+ final String wholeExpr = input .substring ( startIdx , endIdx + endExpr .length () );
158
+ String realExpr = wholeExpr .substring ( startExpr .length (), wholeExpr .length () - endExpr .length () );
185
159
186
- recursionInterceptor .expressionResolutionStarted ( realExpr );
187
- try
160
+ if ( startIdx >= 0 && escapeString != null && escapeString .length () > 0 )
188
161
{
189
- Object value = getExistingAnswer ( realExpr );
190
- Object bestAnswer = null ;
191
-
192
- for ( ValueSource valueSource : valueSources )
162
+ int startEscapeIdx = startIdx == 0 ? 0 : startIdx - escapeString .length ();
163
+ if ( startEscapeIdx >= 0 )
193
164
{
194
- if ( value != null )
165
+ String escape = input .substring ( startEscapeIdx , startIdx );
166
+ if ( escapeString .equals ( escape ) )
195
167
{
196
- break ;
168
+ result .append (wholeExpr );
169
+ result .replace (startEscapeIdx , startEscapeIdx + escapeString .length (), "" );
170
+ continue ;
197
171
}
198
- value = valueSource .getValue ( realExpr );
172
+ }
173
+ }
199
174
200
- if ( value != null && value .toString ().contains ( wholeExpr ) )
201
- {
202
- bestAnswer = value ;
203
- value = null ;
204
- }
175
+ boolean resolved = false ;
176
+ if ( !unresolvable .contains ( wholeExpr ) )
177
+ {
178
+ if ( realExpr .startsWith ( "." ) )
179
+ {
180
+ realExpr = realExpr .substring (1 );
205
181
}
206
182
207
- // this is the simplest recursion check to catch exact recursion
208
- // (non synonym), and avoid the extra effort of more string
209
- // searching.
210
- if ( value == null && bestAnswer != null )
183
+ if ( recursionInterceptor .hasRecursiveExpression ( realExpr ) )
211
184
{
212
185
throw new InterpolationCycleException ( recursionInterceptor , realExpr , wholeExpr );
213
186
}
214
187
215
- if ( value != null )
188
+ recursionInterceptor .expressionResolutionStarted ( realExpr );
189
+ try
216
190
{
217
- value = interpolate ( String .valueOf ( value ), recursionInterceptor , unresolvable );
191
+ Object value = getExistingAnswer ( realExpr );
192
+ Object bestAnswer = null ;
193
+
194
+ for ( ValueSource valueSource : valueSources )
195
+ {
196
+ if ( value != null )
197
+ {
198
+ break ;
199
+ }
200
+ value = valueSource .getValue ( realExpr );
201
+
202
+ if ( value != null && value .toString ().contains ( wholeExpr ) )
203
+ {
204
+ bestAnswer = value ;
205
+ value = null ;
206
+ }
207
+ }
218
208
219
- if ( postProcessors != null && !postProcessors .isEmpty () )
209
+ // this is the simplest recursion check to catch exact recursion
210
+ // (non synonym), and avoid the extra effort of more string
211
+ // searching.
212
+ if ( value == null && bestAnswer != null )
220
213
{
221
- for ( InterpolationPostProcessor postProcessor : postProcessors )
214
+ throw new InterpolationCycleException ( recursionInterceptor , realExpr , wholeExpr );
215
+ }
216
+
217
+ if ( value != null )
218
+ {
219
+ value = interpolate ( String .valueOf (value ), recursionInterceptor , unresolvable );
220
+
221
+ if ( postProcessors != null && !postProcessors .isEmpty () )
222
222
{
223
- Object newVal = postProcessor .execute ( realExpr , value );
224
- if ( newVal != null )
223
+ for ( InterpolationPostProcessor postProcessor : postProcessors )
225
224
{
226
- value = newVal ;
227
- break ;
225
+ Object newVal = postProcessor .execute ( realExpr , value );
226
+ if ( newVal != null )
227
+ {
228
+ value = newVal ;
229
+ break ;
230
+ }
228
231
}
229
232
}
230
- }
231
233
232
- // could use:
233
- // result = matcher.replaceFirst( stringValue );
234
- // but this could result in multiple lookups of stringValue, and replaceAll is not correct
235
- // behaviour
236
- result .append ( String .valueOf ( value ) );
237
- resolved = true ;
234
+ // could use:
235
+ // result = matcher.replaceFirst( stringValue );
236
+ // but this could result in multiple lookups of stringValue, and replaceAll is not correct
237
+ // behaviour
238
+ result .append ( String .valueOf ( value ) );
239
+ resolved = true ;
238
240
239
- if (cacheAnswers )
241
+ if (cacheAnswers )
242
+ {
243
+ existingAnswers .put ( realExpr , value );
244
+ }
245
+ }
246
+ else
240
247
{
241
- existingAnswers . put ( realExpr , value );
248
+ unresolvable . add ( wholeExpr );
242
249
}
243
250
}
244
- else
251
+ finally
245
252
{
246
- unresolvable . add ( wholeExpr );
253
+ recursionInterceptor . expressionResolutionFinished ( realExpr );
247
254
}
248
255
}
249
- finally
256
+
257
+ if (!resolved )
250
258
{
251
- recursionInterceptor .expressionResolutionFinished ( realExpr );
259
+ result .append ( wholeExpr );
260
+ }
261
+
262
+ if ( endIdx > -1 )
263
+ {
264
+ endIdx += endExpr .length () - 1 ;
252
265
}
253
266
}
267
+ while ( ( startIdx = input .indexOf ( startExpr , endIdx + 1 ) ) > -1 );
254
268
255
- if ( ! resolved )
269
+ if ( endIdx == - 1 && startIdx > - 1 )
256
270
{
257
- result .append ( wholeExpr );
271
+ result .append ( input , startIdx , input . length () );
258
272
}
259
-
260
- if ( endIdx > -1 )
273
+ else if ( endIdx < input .length () )
261
274
{
262
- endIdx += endExpr .length () - 1 ;
275
+ result . append ( input , endIdx + 1 , input .length () ) ;
263
276
}
264
- }
265
277
266
- if ( endIdx == -1 && startIdx > -1 )
267
- {
268
- result .append ( input , startIdx , input .length ());
278
+ return result .toString ();
269
279
}
270
- else if ( endIdx < input . length () )
280
+ else
271
281
{
272
- result . append ( input , endIdx + 1 , input . length () ) ;
282
+ return input ;
273
283
}
274
-
275
- return result .toString ();
276
284
}
277
285
278
286
/**
0 commit comments