source: release-kits/lirk3/resources/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/filters/TailFilter.java@ 14982

Last change on this file since 14982 was 14982, checked in by oranfry, 16 years ago

initial import of LiRK3

File size: 7.6 KB
Line 
1/*
2 * Copyright 2002-2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17package org.apache.tools.ant.filters;
18
19import java.io.IOException;
20import java.io.Reader;
21import java.util.LinkedList;
22import org.apache.tools.ant.types.Parameter;
23import org.apache.tools.ant.util.LineTokenizer;
24
25/**
26 * Reads the last <code>n</code> lines of a stream. (Default is last10 lines.)
27 *
28 * Example:
29 *
30 * <pre>&lt;tailfilter lines=&quot;3&quot;/&gt;</pre>
31 *
32 * Or:
33 *
34 * <pre>&lt;filterreader classname=&quot;org.apache.tools.ant.filters.TailFilter&quot;&gt;
35 * &lt;param name=&quot;lines&quot; value=&quot;3&quot;/&gt;
36 * &lt;/filterreader&gt;</pre>
37 *
38 */
39public final class TailFilter extends BaseParamFilterReader
40 implements ChainableReader {
41 /** Parameter name for the number of lines to be returned. */
42 private static final String LINES_KEY = "lines";
43
44 /** Parameter name for the number of lines to be skipped. */
45 private static final String SKIP_KEY = "skip";
46
47 /** Default number of lines to show */
48 private static final int DEFAULT_NUM_LINES = 10;
49
50 /** Number of lines to be returned in the filtered stream. */
51 private long lines = DEFAULT_NUM_LINES;
52
53 /** Number of lines to be skipped. */
54 private long skip = 0;
55
56 /** Whether or not read-ahead been completed. */
57 private boolean completedReadAhead = false;
58
59 /** A line tokenizer */
60 private LineTokenizer lineTokenizer = null;
61
62 /** the current line from the input stream */
63 private String line = null;
64 /** the position in the current line */
65 private int linePos = 0;
66
67 private LinkedList lineList = new LinkedList();
68
69 /**
70 * Constructor for "dummy" instances.
71 *
72 * @see BaseFilterReader#BaseFilterReader()
73 */
74 public TailFilter() {
75 super();
76 }
77
78 /**
79 * Creates a new filtered reader.
80 *
81 * @param in A Reader object providing the underlying stream.
82 * Must not be <code>null</code>.
83 */
84 public TailFilter(final Reader in) {
85 super(in);
86 lineTokenizer = new LineTokenizer();
87 lineTokenizer.setIncludeDelims(true);
88 }
89
90 /**
91 * Returns the next character in the filtered stream. If the read-ahead
92 * has been completed, the next character in the buffer is returned.
93 * Otherwise, the stream is read to the end and buffered (with the buffer
94 * growing as necessary), then the appropriate position in the buffer is
95 * set to read from.
96 *
97 * @return the next character in the resulting stream, or -1
98 * if the end of the resulting stream has been reached
99 *
100 * @exception IOException if the underlying stream throws an IOException
101 * during reading
102 */
103 public final int read() throws IOException {
104 if (!getInitialized()) {
105 initialize();
106 setInitialized(true);
107 }
108
109 while (line == null || line.length() == 0) {
110 line = lineTokenizer.getToken(in);
111 line = tailFilter(line);
112 if (line == null) {
113 return -1;
114 }
115 linePos = 0;
116 }
117
118 int ch = line.charAt(linePos);
119 linePos++;
120 if (linePos == line.length()) {
121 line = null;
122 }
123 return ch;
124 }
125
126 /**
127 * Sets the number of lines to be returned in the filtered stream.
128 *
129 * @param lines the number of lines to be returned in the filtered stream
130 */
131 public final void setLines(final long lines) {
132 this.lines = lines;
133 }
134
135 /**
136 * Returns the number of lines to be returned in the filtered stream.
137 *
138 * @return the number of lines to be returned in the filtered stream
139 */
140 private final long getLines() {
141 return lines;
142 }
143
144 /**
145 * Sets the number of lines to be skipped in the filtered stream.
146 *
147 * @param skip the number of lines to be skipped in the filtered stream
148 */
149 public final void setSkip(final long skip) {
150 this.skip = skip;
151 }
152
153 /**
154 * Returns the number of lines to be skipped in the filtered stream.
155 *
156 * @return the number of lines to be skipped in the filtered stream
157 */
158 private final long getSkip() {
159 return skip;
160 }
161
162 /**
163 * Creates a new TailFilter using the passed in
164 * Reader for instantiation.
165 *
166 * @param rdr A Reader object providing the underlying stream.
167 * Must not be <code>null</code>.
168 *
169 * @return a new filter based on this configuration, but filtering
170 * the specified reader
171 */
172 public final Reader chain(final Reader rdr) {
173 TailFilter newFilter = new TailFilter(rdr);
174 newFilter.setLines(getLines());
175 newFilter.setSkip(getSkip());
176 newFilter.setInitialized(true);
177 return newFilter;
178 }
179
180 /**
181 * Scans the parameters list for the "lines" parameter and uses
182 * it to set the number of lines to be returned in the filtered stream.
183 * also scan for "skip" parameter.
184 */
185 private final void initialize() {
186 Parameter[] params = getParameters();
187 if (params != null) {
188 for (int i = 0; i < params.length; i++) {
189 if (LINES_KEY.equals(params[i].getName())) {
190 setLines(new Long(params[i].getValue()).longValue());
191 continue;
192 }
193 if (SKIP_KEY.equals(params[i].getName())) {
194 skip = new Long(params[i].getValue()).longValue();
195 continue;
196 }
197 }
198 }
199 }
200
201 /**
202 * implement a tail filter on a stream of lines.
203 * line = null is the end of the stream.
204 * @return "" while reading in the lines,
205 * line while outputting the lines
206 * null at the end of outputting the lines
207 */
208 private String tailFilter(String line) {
209 if (!completedReadAhead) {
210 if (line != null) {
211 lineList.add(line);
212 if (lines == -1) {
213 if (lineList.size() > skip) {
214 return (String) lineList.removeFirst();
215 }
216 } else {
217 long linesToKeep = lines + (skip > 0 ? skip : 0);
218 if (linesToKeep < lineList.size()) {
219 lineList.removeFirst();
220 }
221 }
222 return "";
223 }
224 completedReadAhead = true;
225 if (skip > 0) {
226 for (int i = 0; i < skip; ++i) {
227 lineList.removeLast();
228 }
229 }
230 if (lines > -1) {
231 while (lineList.size() > lines) {
232 lineList.removeFirst();
233 }
234 }
235 }
236 if (lineList.size() > 0) {
237 return (String) lineList.removeFirst();
238 }
239 return null;
240 }
241}
Note: See TracBrowser for help on using the repository browser.