1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.net.ftp.parser;
17 import java.io.BufferedReader;
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.text.ParseException;
21 import java.util.StringTokenizer;
22
23 import org.apache.commons.net.ftp.FTPClientConfig;
24 import org.apache.commons.net.ftp.FTPFile;
25 import org.apache.commons.net.ftp.FTPListParseEngine;
26
27 /**
28 * Implementation FTPFileEntryParser and FTPFileListParser for VMS Systems.
29 * This is a sample of VMS LIST output
30 *
31 * "1-JUN.LIS;1 9/9 2-JUN-1998 07:32:04 [GROUP,OWNER] (RWED,RWED,RWED,RE)",
32 * "1-JUN.LIS;2 9/9 2-JUN-1998 07:32:04 [GROUP,OWNER] (RWED,RWED,RWED,RE)",
33 * "DATA.DIR;1 1/9 2-JUN-1998 07:32:04 [GROUP,OWNER] (RWED,RWED,RWED,RE)",
34 * <P><B>
35 * Note: VMSFTPEntryParser can only be instantiated through the
36 * DefaultFTPParserFactory by classname. It will not be chosen
37 * by the autodetection scheme.
38 * </B>
39 * <P>
40 *
41 * @author <a href="Winston.Ojeda@qg.com">Winston Ojeda</a>
42 * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
43 * @author <a href="sestegra@free.fr">Stephane ESTE-GRACIAS</a>
44 * @version $Id: VMSFTPEntryParser.java 155429 2005-02-26 13:13:04Z dirkv $
45 *
46 * @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions)
47 * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
48 */
49 public class VMSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
50 {
51
52 private static final String DEFAULT_DATE_FORMAT
53 = "d-MMM-yyyy HH:mm:ss";
54
55 /**
56 * this is the regular expression used by this parser.
57 */
58 private static final String REGEX =
59 "(.*;[0-9]+)\\s*"
60 + "(\\d+)/\\d+\\s*"
61 +"(\\S+)\\s+(\\S+)\\s+"
62 + "\\[(([0-9$A-Za-z_]+)|([0-9$A-Za-z_]+),([0-9$a-zA-Z_]+))\\]?\\s*"
63 + "\\([a-zA-Z]*,[a-zA-Z]*,[a-zA-Z]*,[a-zA-Z]*\\)";
64
65
66
67 /**
68 * Constructor for a VMSFTPEntryParser object.
69 *
70 * @exception IllegalArgumentException
71 * Thrown if the regular expression is unparseable. Should not be seen
72 * under normal conditions. It it is seen, this is a sign that
73 * <code>REGEX</code> is not a valid regular expression.
74 */
75 public VMSFTPEntryParser()
76 {
77 this(null);
78 }
79
80 /**
81 * This constructor allows the creation of a VMSFTPEntryParser object with
82 * something other than the default configuration.
83 *
84 * @param config The {@link FTPClientConfig configuration} object used to
85 * configure this parser.
86 * @exception IllegalArgumentException
87 * Thrown if the regular expression is unparseable. Should not be seen
88 * under normal conditions. It it is seen, this is a sign that
89 * <code>REGEX</code> is not a valid regular expression.
90 * @since 1.4
91 */
92 public VMSFTPEntryParser(FTPClientConfig config)
93 {
94 super(REGEX);
95 configure(config);
96 }
97
98
99
100 /***
101 * Parses an FTP server file listing and converts it into a usable format
102 * in the form of an array of <code> FTPFile </code> instances. If the
103 * file list contains no files, <code> null </code> should be
104 * returned, otherwise an array of <code> FTPFile </code> instances
105 * representing the files in the directory is returned.
106 * <p>
107 * @param listStream The InputStream from which the file list should be
108 * read.
109 * @return The list of file information contained in the given path. null
110 * if the list could not be obtained or if there are no files in
111 * the directory.
112 * @exception IOException If an I/O error occurs reading the listStream.
113 ***/
114 public FTPFile[] parseFileList(InputStream listStream) throws IOException {
115 FTPListParseEngine engine = new FTPListParseEngine(this);
116 engine.readServerList(listStream);
117 return engine.getFiles();
118 }
119
120
121
122 /**
123 * Parses a line of a VMS FTP server file listing and converts it into a
124 * usable format in the form of an <code> FTPFile </code> instance. If the
125 * file listing line doesn't describe a file, <code> null </code> is
126 * returned, otherwise a <code> FTPFile </code> instance representing the
127 * files in the directory is returned.
128 * <p>
129 * @param entry A line of text from the file listing
130 * @return An FTPFile instance corresponding to the supplied entry
131 */
132 public FTPFile parseFTPEntry(String entry)
133 {
134
135 long longBlock = 512;
136
137 if (matches(entry))
138 {
139 FTPFile f = new FTPFile();
140 f.setRawListing(entry);
141 String name = group(1);
142 String size = group(2);
143 String datestr = group(3)+" "+group(4);
144 String owner = group(5);
145 try
146 {
147 f.setTimestamp(super.parseTimestamp(datestr));
148 }
149 catch (ParseException e)
150 {
151 return null;
152 }
153
154
155 String grp;
156 String user;
157 StringTokenizer t = new StringTokenizer(owner, ",");
158 switch (t.countTokens()) {
159 case 1:
160 grp = null;
161 user = t.nextToken();
162 break;
163 case 2:
164 grp = t.nextToken();
165 user = t.nextToken();
166 break;
167 default:
168 grp = null;
169 user = null;
170 }
171
172 if (name.lastIndexOf(".DIR") != -1)
173 {
174 f.setType(FTPFile.DIRECTORY_TYPE);
175 }
176 else
177 {
178 f.setType(FTPFile.FILE_TYPE);
179 }
180
181
182 if (isVersioning())
183 {
184 f.setName(name);
185 }
186 else
187 {
188 name = name.substring(0, name.lastIndexOf(";"));
189 f.setName(name);
190 }
191
192
193 long sizeInBytes = Long.parseLong(size) * longBlock;
194 f.setSize(sizeInBytes);
195
196 f.setGroup(grp);
197 f.setUser(user);
198
199
200
201
202 return f;
203 }
204 return null;
205 }
206
207
208 /**
209 * Reads the next entry using the supplied BufferedReader object up to
210 * whatever delemits one entry from the next. This parser cannot use
211 * the default implementation of simply calling BufferedReader.readLine(),
212 * because one entry may span multiple lines.
213 *
214 * @param reader The BufferedReader object from which entries are to be
215 * read.
216 *
217 * @return A string representing the next ftp entry or null if none found.
218 * @exception IOException thrown on any IO Error reading from the reader.
219 */
220 public String readNextEntry(BufferedReader reader) throws IOException
221 {
222 String line = reader.readLine();
223 StringBuffer entry = new StringBuffer();
224 while (line != null)
225 {
226 if (line.startsWith("Directory") || line.startsWith("Total")) {
227 line = reader.readLine();
228 continue;
229 }
230
231 entry.append(line);
232 if (line.trim().endsWith(")"))
233 {
234 break;
235 }
236 line = reader.readLine();
237 }
238 return (entry.length() == 0 ? null : entry.toString());
239 }
240
241 protected boolean isVersioning() {
242 return false;
243 }
244
245 /**
246 * Defines a default configuration to be used when this class is
247 * instantiated without a {@link FTPClientConfig FTPClientConfig}
248 * parameter being specified.
249 * @return the default configuration for this parser.
250 */
251 protected FTPClientConfig getDefaultConfiguration() {
252 return new FTPClientConfig(
253 FTPClientConfig.SYST_VMS,
254 DEFAULT_DATE_FORMAT,
255 null, null, null, null);
256 }
257
258
259 }
260
261
262
263
264
265
266
267