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.text.ParseException;
020    
021    import org.apache.commons.net.ftp.Configurable;
022    import org.apache.commons.net.ftp.FTPClientConfig;
023    import org.apache.commons.net.ftp.FTPFile;
024    
025    /**
026     * Implementation of FTPFileEntryParser and FTPFileListParser for NT Systems.
027     *
028     * @author  <a href="Winston.Ojeda@qg.com">Winston Ojeda</a>
029     * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
030     * @version $Id: NTFTPEntryParser.java 1299238 2012-03-10 17:12:28Z sebb $
031     * @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions)
032     */
033    public class NTFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
034    {
035    
036        private static final String DEFAULT_DATE_FORMAT
037            = "MM-dd-yy hh:mma"; //11-09-01 12:30PM
038    
039        private static final String DEFAULT_DATE_FORMAT2
040            = "MM-dd-yy kk:mm"; //11-09-01 18:30
041    
042        private FTPTimestampParser timestampParser;
043    
044        /**
045         * this is the regular expression used by this parser.
046         */
047        private static final String REGEX =
048            "(\\S+)\\s+(\\S+)\\s+"          // MM-dd-yy whitespace hh:mma|kk:mm; swallow trailing spaces
049            + "(?:(<DIR>)|([0-9]+))\\s+"    // <DIR> or ddddd; swallow trailing spaces
050            + "(\\S.*)";                    // First non-space followed by rest of line (name)
051    
052        /**
053         * The sole constructor for an NTFTPEntryParser object.
054         *
055         * @exception IllegalArgumentException
056         * Thrown if the regular expression is unparseable.  Should not be seen
057         * under normal conditions.  It it is seen, this is a sign that
058         * <code>REGEX</code> is  not a valid regular expression.
059         */
060        public NTFTPEntryParser()
061        {
062            this(null);
063        }
064    
065        /**
066         * This constructor allows the creation of an NTFTPEntryParser object
067         * with something other than the default configuration.
068         *
069         * @param config The {@link FTPClientConfig configuration} object used to
070         * configure this parser.
071         * @exception IllegalArgumentException
072         * Thrown if the regular expression is unparseable.  Should not be seen
073         * under normal conditions.  It it is seen, this is a sign that
074         * <code>REGEX</code> is  not a valid regular expression.
075         * @since 1.4
076         */
077         public NTFTPEntryParser(FTPClientConfig config)
078        {
079            super(REGEX);
080            configure(config);
081            FTPClientConfig config2 = new FTPClientConfig(
082                    FTPClientConfig.SYST_NT,
083                    DEFAULT_DATE_FORMAT2,
084                    null, null, null, null);
085            config2.setDefaultDateFormatStr(DEFAULT_DATE_FORMAT2);
086            this.timestampParser = new FTPTimestampParserImpl();
087            ((Configurable)this.timestampParser).configure(config2);
088        }
089    
090        /**
091         * Parses a line of an NT FTP server file listing and converts it into a
092         * usable format in the form of an <code> FTPFile </code> instance.  If the
093         * file listing line doesn't describe a file, <code> null </code> is
094         * returned, otherwise a <code> FTPFile </code> instance representing the
095         * files in the directory is returned.
096         * <p>
097         * @param entry A line of text from the file listing
098         * @return An FTPFile instance corresponding to the supplied entry
099         */
100        public FTPFile parseFTPEntry(String entry)
101        {
102            FTPFile f = new FTPFile();
103            f.setRawListing(entry);
104    
105            if (matches(entry))
106            {
107                String datestr = group(1)+" "+group(2);
108                String dirString = group(3);
109                String size = group(4);
110                String name = group(5);
111                try
112                {
113                    f.setTimestamp(super.parseTimestamp(datestr));
114                }
115                catch (ParseException e)
116                {
117                    // parsing fails, try the other date format
118                    try
119                    {
120                        f.setTimestamp(timestampParser.parseTimestamp(datestr));
121                    }
122                    catch (ParseException e2)
123                    {
124                        // intentionally do nothing
125                    }
126                }
127    
128                if (null == name || name.equals(".") || name.equals(".."))
129                {
130                    return (null);
131                }
132                f.setName(name);
133    
134    
135                if ("<DIR>".equals(dirString))
136                {
137                    f.setType(FTPFile.DIRECTORY_TYPE);
138                    f.setSize(0);
139                }
140                else
141                {
142                    f.setType(FTPFile.FILE_TYPE);
143                    if (null != size)
144                    {
145                      f.setSize(Long.parseLong(size));
146                    }
147                }
148                return (f);
149            }
150            return null;
151        }
152    
153        /**
154         * Defines a default configuration to be used when this class is
155         * instantiated without a {@link  FTPClientConfig  FTPClientConfig}
156         * parameter being specified.
157         * @return the default configuration for this parser.
158         */
159        @Override
160        public FTPClientConfig getDefaultConfiguration() {
161            return new FTPClientConfig(
162                    FTPClientConfig.SYST_NT,
163                    DEFAULT_DATE_FORMAT,
164                    null, null, null, null);
165        }
166    
167    }