Browse Source

split up large method - part 1

tobiasKaminsky 7 years ago
parent
commit
590e617c8a

+ 4 - 4
src/main/java/com/owncloud/android/files/services/FileUploader.java

@@ -615,8 +615,8 @@ public class FileUploader extends Service
                     if (isCreateRemoteFolder) {
                     if (isCreateRemoteFolder) {
                         newUpload.setRemoteFolderToBeCreated();
                         newUpload.setRemoteFolderToBeCreated();
                     }
                     }
-                    newUpload.addDatatransferProgressListener(this);
-                    newUpload.addDatatransferProgressListener((FileUploaderBinder) mBinder);
+                    newUpload.addDataTransferProgressListener(this);
+                    newUpload.addDataTransferProgressListener((FileUploaderBinder) mBinder);
 
 
                     newUpload.addRenameUploadListener(this);
                     newUpload.addRenameUploadListener(this);
 
 
@@ -671,8 +671,8 @@ public class FileUploader extends Service
                     whileChargingOnly
                     whileChargingOnly
             );
             );
 
 
-            newUpload.addDatatransferProgressListener(this);
-            newUpload.addDatatransferProgressListener((FileUploaderBinder) mBinder);
+            newUpload.addDataTransferProgressListener(this);
+            newUpload.addDataTransferProgressListener((FileUploaderBinder) mBinder);
 
 
             newUpload.addRenameUploadListener(this);
             newUpload.addRenameUploadListener(this);
 
 

+ 205 - 164
src/main/java/com/owncloud/android/operations/UploadFileOperation.java

@@ -1,4 +1,4 @@
-/**
+/*
  * ownCloud Android client application
  * ownCloud Android client application
  *
  *
  * @author David A. Velasco
  * @author David A. Velasco
@@ -128,7 +128,7 @@ public class UploadFileOperation extends SyncOperation {
      * Local path to file which is to be uploaded (before any possible renaming or moving).
      * Local path to file which is to be uploaded (before any possible renaming or moving).
      */
      */
     private String mOriginalStoragePath = null;
     private String mOriginalStoragePath = null;
-    private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
+    private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<>();
     private OnRenameListener mRenameUploadListener;
     private OnRenameListener mRenameUploadListener;
 
 
     private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
     private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
@@ -309,7 +309,7 @@ public class UploadFileOperation extends SyncOperation {
         return mDataTransferListeners;
         return mDataTransferListeners;
     }
     }
 
 
-    public void addDatatransferProgressListener(OnDatatransferProgressListener listener) {
+    public void addDataTransferProgressListener(OnDatatransferProgressListener listener) {
         synchronized (mDataTransferListeners) {
         synchronized (mDataTransferListeners) {
             mDataTransferListeners.add(listener);
             mDataTransferListeners.add(listener);
         }
         }
@@ -321,7 +321,7 @@ public class UploadFileOperation extends SyncOperation {
         }
         }
     }
     }
 
 
