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