Coverage Report - wjhk.jupload2.upload.FileUploadThreadFTP
 
Classes in this File Line Coverage Branch Coverage Complexity
FileUploadThreadFTP
0 %
0/178
0 %
0/68
5,923
 
 1  
 //
 2  
 // $Id: FileUploadThreadFTP.java 136 2007-05-12 20:15:36 +0000 (sam., 12 mai
 3  
 // 2007) felfert $
 4  
 //
 5  
 // jupload - A file upload applet.
 6  
 // Copyright 2007 The JUpload Team
 7  
 //
 8  
 // Created: 2007-01-01
 9  
 // Creator: etienne_sf
 10  
 // Last modified: $Date: 2014-05-01 19:03:23 +0200 (jeu., 01 mai 2014) $
 11  
 //
 12  
 // This program is free software; you can redistribute it and/or modify it under
 13  
 // the terms of the GNU General Public License as published by the Free Software
 14  
 // Foundation; either version 2 of the License, or (at your option) any later
 15  
 // version. This program is distributed in the hope that it will be useful, but
 16  
 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 17  
 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 18  
 // details. You should have received a copy of the GNU General Public License
 19  
 // along with this program; if not, write to the Free Software Foundation, Inc.,
 20  
 // 675 Mass Ave, Cambridge, MA 02139, USA.
 21  
 
 22  
 package wjhk.jupload2.upload;
 23  
 
 24  
 import java.io.BufferedOutputStream;
 25  
 import java.io.IOException;
 26  
 import java.io.OutputStream;
 27  
 import java.util.Iterator;
 28  
 import java.util.SortedSet;
 29  
 import java.util.StringTokenizer;
 30  
 import java.util.TreeSet;
 31  
 import java.util.concurrent.BlockingQueue;
 32  
 import java.util.regex.Matcher;
 33  
 import java.util.regex.Pattern;
 34  
 
 35  
 import org.apache.commons.net.ftp.FTP;
 36  
 import org.apache.commons.net.ftp.FTPClient;
 37  
 import org.apache.commons.net.ftp.FTPConnectionClosedException;
 38  
 import org.apache.commons.net.ftp.FTPReply;
 39  
 
 40  
 import wjhk.jupload2.exception.JUploadException;
 41  
 import wjhk.jupload2.exception.JUploadExceptionUploadFailed;
 42  
 import wjhk.jupload2.exception.JUploadIOException;
 43  
 import wjhk.jupload2.policies.UploadPolicy;
 44  
 
 45  
 /**
 46  
  * The FileUploadThreadFTP class is intended to extend the functionality of the
 47  
  * JUpload applet and allow it to handle ftp:// addresses. <br>
 48  
  * Note: this class is not a V4 of the FTP upload. It is named V4, as it
 49  
  * inherits from the {@link FileUploadThread} class. <br>
 50  
  * <br>
 51  
  * In order to use it, simply change the postURL argument to the applet to
 52  
  * contain the appropriate ftp:// link. The format is:
 53  
  * 
 54  
  * <pre>
 55  
  *         ftp://username:password@myhost.com:21/directory
 56  
  * </pre>
 57  
  * 
 58  
  * Where everything but the host is optional. There is another parameter that
 59  
  * can be passed to the applet named 'binary' which will set the file transfer
 60  
  * mode based on the value. The possible values here are 'true' or 'false'. It
 61  
  * was intended to be somewhat intelligent by looking at the file extension and
 62  
  * basing the transfer mode on that, however, it was never implemented. Feel
 63  
  * free to! Also, there is a 'passive' parameter which also has a value of
 64  
  * 'true' or 'false' which sets the connection type to either active or passive
 65  
  * mode.
 66  
  * 
 67  
  * @author Evin Callahan (inheritance from DefaultUploadThread built by
 68  
  *         etienne_sf)
 69  
  * @author Daystar Computer Services
 70  
  * @see FileUploadThread
 71  
  * @see DefaultFileUploadThread
 72  
  * @version 1.0, 01 Jan 2007 * Update march 2007, etienne_sf Adaptation to match
 73  
  *          all JUpload functions: <DIR> <LI>Inheritance from the
 74  
  *          {@link FileUploadThread} class, <LI>Use of the UploadFileData class,
 75  
  *          <LI>Before upload file preparation, <LI>Upload stop by the user. <LI>
 76  
  *          </DIR>
 77  
  */
 78  
 public class FileUploadThreadFTP extends DefaultFileUploadThread {
 79  
 
 80  
     // ////////////////////////////////////////////////////////////////////////////////////
 81  
     // /////////////////////// PRIVATE ATTRIBUTES
 82  
     // ///////////////////////////////////////
 83  
     // ////////////////////////////////////////////////////////////////////////////////////
 84  
 
 85  
     // ////////////////////////////////////////////////////////////////////////////////////
 86  
     // /////////////////////// PRIVATE ATTRIBUTES
 87  
     // ///////////////////////////////////////
 88  
     // ////////////////////////////////////////////////////////////////////////////////////
 89  
 
 90  
     /**
 91  
      * The output stream, where the current file should be written. This output
 92  
      * stream should not be used. The buffered one is much faster.
 93  
      */
 94  0
     private OutputStream ftpOutputStream = null;
 95  
 
 96  
     /**
 97  
      * The buffered stream, that the application should use for upload.
 98  
      */
 99  0
     private BufferedOutputStream bufferedOutputStream = null;
 100  
 
 101  
     private Matcher uriMatch;
 102  
 
 103  
     // the client that does the actual connecting to the server
 104  0
     private FTPClient ftp = new FTPClient();
 105  
 
 106  
     /** FTP user, taken from the postURL applet parameter */
 107  
     private String user;
 108  
 
 109  
     /** FTP password, taken from the postURL applet parameter */
 110  
     private String pass;
 111  
 
 112  
     /** FTP target host, taken from the postURL applet parameter */
 113  
     private String host;
 114  
 
 115  
     /** FTP target port, taken from the postURL applet parameter */
 116  
     private String port;
 117  
 
 118  
     /**
 119  
      * FTP target root folder for the upload, taken from the postURL applet
 120  
      * parameter
 121  
      */
 122  
     private String ftpRootFolder;
 123  
 
 124  
     /**
 125  
      * Indicates whether the connection to the FTP server is open or not. This
 126  
      * allows to connect once on the FTP server, for multiple file upload.
 127  
      */
 128  0
     private boolean bConnected = false;
 129  
 
 130  
     /**
 131  
      * This pattern defines the groups and pattern of the ftp syntax.
 132  
      */
 133  0
     public final Pattern ftpPattern = Pattern
 134  0
             .compile("^ftp://(([^:]+):([^\\@]+)\\@)?([^/:]+):?([0-9]+)?(/(.*))?$");
 135  
 
 136  
     /**
 137  
      * Creates a new instance. Performs the connection to the server based on
 138  
      * the matcher created in the main.
 139  
      * 
 140  
      * @param uploadPolicy
 141  
      * @param packetQueue The queue from wich packets to upload are available.
 142  
      * @param fileUploadManagerThread
 143  
      * @throws JUploadException
 144  
      * @throws IllegalArgumentException if any error occurs. message is error
 145  
      */
 146  
     public FileUploadThreadFTP(UploadPolicy uploadPolicy,
 147  
             BlockingQueue<UploadFilePacket> packetQueue,
 148  
             FileUploadManagerThread fileUploadManagerThread)
 149  
             throws JUploadException {
 150  0
         super("FileUploadThreadFTP thread", packetQueue, uploadPolicy,
 151  
                 fileUploadManagerThread);
 152  0
         this.uploadPolicy.displayDebug("[FileUploadThreadFTP]  Using "
 153  0
                 + this.getClass().getName(), 30);
 154  
 
 155  
         // Some coherence checks, for parameter given to the applet.
 156  
 
 157  
         // stringUploadSuccess: unused in FTP mode. Must be null.
 158  0
         if (uploadPolicy.getStringUploadSuccess() != null) {
 159  0
             uploadPolicy
 160  0
                     .displayWarn("FTP mode: stringUploadSuccess parameter ignored (forced to null)");
 161  0
             uploadPolicy.setProperty(UploadPolicy.PROP_STRING_UPLOAD_SUCCESS,
 162  
                     null);
 163  
         }
 164  
 
 165  
         // nbFilesPerRequest: must be 1 in FTP mode.
 166  0
         if (uploadPolicy.getNbFilesPerRequest() != 1) {
 167  0
             uploadPolicy
 168  0
                     .displayWarn("FTP mode: nbFilesPerRequest parameter ignored (forced to 1)");
 169  0
             uploadPolicy.setProperty(UploadPolicy.PROP_NB_FILES_PER_REQUEST,
 170  
                     "1");
 171  
         }
 172  
 
 173  
         // maxChunkSize: must be unlimited (no chunk management in FTP mode).
 174  0
         if (uploadPolicy.getMaxChunkSize() != Long.MAX_VALUE) {
 175  0
             uploadPolicy
 176  0
                     .displayWarn("FTP mode: maxChunkSize parameter ignored (forced to Long.MAX_VALUE)");
 177  0
             uploadPolicy.setProperty(UploadPolicy.PROP_MAX_CHUNK_SIZE,
 178  0
                     Long.toString(Long.MAX_VALUE));
 179  
         }
 180  0
     }
 181  
 
 182  
     /** @see DefaultFileUploadThread#beforeRequest(UploadFilePacket) */
 183  
     @Override
 184  
     void beforeRequest(UploadFilePacket packet) throws JUploadException {
 185  
 
 186  
         // If we're connected, we need to check the connection.
 187  0
         if (this.bConnected) {
 188  
             // Let's check the connection is still Ok.
 189  
             try {
 190  0
                 this.ftp.sendNoOp();
 191  0
             } catch (FTPConnectionClosedException eClosed) {
 192  
                 // Let's forget this connection.
 193  0
                 this.bConnected = false;
 194  0
             } catch (IOException e) {
 195  
                 // commons-net seems to more generate a specific exception, once
 196  
                 // migrated from 1.4.1 to 2.2.
 197  
                 // Let's check the error message. Hope it won't change,
 198  
                 // depending on the user settings..
 199  0
                 if (e.getMessage().equals("Connection is not open")) {
 200  
                     // Let's forget this connection.
 201  0
                     this.bConnected = false;
 202  
                 } else {
 203  0
                     throw new JUploadIOException(e.getClass().getName()
 204  
                             + " while checking FTP connection to the server", e);
 205  
                 }
 206  0
             }
 207  
         }
 208  
 
 209  
         // If not already connected ... we connect to the server.
 210  0
         if (!this.bConnected) {
 211  
             // Let's connect to the FTP server.
 212  0
             String url = this.uploadPolicy.getPostURL();
 213  0
             this.uriMatch = this.ftpPattern.matcher(url);
 214  0
             if (!this.uriMatch.matches()) {
 215  0
                 throw new JUploadException("invalid URI: " + url);
 216  
             }
 217  0
             this.user = this.uriMatch.group(2) == null ? "anonymous"
 218  0
                     : this.uriMatch.group(2);
 219  0
             this.pass = this.uriMatch.group(3) == null ? "JUpload"
 220  0
                     : this.uriMatch.group(3);
 221  0
             this.host = this.uriMatch.group(4); // no default server
 222  0
             this.port = this.uriMatch.group(5) == null ? "21" : this.uriMatch
 223  0
                     .group(5);
 224  0
             this.ftpRootFolder = (this.uriMatch.group(7) == null) ? null : "/"
 225  0
                     + this.uriMatch.group(7);
 226  
             // The last character must be a slash
 227  0
             if (this.ftpRootFolder != null && !this.ftpRootFolder.endsWith("/")) {
 228  0
                 this.ftpRootFolder += "/";
 229  
             }
 230  
 
 231  
             // do connect.. any error will be thrown up the chain
 232  
             try {
 233  0
                 this.ftp.setDefaultPort(Integer.parseInt(this.port));
 234  0
                 this.ftp.connect(this.host);
 235  0
                 this.uploadPolicy.displayDebug(
 236  
                         "[FileUploadThreadFTP] Connected to " + this.host, 10);
 237  0
                 this.uploadPolicy.displayDebug(this.ftp.getReplyString(), 80);
 238  
 
 239  0
                 if (!FTPReply.isPositiveCompletion(this.ftp.getReplyCode()))
 240  0
                     throw new JUploadException("FTP server refused connection.");
 241  
 
 242  
                 // given the login information, do the login
 243  0
                 this.ftp.login(this.user, this.pass);
 244  0
                 this.uploadPolicy.displayDebug("[FileUploadThreadFTP] "
 245  0
                         + this.ftp.getReplyString(), 80);
 246  
 
 247  0
                 if (!FTPReply.isPositiveCompletion(this.ftp.getReplyCode()))
 248  0
                     throw new JUploadException(
 249  
                             "Invalid ftp username / password");
 250  
 
 251  0
                 this.bConnected = true;
 252  0
             } catch (JUploadException jue) {
 253  
                 // No special action, we keep the exception untouched
 254  0
                 throw jue;
 255  0
             } catch (IOException ioe) {
 256  0
                 throw new JUploadIOException(ioe.getClass().getName()
 257  
                         + "[FTP] Could not connect to server ("
 258  0
                         + ioe.getMessage() + ")", ioe);
 259  0
             } catch (Exception e) {
 260  0
                 throw new JUploadException(e.getClass().getName()
 261  
                         + "[FTP] Could not connect to server ("
 262  0
                         + e.getMessage() + ")", e);
 263  0
             }
 264  
 
 265  
             // now do the same for the passive/active parameter
 266  0
             if (this.uploadPolicy.getFtpTransfertPassive()) {
 267  0
                 this.ftp.enterLocalPassiveMode();
 268  
             } else {
 269  0
                 this.ftp.enterLocalActiveMode();
 270  
             }
 271  
 
 272  
         } // if(!bConnected)
 273  0
     }
 274  
 
 275  
     /** @see DefaultFileUploadThread#afterFile(UploadFileData) */
 276  
     @Override
 277  
     void afterFile(UploadFileData uploadFileData) {
 278  
         // Nothing to do
 279  0
     }
 280  
 
 281  
     /** @see DefaultFileUploadThread#beforeFile(UploadFilePacket, UploadFileData) */
 282  
     @Override
 283  
     void beforeFile(UploadFilePacket uploadFilePacket,
 284  
             UploadFileData uploadFileData) throws JUploadException {
 285  0
         String workingDir = null;
 286  0
         String action = "Starting beforeFile";
 287  
         try {
 288  
             // if configured to, we go to the relative sub-folder of the current
 289  
             // file, or on the root of the postURL.
 290  0
             if (this.uploadPolicy.getFtpCreateDirectoryStructure()) {
 291  
                 // We create the FTP directory structure
 292  
                 // TODO: call it once for all files, not once for each file.
 293  0
                 action = "Before createDirectoryStructure";
 294  0
                 createDirectoryStructure(uploadFilePacket);
 295  
 
 296  0
                 workingDir = this.ftpRootFolder
 297  0
                         + uploadFileData.getRelativeDir();
 298  
                 // We want to have only slashes, as anti-slashes may generate
 299  
                 // FTP errors.
 300  0
                 workingDir = workingDir.replace("\\", "/");
 301  
 
 302  0
                 this.uploadPolicy
 303  0
                         .displayDebug(
 304  
                                 "[FileUploadThreadFTP] ftpCreateDirectoryStructure: Changing working directory to: "
 305  
                                         + workingDir, 80);
 306  
             } else {
 307  0
                 workingDir = this.ftpRootFolder;
 308  
             }
 309  
 
 310  0
             if (workingDir != null && !workingDir.equals("")
 311  0
                     && !workingDir.equals(".")) {
 312  0
                 action = "Before changeWorkingDirectory";
 313  0
                 this.ftp.changeWorkingDirectory(workingDir);
 314  0
                 action = "After changeWorkingDirectory";
 315  0
                 this.uploadPolicy.displayDebug("[FileUploadThreadFTP] "
 316  0
                         + this.ftp.getReplyString(), 80);
 317  
             }
 318  
 
 319  0
             if (!FTPReply.isPositiveCompletion(this.ftp.getReplyCode())) {
 320  0
                 throw new JUploadException(
 321  
                         "[FTP] Error while changing directory to: "
 322  0
                                 + workingDir + " (" + this.ftp.getReplyString()
 323  
                                 + ")");
 324  
             }
 325  
 
 326  0
             action = "Before setTransferType";
 327  0
             setTransferType(uploadFileData);
 328  0
             action = "After setTransferType";
 329  
 
 330  
             // No delete, as the user may not have the right for that. We use,
 331  
             // later, the store command:
 332  
             // If the file already exists, it will be replaced.
 333  
             // ftp.deleteFile(filesToUpload[index].getFileName());
 334  
 
 335  
             // Let's open the stream for this file.
 336  0
             action = "Before storeFileStream";
 337  0
             this.ftpOutputStream = this.ftp.storeFileStream(uploadFileData
 338  0
                     .getFileName());
 339  0
             action = "After storeFileStream";
 340  0
             if (this.ftpOutputStream == null) {
 341  0
                 throw new JUploadIOException(
 342  
                         "Stream connection to the server error. Check that your path on the URL is valid. postURL used is: "
 343  0
                                 + this.uploadPolicy.getPostURL());
 344  
             }
 345  
             // The upload is done through a BufferedOutputStream. This speed up
 346  
             // the upload in an unbelievable way ...
 347  0
             this.bufferedOutputStream = new BufferedOutputStream(
 348  
                     this.ftpOutputStream);
 349  0
         } catch (IOException e) {
 350  0
             throw new JUploadIOException(e.getClass().getName()
 351  
                     + " in the action: " + action, e);
 352  0
         }
 353  0
     }
 354  
 
 355  
     /** @see DefaultFileUploadThread#cleanAll() */
 356  
     @Override
 357  
     void cleanAll() {
 358  
         try {
 359  0
             if (this.ftp.isConnected()) {
 360  0
                 this.ftp.disconnect();
 361  0
                 this.uploadPolicy.displayDebug(
 362  
                         "[FileUploadThreadFTP] disconnected", 50);
 363  
             }
 364  0
         } catch (IOException e) {
 365  
             // then we arent connected
 366  0
             this.uploadPolicy.displayDebug(
 367  
                     "[FileUploadThreadFTP] Not connected", 50);
 368  0
         } finally {
 369  0
             this.ftpOutputStream = null;
 370  0
             this.bufferedOutputStream = null;
 371  0
         }
 372  0
     }
 373  
 
 374  
     /** @see DefaultFileUploadThread#cleanRequest() */
 375  
     @Override
 376  
     void cleanRequest() throws JUploadException {
 377  0
         if (this.bufferedOutputStream != null) {
 378  
             try {
 379  0
                 this.bufferedOutputStream.close();
 380  0
                 this.ftpOutputStream.close();
 381  0
                 if (!this.ftp.completePendingCommand()) {
 382  0
                     throw new JUploadExceptionUploadFailed(
 383  
                             "ftp.completePendingCommand() returned false");
 384  
                 }
 385  0
             } catch (IOException e) {
 386  0
                 throw new JUploadException(e);
 387  
             } finally {
 388  0
                 this.bufferedOutputStream = null;
 389  0
             }
 390  
         }
 391  0
     }
 392  
 
 393  
     /**
 394  
      * @throws JUploadIOException
 395  
      * @see DefaultFileUploadThread#finishRequest()
 396  
      */
 397  
     @Override
 398  
     int finishRequest() throws JUploadException {
 399  
         try {
 400  0
             getOutputStream().flush();
 401  0
             return 200;
 402  0
         } catch (IOException ioe) {
 403  0
             throw new JUploadIOException("FileUploadThreadFTP.finishRequest()",
 404  
                     ioe);
 405  0
         } catch (Exception e) {
 406  
             // When the user may not override an existing file, I got a
 407  
             // NullPointerException. Let's trap all errors here.
 408  0
             throw new JUploadException(
 409  
                     "FileUploadThreadFTP.finishRequest()  (check the user permission on the server)",
 410  
                     e);
 411  
         }
 412  
     }
 413  
 
 414  
     /** @see DefaultFileUploadThread#getAdditionnalBytesForUpload(UploadFileData) */
 415  
     @Override
 416  
     long getAdditionnalBytesForUpload(UploadFileData uploadFileData) {
 417  
         // Default: no additional byte.
 418  0
         return 0;
 419  
     }
 420  
 
 421  
     /** @see DefaultFileUploadThread#getOutputStream() */
 422  
     @Override
 423  
     OutputStream getOutputStream() {
 424  0
         return this.bufferedOutputStream;
 425  
     }
 426  
 
 427  
     /** @see DefaultFileUploadThread#startRequest(long, boolean, int, boolean) */
 428  
     @Override
 429  
     void startRequest(long contentLength, boolean bChunkEnabled, int chunkPart,
 430  
             boolean bLastChunk) {
 431  
         // Nothing to do
 432  0
     }
 433  
 
 434  
     /**
 435  
      * Will set the binary/ascii value based on the parameters to the applet.
 436  
      * This could be done by file extension too but it is not implemented.
 437  
      * 
 438  
      * @param uploadFileData The file that we want to upload.
 439  
      * @throws IOException if an error occurs while setting mode data
 440  
      */
 441  
     private void setTransferType(UploadFileData uploadFileData)
 442  
             throws JUploadIOException {
 443  
         try {
 444  
             // read the value given from the user
 445  0
             if (this.uploadPolicy.getFtpTransfertBinary()) {
 446  0
                 this.ftp.setFileType(FTP.BINARY_FILE_TYPE);
 447  
             } else {
 448  0
                 this.ftp.setFileType(FTP.ASCII_FILE_TYPE);
 449  
             }
 450  0
         } catch (IOException ioe) {
 451  0
             throw new JUploadIOException(
 452  
                     "Cannot set transfert binary or ascii mode (binary: "
 453  0
                             + this.uploadPolicy.getFtpTransfertBinary() + ")",
 454  
                     ioe);
 455  0
         }
 456  0
     }
 457  
 
 458  
     /**
 459  
      * Create all relative sub-directories, so the structure on the server
 460  
      * reflects the structure of the uploaded files.
 461  
      * 
 462  
      * @throws JUploadIOException When an error occurs during folder creation
 463  
      */
 464  
     // A tester
 465  
     private void createDirectoryStructure(UploadFilePacket packet)
 466  
             throws JUploadIOException {
 467  0
         SortedSet<String> foldersToCreate = new TreeSet<String>();
 468  
         String folderName;
 469  
         String intermediateFolderName;
 470  
         StringTokenizer st;
 471  
 
 472  
         // 1) Let's find all folders and sub-folders we'll have to create.
 473  0
         for (UploadFileData uploadFileData : packet) {
 474  0
             if (isInterrupted()) {
 475  0
                 break;
 476  
             }
 477  0
             folderName = uploadFileData.getRelativeDir();
 478  0
             folderName = folderName.replaceAll("\\\\", "/");
 479  
             // Do we already have this folder ?
 480  0
             if (!foldersToCreate.contains(folderName)) {
 481  
                 // We add this folder, and all missing intermediate ones
 482  0
                 st = new StringTokenizer(folderName, "/");
 483  0
                 intermediateFolderName = this.ftpRootFolder;
 484  0
                 while (st.hasMoreTokens()) {
 485  0
                     intermediateFolderName += st.nextToken() + "/";
 486  0
                     if (!foldersToCreate.contains(intermediateFolderName)) {
 487  0
                         this.uploadPolicy.displayDebug(
 488  
                                 "FTP structure identification: Adding subfolder "
 489  
                                         + intermediateFolderName, 80);
 490  0
                         foldersToCreate.add(intermediateFolderName);
 491  
                     }
 492  
                 }
 493  
             }
 494  0
         }
 495  
 
 496  
         // 2) Let's create theses folders.
 497  
         try {
 498  
             String folder;
 499  0
             for (Iterator<String> it = foldersToCreate.iterator(); it.hasNext();) {
 500  0
                 folder = it.next();
 501  
 
 502  
                 // The folder is in the list of folder to create, created from
 503  
                 // the file list.
 504  
                 // We first check if the folder already exist.
 505  0
                 this.ftp.changeWorkingDirectory(folder);
 506  0
                 if (FTPReply.isPositiveCompletion(this.ftp.getReplyCode())) {
 507  0
                     this.uploadPolicy.displayDebug(
 508  
                             "[FileUploadThreadFTP] Folder " + folder
 509  
                                     + " already exist", 80);
 510  
                 } else {
 511  
                     // We can not guess if it's because the folder
 512  
                     // doesn't exist, or if it's a 'real' error.
 513  
                     // Let's try to create the folder.
 514  0
                     this.ftp.mkd(folder);
 515  0
                     this.uploadPolicy.displayDebug(
 516  
                             "[FileUploadThreadFTP] Folder " + folder
 517  
                                     + " created", 80);
 518  0
                     if (!FTPReply.isPositiveCompletion(this.ftp.getReplyCode())) {
 519  0
                         throw new JUploadIOException(
 520  
                                 "Error while creating folder '"
 521  
                                         + folder
 522  
                                         + "' ("
 523  0
                                         + this.ftp.getReplyString().replaceAll(
 524  
                                                 "\r\n", "") + ")");
 525  
                     }
 526  
                 }
 527  
             }
 528  0
         } catch (IOException ioe) {
 529  0
             throw new JUploadIOException(ioe.getClass().getName()
 530  
                     + " in FileUploadThreadFTP.createDirectoryStructure()", ioe);
 531  0
         }
 532  0
     }
 533  
 
 534  
     /** {@inheritDoc} */
 535  
     @Override
 536  
     void interruptionReceived() {
 537  0
         cleanAll();
 538  0
     }
 539  
 }