| %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 | 4 | private List entries = new LinkedList(); |
| 75 | 4 | private ListIterator _internalIterator = entries.listIterator(); |
| 76 | ||
| 77 | 4 | FTPFileEntryParser parser = null; |
| 78 | ||
| 79 | 4 | public FTPListParseEngine(FTPFileEntryParser parser) { |
| 80 | 4 | this.parser = parser; |
| 81 | 4 | } |
| 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 | 4 | this.entries = new LinkedList(); |
| 98 | 4 | readStream(stream, encoding); |
| 99 | 4 | this.parser.preParse(class="keyword">this.entries); |
| 100 | 4 | resetIterator(); |
| 101 | 4 | } |
| 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 | 4 | readServerList(stream, null); |
| 120 | 4 | } |
| 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 | 4 | if (encoding == null) |
| 142 | { |
|
| 143 | 4 | 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 | 4 | String line = this.parser.readNextEntry(reader); |
| 151 | ||
| 152 | 28 | while (line != null) |
| 153 | { |
|
| 154 | 24 | this.entries.add(line); |
| 155 | 24 | line = this.parser.readNextEntry(reader); |
| 156 | } |
|
| 157 | 4 | reader.close(); |
| 158 | 4 | } |
| 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 | 4 | List tmpResults = new LinkedList(); |
| 250 | 4 | Iterator iter = this.entries.iterator(); |
| 251 | 22 | while (iter.hasNext()) { |
| 252 | 18 | String entry = (String) iter.next(); |
| 253 | 18 | FTPFile temp = this.parser.parseFTPEntry(entry); |
| 254 | 18 | tmpResults.add(temp); |
| 255 | } |
|
| 256 | 4 | 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 | 4 | this._internalIterator = class="keyword">this.entries.listIterator(); |
| 287 | 4 | } |
| 288 | } |
| This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |