%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.commons.net.ftp.FTPFileIterator |
|
|
1 | /* |
|
2 | * Copyright 2001-2005 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 | package org.apache.commons.net.ftp; |
|
17 | import java.util.List; |
|
18 | ||
19 | /** |
|
20 | * This class implements a bidirectional iterator over an FTPFileList. |
|
21 | * Elements may be retrieved one at at time using the hasNext() - next() |
|
22 | * syntax familiar from Java 2 collections. Alternatively, entries may |
|
23 | * be receieved as an array of any requested number of entries or all of them. |
|
24 | * |
|
25 | * @author <a href="mailto:scohen@apache.org">Steve Cohen</a> |
|
26 | * @version $Id: FTPFileIterator.java 165675 2005-05-02 20:09:55Z rwinston $ |
|
27 | * @see org.apache.commons.net.ftp.FTPFileList |
|
28 | * @see org.apache.commons.net.ftp.FTPFileEntryParser |
|
29 | * @see org.apache.commons.net.ftp.FTPListParseEngine |
|
30 | * @deprecated This class is deprecated as of version 1.2 and will be |
|
31 | * removed in version 2.0 - use FTPFileParseEngine instead |
|
32 | */ |
|
33 | public class FTPFileIterator |
|
34 | { |
|
35 | /** |
|
36 | * a vector of strings, each representing a possibly valid ftp file |
|
37 | * entry |
|
38 | */ |
|
39 | private List rawlines; |
|
40 | ||
41 | /** |
|
42 | * the parser to which this iterator delegates its parsing duties |
|
43 | */ |
|
44 | private FTPFileEntryParser parser; |
|
45 | ||
46 | /** |
|
47 | * constant shorthand for the situation where the raw listing has not |
|
48 | * yet been scanned |
|
49 | */ |
|
50 | private static final int UNINIT = -1; |
|
51 | ||
52 | /** |
|
53 | * constant shorthand for the situation where the raw listing has been |
|
54 | * scanned and found to have no valid entry. |
|
55 | */ |
|
56 | private static final int DIREMPTY = -2; |
|
57 | ||
58 | /** |
|
59 | * this iterator's current position within <code>rawlines</code>. |
|
60 | */ |
|
61 | 0 | private int itemptr = 0; |
62 | ||
63 | /** |
|
64 | * number within <code>rawlines</code> of the first valid file entry. |
|
65 | */ |
|
66 | 0 | private int firstGoodEntry = UNINIT; |
67 | ||
68 | /** |
|
69 | * "Package-private" constructor. Only the FTPFileList can |
|
70 | * create an iterator, using it's iterator() method. The list |
|
71 | * will be iterated with the list's default parser. |
|
72 | * |
|
73 | * @param rawlist the FTPFileList to be iterated |
|
74 | */ |
|
75 | FTPFileIterator (FTPFileList rawlist) |
|
76 | { |
|
77 | 0 | this(rawlist, rawlist.getParser()); |
78 | 0 | } |
79 | ||
80 | /** |
|
81 | * "Package-private" constructor. Only the FTPFileList can |
|
82 | * create an iterator, using it's iterator() method. The list will be |
|
83 | * iterated with a supplied parser |
|
84 | * |
|
85 | * @param rawlist the FTPFileList to be iterated |
|
86 | * @param parser the system specific parser for raw FTP entries. |
|
87 | */ |
|
88 | FTPFileIterator (FTPFileList rawlist, |
|
89 | FTPFileEntryParser parser) |
|
90 | 0 | { |
91 | 0 | this.rawlines = rawlist.getLines(); |
92 | 0 | this.parser = parser; |
93 | 0 | } |
94 | ||
95 | /** |
|
96 | * Delegates to this object's parser member the job of parsing an |
|
97 | * entry. |
|
98 | * |
|
99 | * @param entry A string containing one entry, as determined by the |
|
100 | * parser's getNextEntry() method. |
|
101 | * |
|
102 | * @return an FTPFile object representing this entry or null if it can't be |
|
103 | * parsed as a file |
|
104 | */ |
|
105 | private FTPFile parseFTPEntry(String entry) |
|
106 | { |
|
107 | 0 | return this.parser.parseFTPEntry(entry); |
108 | } |
|
109 | ||
110 | /** |
|
111 | * Skips over any introductory lines and stuff in the listing that does |
|
112 | * not represent files, returning the line number of the first entry |
|
113 | * that does represent a file. |
|
114 | * |
|
115 | * @return the line number within <code>rawlines</code> of the first good |
|
116 | * entry in the array or DIREMPTY if there are no good entries. |
|
117 | */ |
|
118 | private int getFirstGoodEntry() |
|
119 | { |
|
120 | 0 | FTPFile entry = null; |
121 | 0 | for (int iter = 0; iter < this.rawlines.size(); iter++) |
122 | { |
|
123 | 0 | String line = (String) this.rawlines.get(iter); |
124 | 0 | entry = parseFTPEntry(line); |
125 | 0 | if (null != entry) |
126 | { |
|
127 | 0 | return iter; |
128 | } |
|
129 | } |
|
130 | 0 | return DIREMPTY; |
131 | } |
|
132 | ||
133 | /** |
|
134 | * resets iterator to the beginning of the list. |
|
135 | */ |
|
136 | private void init() |
|
137 | { |
|
138 | 0 | this.itemptr = 0; |
139 | 0 | this.firstGoodEntry = UNINIT; |
140 | 0 | } |
141 | ||
142 | /** |
|
143 | * shorthand for an empty return value. |
|
144 | */ |
|
145 | 0 | private static final FTPFile[] EMPTY = new FTPFile[0]; |
146 | ||
147 | /** |
|
148 | * Returns a list of FTPFile objects for ALL files listed in the server's |
|
149 | * LIST output. |
|
150 | * |
|
151 | * @return a list of FTPFile objects for ALL files listed in the server's |
|
152 | * LIST output. |
|
153 | */ |
|
154 | public FTPFile[] getFiles() |
|
155 | { |
|
156 | 0 | if (this.itemptr != DIREMPTY) |
157 | { |
|
158 | 0 | init(); |
159 | } |
|
160 | 0 | return getNext(0); |
161 | } |
|
162 | ||
163 | /** |
|
164 | * Returns an array of at most <code>quantityRequested</code> FTPFile |
|
165 | * objects starting at this iterator's current position within its |
|
166 | * associated list. If fewer than <code>quantityRequested</code> such |
|
167 | * elements are available, the returned array will have a length equal |
|
168 | * to the number of entries at and after after the current position. |
|
169 | * If no such entries are found, this array will have a length of 0. |
|
170 | * |
|
171 | * After this method is called the current position is advanced by |
|
172 | * either <code>quantityRequested</code> or the number of entries |
|
173 | * available after the iterator, whichever is fewer. |
|
174 | * |
|
175 | * @param quantityRequested |
|
176 | * the maximum number of entries we want to get. A 0 |
|
177 | * passed here is a signal to get ALL the entries. |
|
178 | * |
|
179 | * @return an array of at most <code>quantityRequested</code> FTPFile |
|
180 | * objects starting at the current position of this iterator within its |
|
181 | * list and at least the number of elements which exist in the list at |
|
182 | * and after its current position. |
|
183 | */ |
|
184 | public FTPFile[] getNext(int quantityRequested) |
|
185 | { |
|
186 | ||
187 | // if we haven't gotten past the initial junk do so. |
|
188 | 0 | if (this.firstGoodEntry == UNINIT) |
189 | { |
|
190 | 0 | this.firstGoodEntry = getFirstGoodEntry(); |
191 | } |
|
192 | 0 | if (this.firstGoodEntry == DIREMPTY) |
193 | { |
|
194 | 0 | return EMPTY; |
195 | } |
|
196 | ||
197 | 0 | int max = this.rawlines.size() - class="keyword">this.firstGoodEntry; |
198 | ||
199 | // now that we know the maximum we can possibly get, |
|
200 | // resolve a 0 request to ask for that many. |
|
201 | ||
202 | 0 | int howMany = (quantityRequested == 0) ? max : quantityRequested; |
203 | 0 | howMany = (howMany + this.itemptr < class="keyword">this.rawlines.size()) |
204 | ? howMany |
|
205 | : this.rawlines.size() - class="keyword">this.itemptr; |
|
206 | ||
207 | 0 | FTPFile[] output = new FTPFile[howMany]; |
208 | ||
209 | 0 | for (int i = 0, e = this.firstGoodEntry + class="keyword">this.itemptr ; |
210 | 0 | i < howMany; i++, e++) |
211 | { |
|
212 | 0 | output[i] = parseFTPEntry((String) this.rawlines.get(e)); |
213 | 0 | this.itemptr++; |
214 | } |
|
215 | 0 | return output; |
216 | } |
|
217 | ||
218 | /** |
|
219 | * Method for determining whether getNext() will successfully return a |
|
220 | * non-null value. |
|
221 | * |
|
222 | * @return true if there exist any files after the one currently pointed |
|
223 | * to by the internal iterator, false otherwise. |
|
224 | */ |
|
225 | public boolean hasNext() |
|
226 | { |
|
227 | 0 | int fge = this.firstGoodEntry; |
228 | 0 | if (fge == DIREMPTY) |
229 | { |
|
230 | //directory previously found empty - return false |
|
231 | 0 | return false; |
232 | } |
|
233 | 0 | else if (fge < 0) |
234 | { |
|
235 | // we haven't scanned the list yet so do it first |
|
236 | 0 | fge = getFirstGoodEntry(); |
237 | } |
|
238 | 0 | return fge + this.itemptr < class="keyword">this.rawlines.size(); |
239 | } |
|
240 | ||
241 | /** |
|
242 | * Returns a single parsed FTPFile object corresponding to the raw input |
|
243 | * line at this iterator's current position. |
|
244 | * |
|
245 | * After this method is called the internal iterator is advanced by one |
|
246 | * element (unless already at end of list). |
|
247 | * |
|
248 | * @return a single FTPFile object corresponding to the raw input line |
|
249 | * at the position of the internal iterator over the list of raw input |
|
250 | * lines maintained by this object or null if no such object exists. |
|
251 | */ |
|
252 | public FTPFile next() |
|
253 | { |
|
254 | 0 | FTPFile[] file = getNext(1); |
255 | 0 | if (file.length > 0) |
256 | { |
|
257 | 0 | return file[0]; |
258 | } |
|
259 | else |
|
260 | { |
|
261 | 0 | return null; |
262 | } |
|
263 | } |
|
264 | ||
265 | /** |
|
266 | * Returns an array of at most <code>quantityRequested</code> FTPFile |
|
267 | * objects starting at the position preceding this iterator's current |
|
268 | * position within its associated list. If fewer than |
|
269 | * <code>quantityRequested</code> such elements are available, the |
|
270 | * returned array will have a length equal to the number of entries after |
|
271 | * the iterator. If no such entries are found, this array will have a |
|
272 | * length of 0. The entries will be ordered in the same order as the |
|
273 | * list, not reversed. |
|
274 | * |
|
275 | * After this method is called the current position is moved back by |
|
276 | * either <code>quantityRequested</code> or the number of entries |
|
277 | * available before the current position, whichever is fewer. |
|
278 | * @param quantityRequested the maximum number of entries we want to get. |
|
279 | * A 0 passed here is a signal to get ALL the entries. |
|
280 | * @return an array of at most <code>quantityRequested</code> FTPFile |
|
281 | * objects starting at the position preceding the current position of |
|
282 | * this iterator within its list and at least the number of elements which |
|
283 | * exist in the list prior to its current position. |
|
284 | */ |
|
285 | public FTPFile[] getPrevious(int quantityRequested) |
|
286 | { |
|
287 | 0 | int howMany = quantityRequested; |
288 | // can't retreat further than we've previously advanced |
|
289 | 0 | if (howMany > this.itemptr) |
290 | { |
|
291 | 0 | howMany = this.itemptr; |
292 | } |
|
293 | 0 | FTPFile[] output = new FTPFile[howMany]; |
294 | 0 | for (int i = howMany, e = this.firstGoodEntry + class="keyword">this.itemptr; i > 0;) |
295 | { |
|
296 | 0 | output[--i] = parseFTPEntry((String) this.rawlines.get(--e)); |
297 | 0 | this.itemptr--; |
298 | } |
|
299 | 0 | return output; |
300 | } |
|
301 | ||
302 | /** |
|
303 | * Method for determining whether getPrevious() will successfully return a |
|
304 | * non-null value. |
|
305 | * |
|
306 | * @return true if there exist any files before the one currently pointed |
|
307 | * to by the internal iterator, false otherwise. |
|
308 | */ |
|
309 | public boolean hasPrevious() |
|
310 | { |
|
311 | 0 | int fge = this.firstGoodEntry; |
312 | 0 | if (fge == DIREMPTY) |
313 | { |
|
314 | //directory previously found empty - return false |
|
315 | 0 | return false; |
316 | } |
|
317 | 0 | else if (fge < 0) |
318 | { |
|
319 | // we haven't scanned the list yet so do it first |
|
320 | 0 | fge = getFirstGoodEntry(); |
321 | } |
|
322 | ||
323 | 0 | return this.itemptr > fge; |
324 | } |
|
325 | ||
326 | /** |
|
327 | * Returns a single parsed FTPFile object corresponding to the raw input |
|
328 | * line at the position preceding that of the internal iterator over |
|
329 | * the list of raw lines maintained by this object |
|
330 | * |
|
331 | * After this method is called the internal iterator is retreated by one |
|
332 | * element (unless it is already at beginning of list). |
|
333 | * @return a single FTPFile object corresponding to the raw input line |
|
334 | * at the position immediately preceding that of the internal iterator |
|
335 | * over the list of raw input lines maintained by this object. |
|
336 | */ |
|
337 | public FTPFile previous() |
|
338 | { |
|
339 | 0 | FTPFile[] file = getPrevious(1); |
340 | 0 | if (file.length > 0) |
341 | { |
|
342 | 0 | return file[0]; |
343 | } |
|
344 | else |
|
345 | { |
|
346 | 0 | return null; |
347 | } |
|
348 | } |
|
349 | } |
|
350 | ||
351 | /* Emacs configuration |
|
352 | * Local variables: ** |
|
353 | * mode: java ** |
|
354 | * c-basic-offset: 4 ** |
|
355 | * indent-tabs-mode: nil ** |
|
356 | * End: ** |
|
357 | */ |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |