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 * https://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
18 package org.apache.commons.net.ftp.parser;
19
20 import java.text.ParseException;
21 import java.util.regex.Pattern;
22
23 import org.apache.commons.net.ftp.Configurable;
24 import org.apache.commons.net.ftp.FTPClientConfig;
25 import org.apache.commons.net.ftp.FTPFile;
26 import org.apache.commons.net.ftp.FTPFileEntryParser;
27
28 /**
29 * Implements {@link FTPFileEntryParser} and {@link Configurable} for NT Systems.
30 *
31 * @see FTPFileEntryParser Usage instructions.
32 */
33 public class NTFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
34
35 private static final String DEFAULT_DATE_FORMAT = "MM-dd-yy hh:mma"; // 11-09-01 12:30PM
36
37 private static final String DEFAULT_DATE_FORMAT2 = "MM-dd-yy kk:mm"; // 11-09-01 18:30
38
39 /**
40 * this is the regular expression used by this parser.
41 */
42 private static final String REGEX = "(\\S+)\\s+(\\S+)\\s+" // MM-dd-yy whitespace hh:mma|kk:mm; swallow trailing spaces
43 + "(?:(<DIR>)|([0-9]+))\\s+" // <DIR> or ddddd; swallow trailing spaces
44 + "(\\S.*)"; // First non-space followed by rest of line (name)
45
46 private final FTPTimestampParser timestampParser;
47
48 /**
49 * The sole constructor for an NTFTPEntryParser object.
50 *
51 * @throws IllegalArgumentException Thrown if the regular expression is unparseable. Should not be seen under normal conditions. If it is seen, this is a
52 * sign that {@code REGEX} is not a valid regular expression.
53 */
54 public NTFTPEntryParser() {
55 this(null);
56 }
57
58 /**
59 * This constructor allows the creation of an NTFTPEntryParser object with something other than the default configuration.
60 *
61 * @param config The {@link FTPClientConfig configuration} object used to configure this parser.
62 * @throws IllegalArgumentException Thrown if the regular expression is unparseable. Should not be seen under normal conditions. If it is seen, this is a
63 * sign that {@code REGEX} is not a valid regular expression.
64 * @since 1.4
65 */
66 public NTFTPEntryParser(final FTPClientConfig config) {
67 super(REGEX, Pattern.DOTALL);
68 configure(config);
69 final FTPClientConfig config2 = new FTPClientConfig(FTPClientConfig.SYST_NT, DEFAULT_DATE_FORMAT2, null);
70 config2.setDefaultDateFormatStr(DEFAULT_DATE_FORMAT2);
71 this.timestampParser = new FTPTimestampParserImpl();
72 ((Configurable) this.timestampParser).configure(config2);
73 }
74
75 /**
76 * Gets a new default configuration to be used when this class is instantiated without a {@link FTPClientConfig FTPClientConfig} parameter being specified.
77 *
78 * @return the default configuration for this parser.
79 */
80 @Override
81 public FTPClientConfig getDefaultConfiguration() {
82 return new FTPClientConfig(FTPClientConfig.SYST_NT, DEFAULT_DATE_FORMAT, null);
83 }
84
85 /**
86 * Parses a line of an NT FTP server file listing and converts it into a usable format in the form of an {@code FTPFile} instance. If the file
87 * listing line doesn't describe a file, {@code null} is returned, otherwise a {@code FTPFile} instance representing the files in the
88 * directory is returned.
89 *
90 * @param entry A line of text from the file listing
91 * @return An FTPFile instance corresponding to the supplied entry
92 */
93 @Override
94 public FTPFile parseFTPEntry(final String entry) {
95 if (matches(entry)) {
96 final FTPFile f = new FTPFile();
97 f.setRawListing(entry);
98 final String dateString = group(1) + " " + group(2);
99 final String dirString = group(3);
100 final String size = group(4);
101 final String name = group(5);
102 if (null == name || name.equals(".") || name.equals("..")) {
103 return null;
104 }
105 try {
106 f.setTimestamp(super.parseTimestamp(dateString));
107 } catch (final ParseException e) {
108 // parsing fails, try the other date format
109 try {
110 f.setTimestamp(timestampParser.parseTimestamp(dateString));
111 } catch (final ParseException e2) {
112 // intentionally do nothing
113 }
114 }
115 f.setName(name);
116 if ("<DIR>".equals(dirString)) {
117 f.setType(FTPFile.DIRECTORY_TYPE);
118 f.setSize(0);
119 } else {
120 f.setType(FTPFile.FILE_TYPE);
121 if (null != size) {
122 f.setSize(Long.parseLong(size));
123 }
124 }
125 return f;
126 }
127 return null;
128 }
129
130 }