/*
* Copyright 2001-2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.ftp;
import java.util.List;
/**
* This class implements a bidirectional iterator over an FTPFileList.
* Elements may be retrieved one at at time using the hasNext() - next()
* syntax familiar from Java 2 collections. Alternatively, entries may
* be receieved as an array of any requested number of entries or all of them.
*
* @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
* @version $Id: FTPFileIterator.java 165675 2005-05-02 20:09:55Z rwinston $
* @see org.apache.commons.net.ftp.FTPFileList
* @see org.apache.commons.net.ftp.FTPFileEntryParser
* @see org.apache.commons.net.ftp.FTPListParseEngine
* @deprecated This class is deprecated as of version 1.2 and will be
* removed in version 2.0 - use FTPFileParseEngine instead
*/
public class FTPFileIterator
{
/**
* a vector of strings, each representing a possibly valid ftp file
* entry
*/
private List rawlines;
/**
* the parser to which this iterator delegates its parsing duties
*/
private FTPFileEntryParser parser;
/**
* constant shorthand for the situation where the raw listing has not
* yet been scanned
*/
private static final int UNINIT = -1;
/**
* constant shorthand for the situation where the raw listing has been
* scanned and found to have no valid entry.
*/
private static final int DIREMPTY = -2;
/**
* this iterator's current position within <code>rawlines</code>.
*/
private int itemptr = 0;
/**
* number within <code>rawlines</code> of the first valid file entry.
*/
private int firstGoodEntry = UNINIT;
/**
* "Package-private" constructor. Only the FTPFileList can
* create an iterator, using it's iterator() method. The list
* will be iterated with the list's default parser.
*
* @param rawlist the FTPFileList to be iterated
*/
FTPFileIterator (FTPFileList rawlist)
{
this(rawlist, rawlist.getParser());
}
/**
* "Package-private" constructor. Only the FTPFileList can
* create an iterator, using it's iterator() method. The list will be
* iterated with a supplied parser
*
* @param rawlist the FTPFileList to be iterated
* @param parser the system specific parser for raw FTP entries.
*/
FTPFileIterator (FTPFileList rawlist,
FTPFileEntryParser parser)
{
this.rawlines = rawlist.getLines();
this.parser = parser;
}
/**
* Delegates to this object's parser member the job of parsing an
* entry.
*
* @param entry A string containing one entry, as determined by the
* parser's getNextEntry() method.
*
* @return an FTPFile object representing this entry or null if it can't be
* parsed as a file
*/
private FTPFile parseFTPEntry(String entry)
{
return this.parser.parseFTPEntry(entry);
}
/**
* Skips over any introductory lines and stuff in the listing that does
* not represent files, returning the line number of the first entry
* that does represent a file.
*
* @return the line number within <code>rawlines</code> of the first good
* entry in the array or DIREMPTY if there are no good entries.
*/
private int getFirstGoodEntry()
{
FTPFile entry = null;
for (int iter = 0; iter < this.rawlines.size(); iter++)
{
String line = (String) this.rawlines.get(iter);
entry = parseFTPEntry(line);
if (null != entry)
{
return iter;
}
}
return DIREMPTY;
}
/**
* resets iterator to the beginning of the list.
*/
private void init()
{
this.itemptr = 0;
this.firstGoodEntry = UNINIT;
}
/**
* shorthand for an empty return value.
*/
private static final FTPFile[] EMPTY = new FTPFile[0];
/**
* Returns a list of FTPFile objects for ALL files listed in the server's
* LIST output.
*
* @return a list of FTPFile objects for ALL files listed in the server's
* LIST output.
*/
public FTPFile[] getFiles()
{
if (this.itemptr != DIREMPTY)
{
init();
}
return getNext(0);
}
/**
* Returns an array of at most <code>quantityRequested</code> FTPFile
* objects starting at this iterator's current position within its
* associated list. If fewer than <code>quantityRequested</code> such
* elements are available, the returned array will have a length equal
* to the number of entries at and after after the current position.
* If no such entries are found, this array will have a length of 0.
*
* After this method is called the current position is advanced by
* either <code>quantityRequested</code> or the number of entries
* available after the iterator, whichever is fewer.
*
* @param quantityRequested
* the maximum number of entries we want to get. A 0
* passed here is a signal to get ALL the entries.
*
* @return an array of at most <code>quantityRequested</code> FTPFile
* objects starting at the current position of this iterator within its
* list and at least the number of elements which exist in the list at
* and after its current position.
*/
public FTPFile[] getNext(int quantityRequested)
{
// if we haven't gotten past the initial junk do so.
if (this.firstGoodEntry == UNINIT)
{
this.firstGoodEntry = getFirstGoodEntry();
}
if (this.firstGoodEntry == DIREMPTY)
{
return EMPTY;
}
int max = this.rawlines.size() - this.firstGoodEntry;
// now that we know the maximum we can possibly get,
// resolve a 0 request to ask for that many.
int howMany = (quantityRequested == 0) ? max : quantityRequested;
howMany = (howMany + this.itemptr < this.rawlines.size())
? howMany
: this.rawlines.size() - this.itemptr;
FTPFile[] output = new FTPFile[howMany];
for (int i = 0, e = this.firstGoodEntry + this.itemptr ;
i < howMany; i++, e++)
{
output[i] = parseFTPEntry((String) this.rawlines.get(e));
this.itemptr++;
}
return output;
}
/**
* Method for determining whether getNext() will successfully return a
* non-null value.
*
* @return true if there exist any files after the one currently pointed
* to by the internal iterator, false otherwise.
*/
public boolean hasNext()
{
int fge = this.firstGoodEntry;
if (fge == DIREMPTY)
{
//directory previously found empty - return false
return false;
}
else if (fge < 0)
{
// we haven't scanned the list yet so do it first
fge = getFirstGoodEntry();
}
return fge + this.itemptr < this.rawlines.size();
}
/**
* Returns a single parsed FTPFile object corresponding to the raw input
* line at this iterator's current position.
*
* After this method is called the internal iterator is advanced by one
* element (unless already at end of list).
*
* @return a single FTPFile object corresponding to the raw input line
* at the position of the internal iterator over the list of raw input
* lines maintained by this object or null if no such object exists.
*/
public FTPFile next()
{
FTPFile[] file = getNext(1);
if (file.length > 0)
{
return file[0];
}
else
{
return null;
}
}
/**
* Returns an array of at most <code>quantityRequested</code> FTPFile
* objects starting at the position preceding this iterator's current
* position within its associated list. If fewer than
* <code>quantityRequested</code> such elements are available, the
* returned array will have a length equal to the number of entries after
* the iterator. If no such entries are found, this array will have a
* length of 0. The entries will be ordered in the same order as the
* list, not reversed.
*
* After this method is called the current position is moved back by
* either <code>quantityRequested</code> or the number of entries
* available before the current position, whichever is fewer.
* @param quantityRequested the maximum number of entries we want to get.
* A 0 passed here is a signal to get ALL the entries.
* @return an array of at most <code>quantityRequested</code> FTPFile
* objects starting at the position preceding the current position of
* this iterator within its list and at least the number of elements which
* exist in the list prior to its current position.
*/
public FTPFile[] getPrevious(int quantityRequested)
{
int howMany = quantityRequested;
// can't retreat further than we've previously advanced
if (howMany > this.itemptr)
{
howMany = this.itemptr;
}
FTPFile[] output = new FTPFile[howMany];
for (int i = howMany, e = this.firstGoodEntry + this.itemptr; i > 0;)
{
output[--i] = parseFTPEntry((String) this.rawlines.get(--e));
this.itemptr--;
}
return output;
}
/**
* Method for determining whether getPrevious() will successfully return a
* non-null value.
*
* @return true if there exist any files before the one currently pointed
* to by the internal iterator, false otherwise.
*/
public boolean hasPrevious()
{
int fge = this.firstGoodEntry;
if (fge == DIREMPTY)
{
//directory previously found empty - return false
return false;
}
else if (fge < 0)
{
// we haven't scanned the list yet so do it first
fge = getFirstGoodEntry();
}
return this.itemptr > fge;
}
/**
* Returns a single parsed FTPFile object corresponding to the raw input
* line at the position preceding that of the internal iterator over
* the list of raw lines maintained by this object
*
* After this method is called the internal iterator is retreated by one
* element (unless it is already at beginning of list).
* @return a single FTPFile object corresponding to the raw input line
* at the position immediately preceding that of the internal iterator
* over the list of raw input lines maintained by this object.
*/
public FTPFile previous()
{
FTPFile[] file = getPrevious(1);
if (file.length > 0)
{
return file[0];
}
else
{
return null;
}
}
}
/* Emacs configuration
* Local variables: **
* mode: java **
* c-basic-offset: 4 **
* indent-tabs-mode: nil **
* End: **
*/
|