%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.commons.net.ftp.parser.UnixFTPEntryParser |
|
|
1 | /* |
|
2 | * Copyright 2001-2005 The Apache Software Foundation |
|
3 | * |
|
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
|
5 | * you may not use this file except in compliance with the License. |
|
6 | * You may obtain a copy of the License at |
|
7 | * |
|
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
9 | * |
|
10 | * Unless required by applicable law or agreed to in writing, software |
|
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
13 | * See the License for the specific language governing permissions and |
|
14 | * limitations under the License. |
|
15 | */ |
|
16 | package org.apache.commons.net.ftp.parser; |
|
17 | import java.text.ParseException; |
|
18 | ||
19 | import org.apache.commons.net.ftp.FTPClientConfig; |
|
20 | import org.apache.commons.net.ftp.FTPFile; |
|
21 | ||
22 | /** |
|
23 | * Implementation FTPFileEntryParser and FTPFileListParser for standard |
|
24 | * Unix Systems. |
|
25 | * |
|
26 | * This class is based on the logic of Daniel Savarese's |
|
27 | * DefaultFTPListParser, but adapted to use regular expressions and to fit the |
|
28 | * new FTPFileEntryParser interface. |
|
29 | * @version $Id: UnixFTPEntryParser.java 161712 2005-04-18 02:57:04Z scohen $ |
|
30 | * @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions) |
|
31 | */ |
|
32 | public class UnixFTPEntryParser extends ConfigurableFTPFileEntryParserImpl |
|
33 | { |
|
34 | /** |
|
35 | * months abbreviations looked for by this parser. Also used |
|
36 | * to determine which month is matched by the parser |
|
37 | */ |
|
38 | private static final String DEFAULT_MONTHS = |
|
39 | "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)"; |
|
40 | ||
41 | static final String DEFAULT_DATE_FORMAT |
|
42 | = "MMM d yyyy"; //Nov 9 2001 |
|
43 | ||
44 | static final String DEFAULT_RECENT_DATE_FORMAT |
|
45 | = "MMM d HH:mm"; //Nov 9 20:06 |
|
46 | ||
47 | static final String NUMERIC_DATE_FORMAT |
|
48 | = "yyyy-MM-dd HH:mm"; //2001-11-09 20:06 |
|
49 | ||
50 | /** |
|
51 | * Some Linux distributions are now shipping an FTP server which formats |
|
52 | * file listing dates in an all-numeric format: |
|
53 | * <code>"yyyy-MM-dd HH:mm</code>. |
|
54 | * This is a very welcome development, and hopefully it will soon become |
|
55 | * the standard. However, since it is so new, for now, and possibly |
|
56 | * forever, we merely accomodate it, but do not make it the default. |
|
57 | * <p> |
|
58 | * For now end users may specify this format only via |
|
59 | * <code>UnixFTPEntryParser(FTPClientConfig)</code>. |
|
60 | * Steve Cohen - 2005-04-17 |
|
61 | */ |
|
62 | 5 | public static final FTPClientConfig NUMERIC_DATE_CONFIG = |
63 | new FTPClientConfig( |
|
64 | FTPClientConfig.SYST_UNIX, |
|
65 | NUMERIC_DATE_FORMAT, |
|
66 | null, class="keyword">null, class="keyword">null, class="keyword">null); |
|
67 | ||
68 | /** |
|
69 | * this is the regular expression used by this parser. |
|
70 | * |
|
71 | * Permissions: |
|
72 | * r the file is readable |
|
73 | * w the file is writable |
|
74 | * x the file is executable |
|
75 | * - the indicated permission is not granted |
|
76 | * L mandatory locking occurs during access (the set-group-ID bit is |
|
77 | * on and the group execution bit is off) |
|
78 | * s the set-user-ID or set-group-ID bit is on, and the corresponding |
|
79 | * user or group execution bit is also on |
|
80 | * S undefined bit-state (the set-user-ID bit is on and the user |
|
81 | * execution bit is off) |
|
82 | * t the 1000 (octal) bit, or sticky bit, is on [see chmod(1)], and |
|
83 | * execution is on |
|
84 | * T the 1000 bit is turned on, and execution is off (undefined bit- |
|
85 | * state) |
|
86 | */ |
|
87 | private static final String REGEX = |
|
88 | "([bcdlfmpSs-])" |
|
89 | +"(((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-])))\\+?\\s+" |
|
90 | + "(\\d+)\\s+" |
|
91 | + "(\\S+)\\s+" |
|
92 | + "(?:(\\S+)\\s+)?" |
|
93 | + "(\\d+)\\s+" |
|
94 | ||
95 | /* |
|
96 | numeric or standard format date |
|
97 | */ |
|
98 | + "((?:\\d+[-/]\\d+[-/]\\d+)|(?:\\S+\\s+\\S+))\\s+" |
|
99 | ||
100 | /* |
|
101 | year (for non-recent standard format) |
|
102 | or time (for numeric or recent standard format |
|
103 | */ |
|
104 | + "(\\d+(?::\\d+)?)\\s+" |
|
105 | ||
106 | + "(\\S*)(\\s*.*)"; |
|
107 | ||
108 | ||
109 | /** |
|
110 | * The default constructor for a UnixFTPEntryParser object. |
|
111 | * |
|
112 | * @exception IllegalArgumentException |
|
113 | * Thrown if the regular expression is unparseable. Should not be seen |
|
114 | * under normal conditions. It it is seen, this is a sign that |
|
115 | * <code>REGEX</code> is not a valid regular expression. |
|
116 | */ |
|
117 | public UnixFTPEntryParser() |
|
118 | { |
|
119 | 46 | this(null); |
120 | 46 | } |
121 | ||
122 | /** |
|
123 | * This constructor allows the creation of a UnixFTPEntryParser object with |
|
124 | * something other than the default configuration. |
|
125 | * |
|
126 | * @param config The {@link FTPClientConfig configuration} object used to |
|
127 | * configure this parser. |
|
128 | * @exception IllegalArgumentException |
|
129 | * Thrown if the regular expression is unparseable. Should not be seen |
|
130 | * under normal conditions. It it is seen, this is a sign that |
|
131 | * <code>REGEX</code> is not a valid regular expression. |
|
132 | * @since 1.4 |
|
133 | */ |
|
134 | public UnixFTPEntryParser(FTPClientConfig config) |
|
135 | { |
|
136 | 47 | super(REGEX); |
137 | 47 | configure(config); |
138 | 47 | } |
139 | ||
140 | ||
141 | /** |
|
142 | * Parses a line of a unix (standard) FTP server file listing and converts |
|
143 | * it into a usable format in the form of an <code> FTPFile </code> |
|
144 | * instance. If the file listing line doesn't describe a file, |
|
145 | * <code> null </code> is returned, otherwise a <code> FTPFile </code> |
|
146 | * instance representing the files in the directory is returned. |
|
147 | * <p> |
|
148 | * @param entry A line of text from the file listing |
|
149 | * @return An FTPFile instance corresponding to the supplied entry |
|
150 | */ |
|
151 | public FTPFile parseFTPEntry(String entry) { |
|
152 | 77 | FTPFile file = new FTPFile(); |
153 | 77 | file.setRawListing(entry); |
154 | int type; |
|
155 | 77 | boolean isDevice = false; |
156 | ||
157 | 77 | if (matches(entry)) |
158 | { |
|
159 | 53 | String typeStr = group(1); |
160 | 53 | String hardLinkCount = group(15); |
161 | 53 | String usr = group(16); |
162 | 53 | String grp = group(17); |
163 | 53 | String filesize = group(18); |
164 | 53 | String datestr = group(19) + " " + group(20); |
165 | 53 | String name = group(21); |
166 | 53 | String endtoken = group(22); |
167 | ||
168 | try |
|
169 | { |
|
170 | 53 | file.setTimestamp(super.parseTimestamp(datestr)); |
171 | } |
|
172 | 9 | catch (ParseException e) |
173 | { |
|
174 | 9 | return null; // this is a parsing failure too. |
175 | 44 | } |
176 | ||
177 | ||
178 | // bcdlfmpSs- |
|
179 | 44 | switch (typeStr.charAt(0)) |
180 | { |
|
181 | case 'd': |
|
182 | 9 | type = FTPFile.DIRECTORY_TYPE; |
183 | 9 | break; |
184 | case 'l': |
|
185 | 4 | type = FTPFile.SYMBOLIC_LINK_TYPE; |
186 | 4 | break; |
187 | case 'b': |
|
188 | case 'c': |
|
189 | 2 | isDevice = true; |
190 | // break; - fall through |
|
191 | case 'f': |
|
192 | case '-': |
|
193 | 31 | type = FTPFile.FILE_TYPE; |
194 | 31 | break; |
195 | default: |
|
196 | 0 | type = FTPFile.UNKNOWN_TYPE; |
197 | } |
|
198 | ||
199 | 44 | file.setType(type); |
200 | ||
201 | 44 | int g = 4; |
202 | 176 | for (int access = 0; access < 3; access++, g += 4) |
203 | { |
|
204 | // Use != '-' to avoid having to check for suid and sticky bits |
|
205 | 132 | file.setPermission(access, FTPFile.READ_PERMISSION, |
206 | (!group(g).equals("-"))); |
|
207 | 132 | file.setPermission(access, FTPFile.WRITE_PERMISSION, |
208 | (!group(g + 1).equals("-"))); |
|
209 | ||
210 | 132 | String execPerm = group(g + 2); |
211 | 132 | if (!execPerm.equals("-") && !Character.isUpperCase(execPerm.charAt(0))) |
212 | { |
|
213 | 58 | file.setPermission(access, FTPFile.EXECUTE_PERMISSION, true); |
214 | } |
|
215 | else |
|
216 | { |
|
217 | 74 | file.setPermission(access, FTPFile.EXECUTE_PERMISSION, false); |
218 | } |
|
219 | } |
|
220 | ||
221 | 44 | if (!isDevice) |
222 | { |
|
223 | try |
|
224 | { |
|
225 | 42 | file.setHardLinkCount(Integer.parseInt(hardLinkCount)); |
226 | } |
|
227 | 0 | catch (NumberFormatException e) |
228 | { |
|
229 | // intentionally do nothing |
|
230 | 42 | } |
231 | } |
|
232 | ||
233 | 44 | file.setUser(usr); |
234 | 44 | file.setGroup(grp); |
235 | ||
236 | try |
|
237 | { |
|
238 | 44 | file.setSize(Long.parseLong(filesize)); |
239 | } |
|
240 | 0 | catch (NumberFormatException e) |
241 | { |
|
242 | // intentionally do nothing |
|
243 | 44 | } |
244 | ||
245 | 44 | if (null == endtoken) |
246 | { |
|
247 | 0 | file.setName(name); |
248 | } |
|
249 | else |
|
250 | { |
|
251 | // oddball cases like symbolic links, file names |
|
252 | // with spaces in them. |
|
253 | 44 | name += endtoken; |
254 | 44 | if (type == FTPFile.SYMBOLIC_LINK_TYPE) |
255 | { |
|
256 | ||
257 | 4 | int end = name.indexOf(" -> "); |
258 | // Give up if no link indicator is present |
|
259 | 4 | if (end == -1) |
260 | { |
|
261 | 2 | file.setName(name); |
262 | } |
|
263 | else |
|
264 | { |
|
265 | 2 | file.setName(name.substring(0, end)); |
266 | 2 | file.setLink(name.substring(end + 4)); |
267 | } |
|
268 | ||
269 | } |
|
270 | else |
|
271 | { |
|
272 | 40 | file.setName(name); |
273 | } |
|
274 | } |
|
275 | 44 | return file; |
276 | } |
|
277 | 24 | return null; |
278 | } |
|
279 | ||
280 | /** |
|
281 | * Defines a default configuration to be used when this class is |
|
282 | * instantiated without a {@link FTPClientConfig FTPClientConfig} |
|
283 | * parameter being specified. |
|
284 | * @return the default configuration for this parser. |
|
285 | */ |
|
286 | protected FTPClientConfig getDefaultConfiguration() { |
|
287 | 54 | return new FTPClientConfig( |
288 | FTPClientConfig.SYST_UNIX, |
|
289 | DEFAULT_DATE_FORMAT, |
|
290 | DEFAULT_RECENT_DATE_FORMAT, |
|
291 | null, class="keyword">null, class="keyword">null); |
|
292 | } |
|
293 | ||
294 | ||
295 | ||
296 | ||
297 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |