1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 private int itemptr = 0;
62
63 /**
64 * number within <code>rawlines</code> of the first valid file entry.
65 */
66 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 this(rawlist, rawlist.getParser());
78 }
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 {
91 this.rawlines = rawlist.getLines();
92 this.parser = parser;
93 }
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 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 FTPFile entry = null;
121 for (int iter = 0; iter < this.rawlines.size(); iter++)
122 {
123 String line = (String) this.rawlines.get(iter);
124 entry = parseFTPEntry(line);
125 if (null != entry)
126 {
127 return iter;
128 }
129 }
130 return DIREMPTY;
131 }
132
133 /**
134 * resets iterator to the beginning of the list.
135 */
136 private void init()
137 {
138 this.itemptr = 0;
139 this.firstGoodEntry = UNINIT;
140 }
141
142 /**
143 * shorthand for an empty return value.
144 */
145 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 if (this.itemptr != DIREMPTY)
157 {
158 init();
159 }
160 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
188 if (this.firstGoodEntry == UNINIT)
189 {
190 this.firstGoodEntry = getFirstGoodEntry();
191 }
192 if (this.firstGoodEntry == DIREMPTY)
193 {
194 return EMPTY;
195 }
196
197 int max = this.rawlines.size() - this.firstGoodEntry;
198
199
200
201
202 int howMany = (quantityRequested == 0) ? max : quantityRequested;
203 howMany = (howMany + this.itemptr < this.rawlines.size())
204 ? howMany
205 : this.rawlines.size() - this.itemptr;
206
207 FTPFile[] output = new FTPFile[howMany];
208
209 for (int i = 0, e = this.firstGoodEntry + this.itemptr ;
210 i < howMany; i++, e++)
211 {
212 output[i] = parseFTPEntry((String) this.rawlines.get(e));
213 this.itemptr++;
214 }
215 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 int fge = this.firstGoodEntry;
228 if (fge == DIREMPTY)
229 {
230
231 return false;
232 }
233 else if (fge < 0)
234 {
235
236 fge = getFirstGoodEntry();
237 }
238 return fge + this.itemptr < 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 FTPFile[] file = getNext(1);
255 if (file.length > 0)
256 {
257 return file[0];
258 }
259 else
260 {
261 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 int howMany = quantityRequested;
288
289 if (howMany > this.itemptr)
290 {
291 howMany = this.itemptr;
292 }
293 FTPFile[] output = new FTPFile[howMany];
294 for (int i = howMany, e = this.firstGoodEntry + this.itemptr; i > 0;)
295 {
296 output[--i] = parseFTPEntry((String) this.rawlines.get(--e));
297 this.itemptr--;
298 }
299 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 int fge = this.firstGoodEntry;
312 if (fge == DIREMPTY)
313 {
314
315 return false;
316 }
317 else if (fge < 0)
318 {
319
320 fge = getFirstGoodEntry();
321 }
322
323 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 FTPFile[] file = getPrevious(1);
340 if (file.length > 0)
341 {
342 return file[0];
343 }
344 else
345 {
346 return null;
347 }
348 }
349 }
350
351
352
353
354
355
356
357