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 boolean foundToken = false;
236 for ( int i = 0; i < beginToken.length(); i++ )
237 {
238 if ( ch != beginToken.charAt( i ) || ch == -1 || ( ch == '\n' && !supportMultiLineFiltering ) )
239 {
240
241 break;
242 }
243
244 if ( i == beginToken.length() - 1 )
245 {
246
247 foundToken = true;
248
249 }
250
251 ch = in.read();
252
253 }
254
255 in.reset();
256 in.skip( key.length() );
257 ch = in.read();
258
259
260 if ( inEscape )
261 {
262
263 if ( beginToken != null )
264 {
265 if ( !isPreserveEscapeString() )
266 {
267 key.setLength( 0 );
268 }
269 }
270
271 key.append( (char) ch );
272
273 replaceData = key.toString();
274 replaceIndex = key.length();
275
276 return read();
277
278 }
279
280
281 if ( !foundToken )
282 {
283
284 in.reset();
285 return in.read();
286
287 }
288
289
290
291 key.append( beginToken );
292 in.reset();
293 in.skip( beginToken.length() );
294 ch = in.read();
295
296 int endTokenSize = endToken.length();
297 int end = endTokenSize;
298 do
299 {
300 if ( ch == -1 )
301 {
302 break;
303 }
304 else if ( ch == '\n' && !supportMultiLineFiltering )
305 {
306
307 key.append( (char) ch );
308 break;
309 }
310
311 key.append( (char) ch );
312
313 if ( ch == this.endToken.charAt( endTokenSize - end ) )
314 {
315 end--;
316 if ( end == 0 )
317 {
318 break;
319 }
320 }
321 else
322 {
323 end = endTokenSize;
324 }
325
326 ch = in.read();
327 }
328 while ( true );
329
330
331 String value = null;
332 if ( end == 0 )
333 {
334 try
335 {
336 if ( interpolateWithPrefixPattern )
337 {
338 value = interpolator.interpolate( key.toString(), "", recursionInterceptor );
339 }
340 else
341 {
342 value = interpolator.interpolate( key.toString(), recursionInterceptor );
343 }
344 }
345 catch ( InterpolationException e )
346 {
347 IllegalArgumentException error = new IllegalArgumentException( e.getMessage() );
348 error.initCause( e );
349
350 throw error;
351 }
352 }
353
354
355 if ( value != null )
356 {
357 replaceData = value;
358 replaceIndex = value.length();
359 }
360 else
361 {
362 replaceData = key.toString();
363 replaceIndex = key.length();
364 }
365
366 if ( ch == -1 )
367 {
368 eof = true;
369 }
370 return read();
371
372 }
373
374
375
376
377 public boolean isInterpolateWithPrefixPattern()
378 {
379 return interpolateWithPrefixPattern;
380 }
381
382
383
384
385 public void setInterpolateWithPrefixPattern( boolean interpolateWithPrefixPattern )
386 {
387 this.interpolateWithPrefixPattern = interpolateWithPrefixPattern;
388 }
389
390
391
392
393 public RecursionInterceptor getRecursionInterceptor()
394 {
395 return recursionInterceptor;
396 }
397
398
399
400
401
402 public InterpolatorFilterReaderLineEnding setRecursionInterceptor( RecursionInterceptor theRecursionInterceptor )
403 {
404 this.recursionInterceptor = theRecursionInterceptor;
405 return this;
406 }
407
408 }