%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.commons.net.ftp.FTPListParseEngine |
|
|
1 | /* |
|
2 | * Copyright 2004 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; |
|
17 | ||
18 | import java.io.BufferedReader; |
|
19 | import java.io.IOException; |
|
20 | import java.io.InputStream; |
|
21 | import java.io.InputStreamReader; |
|
22 | import java.util.Iterator; |
|
23 | import java.util.LinkedList; |
|
24 | import java.util.List; |
|
25 | import java.util.ListIterator; |
|
26 | ||
27 | ||
28 | /** |
|
29 | * This class handles the entire process of parsing a listing of |
|
30 | * file entries from the server. |
|
31 | * <p> |
|
32 | * This object defines a two-part parsing mechanism. |
|
33 | * <p> |
|
34 | * The first part is comprised of reading the raw input into an internal |
|
35 | * list of strings. Every item in this list corresponds to an actual |
|
36 | * file. All extraneous matter emitted by the server will have been |
|
37 | * removed by the end of this phase. This is accomplished in conjunction |
|
38 | * with the FTPFileEntryParser associated with this engine, by calling |
|
39 | * its methods <code>readNextEntry()</code> - which handles the issue of |
|
40 | * what delimits one entry from another, usually but not always a line |
|
41 | * feed and <code>preParse()</code> - which handles removal of |
|
42 | * extraneous matter such as the preliminary lines of a listing, removal |
|
43 | * of duplicates on versioning systems, etc. |
|
44 | * <p> |
|
45 | * The second part is composed of the actual parsing, again in conjunction |
|
46 | * with the particular parser used by this engine. This is controlled |
|
47 | * by an iterator over the internal list of strings. This may be done |
|
48 | * either in block mode, by calling the <code>getNext()</code> and |
|
49 | * <code>getPrevious()</code> methods to provide "paged" output of less |
|
50 | * than the whole list at one time, or by calling the |
|
51 | * <code>getFiles()</code> method to return the entire list. |
|
52 | * <p> |
|
53 | * Examples: |
|
54 | * <p> |
|
55 | * Paged access: |
|
56 | * <pre> |
|
57 | * FTPClient f=FTPClient(); |
|
58 | * f.connect(server); |
|
59 | * f.login(username, password); |
|
60 | * FTPListParseEngine engine = f.initiateListParsing(directory); |
|
61 | * |
|
62 | * while (engine.hasNext()) { |
|
63 | * FTPFile[] files = engine.getNext(25); // "page size" you want |
|
64 | * //do whatever you want with these files, display them, etc. |
|
65 | * //expensive FTPFile objects not created until needed. |
|
66 | * } |
|
67 | * </pre> |
|
68 | * <p> |
|
69 | * For unpaged access, simply use FTPClient.listFiles(). That method |
|
70 | * uses this class transparently. |
|
71 | * @version $Id: FTPListParseEngine.java 155429 2005-02-26 13:13:04Z dirkv $ |
|
72 | */ |
|
73 | public class FTPListParseEngine { |
|
74 | 2 | private List entries = new LinkedList(); |
75 | 2 | private ListIterator _internalIterator = entries.listIterator(); |
76 | ||
77 | 2 | FTPFileEntryParser parser = null; |
78 | ||
79 | 2 | public FTPListParseEngine(FTPFileEntryParser parser) { |
80 | 2 | this.parser = parser; |
81 | 2 | } |
82 | ||
83 | /** |
|
84 | * handle the iniitial reading and preparsing of the list returned by |
|
85 | * the server. After this method has completed, this object will contain |
|
86 | * a list of unparsed entries (Strings) each referring to a unique file |
|
87 | * on the server. |
|
88 | * |
|
89 | * @param stream input stream provided by the server socket. |
|
90 | * |
|
91 | * @exception IOException |
|
92 | * thrown on any failure to read from the sever. |
|
93 | */ |
|
94 | public void readServerList(InputStream stream, String encoding) |
|
95 | throws IOException |
|
96 | { |
|
97 | 2 | this.entries = new LinkedList(); |
98 | 2 | readStream(stream, encoding); |
99 | 2 | this.parser.preParse(class="keyword">this.entries); |
100 | 2 | resetIterator(); |
101 | 2 | } |
102 | ||
103 | /** |
|
104 | * handle the iniitial reading and preparsing of the list returned by |
|
105 | * the server. After this method has completed, this object will contain |
|
106 | * a list of unparsed entries (Strings) each referring to a unique file |
|
107 | * on the server. |
|
108 | * |
|
109 | * @param stream input stream provided by the server socket. |
|
110 | * |
|
111 | * @exception IOException |
|
112 | * thrown on any failure to read from the sever. |
|
113 | * |
|
114 | * @deprecated The version of this method which takes an encoding should be used. |
|
115 | */ |
|
116 | public void readServerList(InputStream stream) |
|
117 | throws IOException |
|
118 | { |
|
119 | 2 | readServerList(stream, null); |
120 | 2 | } |
121 | ||
122 | ||
123 | ||
124 | /** |
|
125 | * Internal method for reading the input into the <code>entries</code> list. |
|
126 | * After this method has completed, <code>entries</code> will contain a |
|
127 | * collection of entries (as defined by |
|
128 | * <code>FTPFileEntryParser.readNextEntry()</code>), but this may contain |
|
129 | * various non-entry preliminary lines from the server output, duplicates, |
|
130 | * and other data that will not be part of the final listing. |
|
131 | * |
|
132 | * @param stream The socket stream on which the input will be read. |
|
133 | * @param encoding The encoding to use. |
|
134 | * |
|
135 | * @exception IOException |
|
136 | * thrown on any failure to read the stream |
|
137 | */ |
|
138 | private void readStream(InputStream stream, String encoding) throws IOException |
|
139 | { |
|
140 | BufferedReader reader; |
|
141 | 2 | if (encoding == null) |
142 | { |
|
143 | 2 | reader = new BufferedReader(class="keyword">new InputStreamReader(stream)); |
144 | } |
|
145 | else |
|
146 | { |
|
147 | 0 | reader = new BufferedReader(class="keyword">new InputStreamReader(stream, encoding)); |
148 | } |
|
149 | ||
150 | 2 | String line = this.parser.readNextEntry(reader); |
151 | ||
152 | 14 | while (line != null) |
153 | { |
|
154 | 12 | this.entries.add(line); |
155 | 12 | line = this.parser.readNextEntry(reader); |
156 | } |
|
157 | 2 | reader.close(); |
158 | 2 | } |
159 | ||
160 | /** |
|
161 | * Returns an array of at most <code>quantityRequested</code> FTPFile |
|
162 | * objects starting at this object's internal iterator's current position. |
|
163 | * If fewer than <code>quantityRequested</code> such |
|
164 | * elements are available, the returned array will have a length equal |
|
165 | * to the number of entries at and after after the current position. |
|
166 | * If no such entries are found, this array will have a length of 0. |
|
167 | * |
|
168 | * After this method is called this object's internal iterator is advanced |
|
169 | * by a number of positions equal to the size of the array returned. |
|
170 | * |
|
171 | * @param quantityRequested |
|
172 | * the maximum number of entries we want to get. |
|
173 | * |
|
174 | * @return an array of at most <code>quantityRequested</code> FTPFile |
|
175 | * objects starting at the current position of this iterator within its |
|
176 | * list and at least the number of elements which exist in the list at |
|
177 | * and after its current position. |
|
178 | * <p><b> |
|
179 | * NOTE:</b> This array may contain null members if any of the |
|
180 | * individual file listings failed to parse. The caller should |
|
181 | * check each entry for null before referencing it. |
|
182 | */ |
|
183 | public FTPFile[] getNext(int quantityRequested) { |
|
184 | 0 | List tmpResults = new LinkedList(); |
185 | 0 | int count = quantityRequested; |
186 | 0 | while (count > 0 && this._internalIterator.hasNext()) { |
187 | 0 | String entry = (String) this._internalIterator.next(); |
188 | 0 | FTPFile temp = this.parser.parseFTPEntry(entry); |
189 | 0 | tmpResults.add(temp); |
190 | 0 | count--; |
191 | } |
|
192 | 0 | return (FTPFile[]) tmpResults.toArray(new FTPFile[0]); |
193 | ||
194 | } |
|
195 | ||
196 | /** |
|
197 | * Returns an array of at most <code>quantityRequested</code> FTPFile |
|
198 | * objects starting at this object's internal iterator's current position, |
|
199 | * and working back toward the beginning. |
|
200 | * |
|
201 | * If fewer than <code>quantityRequested</code> such |
|
202 | * elements are available, the returned array will have a length equal |
|
203 | * to the number of entries at and after after the current position. |
|
204 | * If no such entries are found, this array will have a length of 0. |
|
205 | * |
|
206 | * After this method is called this object's internal iterator is moved |
|
207 | * back by a number of positions equal to the size of the array returned. |
|
208 | * |
|
209 | * @param quantityRequested |
|
210 | * the maximum number of entries we want to get. |
|
211 | * |
|
212 | * @return an array of at most <code>quantityRequested</code> FTPFile |
|
213 | * objects starting at the current position of this iterator within its |
|
214 | * list and at least the number of elements which exist in the list at |
|
215 | * and after its current position. This array will be in the same order |
|
216 | * as the underlying list (not reversed). |
|
217 | * <p><b> |
|
218 | * NOTE:</b> This array may contain null members if any of the |
|
219 | * individual file listings failed to parse. The caller should |
|
220 | * check each entry for null before referencing it. |
|
221 | */ |
|
222 | public FTPFile[] getPrevious(int quantityRequested) { |
|
223 | 0 | List tmpResults = new LinkedList(); |
224 | 0 | int count = quantityRequested; |
225 | 0 | while (count > 0 && this._internalIterator.hasPrevious()) { |
226 | 0 | String entry = (String) this._internalIterator.previous(); |
227 | 0 | FTPFile temp = this.parser.parseFTPEntry(entry); |
228 | 0 | tmpResults.add(0,temp); |
229 | 0 | count--; |
230 | } |
|
231 | 0 | return (FTPFile[]) tmpResults.toArray(new FTPFile[0]); |
232 | } |
|
233 | ||
234 | /** |
|
235 | * Returns an array of FTPFile objects containing the whole list of |
|
236 | * files returned by the server as read by this object's parser. |
|
237 | * |
|
238 | * @return an array of FTPFile objects containing the whole list of |
|
239 | * files returned by the server as read by this object's parser. |
|
240 | * <p><b> |
|
241 | * NOTE:</b> This array may contain null members if any of the |
|
242 | * individual file listings failed to parse. The caller should |
|
243 | * check each entry for null before referencing it. |
|
244 | * @exception IOException |
|
245 | */ |
|
246 | public FTPFile[] getFiles() |
|
247 | throws IOException |
|
248 | { |
|
249 | 2 | List tmpResults = new LinkedList(); |
250 | 2 | Iterator iter = this.entries.iterator(); |
251 | 11 | while (iter.hasNext()) { |
252 | 9 | String entry = (String) iter.next(); |
253 | 9 | FTPFile temp = this.parser.parseFTPEntry(entry); |
254 | 9 | tmpResults.add(temp); |
255 | } |
|
256 | 2 | return (FTPFile[]) tmpResults.toArray(new FTPFile[0]); |
257 | ||
258 | } |
|
259 | ||
260 | /** |
|
261 | * convenience method to allow clients to know whether this object's |
|
262 | * internal iterator's current position is at the end of the list. |
|
263 | * |
|
264 | * @return true if internal iterator is not at end of list, false |
|
265 | * otherwise. |
|
266 | */ |
|
267 | public boolean hasNext() { |
|
268 | 0 | return _internalIterator.hasNext(); |
269 | } |
|
270 | ||
271 | /** |
|
272 | * convenience method to allow clients to know whether this object's |
|
273 | * internal iterator's current position is at the beginning of the list. |
|
274 | * |
|
275 | * @return true if internal iterator is not at beginning of list, false |
|
276 | * otherwise. |
|
277 | */ |
|
278 | public boolean hasPrevious() { |
|
279 | 0 | return _internalIterator.hasPrevious(); |
280 | } |
|
281 | ||
282 | /** |
|
283 | * resets this object's internal iterator to the beginning of the list. |
|
284 | */ |
|
285 | public void resetIterator() { |
|
286 | 2 | this._internalIterator = class="keyword">this.entries.listIterator(); |
287 | 2 | } |
288 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |