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 1299238 2012-03-10 17:12:28Z 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    }