KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > 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 JavaDoc;
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 JavaDoc DEFAULT_MONTHS =
39         "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)";
40     
41     static final String JavaDoc DEFAULT_DATE_FORMAT
42         = "MMM d yyyy"; //Nov 9 2001
43

44     static final String JavaDoc DEFAULT_RECENT_DATE_FORMAT
45         = "MMM d HH:mm"; //Nov 9 20:06
46

47     static final String JavaDoc 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     public static final FTPClientConfig NUMERIC_DATE_CONFIG =
63         new FTPClientConfig(
64                 FTPClientConfig.SYST_UNIX,
65                 NUMERIC_DATE_FORMAT,
66                 null, null, null, 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 JavaDoc 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         this(null);
120     }
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         super(REGEX);
137         configure(config);
138     }
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 JavaDoc entry) {
152         FTPFile file = new FTPFile();
153         file.setRawListing(entry);
154         int type;
155         boolean isDevice = false;
156
157         if (matches(entry))
158         {
159             String JavaDoc typeStr = group(1);
160             String JavaDoc hardLinkCount = group(15);
161             String JavaDoc usr = group(16);
162             String JavaDoc grp = group(17);
163             String JavaDoc filesize = group(18);
164             String JavaDoc datestr = group(19) + " " + group(20);
165             String JavaDoc name = group(21);
166             String JavaDoc endtoken = group(22);
167
168             try
169             {
170                 file.setTimestamp(super.parseTimestamp(datestr));
171             }
172             catch (ParseException JavaDoc e)
173             {
174                 return null; // this is a parsing failure too.
175
}
176             
177             
178             // bcdlfmpSs-
179
switch (typeStr.charAt(0))
180             {
181             case 'd':
182                 type = FTPFile.DIRECTORY_TYPE;
183                 break;
184             case 'l':
185                 type = FTPFile.SYMBOLIC_LINK_TYPE;
186                 break;
187             case 'b':
188             case 'c':
189                 isDevice = true;
190                 // break; - fall through
191
case 'f':
192             case '-':
193                 type = FTPFile.FILE_TYPE;
194                 break;
195             default:
196                 type = FTPFile.UNKNOWN_TYPE;
197             }
198
199             file.setType(type);
200
201             int g = 4;
202             for (int access = 0; access < 3; access++, g += 4)
203             {
204                 // Use != '-' to avoid having to check for suid and sticky bits
205
file.setPermission(access, FTPFile.READ_PERMISSION,
206                                    (!group(g).equals("-")));
207                 file.setPermission(access, FTPFile.WRITE_PERMISSION,
208                                    (!group(g + 1).equals("-")));
209
210                 String JavaDoc execPerm = group(g + 2);
211                 if (!execPerm.equals("-") && !Character.isUpperCase(execPerm.charAt(0)))
212                 {
213                     file.setPermission(access, FTPFile.EXECUTE_PERMISSION, true);
214                 }
215                 else
216                 {
217                     file.setPermission(access, FTPFile.EXECUTE_PERMISSION, false);
218                 }
219             }
220
221             if (!isDevice)
222             {
223                 try
224                 {
225                     file.setHardLinkCount(Integer.parseInt(hardLinkCount));
226                 }
227                 catch (NumberFormatException JavaDoc e)
228                 {
229                     // intentionally do nothing
230
}
231             }
232
233             file.setUser(usr);
234             file.setGroup(grp);
235
236             try
237             {
238                 file.setSize(Long.parseLong(filesize));
239             }
240             catch (NumberFormatException JavaDoc e)
241             {
242                 // intentionally do nothing
243
}
244             
245             if (null == endtoken)
246             {
247                 file.setName(name);
248             }
249             else
250             {
251                 // oddball cases like symbolic links, file names
252
// with spaces in them.
253
name += endtoken;
254                 if (type == FTPFile.SYMBOLIC_LINK_TYPE)
255                 {
256
257                     int end = name.indexOf(" -> ");
258                     // Give up if no link indicator is present
259
if (end == -1)
260                     {
261                         file.setName(name);
262                     }
263                     else
264                     {
265                         file.setName(name.substring(0, end));
266                         file.setLink(name.substring(end + 4));
267                     }
268
269                 }
270                 else
271                 {
272                     file.setName(name);
273                 }
274             }
275             return file;
276         }
277         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         return new FTPClientConfig(
288                 FTPClientConfig.SYST_UNIX,
289                 DEFAULT_DATE_FORMAT,
290                 DEFAULT_RECENT_DATE_FORMAT,
291                 null, null, null);
292     }
293     
294     
295     
296
297 }
298
Popular Tags