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