-    public void removeDatatransferProgressListener(OnDatatransferProgressListener listener) {
+    public void removeDataTransferProgressListener(OnDatatransferProgressListener listener) {
         synchronized (mDataTransferListeners) {
         synchronized (mDataTransferListeners) {
             mDataTransferListeners.remove(listener);
             mDataTransferListeners.remove(listener);
         }
         }
@@ -451,35 +451,10 @@ public class UploadFileOperation extends SyncOperation {
 
 
         try {
         try {
 
 
-            if (Device.getNetworkType(mContext).equals(JobRequest.NetworkType.ANY) ||
-                    ConnectivityUtils.isInternetWalled(mContext)) {
-                return new RemoteOperationResult(ResultCode.NO_NETWORK_CONNECTION);
-            }
-
-            /// Check that connectivity conditions are met and delays the upload otherwise
-            if (mOnWifiOnly && !Device.getNetworkType(mContext).equals(JobRequest.NetworkType.UNMETERED)) {
-                Log_OC.d(TAG, "Upload delayed until WiFi is available: " + getRemotePath());
-                return new RemoteOperationResult(ResultCode.DELAYED_FOR_WIFI);
-            }
-
-            // Check if charging conditions are met and delays the upload otherwise
-            if (mWhileChargingOnly && (!Device.getBatteryStatus(mContext).isCharging() && Device.getBatteryStatus
-                    (mContext).getBatteryPercent() < 1)) {
-                Log_OC.d(TAG, "Upload delayed until the device is charging: " + getRemotePath());
-                return new RemoteOperationResult(ResultCode.DELAYED_FOR_CHARGING);
-            }
-
-            // Check that device is not in power save mode
-            if (!mIgnoringPowerSaveMode && PowerUtils.isPowerSaveMode(mContext)) {
-                Log_OC.d(TAG, "Upload delayed because device is in power save mode: " + getRemotePath());
-                return new RemoteOperationResult(ResultCode.DELAYED_IN_POWER_SAVE_MODE);
-            }
-
-            /// check if the file continues existing before schedule the operation
-            if (!originalFile.exists()) {
-                Log_OC.d(TAG, mOriginalStoragePath + " not exists anymore");
-                return new RemoteOperationResult(ResultCode.LOCAL_FILE_NOT_FOUND);
-            }
+            // check conditions 
+            result = checkConditions (originalFile);
+                
+                /***** E2E *****/
 
 
             // Lock folder
             // Lock folder
             LockFileOperation lockFileOperation = new LockFileOperation(parentFile.getLocalId());
             LockFileOperation lockFileOperation = new LockFileOperation(parentFile.getLocalId());
@@ -525,48 +500,24 @@ public class UploadFileOperation extends SyncOperation {
                 throw new Exception("something wrong");
                 throw new Exception("something wrong");
             }
             }
 
 
-            /// automatic rename of file to upload in case of name collision in server
-            Log_OC.d(TAG, "Checking name collision in server");
-            if (!mForceOverwrite) {
-                String remotePath = getAvailableRemotePath(client, mRemotePath, metadata, true);
-                mWasRenamed = !remotePath.equals(mRemotePath);
-                if (mWasRenamed) {
-                    createNewOCFile(remotePath);
-                    Log_OC.d(TAG, "File renamed as " + remotePath);
-                }
-                mRemotePath = remotePath;
-                mRenameUploadListener.onRenameUpload();
-            }
+            /***** E2E *****/
 
 
-            if (mCancellationRequested.get()) {
-                throw new OperationCancelledException();
-            }
+            // check name collision
+            checkNameCollision(client);
 
 
             String expectedPath = FileStorageUtils.getDefaultSavePathFor(mAccount.name, mFile);
             String expectedPath = FileStorageUtils.getDefaultSavePathFor(mAccount.name, mFile);
             expectedFile = new File(expectedPath);
             expectedFile = new File(expectedPath);
 
 
-            /// copy the file locally before uploading
-            if (mLocalBehaviour == FileUploader.LOCAL_BEHAVIOUR_COPY &&
-                    !mOriginalStoragePath.equals(expectedPath)) {
-
-                String temporalPath = FileStorageUtils.getTemporalPath(mAccount.name) + mFile.getRemotePath();
-                mFile.setStoragePath(temporalPath);
-                temporalFile = new File(temporalPath);
-
-                result = copy(originalFile, temporalFile);
-                if (result != null) {
-                    return result;
-                }
-            }
-
-            if (mCancellationRequested.get()) {
-                throw new OperationCancelledException();
+            result = copyFile(originalFile, expectedPath);
+            if (result != null) {
+                return result;
             }
             }
 
 
             // Get the last modification date of the file from the file system
             // Get the last modification date of the file from the file system
             Long timeStampLong = originalFile.lastModified() / 1000;
             Long timeStampLong = originalFile.lastModified() / 1000;
             String timeStamp = timeStampLong.toString();
             String timeStamp = timeStampLong.toString();
 
 
+            /***** E2E *****/
 
 
             // Key
             // Key
             byte[] key = null;
             byte[] key = null;
@@ -612,10 +563,48 @@ public class UploadFileOperation extends SyncOperation {
             fileOutputStream.write(encryptedFile.encryptedBytes);
             fileOutputStream.write(encryptedFile.encryptedBytes);
             fileOutputStream.close();
             fileOutputStream.close();
 
 
+            /***** E2E *****/
+
+            FileChannel channel = null;
+            try {
+                channel = new RandomAccessFile(mFile.getStoragePath(), "rw").getChannel();
+                fileLock = channel.tryLock();
+            } catch (FileNotFoundException e) {
+                // this basically means that the file is on SD card
+                // try to copy file to temporary dir if it doesn't exist
+                String temporalPath = FileStorageUtils.getTemporalPath(mAccount.name) + mFile.getRemotePath();
+                mFile.setStoragePath(temporalPath);
+                temporalFile = new File(temporalPath);
+
+                Files.deleteIfExists(Paths.get(temporalPath));
+                result = copy(originalFile, temporalFile);
+
+                if (result == null) {
+                    if (temporalFile.length() == originalFile.length()) {
+                        channel = new RandomAccessFile(temporalFile.getAbsolutePath(), "rw").getChannel();
+                        fileLock = channel.tryLock();
+                    } else {
+                        result = new RemoteOperationResult(ResultCode.LOCK_FAILED);
+                    }
+                }
+            }
+
+            try {
+                size = channel.size();
+            } catch (IOException e1) {
+                size = new File(mFile.getStoragePath()).length();
+            }
+
+            for (OCUpload ocUpload : uploadsStorageManager.getAllStoredUploads()) {
+                if (ocUpload.getUploadId() == getOCUploadId()) {
+                    ocUpload.setFileSize(size);
+                    uploadsStorageManager.updateUpload(ocUpload);
+                    break;
+                }
+            }
+
             /// perform the upload
             /// perform the upload
-            if (mChunked &&
-                    (new File(mFile.getStoragePath())).length() >
-                            ChunkedUploadRemoteFileOperation.CHUNK_SIZE) {
+            if (mChunked && (size > ChunkedUploadRemoteFileOperation.CHUNK_SIZE)) {
                 mUploadOperation = new ChunkedUploadRemoteFileOperation(mContext, encryptedTempFile.getAbsolutePath(),
                 mUploadOperation = new ChunkedUploadRemoteFileOperation(mContext, encryptedTempFile.getAbsolutePath(),
                         mFile.getParentRemotePath() + encryptedFileName, mFile.getMimetype(),
                         mFile.getParentRemotePath() + encryptedFileName, mFile.getMimetype(),
                         mFile.getEtagInConflict(), timeStamp);
                         mFile.getEtagInConflict(), timeStamp);
@@ -674,11 +663,14 @@ public class UploadFileOperation extends SyncOperation {
 //            }
 //            }
 
 
             result = mUploadOperation.execute(client);
             result = mUploadOperation.execute(client);
+            if (result == null || result.isSuccess() && mUploadOperation != null) {
+                result = mUploadOperation.execute(client);
 
 
-            /// move local temporal file or original file to its corresponding
-            // location in the ownCloud local folder
-            if (!result.isSuccess() && result.getHttpCode() == HttpStatus.SC_PRECONDITION_FAILED) {
-                result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);
+                /// move local temporal file or original file to its corresponding
+                // location in the Nextcloud local folder
+                if (!result.isSuccess() && result.getHttpCode() == HttpStatus.SC_PRECONDITION_FAILED) {
+                    result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);
+                }
             }
             }
 
 
             if (result.isSuccess()) {
             if (result.isSuccess()) {
@@ -725,7 +717,6 @@ public class UploadFileOperation extends SyncOperation {
             result = new RemoteOperationResult(ResultCode.LOCK_FAILED);
             result = new RemoteOperationResult(ResultCode.LOCK_FAILED);
         } catch (Exception e) {
         } catch (Exception e) {
             result = new RemoteOperationResult(e);
             result = new RemoteOperationResult(e);
-
         } finally {
         } finally {
             mUploadStarted.set(false);
             mUploadStarted.set(false);
 
 
@@ -753,6 +744,7 @@ public class UploadFileOperation extends SyncOperation {
             if (result == null) {
             if (result == null) {
                 result = new RemoteOperationResult(ResultCode.UNKNOWN_ERROR);
                 result = new RemoteOperationResult(ResultCode.UNKNOWN_ERROR);
             }
             }
+
             if (result.isSuccess()) {
             if (result.isSuccess()) {
                 Log_OC.i(TAG, "Upload of " + mFile.getStoragePath() + " to " + mFile.getRemotePath() + ": " +
                 Log_OC.i(TAG, "Upload of " + mFile.getStoragePath() + " to " + mFile.getRemotePath() + ": " +
                         result.getLogMessage());
                         result.getLogMessage());
@@ -823,9 +815,51 @@ public class UploadFileOperation extends SyncOperation {
                 break;
                 break;
         }
         }
 
 
+        // TODO
+//        if (result.isSuccess()) {
+//            handleSuccessfulUpload(temporalFile, expectedFile, originalFile, client);
+//        } else if (result.getCode() == ResultCode.SYNC_CONFLICT) {
+//            getStorageManager().saveConflict(mFile, mFile.getEtagInConflict());
+//        }
+
         return result;
         return result;
     }
     }
 
 
+    private RemoteOperationResult checkConditions(File originalFile) {
+        if (Device.getNetworkType(mContext).equals(JobRequest.NetworkType.ANY) ||
+                ConnectivityUtils.isInternetWalled(mContext)) {
+            return new RemoteOperationResult(ResultCode.NO_NETWORK_CONNECTION);
+        }
+        
+        /// Check that connectivity conditions are met and delays the upload otherwise
+        // TODO verify if this can be deleted
+        if (mOnWifiOnly && !Device.getNetworkType(mContext).equals(JobRequest.NetworkType.UNMETERED)) {
+            Log_OC.d(TAG, "Upload delayed until WiFi is available: " + getRemotePath());
+            return new RemoteOperationResult(ResultCode.DELAYED_FOR_WIFI);
+        }
+
+        // TODO verify if this can be deleted
+        // Check if charging conditions are met and delays the upload otherwise
+        if (mWhileChargingOnly && !Device.isCharging(mContext)) {
+            Log_OC.d(TAG, "Upload delayed until the device is charging: " + getRemotePath());
+            return new RemoteOperationResult(ResultCode.DELAYED_FOR_CHARGING);
+        }
+
+        // Check that device is not in power save mode
+        if (!mIgnoringPowerSaveMode && UploadUtils.isPowerSaveMode(mContext)) {
+            Log_OC.d(TAG, "Upload delayed because device is in power save mode: " + getRemotePath());
+            return new RemoteOperationResult(ResultCode.DELAYED_IN_POWER_SAVE_MODE);
+        }
+
+        /// check if the file continues existing before schedule the operation
+        if (!originalFile.exists()) {
+            Log_OC.d(TAG, mOriginalStoragePath + " not exists anymore");
+            return new RemoteOperationResult(ResultCode.LOCAL_FILE_NOT_FOUND);
+        }
+
+        return null;
+    }
+
     private RemoteOperationResult normalUpload(OwnCloudClient client) {
     private RemoteOperationResult normalUpload(OwnCloudClient client) {
         RemoteOperationResult result = null;
         RemoteOperationResult result = null;
         File temporalFile = null;
         File temporalFile = null;
@@ -835,60 +869,18 @@ public class UploadFileOperation extends SyncOperation {
         long size = 0;
         long size = 0;
 
 
         try {
         try {
-            /// Check that connectivity conditions are met and delays the upload otherwise
-            if (mOnWifiOnly && !Device.getNetworkType(mContext).equals(JobRequest.NetworkType.UNMETERED)) {
-                Log_OC.d(TAG, "Upload delayed until WiFi is available: " + getRemotePath());
-                return new RemoteOperationResult(ResultCode.DELAYED_FOR_WIFI);
-            }
+            // check conditions
+            result = checkConditions(originalFile);
 
 
-            // Check if charging conditions are met and delays the upload otherwise
-            if (mWhileChargingOnly && !Device.isCharging(mContext)) {
-                Log_OC.d(TAG, "Upload delayed until the device is charging: " + getRemotePath());
-                return new RemoteOperationResult(ResultCode.DELAYED_FOR_CHARGING);
-            }
-
-            /// check if the file continues existing before schedule the operation
-            if (!originalFile.exists()) {
-                Log_OC.d(TAG, mOriginalStoragePath + " not exists anymore");
-                return new RemoteOperationResult(ResultCode.LOCAL_FILE_NOT_FOUND);
-            }
-
-            /// automatic rename of file to upload in case of name collision in server
-            Log_OC.d(TAG, "Checking name collision in server");
-            if (!mForceOverwrite) {
-                String remotePath = getAvailableRemotePath(client, mRemotePath, null, false);
-                mWasRenamed = !remotePath.equals(mRemotePath);
-                if (mWasRenamed) {
-                    createNewOCFile(remotePath);
-                    Log_OC.d(TAG, "File renamed as " + remotePath);
-                }
-                mRemotePath = remotePath;
-                mRenameUploadListener.onRenameUpload();
-            }
-
-            if (mCancellationRequested.get()) {
-                throw new OperationCancelledException();
-            }
+            // check name collision
+            checkNameCollision(client);
 
 
             String expectedPath = FileStorageUtils.getDefaultSavePathFor(mAccount.name, mFile);
             String expectedPath = FileStorageUtils.getDefaultSavePathFor(mAccount.name, mFile);
             expectedFile = new File(expectedPath);
             expectedFile = new File(expectedPath);
 
 
-            /// copy the file locally before uploading
-            if (mLocalBehaviour == FileUploader.LOCAL_BEHAVIOUR_COPY &&
-                    !mOriginalStoragePath.equals(expectedPath)) {
-
-                String temporalPath = FileStorageUtils.getTemporalPath(mAccount.name) + mFile.getRemotePath();
-                mFile.setStoragePath(temporalPath);
-                temporalFile = new File(temporalPath);
-
-                result = copy(originalFile, temporalFile);
-                if (result != null) {
-                    return result;
-                }
-            }
-
-            if (mCancellationRequested.get()) {
-                throw new OperationCancelledException();
+            result = copyFile(originalFile, expectedPath);
+            if (result != null) {
+                return result;
             }
             }
 
 
             // Get the last modification date of the file from the file system
             // Get the last modification date of the file from the file system
@@ -933,13 +925,11 @@ public class UploadFileOperation extends SyncOperation {
                 }
                 }
             }
             }
 
 
-            /// perform the upload
-            if (mChunked &&
-                    (size > ChunkedUploadRemoteFileOperation.CHUNK_SIZE)) {
+            // perform the upload
+            if (mChunked && (size > ChunkedUploadRemoteFileOperation.CHUNK_SIZE)) {
                 mUploadOperation = new ChunkedUploadRemoteFileOperation(mContext, mFile.getStoragePath(),
                 mUploadOperation = new ChunkedUploadRemoteFileOperation(mContext, mFile.getStoragePath(),
                         mFile.getRemotePath(), mFile.getMimetype(), mFile.getEtagInConflict(), timeStamp);
                         mFile.getRemotePath(), mFile.getMimetype(), mFile.getEtagInConflict(), timeStamp);
             } else {
             } else {
-
                 mUploadOperation = new UploadRemoteFileOperation(mFile.getStoragePath(),
                 mUploadOperation = new UploadRemoteFileOperation(mFile.getStoragePath(),
                         mFile.getRemotePath(), mFile.getMimetype(), mFile.getEtagInConflict(), timeStamp);
                         mFile.getRemotePath(), mFile.getMimetype(), mFile.getEtagInConflict(), timeStamp);
             }
             }
@@ -957,14 +947,11 @@ public class UploadFileOperation extends SyncOperation {
                 result = mUploadOperation.execute(client);
                 result = mUploadOperation.execute(client);
 
 
                 /// move local temporal file or original file to its corresponding
                 /// move local temporal file or original file to its corresponding
-                // location in the ownCloud local folder
+                // location in the Nextcloud local folder
                 if (!result.isSuccess() && result.getHttpCode() == HttpStatus.SC_PRECONDITION_FAILED) {
                 if (!result.isSuccess() && result.getHttpCode() == HttpStatus.SC_PRECONDITION_FAILED) {
                     result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);
                     result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);
                 }
                 }
-
             }
             }
-
-
         } catch (FileNotFoundException e) {
         } catch (FileNotFoundException e) {
             Log_OC.d(TAG, mOriginalStoragePath + " not exists anymore");
             Log_OC.d(TAG, mOriginalStoragePath + " not exists anymore");
             result = new RemoteOperationResult(ResultCode.LOCAL_FILE_NOT_FOUND);
             result = new RemoteOperationResult(ResultCode.LOCAL_FILE_NOT_FOUND);
@@ -973,7 +960,6 @@ public class UploadFileOperation extends SyncOperation {
             result = new RemoteOperationResult(ResultCode.LOCK_FAILED);
             result = new RemoteOperationResult(ResultCode.LOCK_FAILED);
         } catch (Exception e) {
         } catch (Exception e) {
             result = new RemoteOperationResult(e);
             result = new RemoteOperationResult(e);
-
         } finally {
         } finally {
             mUploadStarted.set(false);
             mUploadStarted.set(false);
 
 
@@ -992,6 +978,7 @@ public class UploadFileOperation extends SyncOperation {
             if (result == null) {
             if (result == null) {
                 result = new RemoteOperationResult(ResultCode.UNKNOWN_ERROR);
                 result = new RemoteOperationResult(ResultCode.UNKNOWN_ERROR);
             }
             }
+
             if (result.isSuccess()) {
             if (result.isSuccess()) {
                 Log_OC.i(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath + ": " +
                 Log_OC.i(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath + ": " +
                         result.getLogMessage());
                         result.getLogMessage());
@@ -1004,7 +991,6 @@ public class UploadFileOperation extends SyncOperation {
                         Log_OC.e(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath +
                         Log_OC.e(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath +
                                 ": " + result.getLogMessage(), result.getException());
                                 ": " + result.getLogMessage(), result.getException());
                     }
                     }
-
                 } else {
                 } else {
                     Log_OC.e(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath +
                     Log_OC.e(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath +
                             ": " + result.getLogMessage());
                             ": " + result.getLogMessage());
@@ -1013,9 +999,58 @@ public class UploadFileOperation extends SyncOperation {
         }
         }
 
 
         if (result.isSuccess()) {
         if (result.isSuccess()) {
+            handleSuccessfulUpload(temporalFile, expectedFile, originalFile, client);
+        } else if (result.getCode() == ResultCode.SYNC_CONFLICT) {
+            getStorageManager().saveConflict(mFile, mFile.getEtagInConflict());
+        }
+
+        return result;
+    }
+
+    private RemoteOperationResult copyFile(File originalFile, String expectedPath) throws OperationCancelledException,
+            IOException {
+        RemoteOperationResult result = null;
+
+        if (mLocalBehaviour == FileUploader.LOCAL_BEHAVIOUR_COPY && !mOriginalStoragePath.equals(expectedPath)) {
+            String temporalPath = FileStorageUtils.getTemporalPath(mAccount.name) + mFile.getRemotePath();
+            mFile.setStoragePath(temporalPath);
+            File temporalFile = new File(temporalPath);
+
+            result = copy(originalFile, temporalFile);
+        }
+
+        if (mCancellationRequested.get()) {
+            throw new OperationCancelledException();
+        }
+
+        return result;
+    }
+
+    private void checkNameCollision(OwnCloudClient client) throws OperationCancelledException {
+        /// automatic rename of file to upload in case of name collision in server
+        Log_OC.d(TAG, "Checking name collision in server");
+        if (!mForceOverwrite) {
+            // TODO encrypted always false?
+            String remotePath = getAvailableRemotePath(client, mRemotePath, null, false);
+            mWasRenamed = !remotePath.equals(mRemotePath);
+            if (mWasRenamed) {
+                createNewOCFile(remotePath);
+                Log_OC.d(TAG, "File renamed as " + remotePath);
+            }
+            mRemotePath = remotePath;
+            mRenameUploadListener.onRenameUpload();
+        }
 
 
-            if (mLocalBehaviour == FileUploader.LOCAL_BEHAVIOUR_FORGET) {
+        if (mCancellationRequested.get()) {
+            throw new OperationCancelledException();
+        }
+    }
 
 
+    private void handleSuccessfulUpload(File temporalFile, File expectedFile, File originalFile,
+                                        OwnCloudClient client) {
+        switch (mLocalBehaviour) {
+            case FileUploader.LOCAL_BEHAVIOUR_FORGET:
+            default:
                 String temporalPath = FileStorageUtils.getTemporalPath(mAccount.name) + mFile.getRemotePath();
                 String temporalPath = FileStorageUtils.getTemporalPath(mAccount.name) + mFile.getRemotePath();
                 if (mOriginalStoragePath.equals(temporalPath)) {
                 if (mOriginalStoragePath.equals(temporalPath)) {
                     // delete local file is was pre-copied in temporary folder (see .ui.helpers.UriUploader)
                     // delete local file is was pre-copied in temporary folder (see .ui.helpers.UriUploader)
@@ -1024,37 +1059,44 @@ public class UploadFileOperation extends SyncOperation {
                 }
                 }
                 mFile.setStoragePath("");
                 mFile.setStoragePath("");
                 saveUploadedFile(client);
                 saveUploadedFile(client);
+                break;
 
 
+            case FileUploader.LOCAL_BEHAVIOUR_DELETE:
+                Log_OC.d(TAG, "Delete source file");
 
 
-            } else if (mLocalBehaviour == FileUploader.LOCAL_BEHAVIOUR_DELETE) {
                 originalFile.delete();
                 originalFile.delete();
                 getStorageManager().deleteFileInMediaScan(originalFile.getAbsolutePath());
                 getStorageManager().deleteFileInMediaScan(originalFile.getAbsolutePath());
                 saveUploadedFile(client);
                 saveUploadedFile(client);
-            } else {
+                break;
 
 
-                if (temporalFile != null) {         // FileUploader.LOCAL_BEHAVIOUR_COPY
+            case FileUploader.LOCAL_BEHAVIOUR_COPY:
+                if (temporalFile != null) {
                     try {
                     try {
                         move(temporalFile, expectedFile);
                         move(temporalFile, expectedFile);
                     } catch (IOException e) {
                     } catch (IOException e) {
                         e.printStackTrace();
                         e.printStackTrace();
                     }
                     }
-                } else {                            // FileUploader.LOCAL_BEHAVIOUR_MOVE
-                    try {
-                        move(originalFile, expectedFile);
-                    } catch (IOException e) {
-                        e.printStackTrace();
-                    }
-                    getStorageManager().deleteFileInMediaScan(originalFile.getAbsolutePath());
                 }
                 }
                 mFile.setStoragePath(expectedFile.getAbsolutePath());
                 mFile.setStoragePath(expectedFile.getAbsolutePath());
                 saveUploadedFile(client);
                 saveUploadedFile(client);
                 FileDataStorageManager.triggerMediaScan(expectedFile.getAbsolutePath());
                 FileDataStorageManager.triggerMediaScan(expectedFile.getAbsolutePath());
-            }
-        } else if (result.getCode() == ResultCode.SYNC_CONFLICT) {
-            getStorageManager().saveConflict(mFile, mFile.getEtagInConflict());
-        }
+                break;
 
 
-        return result;
+            case FileUploader.LOCAL_BEHAVIOUR_MOVE:
+                String expectedPath = FileStorageUtils.getDefaultSavePathFor(mAccount.name, mFile);
+                expectedFile = new File(expectedPath);
+
+                try {
+                    move(originalFile, expectedFile);
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+                getStorageManager().deleteFileInMediaScan(originalFile.getAbsolutePath());
+                mFile.setStoragePath(expectedFile.getAbsolutePath());
+                saveUploadedFile(client);
+                FileDataStorageManager.triggerMediaScan(expectedFile.getAbsolutePath());
+                break;
+        }
     }
     }
 
 
     /**
     /**
@@ -1138,20 +1180,20 @@ public class UploadFileOperation extends SyncOperation {
      * Checks if remotePath does not exist in the server and returns it, or adds
      * Checks if remotePath does not exist in the server and returns it, or adds
      * a suffix to it in order to avoid the server file is overwritten.
      * a suffix to it in order to avoid the server file is overwritten.
      *
      *
-     * @param wc
-     * @param remotePath
-     * @param metadata
-     * @return
+     * @param client     OwnCloud client
+     * @param remotePath remote path of the file
+     * @param metadata   metadata of encrypted folder
+     * @return new remote path
      */
      */
-    private String getAvailableRemotePath(OwnCloudClient wc, String remotePath, DecryptedFolderMetadata metadata,
+    private String getAvailableRemotePath(OwnCloudClient client, String remotePath, DecryptedFolderMetadata metadata,
                                           boolean encrypted) {
                                           boolean encrypted) {
-        boolean check = existsFile(wc, remotePath, metadata, encrypted);
+        boolean check = existsFile(client, remotePath, metadata, encrypted);
         if (!check) {
         if (!check) {
             return remotePath;
             return remotePath;
         }
         }
 
 
         int pos = remotePath.lastIndexOf('.');
         int pos = remotePath.lastIndexOf('.');
-        String suffix = "";
+        String suffix;
         String extension = "";
         String extension = "";
         String remotePathWithoutExtension = "";
         String remotePathWithoutExtension = "";
         if (pos >= 0) {
         if (pos >= 0) {
@@ -1162,9 +1204,9 @@ public class UploadFileOperation extends SyncOperation {
         do {
         do {
             suffix = " (" + count + ")";
             suffix = " (" + count + ")";
             if (pos >= 0) {
             if (pos >= 0) {
-                check = existsFile(wc, remotePathWithoutExtension + suffix + "." + extension, metadata, encrypted);
+                check = existsFile(client, remotePathWithoutExtension + suffix + "." + extension, metadata, encrypted);
             } else {
             } else {
-                check = existsFile(wc, remotePath + suffix, metadata, encrypted);
+                check = existsFile(client, remotePath + suffix, metadata, encrypted);
             }
             }
             count++;
             count++;
         } while (check);
         } while (check);
@@ -1189,8 +1231,8 @@ public class UploadFileOperation extends SyncOperation {
 
 
             return false;
             return false;
         } else {
         } else {
-            ExistenceCheckRemoteOperation existsOperation =
-                    new ExistenceCheckRemoteOperation(remotePath, mContext, false);
+            ExistenceCheckRemoteOperation existsOperation = new ExistenceCheckRemoteOperation(remotePath, mContext,
+                    false);
             RemoteOperationResult result = existsOperation.execute(client);
             RemoteOperationResult result = existsOperation.execute(client);
             return result.isSuccess();
             return result.isSuccess();
         }
         }
@@ -1230,7 +1272,7 @@ public class UploadFileOperation extends SyncOperation {
      * @param sourceFile Source file to copy.
      * @param sourceFile Source file to copy.
      * @param targetFile Target location to copy the file.
      * @param targetFile Target location to copy the file.
      * @return {@link RemoteOperationResult}
      * @return {@link RemoteOperationResult}
-     * @throws IOException
+     * @throws IOException exception if file cannot be accessed
      */
      */
     private RemoteOperationResult copy(File sourceFile, File targetFile) throws IOException {
     private RemoteOperationResult copy(File sourceFile, File targetFile) throws IOException {
         Log_OC.d(TAG, "Copying local file");
         Log_OC.d(TAG, "Copying local file");
@@ -1315,13 +1357,13 @@ public class UploadFileOperation extends SyncOperation {
     /**
     /**
      * TODO rewrite with homogeneous fail handling, remove dependency on {@link RemoteOperationResult},
      * TODO rewrite with homogeneous fail handling, remove dependency on {@link RemoteOperationResult},
      * TODO     use Exceptions instead
      * TODO     use Exceptions instead
-     *
+     * <p>
      * TODO refactor both this and 'copy' in a single method
      * TODO refactor both this and 'copy' in a single method
      *
      *
      * @param sourceFile Source file to move.
      * @param sourceFile Source file to move.
      * @param targetFile Target location to move the file.
      * @param targetFile Target location to move the file.
-     * @return {@link RemoteOperationResult}
-     * @throws IOException
+     * @return {@link RemoteOperationResult} result from remote operation
+     * @throws IOException exception if file cannot be read/wrote
      */
      */
     private void move(File sourceFile, File targetFile) throws IOException {
     private void move(File sourceFile, File targetFile) throws IOException {
 
 
@@ -1360,11 +1402,10 @@ public class UploadFileOperation extends SyncOperation {
 
 
     /**
     /**
      * Saves a OC File after a successful upload.
      * Saves a OC File after a successful upload.
-     * <p/>
+     * <p>
      * A PROPFIND is necessary to keep the props in the local database
      * A PROPFIND is necessary to keep the props in the local database
      * synchronized with the server, specially the modification time and Etag
      * synchronized with the server, specially the modification time and Etag
      * (where available)
      * (where available)
-     * <p/>
      */
      */
     private void saveUploadedFile(OwnCloudClient client) {
     private void saveUploadedFile(OwnCloudClient client) {
         OCFile file = mFile;
         OCFile file = mFile;