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