commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bre...@apache.org
Subject cvs commit: jakarta-commons-sandbox/net/xdocs tasks.xml
Date Mon, 29 Apr 2002 03:55:32 GMT
brekke      02/04/28 20:55:32

  Modified:    net      project.xml
               net/src/java/org/apache/commons/net/ftp FTPClient.java
               net/xdocs tasks.xml
  Added:       net/src/java/org/apache/commons/net/ftp/ftp2 FTPClient2.java
                        FTPFileEntryParser.java FTPFileIterator.java
                        FTPFileList.java
               net/src/java/org/apache/commons/net/ftp/ftp2/parser
                        MatchApparatus.java NTFTPEntryParser.java
                        OS2FTPEntryParser.java UnixFTPEntryParser.java
                        VMSFTPEntryParser.java
               net/src/test/org/apache/commons/net/ftp/ftp2/parser
                        FTPParseTestFramework.java
                        NTFTPEntryParserTest.java
                        OS2FTPEntryParserTest.java
                        UnixFTPEntryParserTest.java
                        VMSFTPEntryParserTest.java
  Log:
  Patch/Description provided by Steve Cohen:
  
  This code implements Daniel's suggested for a Parser implementation that
  is less wasteful of memory since it saves only the original listing and
  creates more expensive FTPFile instances on an as needed basis only.  It
  supports paged and single file iteration through the list using iterator-like
  hasNext() - next() syntax.  The next() methods can return either one or
  many entries.  Iteration is bidirectional.  There are hasPrevious() and
  previous() methods as well.  It should be possible, using this system to
  create attractive, efficient, paged GUI displays of FTP directories.
  
  It also features a revised version of Daniel's DefaultFTPFileLister that
  uses regular expressions, as well as revised versions of Winston Ojeda's
  VMS, OS2, and NT parsers that make more use of regular expressions and
  in some cases, recover more information than the originals did.  However
  these implementations were skeletal and they are still not complete.  I think
  they are also rather old and I would be highly surprised if OS2 and NT
  FTP servers have not been released in a Y2K compliant way in the past couple
  of years.  Someone more experienced with these systems should have a look
  at these parsers and see if they can't be improved.  I'm quite sure they can.
  
  My design of this subsystem decouples the parsing aspect from the listing
  aspect.  A single file ENTRY is parsed, not a LIST of files.
  
  In order to achieve this design, a new interface, FTPFileEntryParser, has
  been created to be used in place of FTPFileListParser.  The listing portion
  is handled by a new FTPFileList class and the iterative aspect has been
  encapsulated in an FTPFileIterator class.
  
  I had a hard time in designing these enhancements, deciding how to lay out
  the classes.  Support for the new file listing mechanism would require
  massive changes to FTPClient.  I was very leery of making these because it
  seemed to me that this would add large doses of confusion to the system, and
  might well lead to it not being accepted by the community.  This is especially
  so at this time, when the community process for NetComponents is very much
  up in the air.
  
  Accordingly I decided to make NO changes to FTPClient, and instead to place the
  new code in a class DERIVED from FTPClient to keep the two systems separable in
  the minds of users, which would help the emerging NetComponents community decide
  whether and how to best incorporate the new ideas.  I almost succeeded in this
  goal - I did have to make the __openDataConnection() method of FTPClient
  protected instead of private in order to use it with the new derived class.
  
  In line with keeping the experimental part of this revision as separate as possible,
  all of my new code except the change to FTPClient is furthermore placed in
  a new package com.oroinc.net.ftp.ftp2.  This will probably not be its
  final home, but it will do for now, again to help the community evaluate
  these changes.
  
  As mentioned above, I have incorporated into this version revised versions
  of Winston Ojeda's replacement parsers, which work with the FTPFileEntryParser.
  These derive from a helper class that encapsulates the Regular Expression
  code in one place, making more possible replacement by a different regex
  engine sometime in the future, if desired, although the present one seems
  quite good enough.  I also took the liberty of removing the main() functions
  in Winston's code for testing and included a JUnit testing apparatus that
  is reachable from ant.
  
  Revision  Changes    Path
  1.6       +22 -2     jakarta-commons-sandbox/net/project.xml
  
  Index: project.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/net/project.xml,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- project.xml	27 Apr 2002 17:33:25 -0000	1.5
  +++ project.xml	29 Apr 2002 03:55:31 -0000	1.6
  @@ -58,14 +58,34 @@
         <organization>Quad/Graphics, Inc.</organization>
       </developer>
       <developer>
  +      <name>Steve Cohen</name>
  +      <id></id>
  +      <email>stevecoh1@attbi.com</email>
  +      <organization></organization>
  +    </developer>
  +    <developer>
  +      <name>Winston Ojeda</name>
  +      <id></id>
  +      <email>Winston.Ojeda@qg.com</email>
  +      <organization>Quad/Graphics, Inc.</organization>
  +    </developer>
  +    <developer>
         <name>Daniel F. Savarese</name>
         <id>savarese</id>
         <email>savarese@apache.org</email>
         <organization>savarese.org</organization>
       </developer>
     </developers>
  -  
  -  <dependencies/>
  +
  +  <dependencies>  
  +    <dependency>
  +      <name>jakarta-oro</name>
  +      <type>required</type>
  +      <version>2.0.6</version>
  +      <jar>jakarta-oro-2.0.6.jar</jar>
  +      <url>http://jakarta.apache.org/oro/</url>
  +    </dependency>
  +  </dependencies>
     
     <build>
     
  
  
  
  1.3       +1 -1      jakarta-commons-sandbox/net/src/java/org/apache/commons/net/ftp/FTPClient.java
  
  Index: FTPClient.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/net/src/java/org/apache/commons/net/ftp/FTPClient.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- FTPClient.java	12 Apr 2002 04:42:46 -0000	1.2
  +++ FTPClient.java	29 Apr 2002 03:55:31 -0000	1.3
  @@ -337,7 +337,7 @@
   
   
       // null arg if no arg
  -    private Socket __openDataConnection(int command, String arg)
  +    protected Socket __openDataConnection(int command, String arg)
       throws IOException
       {
           Socket socket;
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/net/ftp/ftp2/FTPClient2.java
  
  Index: FTPClient2.java
  ===================================================================
  package org.apache.commons.net.ftp.ftp2;
  
  /* ====================================================================
   * 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",
   *    "Apache Turbine", 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.IOException;
  import java.net.Socket;
  import org.apache.commons.net.ftp.FTPClient;
  import org.apache.commons.net.ftp.FTPCommand;
  import org.apache.commons.net.ftp.FTPFile;
  import org.apache.commons.net.ftp.ftp2.FTPFileEntryParser;
  import org.apache.commons.net.ftp.ftp2.parser.UnixFTPEntryParser;
  
  /**
   * FTPClient2.java
   * This class is derived by design from Daniel Savarese's FTPClient.
   * It is designed to have all the same functionality, but add support 
   * for a new alternative design for File List Parsing.  There is no reason 
   * why this  could not have been included in FTPClient, but it is a fairly 
   * sizable chunk  of code and given that the community process for this 
   * project is still  a work in progress I thought it would be better to keep a
   * fairly  clear line between the old and the new; it's less confusing that 
   * way.
   *
   * @author <a href="mailto:stevecoh1@attbi.com">Steve Cohen</a>
   * @version $Id: FTPClient2.java,v 1.1 2002/04/29 03:55:31 brekke Exp $
   */
  public class FTPClient2 extends FTPClient
  {
      private FTPFileEntryParser __fileEntryParser;
      public FTPClient2()
      {
          super();
          __fileEntryParser = new UnixFTPEntryParser();
      }
      
      /**
       * Using a programmer specified <code> FTPFileEntryParser </code>, obtain a 
       * list of file information for a directory or information for
       * just a single file.  This information is obtained through the LIST
       * command.  The contents of the returned array is determined 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 the server file listing.   
       * @param pathname  The file or directory to list.
       * @return The list of file information contained in the given path in
       *         the format determined by the <code> parser </code> parameter.
       * @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.
       */
      public FTPFile[] listFiles(FTPFileEntryParser parser, String pathname)
      throws IOException
      {
          FTPFileList lister = createFileList(pathname, parser);
          FTPFile[] list = lister.getFiles();
          return list;
      }
  
      /**
       * Using the <code> DefaultFTPFileListEntryParser </code>, obtain a list of
       * file information
       * for a directory or information for just a single file.  This information
       * is obtained through the LIST command.  If the given
       * pathname is a directory and contains no files, <code> null </code> is
       * returned, otherwise an array of <code> FTPFile </code> instances
       * representing the files in the directory is returned.
       * If the pathname corresponds to a file, only the information for that
       * file will be contained in the array (which will be of length 1).  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 pathname  The file or directory to list.
       * @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 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.
       */
      public FTPFile[] listFiles(String pathname) throws IOException
      {
          return listFiles(__fileEntryParser, pathname);
      }
      
      /**
       * Using the <code> DefaultFTPFileEntryParser </code>, obtain a list of 
       * file information for the current working directory.  This information
       * is obtained through the LIST command.  If the given
       * current directory contains no files null is returned, otherwise an 
       * array of <code> FTPFile </code> instances representing the files in the
       * directory is returned.
       * <p>
       * @return The list of file information contained in the current working
       *     directory.  null if the list could not be obtained or if there are
       *     no files in the directory.
       * @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.
       */
      public FTPFile[] listFiles() throws IOException
      {
          return listFiles(__fileEntryParser, null);
      }
  
      /**
       * Using the default <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 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 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() throws IOException
      {
          return createFileList(null, this.__fileEntryParser);
      }
  
      /**
       * Using the default <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 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 basedir) throws IOException
      {
          return createFileList(basedir, this.__fileEntryParser);
      }
  
      /**
       * 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;
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/net/ftp/ftp2/FTPFileEntryParser.java
  
  Index: FTPFileEntryParser.java
  ===================================================================
  package org.apache.commons.net.ftp.ftp2;
  
  /* ====================================================================
   * 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",
   *    "Apache Turbine", 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 org.apache.commons.net.ftp.FTPFile;
  
  /**
   * 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 2002/04/29 03:55:31 brekke 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);
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/net/ftp/ftp2/FTPFileIterator.java
  
  Index: FTPFileIterator.java
  ===================================================================
  package org.apache.commons.net.ftp.ftp2;
  
  /* ====================================================================
   * 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",
   *    "Apache Turbine", 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 org.apache.commons.net.ftp.FTPFile;
  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 2002/04/29 03:55:31 brekke 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>howMany</code> FTPFile objects
       * starting at this iterator's current position  within its associated
       * list. If fewer than <code>howMany</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>howMany</code> or the number of entries available after the
       * iterator, whichever is fewer.
       * @param howMany 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>howMany</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 howMany)
      {
  
          // 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 = (howMany == 0) ? max : howMany;
          _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>howMany</code> FTPFile objects
       * starting at the position preceding this iterator's current position
       * within its associated list. If fewer than <code>howMany</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>howMany</code> or the number of entries available before the
       * current position, whichever is fewer.
       * @param howMany 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>howMany</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 howMany)
      {
          int _howMany = howMany;
          // can't retreat further than we've come.
          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-sandbox/net/src/java/org/apache/commons/net/ftp/ftp2/FTPFileList.java
  
  Index: FTPFileList.java
  ===================================================================
  package org.apache.commons.net.ftp.ftp2;
  
  /* ====================================================================
   * 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",
   *    "Apache Turbine", 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.Enumeration;
  import java.util.Vector;
  import org.apache.commons.net.ftp.FTPFile;
  import org.apache.commons.net.ftp.ftp2.FTPFileEntryParser;
  
  /**
   * 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 2002/04/29 03:55:32 brekke Exp $
   * @see FTPClient2#listFiles
   * @see FTPClient2#createFileList
   */
  public class FTPFileList
  {
      private Vector lines = null;
      private FTPFileEntryParser parser;
      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.
       * @param sleepInterval - amount of time in milliseconds to sleep
       *                        between lines read.
       * @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.
       */
      public static FTPFileList create( InputStream stream,
                                        FTPFileEntryParser parser)
      {
          try
          {
              FTPFileList list = new FTPFileList(parser);
              list.readStream(stream);
              return list;
  
          }
          catch (IOException e)
          {
              System.out.println("IOException " + e.getMessage());
              return null;
          }
      }
  
      private void readStream(InputStream stream) throws IOException
      {
          BufferedReader reader =
              new BufferedReader(new InputStreamReader(stream));
  
          String line = reader.readLine();
  
          while (line != null)
          {
              this.lines.addElement(line);
              line = reader.readLine();
          }
          reader.close();
      }
  
      FTPFileEntryParser getParser()
      {
          return this.parser;
      }
  
      Vector getLines()
      {
          return this.lines;
      }
  
      public FTPFileIterator iterator()
      {
          return new FTPFileIterator(this);
      }
      public FTPFileIterator iterator(FTPFileEntryParser parser)
      {
          return new FTPFileIterator(this, parser);
      }
  
      private FTPFile parseFTPEntry(String entry)
      {
          return this.parser.parseFTPEntry(entry);
      }
  
      /**
       * 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-sandbox/net/src/java/org/apache/commons/net/ftp/ftp2/parser/MatchApparatus.java
  
  Index: MatchApparatus.java
  ===================================================================
  package org.apache.commons.net.ftp.ftp2.parser;
  
  /* ====================================================================
   * 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",
   *    "Apache Turbine", 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 org.apache.oro.text.regex.Pattern;
  import org.apache.oro.text.regex.Perl5Matcher;
  import org.apache.oro.text.regex.Perl5Compiler;
  import org.apache.oro.text.regex.MatchResult;
  import org.apache.commons.net.ftp.FTPFileListParser;
  import org.apache.commons.net.ftp.FTPFile;
  
  /**
   * This class is based on the logic of Winston Ojeda's ListParser.  It uses
   * a similar approach to Regular Expressions but is designed to fit within
   * FTPFileEntryParser design rather than the FTPFileListParser design.
   * It is also designed to encapsulate access to the oro.text.regex
   * classes in one place.
   * @author <a href="mailto:scohen@ignitesports.com">Steve Cohen</a>
   * @version $Id: MatchApparatus.java,v 1.1 2002/04/29 03:55:32 brekke Exp $
   */
  abstract class MatchApparatus
  {
      MatchApparatus()
      {
          this.prefix = "[" + getClass().getName() + "] ";
      }
  
      private String prefix;
      private boolean initialized = false;
      private Perl5Compiler compiler = null;
      private Pattern pattern = null;
      private Perl5Matcher matcher = null;
      private MatchResult result = null;
  
      private void initialize()
      {
          if (!initialized)
          {
              compiler = new Perl5Compiler();
              matcher = new Perl5Matcher();
              String regex = getRegEx();
              try
              {
                  pattern = compiler.compile(regex);
                  initialized = true;
              }
              catch (Exception e)
              {
                  System.out.println(prefix +
                                     "Unable to compile regular expression: [" + regex + "]" );
              }
          }
      }
  
      /**
       * 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)
      {
          initialize();
          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);
      }
  
  
      /**
       * Each derived class must define this function so that it returns a 
       * properly formatted regular expression string which will be used to do
       * the pattern matching.
       *
       * @return the string to be used to build the regular expression pattern
       * for matching
       */
      protected abstract String getRegEx();
  
  
      /**
       * For debugging purposes - shows each match group by number.
       */
      public void showGroups()
      {
          for (int i = 1; i <= this.result.groups(); i++)
          {
              System.out.println("" + i + ") " + this.result.group(i));
          }
  
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/net/ftp/ftp2/parser/NTFTPEntryParser.java
  
  Index: NTFTPEntryParser.java
  ===================================================================
  package org.apache.commons.net.ftp.ftp2.parser;
  
  /* ====================================================================
   * 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",
   *    "Apache Turbine", 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.Calendar;
  import org.apache.commons.net.ftp.FTPFile;
  import org.apache.commons.net.ftp.ftp2.FTPFileEntryParser;
  
  /**
   * This Class uses the ListParser class to validate the input string.
   * It also requires the NetComponents library version 1.3.7 or later
   * and the OROMatcher library for the regualar expressions stuff.
   *
   *
   * <P><B>USAGE:</B></P>
   * <LI>Create an instance of NTListParser</LI>
   *   <dd>NTListParser parser = new NTListParser();
   * <LI>Create an instance of FTPClient</LI>
   *   <dd>FTPClient FTPClientObj = new FTPClient();
   * <LI>Connect to the NODE </LI>
   *   <dd>FTPClientObj.connect();
   * <LI>Login to the NODE </LI>
   *   <dd>FTPClientObj.login(username,password);
   * <LI>Switch directories if you have to</LI>
   *   <dd>FTPClientObj.changeWorkingDirectory(thePath);
   * <LI>You might want to check if you are truly in a NT System</LI>
   *   <dd><B>String am_I_NT =  FTPClientObj.getSystemName()</B>
   *    <dd>parse am_I_NT to find out
   * <LI>Call listFiles passing the newly created parser and a filename or a mask to look for </LI>
   *   <dd>FTPClientObj.listFiles(parser,filename);
   * <LI>You'll get back the list as an array of FTPFiles like this
   *   <dd>FTPFile[] myNTFiles = FTPClientObj.listFiles(parser,filename);  (or)
   *    <dd>FTPFile[] myNTFiles = FTPClientObj.listFiles(parser);
   * <P>
   * That's all there is to it.
   * <P>
   * Each FTPFile object is populated just like any other FTPFile
   * object. The only thing not implemented at this time is the file
   * permissions, but I can do it if there is a real need for it.
   * <P>
   * !NOTE/WARNING!:Before you pass the parser to listFiles, make sure you are in the
   * directory that you need to be. This parser will return the filtered
   * files from the directory it is in. This becomes crucial specialy if your
   * goal is to delete the output of the parser.
   * <P>
   *
   * @author  <a href="Winston.Ojeda@qg.com">Winston Ojeda</a>
   * @author <a href="mailto:stevecoh1@attbi.com">Steve Cohen</a>
   * @version $Id: NTFTPEntryParser.java,v 1.1 2002/04/29 03:55:32 brekke Exp $
   * @see org.apache.commons.net.ftp.FTPFileListParser
   */
  public class NTFTPEntryParser
              extends MatchApparatus implements FTPFileEntryParser
  {
      private static final String regEx =
          "((?:0[1-9])|(?:1[0-2]))-" +
          "((?:0[1-9])|(?:[1-2]\\d)|(?:3[0-1]))-" +
          "(\\d\\d)\\s*" +
          "((?:0[1-9])|(?:1[012])):" +
          "([0-5]\\d)\\s*" +
          "([AP])M\\s*" +
          "(<DIR>\\s*)?" +
          "([0-9]+)?\\s*" +
          "(\\S.*)";
  
      protected String getRegEx()
      {
          return (regEx);
      }
  
      public FTPFile parseFTPEntry(String entry)
      {
          FTPFile f = new FTPFile();
          f.setRawListing(entry);
          int type;
          boolean isDevice = false;
  
          if (matches(entry))
          {
              String mo = group(1);
              String da = group(2);
              String yr = group(3);
              String hr = group(4);
              String min = group(5);
              String ampm = group(6);
              String dirString = group(7);
              String size = group(8);
              String name = group(9);
              if (null == name || name.equals(".") || name.equals(".."))
              {
                  return (null);
              }
              f.setName(name);
              //convert all the calendar stuff to ints
              int month = new Integer(mo).intValue();
              int day = new Integer(da).intValue();
              int year = new Integer(yr).intValue() + 2000;
              int hour = new Integer(hr).intValue();
              int minutes = new Integer(min).intValue();
  
              // Y2K stuff? this will break again in 2080 but I will
              // be sooooo dead anyways who cares.
              // SMC - IS NT's directory date REALLY still not Y2K-compliant?
              if (year > 2080)
                  year -= 100;
  
              Calendar cal = Calendar.getInstance();
              //set the calendar
              cal.set(Calendar.SECOND, 0);
              cal.set(Calendar.MINUTE, minutes);
              cal.set(Calendar.HOUR, hour);
              cal.set(Calendar.YEAR, year);
              cal.set(Calendar.DATE, day);
              cal.set(Calendar.MONTH, month);
              int ap = Calendar.AM;
              if ("P".equals(ampm))
              {
                  ap = Calendar.PM;
              }
              cal.set(Calendar.AM_PM, ap);
              f.setTimestamp(cal);
  
              if ("<DIR>".equals(dirString))
              {
                  f.setType(FTPFile.DIRECTORY_TYPE);
                  f.setSize(0);
              }
              else
              {
                  f.setType(FTPFile.FILE_TYPE);
                  if (null != size)
                  {
                      f.setSize(new Integer(size).intValue());
                  }
              }
              return (f);
          }
          return null;
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/net/ftp/ftp2/parser/OS2FTPEntryParser.java
  
  Index: OS2FTPEntryParser.java
  ===================================================================
  package org.apache.commons.net.ftp.ftp2.parser;
  
  /* ====================================================================
   * 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",
   *    "Apache Turbine", 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.Calendar;
  import org.apache.commons.net.ftp.FTPFile;
  import org.apache.commons.net.ftp.ftp2.FTPFileEntryParser;
  
  /**
   * This Class uses the ListParser class to validate the input string.
   * It also requires the NetComponents library version 1.3.7 or later
   * and the OROMatcher library for the regualar expressions stuff.
   *
   *
   * <P><B>USAGE:</B></P>
   * <LI>Create an instance of OS2FTPEntryParser</LI>
   *   <dd>OS2FTPEntryParser parser = new OS2FTPEntryParser();
   * <LI>Create an instance of FTPClient</LI>
   *   <dd>FTPClient FTPClientObj = new FTPClient();
   * <LI>Connect to the NODE </LI>
   *   <dd>FTPClientObj.connect();
   * <LI>Login to the NODE </LI>
   *   <dd>FTPClientObj.login(username,password);
   * <LI>Switch directories if you have to</LI>
   *   <dd>FTPClientObj.changeWorkingDirectory(thePath);
   * <LI>You might want to check if you are truly in a OS2 System</LI>
   *   <dd><B>String am_I_OS2 =  FTPClientObj.getSystemName()</B>
   *    <dd>parse am_I_OS2 to find out
   * <LI>Call listFiles passing the newly created parser and a filename or a mask to look for </LI>
   *   <dd>FTPClientObj.listFiles(parser,filename);
   * <LI>You'll get back the list as an array of FTPFiles like this
   *   <dd>FTPFile[] myOS2Files = FTPClientObj.listFiles(parser,filename);  (or)
   *    <dd>FTPFile[] myOS2Files = FTPClientObj.listFiles(parser);
   * <P>
   * That's all there is to it.
   * <P>
   * Each FTPFile object is populated just like any other FTPFile
   * object. The only thing not implemented at this time is the file
   * permissions, but I can do it if there is a real need for it.
   * <P>
   * !NOTE/WARNING!:Before you pass the parser to listFiles, make sure you are in the
   * directory that you need to be. This parser will return the filtered
   * files from the directory it is in. This becomes specially crucial if your
   * goal is to delete the output of the parser.
   * <P>
   * @author  <a href="Winston.Ojeda@qg.com">Winston Ojeda</a>
   * @author <a href="mailto:stevecoh1@attbi.com">Steve Cohen</a>
   * @version $Id: OS2FTPEntryParser.java,v 1.1 2002/04/29 03:55:32 brekke Exp $
   * @see org.apache.commons.net.ftp.FTPFileListParser
   */
  public class OS2FTPEntryParser
              extends MatchApparatus implements FTPFileEntryParser
  
  {
      private String prefix = "[" + getClass().getName() + "] ";
  
      private static final String regEx =
          "(\\s+|[0-9]+)\\s*" +
          "(\\s+|[A-Z]+)\\s*" +
          "(DIR|\\s+)\\s*" +
          "((?:0[1-9])|(?:1[0-2]))-" +
          "((?:0[1-9])|(?:[1-2]\\d)|(?:3[0-1]))-" +
          "(\\d\\d)\\s*" +
          "(?:([0-1]\\d)|(?:2[0-3])):" +
          "([0-5]\\d)\\s*" +
          "(\\S.*)";
  
      public OS2FTPEntryParser()
      {}
  
  
      protected String getRegEx()
      {
          return (regEx);
      }
  
  
      public FTPFile parseFTPEntry(String entry)
      {
  
          FTPFile f = new FTPFile();
          if (matches(entry))
          {
              String size = group(1);
              String attrib = group(2);
              String dirString = group(3);
              String mo = group(4);
              String da = group(5);
              String yr = group(6);
              String hr = group(7);
              String min = group(8);
              String name = group(9);
  
              //is it a DIR or a file
              if (dirString.trim().equals("DIR") || attrib.trim().equals("DIR"))
                  f.setType(FTPFile.DIRECTORY_TYPE);
              else
                  f.setType(FTPFile.FILE_TYPE);
  
              Calendar cal = Calendar.getInstance();
  
  
              //convert all the calendar stuff to ints
              int month = new Integer(mo).intValue();
              int day = new Integer(da).intValue();
              int year = new Integer(yr).intValue() + 2000;
              int hour = new Integer(hr).intValue();
              int minutes = new Integer(min).intValue();
  
              // Y2K stuff? this will break again in 2080 but I will
              // be sooooo dead anyways who cares.
              // SMC - IS OS2's directory date REALLY still not Y2K-compliant?
              if (year > 2080)
                  year -= 100;
  
              //set the calendar
              cal.set(Calendar.SECOND, 0);
              cal.set(Calendar.MINUTE, minutes);
              cal.set(Calendar.HOUR_OF_DAY, hour);
              cal.set(Calendar.YEAR, year);
              cal.set(Calendar.DATE, day);
              cal.set(Calendar.MONTH, month);
              f.setTimestamp(cal);
  
              //set the name
              f.setName(name.trim());
  
              //set the size
              Long theSize = new Long(size.trim());
              theSize = new Long(String.valueOf(theSize.intValue()));
              f.setSize(theSize.longValue());
  
              return (f);
          }
          return null;
  
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/net/ftp/ftp2/parser/UnixFTPEntryParser.java
  
  Index: UnixFTPEntryParser.java
  ===================================================================
  package org.apache.commons.net.ftp.ftp2.parser;
  
  /* ====================================================================
   * 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",
   *    "Apache Turbine", 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.Calendar;
  import org.apache.commons.net.ftp.FTPFile;
  import org.apache.commons.net.ftp.ftp2.FTPFileEntryParser;
  
  /**
   * This class is based on the logic of Daniel Savarese's
   * DefaultFTPListParser, but adapted to use regular expressions and to fit the
   * new FTPFileEntryParser interface.
   * @author <a href="mailto:scohen@ignitesports.com">Steve Cohen</a>
   * @version $Id: UnixFTPEntryParser.java,v 1.1 2002/04/29 03:55:32 brekke Exp $
   */
  public class UnixFTPEntryParser
              extends MatchApparatus implements FTPFileEntryParser
  {
      private static final String months =
          "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)";
      private static final String regEx =
          "([bcdlf])"
          + "(((r|-)(w|-)(x|-))((r|-)(w|-)(x|-))((r|-)(w|-)(x|-)))\\s*"
          + "(\\d*)\\s*"
          + "(\\S*)\\s*"
          + "(\\S*)\\s*"
          + "(\\d*)\\s*"
          + months + "\\s*"
          + "((?:[012]\\d*)|(?:3[01]))\\s*"
          + "((\\d\\d\\d\\d)|((?:[01]\\d)|(?:2[0123])):([012345]\\d))\\s"
          + "(\\S*)(\\s*.*)";
      public String getRegEx()
      {
          return this.regEx;
      }
  
      public FTPFile parseFTPEntry(String entry)
      {
  
          FTPFile file = new FTPFile();
          file.setRawListing(entry);
          int type;
          boolean isDevice = false;
  
          if (matches(entry))
          {
              String typeStr = group(1);
              String hardLinkCount = group(15);
              String usr = group(16);
              String grp = group(17);
              String filesize = group(18);
              String mo = group(19);
              String da = group(20);
              String yr = group(22);
              String hr = group(23);
              String min = group(24);
              String name = group(25);
              String endtoken = group(26);
  
  
              switch (typeStr.charAt(0))
              {
              case 'd':
                  type = FTPFile.DIRECTORY_TYPE;
                  break;
              case 'l':
                  type = FTPFile.SYMBOLIC_LINK_TYPE;
                  break;
              case 'b':
              case 'c':
                  isDevice = true;
                  // break; - fall through
              default:
                  type = FTPFile.FILE_TYPE;
              }
              int g = 4;
              for (int access = 0; access < 3; access++, g += 4)
              {
                  // Use != '-' to avoid having to check for suid and sticky bits
                  file.setPermission(access, FTPFile.READ_PERMISSION,
                                     (!group(g).equals("-")));
                  file.setPermission(access, FTPFile.WRITE_PERMISSION,
                                     (!group(g + 1).equals("-")));
                  file.setPermission(access, FTPFile.EXECUTE_PERMISSION,
                                     (!group(g + 2).equals("-")));
              }
  
              if (!isDevice)
              {
                  try
                  {
                      file.setHardLinkCount(Integer.parseInt(hardLinkCount));
                  }
                  catch (NumberFormatException e)
                  {
                      // intentionally do nothing
                  }
              }
  
              file.setUser(usr);
              file.setGroup(grp);
  
              try
              {
                  file.setSize(Integer.parseInt(filesize));
              }
              catch (NumberFormatException e)
              {
                  // intentionally do nothing
              }
  
              Calendar cal = Calendar.getInstance();
              cal.set(Calendar.SECOND, 0);
              cal.set(Calendar.MINUTE, 0);
              cal.set(Calendar.HOUR_OF_DAY, 0);
  
              try
              {
                  int pos = months.indexOf(mo);
                  int month = pos / 4;
  
                  if (null != yr)
                  {
                      // it's a year
                      cal.set(Calendar.YEAR, Integer.parseInt(yr));
                  }
                  else
                  {
                      // it must be  hour/minute or we wouldn't have matched
                      int year = cal.get(Calendar.YEAR);
                      // if the month we're reading is greater than now, it must
                      // be last year
                      if (cal.get(Calendar.MONTH) < month)
                      {
                          year--;
                      }
                      cal.set(Calendar.YEAR, year);
                      cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hr));
                      cal.set(Calendar.MINUTE, Integer.parseInt(min));
                  }
                  cal.set(Calendar.MONTH, month);
  
                  cal.set(Calendar.DATE, Integer.parseInt(da));
                  file.setTimestamp(cal);
              }
              catch (NumberFormatException e)
              {
                  // do nothing, date will be uninitialized
              }
              if (null == endtoken)
              {
                  file.setName(name);
              }
              else
              {
                  // oddball cases like symbolic links, file names
                  // with spaces in them.
                  name += endtoken;
                  if (type == FTPFile.SYMBOLIC_LINK_TYPE)
                  {
  
                      int end = name.indexOf(" -> ");
                      // Give up if no link indicator is present
                      if (end == -1)
                      {
                          file.setName(name);
                      }
                      else
                      {
                          file.setName(name.substring(0, end));
                          file.setLink(name.substring(end + 4));
                      }
  
                  }
                  else
                  {
                      file.setName(name);
                  }
              }
              return file;
          }
  
          return null;
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/net/ftp/ftp2/parser/VMSFTPEntryParser.java
  
  Index: VMSFTPEntryParser.java
  ===================================================================
  package org.apache.commons.net.ftp.ftp2.parser;
  
  /* ====================================================================
   * 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",
   *    "Apache Turbine", 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.Calendar;
  import org.apache.commons.net.ftp.FTPFile;
  import org.apache.commons.net.ftp.ftp2.FTPFileEntryParser;
  
  /**
   * This Class uses the FTPEntryParser class to validate the input string.
   * It also requires the NetComponents library version 1.3.7 or later
   * and the OROMatcher library for the regualar expressions stuff.
   *
   *
   * <P><B>USAGE:</B></P>
   * <LI>Create an instance of VMSFTPEntryParser</LI>
   *   <dd>VMSFTPEntryParser parser = new VMSFTPEntryParser(boolean);
   *  <dd><code>True</code>  = returns all versions of a file with the respective ;#
   *  <dd><code>False</code> = only the last version will return <B>(Default)</B>
   * <LI>Create an instance of FTPClient</LI>
   *   <dd>FTPClient FTPClientObj = new FTPClient();
   * <LI>Connect to the NODE </LI>
   *   <dd>FTPClientObj.connect();
   * <LI>Login to the NODE </LI>
   *   <dd>FTPClientObj.login(username,password);
   * <LI>Switch directories if you have to</LI>
   *   <dd>FTPClientObj.changeWorkingDirectory(thePath);
   * <LI>You might want to check if you are truly in a VMS System</LI>
   *   <dd>And how do I do that you ask? easy...  VMS is such a wonderful OS that when we do
   *   <dd><B>String am_I_VMS =  FTPClientObj.getSystemName()</B>
   *   <dd>it returns NULL, while everyone else returns the FTP servername
   * <LI>Call listFiles passing the newly created parser and a filename or a mask to look for </LI>
   *   <dd>FTPClientObj.listFiles(parser,filename);
   * <LI>You'll get back the list as an array of FTPFile objects like this
   *   <dd>FTPFile[] myVMSFiles = FTPClientObj.listFiles(parser,filename);  (or)
   *    <dd>FTPFile[] myVMSFiles = FTPClientObj.listFiles(parser);
   *    <dd>If <code>filename</code> is a filename and versioning is OFF, the version
   *    <dd>you requested will come back without the ;#
   * <P>
   * That's all there is to it.
   * <P>
   * Each FTPFile object is populated just like any other FTPFile
   * object. The only thing not implemented at this time is the file
   * permissions, but I can do it if there is a real need for it.
   * <P>
   * !NOTE/WARNING!:Before you pass the parser to listFiles, make sure you are in the
   * directory that you need to be. This parser will return the filtered
   * files from the directory it is in. This becomes crucial specialy if your
   * goal is to delete the output of the parser.
   * <P>
   * @author  <a href="Winston.Ojeda@qg.com">Winston Ojeda</a>
   * @author <a href="mailto:stevecoh1@attbi.com">Steve Cohen</a>
   * @version $Id: VMSFTPEntryParser.java,v 1.1 2002/04/29 03:55:32 brekke Exp $
   * @see org.apache.commons.net.ftp.FTPFileFTPEntryParser
   */
  public class VMSFTPEntryParser
              extends MatchApparatus implements FTPFileEntryParser
  {
      private String prefix = "[" + getClass().getName() + "] ";
      private boolean versioning;
  
      // This is how a VMS LIST output really looks
      /*
            "1-JUN.LIS;1              9/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,RE)",
            "1-JUN.LIS;2              9/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,RE)",
            "DATA.DIR;1               1/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,RE)",
      */
      private static final String months =
          "(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)";
  
      private static final String regEx =
          "(.*;[0-9]+)\\s*" +
          "(\\d+)/\\d+\\s*" +
          "(\\d{1,2})-" +
          months +
          "-([0-9]{4})\\s*" +
          "((?:[01]\\d)|(?:2[0-3])):([012345]\\d):([012345]\\d)\\s*" +
          "(\\[[0-9$A-Za-z_]+),([0-9$a-zA-Z_]+)\\]\\s*" +
          "(\\([a-zA-Z]*,[a-zA-Z]*,[a-zA-Z]*,[a-zA-Z]*\\))";
  
  
      public VMSFTPEntryParser(boolean versioning)
      {
          this.versioning = versioning;
      }
  
      public VMSFTPEntryParser()
      {
          this(false);
      }
  
  
      protected String getRegEx()
      {
          return (regEx);
      }
  
      public FTPFile parseFTPEntry(String entry)
      {
          //one block in VMS equals 512 bytes
          Integer oneBlock = new Integer(512);
          int intBlock = oneBlock.intValue();
          long longBlock = 512;
  
  
          if (matches(entry))
          {
              FTPFile f = new FTPFile();
              f.setRawListing(entry);
              String name = group(1);
              String size = group(2);
              String day = group(3);
              String mo = group(4);
              String yr = group(5);
              String hr = group(6);
              String min = group(7);
              String sec = group(8);
              String grp = group(9);
              String owner = group(10);
  
              if (name.lastIndexOf(".DIR") != -1)
                  f.setType(FTPFile.DIRECTORY_TYPE);
              else
                  f.setType(FTPFile.FILE_TYPE);
              //set FTPFile name
              //Check also for versions to be returned or not
              if (versioning)
                  f.setName(name);
              else
              {
                  name = name.substring(0, name.lastIndexOf(";"));
                  f.setName(name);
              }
              //size is retreived in blocks and needs to be put in bytes
              //for us humans and added to the FTPFile array
              Long theSize = new Long(size);
              long sizeInBytes = theSize.longValue() * longBlock;
              f.setSize(sizeInBytes);
  
              //set the date
              Calendar cal = Calendar.getInstance();
  
              cal.clear();
  
              cal.set(Calendar.DATE, new Integer(day).intValue());
              cal.set(Calendar.MONTH, months.indexOf(mo) / 4);
              cal.set(Calendar.YEAR, new Integer(yr).intValue());
              cal.set(Calendar.HOUR_OF_DAY, new Integer(hr).intValue());
              cal.set(Calendar.MINUTE, new Integer(min).intValue());
              cal.set(Calendar.SECOND, new Integer(sec).intValue());
              f.setTimestamp(cal);
  
              f.setGroup(grp);
              f.setUser(owner);
              //set group and owner
              //Since I don't need the persmissions on this file (RWED), I'll leave that
              //for further development. 'Cause it will be a bit elaborate to do it
              //right with VMSes World, Global and so forth.
              return (f);
          }
          return null;
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/test/org/apache/commons/net/ftp/ftp2/parser/FTPParseTestFramework.java
  
  Index: FTPParseTestFramework.java
  ===================================================================
  package org.apache.commons.net.ftp.ftp2.parser;
  
  /* ====================================================================
   * 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",
   *    "Apache Turbine", 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 junit.framework.TestCase;
  import org.apache.commons.net.ftp.FTPFile;
  import org.apache.commons.net.ftp.ftp2.FTPFileEntryParser;
  
  /**
   * FTPParseTestFramework.java
   * This provides a basic framework for pass-fail testing of
   * sample FTP directory strings in a particular format.
   *
   * @author <a href="mailto:stevecoh1@attbi.com">Steve Cohen</a>
   * @version $Id: FTPParseTestFramework.java,v 1.1 2002/04/29 03:55:32 brekke Exp $
   */
  
  public abstract class FTPParseTestFramework extends TestCase
  {
      FTPFileEntryParser parser;
  
      public FTPParseTestFramework (String name, FTPFileEntryParser parser)
      {
          super(name);
          this.parser = parser;
      }
  
      protected void _testPositive(String[] goodsamples) throws Exception
      {
          for (int i = 0; i < goodsamples.length; i++)
          {
              String test = goodsamples[i];
              FTPFile f = this.parser.parseFTPEntry(test);
              assertNotNull( "Failed to parse " + test, f);
          }
      }
  
      protected void _testNegative(String[] badsamples) throws Exception
      {
          for (int i = 0; i < badsamples.length; i++)
          {
              String test = badsamples[i];
              FTPFile f = this.parser.parseFTPEntry(test);
              assertNull( "Should have Failed to parse " + test, f);
          }
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/test/org/apache/commons/net/ftp/ftp2/parser/NTFTPEntryParserTest.java
  
  Index: NTFTPEntryParserTest.java
  ===================================================================
  package org.apache.commons.net.ftp.ftp2.parser;
  
  /* ====================================================================
   * 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",
   *    "Apache Turbine", 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/>.
   */
  
  /**
   * NTFTPEntryParserTest.java
   * Tests the NTFTPEntryParser
   *
   * @author <a href="mailto:scohen@stevecoh1@attbi.com">Steve Cohen</a>
   * @versionn $Id: NTFTPEntryParserTest.java,v 1.1 2002/04/29 03:55:32 brekke Exp $
   */
  public class NTFTPEntryParserTest extends FTPParseTestFramework
  {
  
      private static final String [] goodsamples = {
                  "05-26-95  10:57AM               143712 $LDR$",
                  "05-20-97  03:31PM                  681 .bash_history",
                  "12-05-96  05:03PM       <DIR>          absoft2",
                  "11-14-97  04:21PM                  953 AUDITOR3.INI",
                  "05-22-97  08:08AM                  828 AUTOEXEC.BAK",
                  "01-22-98  01:52PM                  795 AUTOEXEC.BAT",
                  "05-13-97  01:46PM                  828 AUTOEXEC.DOS",
                  "12-03-96  06:38AM                  403 AUTOTOOL.LOG",
                  "01-20-97  03:48PM       <DIR>          bin",
  
              };
  
      private static final String [] badsamples = {
                  "05-26-1995  10:57AM               143712 $LDR$",
                  "20-05-97  03:31PM                  681 .bash_history",
                  "12-05-96  17:03         <DIR>          absoft2",
                  "05-22-97  08:08                    828 AUTOEXEC.BAK",
                  "     0           DIR   05-19-97   12:56  local",
                  "     0           DIR   05-12-97   16:52  Maintenance Desktop",
  
              };
  
      public NTFTPEntryParserTest (String name)
      {
          super(name, new NTFTPEntryParser());
      }
  
      public void testPositive() throws Exception
      {
          _testPositive(goodsamples);
      }
      public void testNegative() throws Exception
      {
          _testNegative(badsamples);
  
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/test/org/apache/commons/net/ftp/ftp2/parser/OS2FTPEntryParserTest.java
  
  Index: OS2FTPEntryParserTest.java
  ===================================================================
  package org.apache.commons.net.ftp.ftp2.parser;
  
  /* ====================================================================
   * 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",
   *    "Apache Turbine", 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/>.
   */
  
  /**
   * OS2FTPEntryParserTest.java
   * Tests the OS2FTPEntryParser
   *
   * @author <a href="mailto:scohen@stevecoh1@attbi.com">Steve Cohen</a>
   * @version $Id: OS2FTPEntryParserTest.java,v 1.1 2002/04/29 03:55:32 brekke Exp $
   */
  public class OS2FTPEntryParserTest extends FTPParseTestFramework
  {
  
      private static final String [] goodsamples = {
                  "     0           DIR   12-30-97   12:32  jbrekke",
                  "     0           DIR   11-25-97   09:42  junk",
                  "     0           DIR   05-12-97   16:44  LANGUAGE",
                  "     0           DIR   05-19-97   12:56  local",
                  "     0           DIR   05-12-97   16:52  Maintenance Desktop",
                  "     0           DIR   05-13-97   10:49  MPTN",
                  "587823    RSA    DIR   01-08-97   13:58  OS2KRNL",
                  " 33280      A          02-09-97   13:49  OS2LDR",
                  "     0           DIR   11-28-97   09:42  PC",
                  "149473      A          11-17-98   16:07  POPUPLOG.OS2",
                  "     0           DIR   05-12-97   16:44  PSFONTS"
  
              };
  
      private static final String [] badsamples = {
                  "                 DIR   12-30-97   12:32  jbrekke",
                  "     0    rsa    DIR   11-25-97   09:42  junk",
                  "     0           dir   05-12-97   16:44  LANGUAGE",
                  "     0           DIR   05-19-2000 12:56  local",
                  "     0           DIR   13-05-97   25:49  MPTN",
                  "587823    RSA    DIR   Jan-08-97   13:58  OS2KRNL",
                  " 33280      A          1997-02-03  13:49  OS2LDR",
                  "12-05-96  05:03PM       <DIR>          absoft2",
                  "11-14-97  04:21PM                  953 AUDITOR3.INI",
              };
  
  
      public OS2FTPEntryParserTest (String name)
      {
          super(name, new OS2FTPEntryParser());
      }
  
      public void testPositive() throws Exception
      {
          _testPositive(goodsamples);
      }
      public void testNegative() throws Exception
      {
          _testNegative(badsamples);
  
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/test/org/apache/commons/net/ftp/ftp2/parser/UnixFTPEntryParserTest.java
  
  Index: UnixFTPEntryParserTest.java
  ===================================================================
  package org.apache.commons.net.ftp.ftp2.parser;
  
  /* ====================================================================
   * 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",
   *    "Apache Turbine", 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/>.
   */
  
  /**
   * UnixFTPEntryParserTest.java
   * Tests the UnixFTPEntryParser
   *
   * @author <a href="mailto:scohen@stevecoh1@attbi.com">Steve Cohen</a>
   * @versionn $Id: UnixFTPEntryParserTest.java,v 1.1 2002/04/29 03:55:32 brekke Exp $
   */
  public class UnixFTPEntryParserTest extends FTPParseTestFramework
  {
      private static final String[] goodsamples = {
                  "drwxr-xr-x   2 root     root         4096 Mar  2 15:13 zxbox",
                  "drwxr-xr-x   2 root     root         4096 Aug 24  2001 zxjdbc",
                  "drwxr-xr-x   2 root     root         4096 Jan  4 00:03 zziplib",
                  "drwxr-xr-x   2 root     99           4096 Feb 23  2001 zzplayer",
                  "drwxr-xr-x   2 root     root         4096 Aug  6  2001 zztpp",
                  "-rw-r--r--   1 14       staff       80284 Aug 22  2000 zxJDBC-1.2.3.tar.gz",
                  "-rw-r--r--   1 14       staff      119926 Aug 22  2000 zxJDBC-1.2.3.zip",
                  "-rw-r--r--   1 ftp      nogroup     83853 Jan 22  2001 zxJDBC-1.2.4.tar.gz",
                  "-rw-r--r--   1 ftp      nogroup    126552 Jan 22  2001 zxJDBC-1.2.4.zip",
                  "-rw-r--r--   1 root     root       111325 Apr 27  2001 zxJDBC-2.0.1b1.tar.gz",
                  "-rw-r--r--   1 root     root       190144 Apr 27  2001 zxJDBC-2.0.1b1.zip"
              };
      private static final String[] badsamples = {
                  "zrwxr-xr-x   2 root     root         4096 Mar  2 15:13 zxbox",
                  "dxrwr-xr-x   2 root     root         4096 Aug 24  2001 zxjdbc",
                  "drwxr-xr-x   2 root     root         4096 Jam  4 00:03 zziplib",
                  "drwxr-xr-x   2 root     99           4096 Feb 23 30:01 zzplayer",
                  "drwxr-xr-x   2 root     root         4096 Aug 36  2001 zztpp",
                  "-rw-r--r--   1 14       staff       80284 Aug 22  zxJDBC-1.2.3.tar.gz",
                  "-rw-r--r--   1 14       staff      119:26 Aug 22  2000 zxJDBC-1.2.3.zip",
                  "-rw-r--r--   1 ftp      no group    83853 Jan 22  2001 zxJDBC-1.2.4.tar.gz",
                  "-rw-r--r--   1ftp       nogroup    126552 Jan 22  2001 zxJDBC-1.2.4.zip",
                  "-rw-r--r--   1 root     root       111325 Apr -7 18:79 zxJDBC-2.0.1b1.tar.gz",
              };
  
  
  
  
      public UnixFTPEntryParserTest (String name)
      {
          super(name, new UnixFTPEntryParser());
      }
  
      public void testPositive() throws Exception
      {
          _testPositive(goodsamples);
      }
      public void testNegative() throws Exception
      {
          _testNegative(badsamples);
  
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/test/org/apache/commons/net/ftp/ftp2/parser/VMSFTPEntryParserTest.java
  
  Index: VMSFTPEntryParserTest.java
  ===================================================================
  package org.apache.commons.net.ftp.ftp2.parser;
  
  /* ====================================================================
   * 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",
   *    "Apache Turbine", 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/>.
   */
  
  /**
   * VMSFTPEntryParserTest.java
   * Tests the VMSFTPEntryParser
   *
   * @author <a href="mailto:scohen@stevecoh1@attbi.com">Steve Cohen</a>
   * @version $Id: VMSFTPEntryParserTest.java,v 1.1 2002/04/29 03:55:32 brekke Exp $
   */
  public class VMSFTPEntryParserTest extends FTPParseTestFramework
  {
  
      private static final String [] goodsamples = {
                  "1-JUN.LIS;1              9/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,RE)",
                  "1-JUN.LIS;2              9/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,)",
                  "1-JUN.LIS;2              9/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,)",
                  "DATA.DIR;1               1/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (,RWED,RWED,RE)",
                  "120196.TXT;1           118/126        14-APR-1997 12:45:27  [GROUP,OWNER]    (RWED,,RWED,RE)",
                  "30CHARBAR.TXT;1         11/18          2-JUN-1998 08:38:42  [GROUP,OWNER]    (RWED,RWED,RWED,RE)",
                  "A.;2                    18/18          1-JUL-1998 08:43:20  [GROUP,OWNER]    (RWED,RWED,RWED,RE)",
                  "AA.;2                  152/153        13-FEB-1997 08:13:43  [GROUP,OWNER]    (RWED,RWED,RWED,RE)",
              };
  
      private static final String [] badsamples = {
                  "1-JUN.LIS;1              9/9           2-jun-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,RE)",
                  "1-JUN.LIS;2              9/9           JUN-2-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,)",
                  "1-JUN.LIS;2              a/9           2-JUN-98 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,)",
                  "DATA.DIR; 1              1/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (,RWED,RWED,RE)",
                  "120196.TXT;1           118/126        14-APR-1997 12:45:27 PM  [GROUP,OWNER]    (RWED,,RWED,RE)",
                  "30CHARBAR.TXT;1         11/18          2-JUN-1998 08:38:42  [GROUP-1,OWNER]    (RWED,RWED,RWED,RE)",
                  "A.;2                    18/18          1-JUL-1998 08:43:20  [GROUP,OWNER]    (RWED2,RWED,RWED,RE)",
                  "AA.;2                  152/153        13-FED-1997 08:13:43  [GROUP,OWNER]    (RWED,RWED,RWED,RE)",
              };
  
  
      public VMSFTPEntryParserTest (String name)
      {
          super(name, new VMSFTPEntryParser());
      }
  
      public void testPositive() throws Exception
      {
          _testPositive(goodsamples);
      }
      public void testNegative() throws Exception
      {
          _testNegative(badsamples);
  
      }
  }
  
  
  
  1.2       +4 -13     jakarta-commons-sandbox/net/xdocs/tasks.xml
  
  Index: tasks.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/net/xdocs/tasks.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- tasks.xml	7 Apr 2002 03:04:15 -0000	1.1
  +++ tasks.xml	29 Apr 2002 03:55:32 -0000	1.2
  @@ -11,20 +11,11 @@
         <p>
           <ul>
             <li>
  -            Convert code to specified coding standards.  Use checkstyle once
  -            it is integrated into Maven.
  +            Convert code to specified coding standards.  Checkstyle report provided.
             </li>
             <li>
  -            Evaluate/Integrate existing file list parsing patch from Steve Cohen.
  -            <ul>
  -              <li>
  -                <a href="http://groups.yahoo.com/group/devel-netcomponents/files/NetComponents-1.3.8a-src.tar.gz">
  -                Patch</a>
  -              </li>
  -              <li>
  -                <a href="http://groups.yahoo.com/group/devel-netcomponents/message/85">Description</a>
  -              </li>
  -            </ul>
  +            Evaluate options for integrating FTPClient2/parsing into FTPClient while maintaining (deprecated) 
  +            old interface.
             </li>
             <li>
               Clean out any classes that don't belong in this project.  Probably classes from
  @@ -47,7 +38,7 @@
               a user runs across an unsupported server, he can register a 
               regular expression rather than create a completely new 
               hand-parsed FTPFileLister implementation. ( Partially implemented
  -            by patch listed above )
  +            by Steve Cohen )
             </li>
             <li>
               Make buffer size settable for FTP data transfers using 
  
  
  

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


Mime
View raw message