You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by sc...@apache.org on 2003/03/02 19:15:24 UTC

cvs commit: jakarta-commons/net/src/java/org/apache/commons/net/ftp FTPFileEntryParser.java FTPFileIterator.java FTPFileList.java FTPFileListParserImpl.java FTPClient.java

scohen      2003/03/02 10:15:24

  Modified:    net/src/java/org/apache/commons/net/ftp FTPClient.java
  Added:       net/src/java/org/apache/commons/net/ftp
                        FTPFileEntryParser.java FTPFileIterator.java
                        FTPFileList.java FTPFileListParserImpl.java
  Log:
  new parsing system formerly in ftp 2 directory, moving to main stem now.  This version provides a means of solving the problem of ftp entries that span more than one
  line.
  
  Revision  Changes    Path
  1.6       +84 -0     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.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- FTPClient.java	26 Jan 2003 00:21:43 -0000	1.5
  +++ FTPClient.java	2 Mar 2003 18:15:24 -0000	1.6
  @@ -2020,6 +2020,90 @@
           return listFiles(__fileListParser);
       }
   
  +    /**
  +     * Using a programmer specified <code> FTPFileEntryParser </code>, 
  +     * initialize an object containing a raw file information for the 
  +     * current working directory.  This information is obtained through 
  +     * the LIST command.  This object is then capable of being iterated to 
  +     * return a sequence of FTPFile objects with information filled in by the
  +     * <code> FTPFileEntryParser </code> used.
  +     * The server may or may not expand glob expressions.  You should avoid
  +     * using glob expressions because the return format for glob listings
  +     * differs from server to server and will likely cause this method to fail.
  +     * <p>
  +     * @param parser The <code> FTPFileEntryParser </code> that should be
  +     *         used to parse each server file listing.   
  +     * @return An iteratable object that holds the raw information and is 
  +     * capable of providing parsed FTPFile objects, one for each file containing
  +     * information contained in the given path in the format determined by the 
  +     * <code> parser </code> parameter.   Null will be returned if a 
  +     * data connection cannot be opened.  If the current working directory 
  +     * contains no files, an empty array will be the return.
  +     * @exception FTPConnectionClosedException
  +     *      If the FTP server prematurely closes the connection as a result
  +     *      of the client being idle or some other reason causing the server
  +     *      to send FTP reply code 421.  This exception may be caught either
  +     *      as an IOException or independently as itself.
  +     * @exception IOException  If an I/O error occurs while either sending a
  +     *      command to the server or receiving a reply from the server.
  +     * @see FTPFileList
  +     */
  +    public FTPFileList createFileList(FTPFileEntryParser parser)
  +    throws IOException
  +    {
  +        return createFileList(null, parser);
  +    }
  +
  +    /**
  +     * Using a programmer specified <code> FTPFileEntryParser </code>, 
  +     * initialize an object containing a raw file information for a directory 
  +     * or information for a single file.  This information is obtained through 
  +     * the LIST command.  This object is then capable of being iterated to 
  +     * return a sequence of FTPFile objects with information filled in by the
  +     * <code> FTPFileEntryParser </code> used.
  +     * The server may or may not expand glob expressions.  You should avoid
  +     * using glob expressions because the return format for glob listings
  +     * differs from server to server and will likely cause this method to fail.
  +     * <p>
  +     * @param parser The <code> FTPFileEntryParser </code> that should be
  +     *         used to parse each server file listing.   
  +     * @param pathname  The file or directory to list.
  +     * @return An iteratable object that holds the raw information and is 
  +     * capable of providing parsed FTPFile objects, one for each file containing
  +     * information contained in the given path in the format determined by the 
  +     * <code> parser </code> parameter.  Null will be returned if a 
  +     * data connection cannot be opened.  If the supplied path contains
  +     * no files, an empty array will be the return.
  +     * @exception FTPConnectionClosedException
  +     *      If the FTP server prematurely closes the connection as a result
  +     *      of the client being idle or some other reason causing the server
  +     *      to send FTP reply code 421.  This exception may be caught either
  +     *      as an IOException or independently as itself.
  +     * @exception IOException  If an I/O error occurs while either sending a
  +     *      command to the server or receiving a reply from the server.
  +     * @see FTPFileList
  +     */
  +    public FTPFileList createFileList(String pathname,
  +                                      FTPFileEntryParser parser)
  +    throws IOException
  +    {
  +        Socket socket;
  +        FTPFile[] results;
  +
  +        if ((socket = __openDataConnection(FTPCommand.LIST, pathname)) == null)
  +        {
  +            return null;
  +        }
  +
  +        FTPFileList list =
  +            FTPFileList.create(socket.getInputStream(), parser);
  +
  +        socket.close();
  +
  +        completePendingCommand();
  +
  +        return list;
  +    }
   
       /***
        * Issue the FTP STAT command to the server.
  
  
  
  1.1                  jakarta-commons/net/src/java/org/apache/commons/net/ftp/FTPFileEntryParser.java
  
  Index: FTPFileEntryParser.java
  ===================================================================
  package org.apache.commons.net.ftp;
  import java.io.BufferedReader;
  import java.io.IOException;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 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
   * <http://www.apache.org/>.
   */
  
  /**
   * FTPFileEntryParser defines the interface for parsing a single FTP file
   * listing and converting that information into an 
   * <a href="org.apache.commons.net.ftp.FTPFile.html"> FTPFile </a> instance.
   * Sometimes you will want to parse unusual listing formats, in which
   * case you would create your own implementation of FTPFileEntryParser and
   * if necessary, subclass FTPFile.
   *
   * @author <a href="mailto:stevecoh1@attbi.com">Steve Cohen</a>
   * @version $Id: FTPFileEntryParser.java,v 1.1 2003/03/02 18:15:24 scohen Exp $
   * @see org.apache.commons.net.ftp.FTPFile
   * @see FTPClient2#listFiles
   */
  public interface FTPFileEntryParser
  {
      /**
       * Parses a line of an FTP server file listing and converts it into a usable
       * format in the form of an <code> FTPFile </code> instance.  If the
       * file listing line doesn't describe a file, <code> null </code> should be
       * returned, otherwise a <code> FTPFile </code> instance representing the
       * files in the directory is returned.
       * <p>
       * @param listEntry A line of text from the file listing
       * @return An FTPFile instance corresponding to the supplied entry
       */
      public FTPFile parseFTPEntry(String listEntry);
  
      /**
       * Reads the next entry using the supplied BufferedReader object up to 
       * whatever delemits one entry from the next.  Implementors must define
       * this for the particular ftp system being parsed.  In many but not all 
       * cases, this can be defined simply by calling BufferedReader.readLine().
       * 
       * @param reader The BufferedReader object from which entries are to be read.
       * 
       * @return A string representing the next ftp entry or null if none found.
       * @exception IOException thrown on any IO Error reading from the reader.
       */
      public String readNextEntry(BufferedReader reader) throws IOException;
  }
  
  
  
  1.1                  jakarta-commons/net/src/java/org/apache/commons/net/ftp/FTPFileIterator.java
  
  Index: FTPFileIterator.java
  ===================================================================
  package org.apache.commons.net.ftp;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 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
   * <http://www.apache.org/>.
   */
  
  import java.util.Vector;
  
  /**
   * FTPFileIterator.java
   * 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:stevecoh1@attbi.com">Steve Cohen</a>
   * @version $Id: FTPFileIterator.java,v 1.1 2003/03/02 18:15:24 scohen Exp $
   * @see org.apache.commons.net.ftp.ftp2.FTPFileList
   */
  public class FTPFileIterator
  {
      private Vector rawlines;
      private FTPFileEntryParser parser;
  
      private static final int UNINIT = -1;
      private static final int DIREMPTY = -2;
      private int itemptr = 0;
      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;
      }
  
      private FTPFile parseFTPEntry(String entry)
      {
          return this.parser.parseFTPEntry(entry);
      }
  
      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;
      }
  
      private void init()
      {
          this.itemptr = 0;
          this.firstGoodEntry = UNINIT;
      }
  
      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.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 <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.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;
          }
      }
  }
  
  
  
  1.1                  jakarta-commons/net/src/java/org/apache/commons/net/ftp/FTPFileList.java
  
  Index: FTPFileList.java
  ===================================================================
  package org.apache.commons.net.ftp;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 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
   * <http://www.apache.org/>.
   */
  
  import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.util.Vector;
  
  /**
   * FTPFileList.java
   * 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 <code>(FTPClient.listFiles()</code> methods did, 
   * which required a bigger memory hit.
   *
   * @author <a href="mailto:stevecoh1@attbi.com">Steve Cohen</a>
   * @version $Id: FTPFileList.java,v 1.1 2003/03/02 18:15:24 scohen Exp $
   * @see FTPClient2#listFiles
   * @see FTPClient2#createFileList
   */
  public 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 <code>FTPFileEntryParser</code> 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 <code>FTPFileList</code> object.  Invokes
       * the private constructor and then reads the stream  supplied stream to
       * build the intermediate array of "lines" which will later be parsed
       * into <code>FTPFile</code> object.
       *
       * @param stream The input stream created by reading the socket on which 
       * the output of the LIST command was returned
       * @param parser the default <code>FTPFileEntryParser</code> to be used
       * by this object.  This may later be changed using the init() method.
       * 
       * @return the <code>FTPFileList</code> created, with an initialized
       * of unparsed lines of output.  Will be null if the listing cannot
       * be read from the stream.
       * @exception IOException
       *                   Thrown on any failure to read from the socket.
       */
      public static FTPFileList create( InputStream stream,
                                        FTPFileEntryParser parser)
              throws IOException
      {
          FTPFileList list = new FTPFileList(parser);
          list.readStream(stream);
          return list;
      } 
  
      /**
       * internal method for reading the input into the <code>lines</code> vector.
       * 
       * @param stream The socket stream on which the input will be read.
       * 
       * @exception IOException
       */
      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);
      }
      /**
       * 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 FTPFileIterator(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().getNext(0);
      }
  }
  
  
  
  1.1                  jakarta-commons/net/src/java/org/apache/commons/net/ftp/FTPFileListParserImpl.java
  
  Index: FTPFileListParserImpl.java
  ===================================================================
  package org.apache.commons.net.ftp;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 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
   * <http://www.apache.org/>.
   */
  
  import java.io.InputStream;
  import java.io.BufferedReader;
  import java.io.IOException;
  
  import org.apache.oro.text.regex.Pattern;
  import org.apache.oro.text.regex.MalformedPatternException;
  import org.apache.oro.text.regex.PatternMatcher;
  import org.apache.oro.text.regex.Perl5Matcher;
  import org.apache.oro.text.regex.Perl5Compiler;
  import org.apache.oro.text.regex.MatchResult;
  
  public abstract class FTPFileListParserImpl 
      implements FTPFileListParser, FTPFileEntryParser
  {
      private String prefix;
      private Pattern pattern = null;
      private PatternMatcher matcher = null;
      private MatchResult result = null;
      
      /**
       * The constructor for a MatchApparatus object.
       * 
       * @param regex  The regular expression with which this object is 
       * initialized.
       * 
       * @exception IllegalArgumentException
       * Thrown if the regular expression is unparseable.  Should not be seen in 
       * normal conditions.  It it is seen, this is a sign that a subclass has 
       * been created with a bad regular expression.   Since the parser must be 
       * created before use, this means that any bad parser subclasses created 
       * from this will bomb very quickly,  leading to easy detection.  
       */
      public FTPFileListParserImpl(String regex) 
      {
          try 
          {
              this.prefix = "[" + getClass().getName() + "] ";
              this.matcher = new Perl5Matcher();
              this.pattern = new Perl5Compiler().compile(regex);
          } 
          catch (MalformedPatternException e) 
          {
              throw new IllegalArgumentException (
                  "Unparseable regex supplied:  " + regex);
          }
      }
      
  
      /***
       * Parses an FTP server file listing and converts it into a usable format
       * in the form of an array of <code> FTPFile </code> instances.  If the
       * file list contains no files, <code> null </code> should be
       * returned, otherwise an array of <code> FTPFile </code> instances
       * representing the files in the directory is returned.
       * <p>
       * @param listStream The InputStream from which the file list should be
       *        read.
       * @return The list of file information contained in the given path.  null
       *     if the list could not be obtained or if there are no files in
       *     the directory.
       * @exception IOException  If an I/O error occurs reading the listStream.
       ***/
      public FTPFile[] parseFileList(InputStream listStream) throws IOException {
          FTPFileList ffl = FTPFileList.create(listStream, this);
          return ffl.getFiles();
  
      }
  
  
  
      /**
       * Convenience method delegates to the internal MatchResult's matches()
       * method.
       *
       * @param s the String to be matched
       * @return true if s matches this object's regular expression.
       */
      public boolean matches(String s)
      {
          this.result = null;
          if (matcher.matches(s.trim(), this.pattern))
          {
              this.result = matcher.getMatch();
          }
          return null != this.result;
      }
  
      /**
       * Convenience method delegates to the internal MatchResult's groups()
       * method.
       *
       * @return the number of groups() in the internal MatchResult.
       */
      public int getGroupCnt()
      {
          if (this.result == null)
          {
              return 0;
          }
          return this.result.groups();
      }
  
      /**
       * Convenience method delegates to the internal MatchResult's group()
       * method.  
       *
       * @return the content of the <code>matchnum'th<code> group of the internal
       * match or null if this method is called without a match having been made.
       */
      public String group(int matchnum)
      {
          if (this.result == null)
          {
              return null;
          }
          return this.result.group(matchnum);
      }
  
      /**
       * For debugging purposes - returns a string shows each match group by 
       * number.
       * 
       * @return a string shows each match group by number.
       */
      public String getGroupsAsString()
      {
          StringBuffer b = new StringBuffer();
          for (int i = 1; i <= this.result.groups(); i++)
          {
              b.append(i).append(") ").append(this.result.group(i))
                  .append(System.getProperty("line.separator"));
          }
          return b.toString();
  
      }
  
      /**
       * Reads the next entry using the supplied BufferedReader object up to
       * whatever delemits one entry from the next.  This default implementation
       * simply calls BufferedReader.readLine().
       *
       * @param reader The BufferedReader object from which entries are to be read.
       *
       * @return A string representing the next ftp entry or null if none found.
       * @exception IOException thrown on any IO Error reading from the reader.
       */
      public String readNextEntry(BufferedReader reader) throws IOException {
          return reader.readLine();
      }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org