EnterpriseUnixFTPEntryParser.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. package org.apache.commons.net.ftp.parser;

  18. import java.util.Calendar;

  19. import org.apache.commons.net.ftp.FTPFile;

  20. /**
  21.  * Parser for the Connect Enterprise UNIX FTP Server From Sterling Commerce. Here is a sample of the sort of output line this parser processes:
  22.  *
  23.  * <pre>
  24.  * "-C--E-----FTP B QUA1I1      18128       41 Aug 12 13:56 QUADTEST"
  25.  * </pre>
  26.  * <p>
  27.  * Note: EnterpriseUnixFTPEntryParser can only be instantiated through the DefaultFTPParserFactory by class name. It will not be chosen by the autodetection
  28.  * scheme.
  29.  * </p>
  30.  *
  31.  * @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions)
  32.  * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
  33.  */
  34. public class EnterpriseUnixFTPEntryParser extends RegexFTPFileEntryParserImpl {

  35.     /**
  36.      * months abbreviations looked for by this parser. Also used to determine <b>which</b> month has been matched by the parser.
  37.      */
  38.     private static final String MONTHS = "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)";

  39.     /**
  40.      * this is the regular expression used by this parser.
  41.      */
  42.     private static final String REGEX = "(([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])"
  43.             + "([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z]))" + "(\\S*)\\s*" // 12
  44.             + "(\\S+)\\s*" // 13
  45.             + "(\\S*)\\s*" // 14 user
  46.             + "(\\d*)\\s*" // 15 group
  47.             + "(\\d*)\\s*" // 16 filesize
  48.             + MONTHS // 17 month
  49.             + "\\s*" // TODO should the space be optional?
  50.             // TODO \\d* should be \\d? surely ? Otherwise 01111 is allowed
  51.             + "((?:[012]\\d*)|(?:3[01]))\\s*" // 18 date [012]\d* or 3[01]
  52.             + "((\\d\\d\\d\\d)|((?:[01]\\d)|(?:2[0123])):([012345]\\d))\\s"
  53.             // 20 \d\d\d\d = year OR
  54.             // 21 [01]\d or 2[0123] hour + ':'
  55.             // 22 [012345]\d = minute
  56.             + "(\\S*)(\\s*.*)"; // 23 name

  57.     /**
  58.      * The sole constructor for a EnterpriseUnixFTPEntryParser object.
  59.      */
  60.     public EnterpriseUnixFTPEntryParser() {
  61.         super(REGEX);
  62.     }

  63.     /**
  64.      * Parses a line of a unix FTP server file listing and converts it into a usable format in the form of an <code>FTPFile</code> instance. If the file
  65.      * listing line doesn't describe a file, <code>null</code> is returned, otherwise a <code>FTPFile</code> instance representing the files in the
  66.      * directory is returned.
  67.      *
  68.      * @param entry A line of text from the file listing
  69.      * @return An FTPFile instance corresponding to the supplied entry
  70.      */
  71.     @Override
  72.     public FTPFile parseFTPEntry(final String entry) {

  73.         final FTPFile file = new FTPFile();
  74.         file.setRawListing(entry);

  75.         if (matches(entry)) {
  76.             final String usr = group(14);
  77.             final String grp = group(15);
  78.             final String filesize = group(16);
  79.             final String mo = group(17);
  80.             final String da = group(18);
  81.             final String yr = group(20);
  82.             final String hr = group(21);
  83.             final String min = group(22);
  84.             final String name = group(23);

  85.             file.setType(FTPFile.FILE_TYPE);
  86.             file.setUser(usr);
  87.             file.setGroup(grp);
  88.             try {
  89.                 file.setSize(Long.parseLong(filesize));
  90.             } catch (final NumberFormatException e) {
  91.                 // intentionally do nothing
  92.             }

  93.             final Calendar cal = Calendar.getInstance();
  94.             cal.set(Calendar.MILLISECOND, 0);
  95.             cal.set(Calendar.SECOND, 0);
  96.             cal.set(Calendar.MINUTE, 0);
  97.             cal.set(Calendar.HOUR_OF_DAY, 0);

  98.             final int pos = MONTHS.indexOf(mo);
  99.             final int month = pos / 4;
  100.             final int missingUnit; // the first missing unit
  101.             try {

  102.                 if (yr != null) {
  103.                     // it's a year; there are no hours and minutes
  104.                     cal.set(Calendar.YEAR, Integer.parseInt(yr));
  105.                     missingUnit = Calendar.HOUR_OF_DAY;
  106.                 } else {
  107.                     // it must be hour/minute, or we wouldn't have matched
  108.                     missingUnit = Calendar.SECOND;
  109.                     int year = cal.get(Calendar.YEAR);

  110.                     // if the month we're reading is greater than now, it must
  111.                     // be last year
  112.                     if (cal.get(Calendar.MONTH) < month) {
  113.                         year--;
  114.                     }
  115.                     cal.set(Calendar.YEAR, year);
  116.                     cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hr));
  117.                     cal.set(Calendar.MINUTE, Integer.parseInt(min));
  118.                 }
  119.                 cal.set(Calendar.MONTH, month);
  120.                 cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(da));
  121.                 cal.clear(missingUnit);
  122.                 file.setTimestamp(cal);
  123.             } catch (final NumberFormatException e) {
  124.                 // do nothing, date will be uninitialized
  125.             }
  126.             file.setName(name);

  127.             return file;
  128.         }
  129.         return null;
  130.     }
  131. }