1 package org.apache.maven.shared.filtering;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.BufferedReader;
23 import java.io.IOException;
24 import java.io.Reader;
25
26 import org.codehaus.plexus.interpolation.InterpolationException;
27 import org.codehaus.plexus.interpolation.Interpolator;
28 import org.codehaus.plexus.interpolation.RecursionInterceptor;
29 import org.codehaus.plexus.interpolation.SimpleRecursionInterceptor;
30
31
32
33
34
35
36
37
38
39 public class InterpolatorFilterReaderLineEnding
40 extends AbstractFilterReaderLineEnding
41 {
42
43
44
45
46 private Interpolator interpolator;
47
48 private RecursionInterceptor recursionInterceptor;
49
50
51
52
53 private String replaceData = null;
54
55
56
57
58 private int replaceIndex = 0;
59
60
61
62
63 public static final String DEFAULT_BEGIN_TOKEN = "${";
64
65
66
67
68 public static final String DEFAULT_END_TOKEN = "}";
69
70 private String beginToken;
71
72 private String endToken;
73
74
75
76
77 private boolean interpolateWithPrefixPattern = true;
78
79 private boolean supportMultiLineFiltering;
80
81 private boolean eof = false;
82
83
84
85
86
87
88
89
90 public InterpolatorFilterReaderLineEnding( Reader in, Interpolator interpolator, String beginToken, String endToken,
91 boolean supportMultiLineFiltering )
92 {
93 this( in, interpolator, beginToken, endToken, new SimpleRecursionInterceptor(), supportMultiLineFiltering );
94 }
95
96
97
98
99
100
101
102
103
104 private InterpolatorFilterReaderLineEnding( Reader in, Interpolator interpolator, String beginToken,
105 String endToken, RecursionInterceptor ri,
106 boolean supportMultiLineFiltering )
107 {
108
109 super( new BufferedReader( in ) );
110
111 this.interpolator = interpolator;
112
113 this.beginToken = beginToken;
114
115 this.endToken = endToken;
116
117 recursionInterceptor = ri;
118
119 this.supportMultiLineFiltering = supportMultiLineFiltering;
120
121 calculateMarkLength();
122
123 }
124
125
126
127
128
129
130
131
132
133 public long skip( long n )
134 throws IOException
135 {
136 if ( n < 0L )
137 {
138 throw new IllegalArgumentException( "skip value is negative" );
139 }
140
141 for ( long i = 0; i < n; i++ )
142 {
143 if ( read() == -1 )
144 {
145 return i;
146 }
147 }
148 return n;
149 }
150
151
152
153
154
155
156
157
158
159
160
161 public int read( char cbuf[], int off, int len )
162 throws IOException
163 {
164 for ( int i = 0; i < len; i++ )
165 {
166 int ch = read();
167 if ( ch == -1 )
168 {
169 if ( i == 0 )
170 {
171 return -1;
172 }
173 else
174 {
175 return i;
176 }
177 }
178 cbuf[off + i] = (char) ch;
179 }
180 return len;
181 }
182
183
184
185
186
187
188
189 public int read()
190 throws IOException
191 {
192 if ( replaceIndex > 0 )
193 {
194 return replaceData.charAt( replaceData.length() - ( replaceIndex-- ) );
195 }
196 if ( eof )
197 {
198 return -1;
199 }
200
201 in.mark( markLength );
202
203 int ch = in.read();
204 if ( ch == -1 || ( ch == '\n' && !supportMultiLineFiltering ) )
205 {
206 return ch;
207 }
208
209 boolean inEscape = useEscape && ch == getEscapeString().charAt( 0 );
210
211 StringBuilder key = new StringBuilder();
212
213
214 if ( inEscape )
215 {
216 for ( int i = 0; i < getEscapeString().length(); i++ )
217 {
218 key.append( (char) ch );
219
220 if ( ch != getEscapeString().charAt( i ) || ch == -1 || ( ch == '\n' && !supportMultiLineFiltering ) )
221 {
222
223 in.reset();
224 inEscape = false;
225 key.setLength( 0 );
226 break;
227 }
228
229 ch = in.read();
230
231 }
232
233 }
234
235
236 boolean foundToken = false;
237 for ( int i = 0; i < beginToken.length(); i++ )
238 {
239 if ( ch != beginToken.charAt( i ) || ch == -1 || ( ch == '\n' && !supportMultiLineFiltering ) )
240 {
241
242 break;
243 }
244
245 if ( i == beginToken.length() - 1 )
246 {
247
248 foundToken = true;
249
250 }
251
252 ch = in.read();
253
254 }
255
256 in.reset();
257 in.skip( key.length() );
258 ch = in.read();
259
260
261 if ( inEscape )
262 {
263
264 if ( beginToken != null )
265 {
266 if ( !isPreserveEscapeString() )
267 {
268 key.setLength( 0 );
269 }
270 }
271
272 key.append( (char) ch );
273
274 replaceData = key.toString();
275 replaceIndex = key.length();
276
277 return read();
278
279 }
280
281
282 if ( !foundToken )
283 {
284
285 in.reset();
286 return in.read();
287
288 }
289
290
291
292 key.append( beginToken );
293 in.reset();
294 in.skip( beginToken.length() );
295 ch = in.read();
296
297 int endTokenSize = endToken.length();
298 int end = endTokenSize;
299 do
300 {
301 if ( ch == -1 )
302 {
303 break;
304 }
305 else if ( ch == '\n' && !supportMultiLineFiltering )
306 {
307
308 key.append( (char) ch );
309 break;
310 }
311
312 key.append( (char) ch );
313
314 if ( ch == this.endToken.charAt( endTokenSize - end ) )
315 {
316 end--;
317 if ( end == 0 )
318 {
319 break;
320 }
321 }
322 else
323 {
324 end = endTokenSize;
325 }
326
327 ch = in.read();
328 }
329 while ( true );
330
331
332 String value = null;
333 if ( end == 0 )
334 {
335 try
336 {
337 if ( interpolateWithPrefixPattern )
338 {
339 value = interpolator.interpolate( key.toString(), "", recursionInterceptor );
340 }
341 else
342 {
343 value = interpolator.interpolate( key.toString(), recursionInterceptor );
344 }
345 }
346 catch ( InterpolationException e )
347 {
348 IllegalArgumentException error = new IllegalArgumentException( e.getMessage() );
349 error.initCause( e );
350
351 throw error;
352 }
353 }
354
355
356 if ( value != null )
357 {
358 replaceData = value;
359 replaceIndex = value.length();
360 }
361 else
362 {
363 replaceData = key.toString();
364 replaceIndex = key.length();
365 }
366
367 if ( ch == -1 )
368 {
369 eof = true;
370 }
371 return read();
372
373 }
374
375
376
377
378 public boolean isInterpolateWithPrefixPattern()
379 {
380 return interpolateWithPrefixPattern;
381 }
382
383
384
385
386 public void setInterpolateWithPrefixPattern( boolean interpolateWithPrefixPattern )
387 {
388 this.interpolateWithPrefixPattern = interpolateWithPrefixPattern;
389 }
390
391
392
393
394 public RecursionInterceptor getRecursionInterceptor()
395 {
396 return recursionInterceptor;
397 }
398
399
400
401
402
403 public InterpolatorFilterReaderLineEnding setRecursionInterceptor( RecursionInterceptor theRecursionInterceptor )
404 {
405 this.recursionInterceptor = theRecursionInterceptor;
406 return this;
407 }
408
409 }