    001    /*
    002     * Licensed to the Apache Software Foundation (ASF) under one or more
    003     * contributor license agreements.  See the NOTICE file distributed with
    004     * this work for additional information regarding copyright ownership.
    005     * The ASF licenses this file to You under the Apache License, Version 2.0
    006     * (the "License"); you may not use this file except in compliance with
    007     * the License.  You may obtain a copy of the License at
    008     *
    009     *      http://www.apache.org/licenses/LICENSE-2.0
    010     *
    011     * Unless required by applicable law or agreed to in writing, software
    012     * distributed under the License is distributed on an "AS IS" BASIS,
    013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014     * See the License for the specific language governing permissions and
    015     * limitations under the License.
    016     */
    017
    018    package org.apache.commons.net.ftp.parser;
    019    import java.util.Calendar;
    020
    021    import org.apache.commons.net.ftp.FTPFile;
    022
    023    /**
    024     * Parser for the Connect Enterprise Unix FTP Server From Sterling Commerce.
    025     * Here is a sample of the sort of output line this parser processes:
    026     *  "-C--E-----FTP B QUA1I1      18128       41 Aug 12 13:56 QUADTEST"
    027     * <P><B>
    028     * Note: EnterpriseUnixFTPEntryParser can only be instantiated through the
    029     * DefaultFTPParserFactory by classname.  It will not be chosen
    030     * by the autodetection scheme.
    031     * </B>
    032     * @version $Id: EnterpriseUnixFTPEntryParser.java 658518 2008-05-21 01:04:30Z sebb $
    033     * @author <a href="Winston.Ojeda@qg.com">Winston Ojeda</a>
    034     * @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions)
    035     * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
    036     */
    037    public class EnterpriseUnixFTPEntryParser extends RegexFTPFileEntryParserImpl
    038    {
    039
    040        /**
    041         * months abbreviations looked for by this parser.  Also used
    042         * to determine <b>which</b> month has been matched by the parser.
    043         */
    044        private static final String MONTHS =
    045            "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)";
    046
    047        /**
    048         * this is the regular expression used by this parser.
    049         */
    050        private static final String REGEX =
    051            "(([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])"
    052            + "([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z]))"
    053            + "(\\S*)\\s*"
    054            + "(\\S+)\\s*"
    055            + "(\\S*)\\s*"
    056            + "(\\d*)\\s*"
    057            + "(\\d*)\\s*"
    058            + MONTHS
    059            + "\\s*"
    060            + "((?:[012]\\d*)|(?:3[01]))\\s*"
    061            + "((\\d\\d\\d\\d)|((?:[01]\\d)|(?:2[0123])):([012345]\\d))\\s"
    062            + "(\\S*)(\\s*.*)";
    063
    064        /**
    065         * The sole constructor for a EnterpriseUnixFTPEntryParser object.
    066         *
    067         */
    068        public EnterpriseUnixFTPEntryParser()
    069        {
    070            super(REGEX);
    071        }
    072
    073        /**
    074         * Parses a line of a unix FTP server file listing and converts  it into a
    075         * usable format in the form of an <code> FTPFile </code>  instance.  If
    076         * the file listing line doesn't describe a file,  <code> null </code> is
    077         * returned, otherwise a <code> FTPFile </code>  instance representing the
    078         * files in the directory is returned.
    079         *
    080         * @param entry A line of text from the file listing
    081         * @return An FTPFile instance corresponding to the supplied entry
    082         */
    083        public FTPFile parseFTPEntry(String entry)
    084        {
    085
    086            FTPFile file = new FTPFile();
    087            file.setRawListing(entry);
    088
    089            if (matches(entry))
    090            {
    091                String usr = group(14);
    092                String grp = group(15);
    093                String filesize = group(16);
    094                String mo = group(17);
    095                String da = group(18);
    096                String yr = group(20);
    097                String hr = group(21);
    098                String min = group(22);
    099                String name = group(23);
    100
    101                file.setType(FTPFile.FILE_TYPE);
    102                file.setUser(usr);
    103                file.setGroup(grp);
    104                try
    105                {
    106                    file.setSize(Long.parseLong(filesize));
    107                }
    108                catch (NumberFormatException e)
    109                {
    110                    // intentionally do nothing
    111                }
    112
    113                Calendar cal = Calendar.getInstance();
    114            cal.set(Calendar.MILLISECOND, 0);
    115                cal.set(Calendar.SECOND,
    116                        0);
    117                cal.set(Calendar.MINUTE,
    118                        0);
    119                cal.set(Calendar.HOUR_OF_DAY,
    120                        0);
    121                try
    122                {
    123
    124                    int pos = MONTHS.indexOf(mo);
    125                    int month = pos / 4;
    126                    if (yr != null)
    127                    {
    128                        // it's a year
    129                        cal.set(Calendar.YEAR,
    130                                Integer.parseInt(yr));
    131                    }
    132                    else
    133                    {
    134                        // it must be  hour/minute or we wouldn't have matched
    135                        int year = cal.get(Calendar.YEAR);
    136
    137                        // if the month we're reading is greater than now, it must
    138                        // be last year
    139                        if (cal.get(Calendar.MONTH) < month)
    140                        {
    141                            year--;
    142                        }
    143                        cal.set(Calendar.YEAR,
    144                                year);
    145                        cal.set(Calendar.HOUR_OF_DAY,
    146                                Integer.parseInt(hr));
    147                        cal.set(Calendar.MINUTE,
    148                                Integer.parseInt(min));
    149                    }
    150                    cal.set(Calendar.MONTH,
    151                            month);
    152                    cal.set(Calendar.DATE,
    153                            Integer.parseInt(da));
    154                    file.setTimestamp(cal);
    155                }
    156                catch (NumberFormatException e)
    157                {
    158                    // do nothing, date will be uninitialized
    159                }
    160                file.setName(name);
    161
    162                return file;
    163            }
    164            return null;
    165        }
    166    }