| %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. |