From c6b41e42c5d97c11867e806520b5dfbb458ea363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garci=CC=81a=20de=20Prada?= Date: Tue, 18 Jan 2022 13:02:52 +0100 Subject: [PATCH] Migrate old request bodies from java to kotlin --- .../network/ChunkFromFileRequestBody.java | 114 ----------------- .../network/ChunkFromFileRequestBody.kt | 91 ++++++++++++++ .../lib/common/network/FileRequestBody.java | 119 ------------------ .../lib/common/network/FileRequestBody.kt | 97 ++++++++++++++ .../UploadFileFromFileSystemOperation.kt | 2 +- 5 files changed, 189 insertions(+), 234 deletions(-) delete mode 100644 owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/ChunkFromFileRequestBody.java create mode 100644 owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/ChunkFromFileRequestBody.kt delete mode 100644 owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/FileRequestBody.java create mode 100644 owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/FileRequestBody.kt diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/ChunkFromFileRequestBody.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/ChunkFromFileRequestBody.java deleted file mode 100644 index a43b2c37..00000000 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/ChunkFromFileRequestBody.java +++ /dev/null @@ -1,114 +0,0 @@ -/* ownCloud Android Library is available under MIT license - * Copyright (C) 2020 ownCloud GmbH. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -package com.owncloud.android.lib.common.network; - -import okhttp3.MediaType; -import okio.BufferedSink; -import timber.log.Timber; - -import java.io.File; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; -import java.util.Iterator; - -/** - * A Request body that represents a file chunk and include information about the progress when uploading it - * - * @author David González Verdugo - */ -public class ChunkFromFileRequestBody extends FileRequestBody { - - private final FileChannel mChannel; - private final long mChunkSize; - private long mOffset; - private long mTransferred; - private ByteBuffer mBuffer = ByteBuffer.allocate(4096); - - public ChunkFromFileRequestBody(File file, MediaType contentType, FileChannel channel, long chunkSize) { - super(file, contentType); - if (channel == null) { - throw new IllegalArgumentException("File may not be null"); - } - if (chunkSize <= 0) { - throw new IllegalArgumentException("Chunk size must be greater than zero"); - } - this.mChannel = channel; - this.mChunkSize = chunkSize; - mOffset = 0; - mTransferred = 0; - } - - @Override - public long contentLength() { - try { - return Math.min(mChunkSize, mChannel.size() - mChannel.position()); - } catch (IOException e) { - return mChunkSize; - } - } - - @Override - public void writeTo(BufferedSink sink) { - int readCount; - Iterator it; - - try { - mChannel.position(mOffset); - long size = mFile.length(); - if (size == 0) { - size = -1; - } - long maxCount = Math.min(mOffset + mChunkSize, mChannel.size()); - while (mChannel.position() < maxCount) { - - readCount = mChannel.read(mBuffer); - - int bytesToWriteInBuffer = (int) Math.min(readCount, mFile.length() - mTransferred); - sink.getBuffer().write(mBuffer.array(), 0, bytesToWriteInBuffer); - - sink.flush(); - - mBuffer.clear(); - if (mTransferred < maxCount) { // condition to avoid accumulate progress for repeated chunks - mTransferred += readCount; - } - synchronized (mDataTransferListeners) { - it = mDataTransferListeners.iterator(); - while (it.hasNext()) { - it.next().onTransferProgress(readCount, mTransferred, size, mFile.getAbsolutePath()); - } - } - } - - } catch (Exception exception) { - Timber.e(exception, "Transferred " + mTransferred + " bytes from a total of " + mFile.length()); - } - } - - public void setOffset(long offset) { - this.mOffset = offset; - } -} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/ChunkFromFileRequestBody.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/ChunkFromFileRequestBody.kt new file mode 100644 index 00000000..a1275bf9 --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/ChunkFromFileRequestBody.kt @@ -0,0 +1,91 @@ +/* ownCloud Android Library is available under MIT license + * Copyright (C) 2022 ownCloud GmbH. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package com.owncloud.android.lib.common.network + +import okhttp3.MediaType +import okio.BufferedSink +import timber.log.Timber +import java.io.File +import java.nio.ByteBuffer +import java.nio.channels.FileChannel + +/** + * A Request body that represents a file chunk and include information about the progress when uploading it + * + * @author David González Verdugo + */ +class ChunkFromFileRequestBody( + file: File, + contentType: MediaType?, + private val channel: FileChannel, + private val chunkSize: Long +) : FileRequestBody(file, contentType) { + + private var offset: Long = 0 + private var alreadyTransferred: Long = 0 + private val buffer = ByteBuffer.allocate(4_096) + + init { + require(chunkSize > 0) { "Chunk size must be greater than zero" } + } + + override fun contentLength(): Long { + return chunkSize.coerceAtMost(channel.size() - channel.position()) + } + + override fun writeTo(sink: BufferedSink) { + var readCount: Int + var iterator: Iterator + try { + channel.position(offset) + + val maxCount = (offset + chunkSize).coerceAtMost(channel.size()) + while (channel.position() < maxCount) { + readCount = channel.read(buffer) + val bytesToWriteInBuffer = readCount.toLong().coerceAtMost(file.length() - alreadyTransferred).toInt() + sink.buffer.write(buffer.array(), 0, bytesToWriteInBuffer) + sink.flush() + buffer.clear() + + if (alreadyTransferred < maxCount) { // condition to avoid accumulate progress for repeated chunks + alreadyTransferred += readCount.toLong() + } + + synchronized(dataTransferListeners) { + iterator = dataTransferListeners.iterator() + while (iterator.hasNext()) { + iterator.next().onTransferProgress(readCount.toLong(), alreadyTransferred, file.length(), file.absolutePath) + } + } + } + } catch (exception: Exception) { + Timber.e(exception, "Transferred " + alreadyTransferred + " bytes from a total of " + file.length()) + } + } + + fun setOffset(newOffset: Long) { + offset = newOffset + } + +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/FileRequestBody.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/FileRequestBody.java deleted file mode 100644 index 18746ba7..00000000 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/FileRequestBody.java +++ /dev/null @@ -1,119 +0,0 @@ -/* ownCloud Android Library is available under MIT license - * Copyright (C) 2020 ownCloud GmbH. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -package com.owncloud.android.lib.common.network; - -import okhttp3.MediaType; -import okhttp3.RequestBody; -import okio.BufferedSink; -import okio.Okio; -import okio.Source; -import timber.log.Timber; - -import java.io.File; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -/** - * A Request body that represents a file and include information about the progress when uploading it - * - * @author David González Verdugo - */ -public class FileRequestBody extends RequestBody implements ProgressiveDataTransferer { - - final Set mDataTransferListeners = new HashSet<>(); - protected File mFile; - private MediaType mContentType; - - public FileRequestBody(File file, MediaType contentType) { - mFile = file; - mContentType = contentType; - } - - @Override - public boolean isOneShot() { - return true; - } - - @Override - public MediaType contentType() { - return mContentType; - } - - @Override - public long contentLength() { - return mFile.length(); - } - - @Override - public void writeTo(BufferedSink sink) { - Source source; - Iterator it; - try { - source = Okio.source(mFile); - - long transferred = 0; - long read; - - while ((read = source.read(sink.buffer(), 4096)) != -1) { - transferred += read; - sink.flush(); - synchronized (mDataTransferListeners) { - it = mDataTransferListeners.iterator(); - while (it.hasNext()) { - it.next().onTransferProgress(read, transferred, mFile.length(), mFile.getAbsolutePath()); - } - } - } - - Timber.d("File with name " + mFile.getName() + " and size " + mFile.length() + " written in request body"); - - } catch (Exception e) { - Timber.e(e); - } - } - - @Override - public void addDatatransferProgressListener(OnDatatransferProgressListener listener) { - synchronized (mDataTransferListeners) { - mDataTransferListeners.add(listener); - } - } - - @Override - public void addDatatransferProgressListeners(Collection listeners) { - synchronized (mDataTransferListeners) { - mDataTransferListeners.addAll(listeners); - } - } - - @Override - public void removeDatatransferProgressListener(OnDatatransferProgressListener listener) { - synchronized (mDataTransferListeners) { - mDataTransferListeners.remove(listener); - } - } -} \ No newline at end of file diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/FileRequestBody.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/FileRequestBody.kt new file mode 100644 index 00000000..fd5f8dd3 --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/FileRequestBody.kt @@ -0,0 +1,97 @@ +/* ownCloud Android Library is available under MIT license + * Copyright (C) 2022 ownCloud GmbH. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package com.owncloud.android.lib.common.network + +import okhttp3.MediaType +import okhttp3.RequestBody +import okio.BufferedSink +import okio.Source +import okio.source +import timber.log.Timber +import java.io.File +import java.util.HashSet + +/** + * A Request body that represents a file and include information about the progress when uploading it + * + * @author David González Verdugo + */ +open class FileRequestBody( + val file: File, + private val contentType: MediaType?, +) : RequestBody(), ProgressiveDataTransferer { + + val dataTransferListeners: MutableSet = HashSet() + + override fun isOneShot(): Boolean = true + + override fun contentType(): MediaType? = contentType + + override fun contentLength(): Long = file.length() + + override fun writeTo(sink: BufferedSink) { + val source: Source + var it: Iterator + try { + source = file.source() + var transferred: Long = 0 + var read: Long + while (source.read(sink.buffer, BYTES_TO_READ).also { read = it } != -1L) { + transferred += read + sink.flush() + synchronized(dataTransferListeners) { + it = dataTransferListeners.iterator() + while (it.hasNext()) { + it.next().onTransferProgress(read, transferred, file.length(), file.absolutePath) + } + } + } + Timber.d("File with name ${file.name} and size ${file.length()} written in request body") + } catch (e: Exception) { + Timber.e(e) + } + } + + override fun addDatatransferProgressListener(listener: OnDatatransferProgressListener) { + synchronized(dataTransferListeners) { + dataTransferListeners.add(listener) + } + } + + override fun addDatatransferProgressListeners(listeners: Collection) { + synchronized(dataTransferListeners) { + dataTransferListeners.addAll(listeners) + } + } + + override fun removeDatatransferProgressListener(listener: OnDatatransferProgressListener) { + synchronized(dataTransferListeners) { + dataTransferListeners.remove(listener) + } + } + + companion object { + private const val BYTES_TO_READ = 4_096L + } +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/UploadFileFromFileSystemOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/UploadFileFromFileSystemOperation.kt index e4caa869..e532c678 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/UploadFileFromFileSystemOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/UploadFileFromFileSystemOperation.kt @@ -26,9 +26,9 @@ package com.owncloud.android.lib.resources.files import com.owncloud.android.lib.common.OwnCloudClient import com.owncloud.android.lib.common.http.HttpConstants import com.owncloud.android.lib.common.http.methods.webdav.PutMethod -import com.owncloud.android.lib.common.network.FileRequestBody import com.owncloud.android.lib.common.network.OnDatatransferProgressListener import com.owncloud.android.lib.common.network.WebdavUtils +import com.owncloud.android.lib.common.network.FileRequestBody import com.owncloud.android.lib.common.operations.OperationCancelledException import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult