Return-Path: Delivered-To: apmail-jakarta-commons-dev-archive@www.apache.org Received: (qmail 56735 invoked from network); 9 Jan 2004 09:07:11 -0000 Received: from daedalus.apache.org (HELO mail.apache.org) (208.185.179.12) by minotaur-2.apache.org with SMTP; 9 Jan 2004 09:07:11 -0000 Received: (qmail 59629 invoked by uid 500); 9 Jan 2004 09:06:40 -0000 Delivered-To: apmail-jakarta-commons-dev-archive@jakarta.apache.org Received: (qmail 59556 invoked by uid 500); 9 Jan 2004 09:06:39 -0000 Mailing-List: contact commons-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Jakarta Commons Developers List" Reply-To: "Jakarta Commons Developers List" Delivered-To: mailing list commons-dev@jakarta.apache.org Received: (qmail 59543 invoked by uid 500); 9 Jan 2004 09:06:39 -0000 Received: (qmail 59540 invoked from network); 9 Jan 2004 09:06:39 -0000 Received: from unknown (HELO minotaur.apache.org) (209.237.227.194) by daedalus.apache.org with SMTP; 9 Jan 2004 09:06:39 -0000 Received: (qmail 56673 invoked by uid 1170); 9 Jan 2004 09:07:03 -0000 Date: 9 Jan 2004 09:07:03 -0000 Message-ID: <20040109090703.56672.qmail@minotaur.apache.org> From: dfs@apache.org To: jakarta-commons-cvs@apache.org Subject: cvs commit: jakarta-commons/net/src/java/org/apache/commons/net/ftp/parser VMSFTPEntryParser.java X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N dfs 2004/01/09 01:07:03 Modified: net/src/java/org/apache/commons/net/ftp FTPClient.java FTPFileEntryParser.java FTPFileIterator.java FTPFileList.java FTPFileListParserImpl.java net/src/java/org/apache/commons/net/ftp/parser VMSFTPEntryParser.java Added: net/src/java/org/apache/commons/net/ftp DefaultFTPFileIterator.java DefaultFTPFileList.java Log: Made FTPFileList and FTPFileIterator abstract. Moved implementations into DefaultFTPFileList and DefaultFTPFileIterator. Added createFTPFileList method (the name is not fixed in stone and should probably change) in FTPFileEntryParser to take over role of FTPFilelist.create. These changes were made to allow customization of file list handling by entry parseres. Finally, changed VMSFTPEntryParser to return an FTPFileList that filters out duplicates. Revision Changes Path 1.25 +1 -1 jakarta-commons/net/src/java/org/apache/commons/net/ftp/FTPClient.java Index: FTPClient.java =================================================================== RCS file: /home/cvs/jakarta-commons/net/src/java/org/apache/commons/net/ftp/FTPClient.java,v retrieving revision 1.24 retrieving revision 1.25 diff -u -r1.24 -r1.25 --- FTPClient.java 6 Jan 2004 19:02:02 -0000 1.24 +++ FTPClient.java 9 Jan 2004 09:07:03 -0000 1.25 @@ -2334,7 +2334,7 @@ } FTPFileList list = - FTPFileList.create(socket.getInputStream(), parser); + parser.createFTPFileList(socket.getInputStream()); socket.close(); 1.12 +26 -1 jakarta-commons/net/src/java/org/apache/commons/net/ftp/FTPFileEntryParser.java Index: FTPFileEntryParser.java =================================================================== RCS file: /home/cvs/jakarta-commons/net/src/java/org/apache/commons/net/ftp/FTPFileEntryParser.java,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- FTPFileEntryParser.java 6 Jan 2004 22:24:24 -0000 1.11 +++ FTPFileEntryParser.java 9 Jan 2004 09:07:03 -0000 1.12 @@ -161,4 +161,29 @@ * @exception IOException thrown on any IO Error reading from the reader. */ String readNextEntry(BufferedReader reader) throws IOException; + + /** + * Creates an FTPFileList object from a stream containing + * a file listing. + * + * @param stream The input stream created by reading the socket on which + * the output of the LIST command was returned + * + * @return the FTPFileList created. + * Will be null if the listing cannot be read from the stream. + * @exception IOException + * Thrown on any failure to read from the stream. + */ + public FTPFileList createFTPFileList(InputStream stream) + throws IOException; + } + + +/* Emacs configuration + * Local variables: ** + * mode: java ** + * c-basic-offset: 4 ** + * indent-tabs-mode: nil ** + * End: ** + */ 1.7 +18 -225 jakarta-commons/net/src/java/org/apache/commons/net/ftp/FTPFileIterator.java Index: FTPFileIterator.java =================================================================== RCS file: /home/cvs/jakarta-commons/net/src/java/org/apache/commons/net/ftp/FTPFileIterator.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- FTPFileIterator.java 2 Jan 2004 03:39:04 -0000 1.6 +++ FTPFileIterator.java 9 Jan 2004 09:07:03 -0000 1.7 @@ -68,134 +68,16 @@ * @see org.apache.commons.net.ftp.FTPFileList * @see org.apache.commons.net.ftp.FTPFileEntryParser */ -public class FTPFileIterator +public abstract class FTPFileIterator { /** - * a vector of strings, each representing a possibly valid ftp file - * entry - */ - private Vector 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 rawlines. - */ - private int itemptr = 0; - - /** - * number within rawlines 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 rawlines 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.elementAt(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); - } + public abstract FTPFile[] getFiles(); /** * Returns an array of at most quantityRequested FTPFile @@ -218,40 +100,8 @@ * 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; + public abstract FTPFile[] getNext(int quantityRequested); - FTPFile[] output = new FTPFile[howMany]; - - for (int i = 0, e = this.firstGoodEntry + this.itemptr ; - i < howMany; i++, e++) - { - output[i] = parseFTPEntry((String) this.rawlines.elementAt(e)); - this.itemptr++; - - } - return output; - } /** * Method for determining whether getNext() will successfully return a @@ -260,21 +110,7 @@ * @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(); - } + public abstract boolean hasNext(); /** * Returns a single parsed FTPFile object corresponding to the raw input @@ -287,18 +123,7 @@ * 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; - } - } + public abstract FTPFile next(); /** * Returns an array of at most quantityRequested FTPFile @@ -320,22 +145,7 @@ * 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.elementAt(--e)); - this.itemptr--; - } - return output; - } + public abstract FTPFile[] getPrevious(int quantityRequested); /** * Method for determining whether getPrevious() will successfully return a @@ -344,22 +154,7 @@ * @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; - } + public abstract boolean hasPrevious(); /** * Returns a single parsed FTPFile object corresponding to the raw input @@ -372,16 +167,14 @@ * 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; - } - } + public abstract FTPFile previous(); } + + +/* Emacs configuration + * Local variables: ** + * mode: java ** + * c-basic-offset: 4 ** + * indent-tabs-mode: nil ** + * End: ** + */ 1.7 +18 -84 jakarta-commons/net/src/java/org/apache/commons/net/ftp/FTPFileList.java Index: FTPFileList.java =================================================================== RCS file: /home/cvs/jakarta-commons/net/src/java/org/apache/commons/net/ftp/FTPFileList.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- FTPFileList.java 2 Jan 2004 03:39:04 -0000 1.6 +++ FTPFileList.java 9 Jan 2004 09:07:03 -0000 1.7 @@ -81,35 +81,9 @@ * @see org.apache.commons.net.ftp.FTPFileIterator * @see org.apache.commons.net.ftp.FTPFileEntryParser */ -public class FTPFileList +public abstract class FTPFileList { /** - * storage for the raw lines of input read from the FTP server - */ - private Vector lines = null; - /** - * the FTPFileEntryParser assigned to be used with this lister - */ - private FTPFileEntryParser parser; - /** - * private status code for an empty directory - */ - private static final int EMPTY_DIR = -2; - - /** - * The only constructor for FTPFileList, private because - * construction only invoked at createFTPFileList() - * - * @param parser a FTPFileEntryParser value that knows - * how to parse the entries returned by a particular FTP site. - */ - private FTPFileList (FTPFileEntryParser parser) - { - this.parser = parser; - this.lines = new Vector(); - } - - /** * The only way to create an FTPFileList object. Invokes * the private constructor and then reads the stream supplied stream to * build the intermediate array of "lines" which will later be parsed @@ -125,69 +99,27 @@ * be read from the stream. * @exception IOException * Thrown on any failure to read from the socket. + * @deprecated This method is no longer used internally by the API + * and should not be called by API users. It will be removed in + * version 2.0. */ public static FTPFileList create(InputStream stream, FTPFileEntryParser parser) throws IOException { - FTPFileList list = new FTPFileList(parser); + DefaultFTPFileList list = new DefaultFTPFileList(parser); list.readStream(stream); return list; } /** - * internal method for reading the input into the lines vector. - * - * @param stream The socket stream on which the input will be read. - * - * @exception IOException thrown on any failure to read the stream - */ - private void readStream(InputStream stream) throws IOException - { - BufferedReader reader = - new BufferedReader(new InputStreamReader(stream)); - - String line = this.parser.readNextEntry(reader); - - while (line != null) - { - this.lines.addElement(line); - line = this.parser.readNextEntry(reader); - } - reader.close(); - } - - /** - * Accessor for this object's default parser. - * - * @return this object's default parser. - */ - FTPFileEntryParser getParser() - { - return this.parser; - } - - /** - * Package private accessor for the collection of raw input lines. - * - * @return vector containing all the raw input lines returned from the FTP - * server - */ - Vector getLines() - { - return this.lines; - } - - /** * create an iterator over this list using the parser with which this list * was initally created * * @return an iterator over this list using the list's default parser. */ - public FTPFileIterator iterator() - { - return new FTPFileIterator(this); - } + public abstract FTPFileIterator iterator(); + /** * create an iterator over this list using the supplied parser * @@ -196,10 +128,7 @@ * * @return an iterator over this list using the supplied parser. */ - public FTPFileIterator iterator(FTPFileEntryParser parser) - { - return new FTPFileIterator(this, parser); - } + public abstract FTPFileIterator iterator(FTPFileEntryParser parser); /** @@ -209,8 +138,13 @@ * @return an array of FTPFile objects for all the files in the directory * listinge */ - public FTPFile[] getFiles() - { - return iterator().getNext(0); - } + public abstract FTPFile[] getFiles(); } + +/* Emacs configuration + * Local variables: ** + * mode: java ** + * c-basic-offset: 4 ** + * indent-tabs-mode: nil ** + * End: ** + */ 1.6 +8 -1 jakarta-commons/net/src/java/org/apache/commons/net/ftp/FTPFileListParserImpl.java Index: FTPFileListParserImpl.java =================================================================== RCS file: /home/cvs/jakarta-commons/net/src/java/org/apache/commons/net/ftp/FTPFileListParserImpl.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- FTPFileListParserImpl.java 2 Jan 2004 03:39:04 -0000 1.5 +++ FTPFileListParserImpl.java 9 Jan 2004 09:07:03 -0000 1.6 @@ -137,11 +137,18 @@ ***/ public FTPFile[] parseFileList(InputStream listStream) throws IOException { - FTPFileList ffl = FTPFileList.create(listStream, this); + FTPFileList ffl = createFTPFileList(listStream); return ffl.getFiles(); } + public FTPFileList createFTPFileList(InputStream stream) + throws IOException + { + DefaultFTPFileList list = new DefaultFTPFileList(this); + list.readStream(stream); + return list; + } /** 1.1 jakarta-commons/net/src/java/org/apache/commons/net/ftp/DefaultFTPFileIterator.java Index: DefaultFTPFileIterator.java =================================================================== package org.apache.commons.net.ftp; /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001-2004 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache Commons" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ import java.util.Vector; /** * 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 Steve Cohen * @version $Id: DefaultFTPFileIterator.java,v 1.1 2004/01/09 09:07:03 dfs Exp $ * @see org.apache.commons.net.ftp.FTPFileList * @see org.apache.commons.net.ftp.FTPFileEntryParser */ class DefaultFTPFileIterator extends FTPFileIterator { /** * a vector of strings, each representing a possibly valid ftp file * entry */ private Vector 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 rawlines. */ private int itemptr = 0; /** * number within rawlines 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 */ DefaultFTPFileIterator (DefaultFTPFileList 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. */ DefaultFTPFileIterator (DefaultFTPFileList 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 rawlines 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.elementAt(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 quantityRequested FTPFile * objects starting at this iterator's current position within its * associated list. If fewer than quantityRequested 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 quantityRequested 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 quantityRequested 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.elementAt(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 quantityRequested FTPFile * objects starting at the position preceding this iterator's current * position within its associated list. If fewer than * quantityRequested 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 quantityRequested 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 quantityRequested 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.elementAt(--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: ** */ 1.1 jakarta-commons/net/src/java/org/apache/commons/net/ftp/DefaultFTPFileList.java Index: DefaultFTPFileList.java =================================================================== package org.apache.commons.net.ftp; /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001-2004 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache Commons" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Vector; /** * This class encapsulates a listing of files from an FTP server. It is * initialized with an input stream which is read and the input split into * lines, each of which (after some possible initial verbiage) represents * a file on the FTP server. A parser is also supplied, which is used to * iterate through the internal list of lines parsing each into an FTPFile * object which is returned to the caller of the iteration methods. This * parser may be replaced with another, allowing the same list to be parsed * with different parsers. * Parsing takes place on an as-needed basis, basically, the first time a * position is iterated over. This happens at the time of iteration, not * prior to it as the older (FTPClient.listFiles() methods did, * which required a bigger memory hit. * * @author Steve Cohen * @version $Id: DefaultFTPFileList.java,v 1.1 2004/01/09 09:07:03 dfs Exp $ * @see org.apache.commons.net.ftp.FTPClient#createFileList * @see org.apache.commons.net.ftp.FTPFileIterator * @see org.apache.commons.net.ftp.FTPFileEntryParser */ public class DefaultFTPFileList extends FTPFileList { /** * storage for the raw lines of input read from the FTP server */ private Vector lines = null; /** * the FTPFileEntryParser assigned to be used with this lister */ private FTPFileEntryParser parser; /** * private status code for an empty directory */ private static final int EMPTY_DIR = -2; /** * @param parser a FTPFileEntryParser value that knows * how to parse the entries returned by a particular FTP site. */ public DefaultFTPFileList (FTPFileEntryParser parser) { this.parser = parser; this.lines = new Vector(); } /** * internal method for reading the input into the lines vector. * * @param stream The socket stream on which the input will be read. * * @exception IOException thrown on any failure to read the stream */ public void readStream(InputStream stream) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); String line = this.parser.readNextEntry(reader); while (line != null) { this.lines.addElement(line); line = this.parser.readNextEntry(reader); } reader.close(); } /** * Accessor for this object's default parser. * * @return this object's default parser. */ FTPFileEntryParser getParser() { return this.parser; } /** * Package private accessor for the collection of raw input lines. * * @return vector containing all the raw input lines returned from the FTP * server */ Vector getLines() { return this.lines; } /** * create an iterator over this list using the parser with which this list * was initally created * * @return an iterator over this list using the list's default parser. */ public FTPFileIterator iterator() { return new DefaultFTPFileIterator(this); } /** * create an iterator over this list using the supplied parser * * @param parser The user-supplied parser with which the list is to be * iterated, may be different from this list's default parser. * * @return an iterator over this list using the supplied parser. */ public FTPFileIterator iterator(FTPFileEntryParser parser) { return new DefaultFTPFileIterator(this, parser); } /** * returns an array of FTPFile objects for all the files in the directory * listing * * @return an array of FTPFile objects for all the files in the directory * listinge */ public FTPFile[] getFiles() { return iterator().getFiles(); } } /* Emacs configuration * Local variables: ** * mode: java ** * c-basic-offset: 4 ** * indent-tabs-mode: nil ** * End: ** */ 1.12 +151 -27 jakarta-commons/net/src/java/org/apache/commons/net/ftp/parser/VMSFTPEntryParser.java Index: VMSFTPEntryParser.java =================================================================== RCS file: /home/cvs/jakarta-commons/net/src/java/org/apache/commons/net/ftp/parser/VMSFTPEntryParser.java,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- VMSFTPEntryParser.java 5 Jan 2004 23:56:49 -0000 1.11 +++ VMSFTPEntryParser.java 9 Jan 2004 09:07:03 -0000 1.12 @@ -70,6 +70,9 @@ import org.apache.oro.text.regex.MalformedPatternException; import org.apache.commons.net.ftp.FTPFile; +import org.apache.commons.net.ftp.FTPFileIterator; +import org.apache.commons.net.ftp.FTPFileList; +import org.apache.commons.net.ftp.DefaultFTPFileList; import org.apache.commons.net.ftp.FTPFileListParserImpl; /** @@ -90,6 +93,133 @@ */ public class VMSFTPEntryParser extends FTPFileListParserImpl { + private static class DuplicateFilteringFileIterator extends FTPFileIterator + { + FTPFile[] files; + int current; + + public DuplicateFilteringFileIterator(FTPFileIterator iterator) { + FTPFile[] tempFiles = iterator.getFiles(); + Hashtable filesHash = new Hashtable(); + String fileName; + + + for (int index = 0; index < tempFiles.length; index++) { + fileName = tempFiles[index].getName(); + + if (!filesHash.containsKey(fileName)) { + filesHash.put(fileName, (FTPFile) tempFiles[index]); + } + } + + files = new FTPFile[filesHash.size()]; + + Enumeration e = filesHash.keys(); + int index = 0; + + while (e.hasMoreElements()) { + FTPFile ftpf = (FTPFile) filesHash.get(e.nextElement()); + files[index++] = ftpf; + } + + current = 0; + } + + public FTPFile[] getFiles() { + FTPFile[] result = new FTPFile[files.length]; + System.arraycopy(files, 0, result, 0, result.length); + return result; + } + + public FTPFile[] getNext(int quantityRequested) { + FTPFile[] result; + int remaining; + + remaining = files.length - current; + + if(quantityRequested > remaining) + quantityRequested = remaining; + else if(quantityRequested < 0) + quantityRequested = 0; + else if(quantityRequested == 0) { + // interpret a 0 as meaning all remaining items. + // ask Steve if this is what he intended. + quantityRequested = remaining; + } + + result = new FTPFile[quantityRequested]; + System.arraycopy(files, current, result, 0, result.length); + current+=quantityRequested; + + return result; + } + + public boolean hasNext() { + return (current < files.length && files.length > 0); + } + + public FTPFile next() { + FTPFile result = null; + + if(hasNext()) { + result = files[current]; + ++current; + } + + return result; + } + + public FTPFile[] getPrevious(int quantityRequested) { + FTPFile[] result; + int start = 0; + + if(quantityRequested > current) + quantityRequested = current; + else if(quantityRequested < 0) + quantityRequested = 0; + else if(quantityRequested == 0) { + // interpret a 0 as meaning all items between 0 and current. + // ask Steve if this is what he intended. + quantityRequested = current; + } else + start = current - quantityRequested; + + result = new FTPFile[quantityRequested]; + System.arraycopy(files, start, result, 0, result.length); + current = start; + + return result; + } + + public boolean hasPrevious() { + return (current > 0 && files.length > 0); + } + + public FTPFile previous() { + FTPFile result = null; + + if(hasPrevious()) { + --current; + result = files[current]; + } + + return result; + } + } + + + private class DuplicateFilteringFileList extends DefaultFTPFileList { + + public DuplicateFilteringFileList() { + super(VMSFTPEntryParser.this); + } + + public FTPFileIterator iterator() { + return new DuplicateFilteringFileIterator(super.iterator()); + } + } + + /** * settable option of whether or not to include versioning information * with the file list. @@ -181,9 +311,17 @@ * @exception IOException If an I/O error occurs reading the listStream. ***/ public FTPFile[] parseFileList(InputStream listStream) throws IOException { - BufferedReader reader = new BufferedReader(new InputStreamReader(listStream)); + return createFTPFileList(listStream).getFiles(); + } + + + public FTPFileList createFTPFileList(InputStream listStream) + throws IOException + { + FTPFileList list; + BufferedReader reader = + new BufferedReader(new InputStreamReader(listStream)); String listing = null; - FTPFile[] files; String line = reader.readLine(); while (line != null) { @@ -205,31 +343,17 @@ byte[] bytes = listing.getBytes(); ByteArrayInputStream listingStream = new ByteArrayInputStream(bytes); - - if (versioning) { - files = super.parseFileList(listingStream); - } else { - FTPFile[] tempFiles = super.parseFileList(listingStream); - Hashtable filesHash = new Hashtable(); - String fileName; - - for (int index = 0; index < tempFiles.length; index++) { - fileName = tempFiles[index].getName(); - if (!filesHash.containsKey(fileName)) { - filesHash.put(fileName, (FTPFile) tempFiles[index]); - } - } - files = new FTPFile[filesHash.size()]; - Enumeration e = filesHash.keys(); - int index = 0; - while (e.hasMoreElements()) { - FTPFile ftpf = (FTPFile) filesHash.get(e.nextElement()); - files[index++] = ftpf; - } - + + if(versioning) + list = super.createFTPFileList(listingStream); + else { + DefaultFTPFileList dlist; + dlist = new DuplicateFilteringFileList(); + dlist.readStream(listingStream); + list = dlist; } - - return files; + + return list; } --------------------------------------------------------------------- To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org For additional commands, e-mail: commons-dev-help@jakarta.apache.org