1
0
mirror of https://github.com/owncloud/android-library.git synced 2025-06-07 16:06:08 +00:00

Refactor copy remote file operation. Make overwrite false as default to avoid some potential errors

This commit is contained in:
Abel García de Prada 2021-05-21 14:01:25 +02:00 committed by Abel García de Prada
parent 61314fe6d9
commit 2c75099a95
2 changed files with 31 additions and 25 deletions

View File

@ -36,7 +36,7 @@ import java.net.URL
class CopyMethod( class CopyMethod(
val url: URL, val url: URL,
private val destinationUrl: String, private val destinationUrl: String,
private val forceOverride: Boolean private val forceOverride: Boolean = false
) : DavMethod(url) { ) : DavMethod(url) {
@Throws(Exception::class) @Throws(Exception::class)
public override fun onDavExecute(davResource: DavOCResource): Int { public override fun onDavExecute(davResource: DavOCResource): Int {

View File

@ -1,5 +1,5 @@
/* ownCloud Android Library is available under MIT license /* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH. * Copyright (C) 2022 ownCloud GmbH.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -30,6 +30,7 @@ import com.owncloud.android.lib.common.network.WebdavUtils
import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperation
import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode
import com.owncloud.android.lib.common.utils.isOneOf
import timber.log.Timber import timber.log.Timber
import java.net.URL import java.net.URL
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@ -44,13 +45,12 @@ import java.util.concurrent.TimeUnit
* @author Christian Schabesberger * @author Christian Schabesberger
* @author David González V. * @author David González V.
* *
* @param srcRemotePath Remote path of the file/folder to move. * @param srcRemotePath Remote path of the file/folder to copy.
* @param targetRemotePath Remove path desired for the file/folder after moving it. * @param targetRemotePath Remote path desired for the file/folder to copy it.
*/ */
class CopyRemoteFileOperation( class CopyRemoteFileOperation(
private val srcRemotePath: String, private val srcRemotePath: String,
private val targetRemotePath: String, private val targetRemotePath: String,
private val overwrite: Boolean
) : RemoteOperation<String?>() { ) : RemoteOperation<String?>() {
/** /**
* Performs the rename operation. * Performs the rename operation.
@ -72,37 +72,43 @@ class CopyRemoteFileOperation(
val copyMethod = CopyMethod( val copyMethod = CopyMethod(
URL(client.userFilesWebDavUri.toString() + WebdavUtils.encodePath(srcRemotePath)), URL(client.userFilesWebDavUri.toString() + WebdavUtils.encodePath(srcRemotePath)),
client.userFilesWebDavUri.toString() + WebdavUtils.encodePath(targetRemotePath), client.userFilesWebDavUri.toString() + WebdavUtils.encodePath(targetRemotePath),
overwrite
).apply { ).apply {
setReadTimeout(COPY_READ_TIMEOUT.toLong(), TimeUnit.SECONDS) setReadTimeout(COPY_READ_TIMEOUT, TimeUnit.SECONDS)
setConnectionTimeout(COPY_CONNECTION_TIMEOUT.toLong(), TimeUnit.SECONDS) setConnectionTimeout(COPY_CONNECTION_TIMEOUT, TimeUnit.SECONDS)
} }
val status = client.executeHttpMethod(copyMethod) val status = client.executeHttpMethod(copyMethod)
when {
isSuccess(status) -> {
val fileRemoteId = copyMethod.getResponseHeader(HttpConstants.OC_FILE_REMOTE_ID)
result = RemoteOperationResult(ResultCode.OK)
result.setData(fileRemoteId)
}
isPreconditionFailed(status) -> {
result = RemoteOperationResult(ResultCode.INVALID_OVERWRITE)
client.exhaustResponse(copyMethod.getResponseBodyAsStream())
if (status == HttpConstants.HTTP_CREATED || status == HttpConstants.HTTP_NO_CONTENT) { /// for other errors that could be explicitly handled, check first:
val fileRemoteId = copyMethod.getResponseHeader(HttpConstants.OC_FILE_REMOTE_ID) /// http://www.webdav.org/specs/rfc4918.html#rfc.section.9.9.4
result = RemoteOperationResult(ResultCode.OK) }
result.setData(fileRemoteId) else -> {
} else if (status == HttpConstants.HTTP_PRECONDITION_FAILED && !overwrite) { result = RemoteOperationResult(copyMethod)
result = RemoteOperationResult(ResultCode.INVALID_OVERWRITE) client.exhaustResponse(copyMethod.getResponseBodyAsStream())
client.exhaustResponse(copyMethod.getResponseBodyAsStream()) }
/// for other errors that could be explicitly handled, check first:
/// http://www.webdav.org/specs/rfc4918.html#rfc.section.9.9.4
} else {
result = RemoteOperationResult(copyMethod)
client.exhaustResponse(copyMethod.getResponseBodyAsStream())
} }
Timber.i("Copy " + srcRemotePath + " to " + targetRemotePath + ": " + result.logMessage) Timber.i("Copy $srcRemotePath to $targetRemotePath: ${result.logMessage}")
} catch (e: Exception) { } catch (e: Exception) {
result = RemoteOperationResult(e) result = RemoteOperationResult(e)
Timber.e(e, "Copy " + srcRemotePath + " to " + targetRemotePath + ": " + result.logMessage) Timber.e(e, "Copy $srcRemotePath to $targetRemotePath: ${result.logMessage}")
} }
return result return result
} }
private fun isSuccess(status: Int) = status.isOneOf(HttpConstants.HTTP_CREATED, HttpConstants.HTTP_NO_CONTENT)
private fun isPreconditionFailed(status: Int) = status == HttpConstants.HTTP_PRECONDITION_FAILED
companion object { companion object {
private const val COPY_READ_TIMEOUT = 600_000 private const val COPY_READ_TIMEOUT = 10L
private const val COPY_CONNECTION_TIMEOUT = 5_000 private const val COPY_CONNECTION_TIMEOUT = 6L
} }
} }