From 73c317916769c1f6f72bab72663947ad14148987 Mon Sep 17 00:00:00 2001 From: A117870935 Date: Mon, 2 Jun 2025 18:47:20 +0530 Subject: [PATCH 1/8] Album remote operations. Signed-off-by: A117870935 Signed-off-by: Surinder Kumar --- .../android/lib/common/network/WebdavEntry.kt | 6 + .../lib/common/network/WebdavUtils.java | 15 ++ .../lib/common/utils/WebDavFileUtils.java | 28 +++ .../CopyFileToAlbumRemoteOperation.java | 159 ++++++++++++++++++ .../albums/CreateNewAlbumRemoteOperation.java | 72 ++++++++ .../lib/resources/albums/PhotoAlbumEntry.kt | 106 ++++++++++++ .../albums/ReadAlbumItemsRemoteOperation.java | 99 +++++++++++ .../albums/ReadAlbumsRemoteOperation.java | 99 +++++++++++ .../RemoveAlbumFileRemoteOperation.java | 62 +++++++ .../albums/RemoveAlbumRemoteOperation.java | 64 +++++++ .../albums/RenameAlbumRemoteOperation.java | 72 ++++++++ .../ToggleAlbumFavoriteRemoteOperation.java | 80 +++++++++ 12 files changed, 862 insertions(+) create mode 100644 library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.java create mode 100644 library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.java create mode 100644 library/src/main/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntry.kt create mode 100644 library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.java create mode 100644 library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.java create mode 100644 library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumFileRemoteOperation.java create mode 100644 library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.java create mode 100644 library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.java create mode 100644 library/src/main/java/com/owncloud/android/lib/resources/albums/ToggleAlbumFavoriteRemoteOperation.java diff --git a/library/src/main/java/com/owncloud/android/lib/common/network/WebdavEntry.kt b/library/src/main/java/com/owncloud/android/lib/common/network/WebdavEntry.kt index 23edd98917..2cb6031739 100644 --- a/library/src/main/java/com/owncloud/android/lib/common/network/WebdavEntry.kt +++ b/library/src/main/java/com/owncloud/android/lib/common/network/WebdavEntry.kt @@ -1,6 +1,7 @@ /* * Nextcloud Android Library * + * SPDX-FileCopyrightText: 2025 TSI-mc * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2023 Alper Ozturk * SPDX-FileCopyrightText: 2023 Álvaro Brey @@ -679,6 +680,11 @@ class WebdavEntry constructor( const val SHAREES_SHARE_TYPE = "type" const val PROPERTY_QUOTA_USED_BYTES = "quota-used-bytes" const val PROPERTY_QUOTA_AVAILABLE_BYTES = "quota-available-bytes" + const val PROPERTY_LAST_PHOTO = "last-photo" + const val PROPERTY_NB_ITEMS = "nbItems" + const val PROPERTY_LOCATION = "location" + const val PROPERTY_DATE_RANGE = "dateRange" + const val PROPERTY_COLLABORATORS = "collaborators" private const val IS_ENCRYPTED = "1" private const val CODE_PROP_NOT_FOUND = 404 } diff --git a/library/src/main/java/com/owncloud/android/lib/common/network/WebdavUtils.java b/library/src/main/java/com/owncloud/android/lib/common/network/WebdavUtils.java index e83afbbcd9..c900f6d163 100644 --- a/library/src/main/java/com/owncloud/android/lib/common/network/WebdavUtils.java +++ b/library/src/main/java/com/owncloud/android/lib/common/network/WebdavUtils.java @@ -1,6 +1,7 @@ /* * Nextcloud Android Library * + * SPDX-FileCopyrightText: 2025 TSI-mc * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2023 Alper Ozturk * SPDX-FileCopyrightText: 2022 Álvaro Brey @@ -221,6 +222,20 @@ public static DavPropertyNameSet getChunksPropSet() { return propSet; } + public static DavPropertyNameSet getAlbumPropSet() { + DavPropertyNameSet propertySet = new DavPropertyNameSet(); + Namespace ncNamespace = Namespace.getNamespace("nc",WebdavEntry.NAMESPACE_NC); + + propertySet.add(DavPropertyName.create(WebdavEntry.PROPERTY_LAST_PHOTO,ncNamespace)); + propertySet.add(DavPropertyName.create(WebdavEntry.PROPERTY_NB_ITEMS, ncNamespace)); + propertySet.add(DavPropertyName.create(WebdavEntry.PROPERTY_LOCATION, ncNamespace)); + propertySet.add(DavPropertyName.create(WebdavEntry.PROPERTY_DATE_RANGE, ncNamespace)); + propertySet.add(DavPropertyName.create(WebdavEntry.PROPERTY_COLLABORATORS, ncNamespace)); + + return propertySet; + } + + /** * * @param rawEtag diff --git a/library/src/main/java/com/owncloud/android/lib/common/utils/WebDavFileUtils.java b/library/src/main/java/com/owncloud/android/lib/common/utils/WebDavFileUtils.java index bb19408b84..80bc1c511c 100644 --- a/library/src/main/java/com/owncloud/android/lib/common/utils/WebDavFileUtils.java +++ b/library/src/main/java/com/owncloud/android/lib/common/utils/WebDavFileUtils.java @@ -1,12 +1,15 @@ /* * Nextcloud Android Library * + * SPDX-FileCopyrightText: 2025 TSI-mc * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2017 Mario Danic * SPDX-License-Identifier: MIT */ package com.owncloud.android.lib.common.utils; +import android.net.Uri; + import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.network.WebdavEntry; import com.owncloud.android.lib.resources.files.model.RemoteFile; @@ -59,4 +62,29 @@ public ArrayList readData(MultiStatus remoteData, return mFolderAndFiles; } + + /** + * Read the data retrieved from the server about the contents of the target folder + * + * @param remoteData Full response got from the server with the data of the target + * folder and its direct children. + * @param client Client instance to the remote server where the data were + * retrieved. + * @return + */ + public ArrayList readAlbumData(MultiStatus remoteData, OwnCloudClient client) { + String url = client.getBaseUri() + "/remote.php/dav/photos/" + client.getUserId(); + + ArrayList mFolderAndFiles = new ArrayList<>(); + + // loop to update every child + // reading from 1 as 0th item will be just the root album path + for (int i = 1; i < remoteData.getResponses().length; ++i) { + /// new OCFile instance with the data from the server + WebdavEntry we = new WebdavEntry(remoteData.getResponses()[i], Uri.parse(url).getEncodedPath()); + RemoteFile remoteFile = new RemoteFile(we); + mFolderAndFiles.add(remoteFile); + } + return mFolderAndFiles; + } } diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.java b/library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.java new file mode 100644 index 0000000000..15e23a9e1e --- /dev/null +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.java @@ -0,0 +1,159 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2025 TSI-mc + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package com.owncloud.android.lib.resources.albums; + +import android.util.Log; + +import com.nextcloud.common.SessionTimeOut; +import com.nextcloud.common.SessionTimeOutKt; +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.network.WebdavUtils; +import com.owncloud.android.lib.common.operations.RemoteOperation; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; + +import org.apache.commons.httpclient.HttpStatus; +import org.apache.jackrabbit.webdav.DavException; +import org.apache.jackrabbit.webdav.MultiStatusResponse; +import org.apache.jackrabbit.webdav.Status; +import org.apache.jackrabbit.webdav.client.methods.CopyMethod; + +import java.io.IOException; + + +/** + * Remote operation moving a remote file or folder in the ownCloud server to a different folder + * in the same account. + *

+ * Allows renaming the moving file/folder at the same time. + */ +public class CopyFileToAlbumRemoteOperation extends RemoteOperation { + private static final String TAG = CopyFileToAlbumRemoteOperation.class.getSimpleName(); + + private final String mSrcRemotePath; + private final String mTargetRemotePath; + + private final SessionTimeOut sessionTimeOut; + + public CopyFileToAlbumRemoteOperation(String srcRemotePath, String targetRemotePath) { + this(srcRemotePath, targetRemotePath, SessionTimeOutKt.getDefaultSessionTimeOut()); + } + + public CopyFileToAlbumRemoteOperation(String srcRemotePath, String targetRemotePath, SessionTimeOut sessionTimeOut) { + mSrcRemotePath = srcRemotePath; + mTargetRemotePath = targetRemotePath; + this.sessionTimeOut = sessionTimeOut; + } + + /** + * Performs the operation. + * + * @param client Client object to communicate with the remote ownCloud server. + */ + @Override + protected RemoteOperationResult run(OwnCloudClient client) { + + /// check parameters + if (mTargetRemotePath.equals(mSrcRemotePath)) { + // nothing to do! + return new RemoteOperationResult<>(ResultCode.OK); + } + + if (mTargetRemotePath.startsWith(mSrcRemotePath)) { + return new RemoteOperationResult<>(ResultCode.INVALID_COPY_INTO_DESCENDANT); + } + + /// perform remote operation + CopyMethod copyMethod = null; + RemoteOperationResult result; + try { + copyMethod = new CopyMethod( + client.getFilesDavUri(this.mSrcRemotePath), + client.getBaseUri() + "/remote.php/dav/photos/" + client.getUserId() + "/albums" + WebdavUtils.encodePath(mTargetRemotePath), + false + ); + int status = client.executeMethod(copyMethod, sessionTimeOut.getReadTimeOut(), sessionTimeOut.getConnectionTimeOut()); + + /// process response + if (status == HttpStatus.SC_MULTI_STATUS) { + result = processPartialError(copyMethod); + + } else if (status == HttpStatus.SC_PRECONDITION_FAILED) { + + result = new RemoteOperationResult<>(ResultCode.INVALID_OVERWRITE); + client.exhaustResponse(copyMethod.getResponseBodyAsStream()); + + } else { + result = new RemoteOperationResult<>(isSuccess(status), copyMethod); + client.exhaustResponse(copyMethod.getResponseBodyAsStream()); + } + + Log.i(TAG, "Copy " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + result.getLogMessage()); + + } catch (Exception e) { + result = new RemoteOperationResult<>(e); + Log.e(TAG, "Copy " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + result.getLogMessage(), e); + + } finally { + if (copyMethod != null) { + copyMethod.releaseConnection(); + } + } + + return result; + } + + + /** + * Analyzes a multistatus response from the OC server to generate an appropriate result. + *

+ * In WebDAV, a COPY request on collections (folders) can be PARTIALLY successful: some + * children are copied, some other aren't. + *

+ * According to the WebDAV specification, a multistatus response SHOULD NOT include partial + * successes (201, 204) nor for descendants of already failed children (424) in the response + * entity. But SHOULD NOT != MUST NOT, so take carefully. + * + * @param copyMethod Copy operation just finished with a multistatus response + * @return A result for the {@link CopyFileToAlbumRemoteOperation} caller + * @throws java.io.IOException If the response body could not be parsed + * @throws org.apache.jackrabbit.webdav.DavException If the status code is other than MultiStatus or if obtaining + * the response XML document fails + */ + private RemoteOperationResult processPartialError(CopyMethod copyMethod) + throws IOException, DavException { + // Adding a list of failed descendants to the result could be interesting; or maybe not. + // For the moment, let's take the easy way. + + /// check that some error really occurred + MultiStatusResponse[] responses = copyMethod.getResponseBodyAsMultiStatus().getResponses(); + Status[] status; + boolean failFound = false; + for (int i = 0; i < responses.length && !failFound; i++) { + status = responses[i].getStatus(); + failFound = ( + status != null && + status.length > 0 && + status[0].getStatusCode() > 299 + ); + } + + RemoteOperationResult result; + if (failFound) { + result = new RemoteOperationResult<>(ResultCode.PARTIAL_COPY_DONE); + } else { + result = new RemoteOperationResult<>(true, copyMethod); + } + + return result; + } + + protected boolean isSuccess(int status) { + return status == HttpStatus.SC_CREATED || status == HttpStatus.SC_NO_CONTENT; + } +} diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.java b/library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.java new file mode 100644 index 0000000000..dbaa5d5cf7 --- /dev/null +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.java @@ -0,0 +1,72 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2025 TSI-mc + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package com.owncloud.android.lib.resources.albums; + +import com.nextcloud.common.SessionTimeOut; +import com.nextcloud.common.SessionTimeOutKt; +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.network.WebdavUtils; +import com.owncloud.android.lib.common.operations.RemoteOperation; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.common.utils.Log_OC; + +import org.apache.jackrabbit.webdav.client.methods.MkColMethod; + +public class CreateNewAlbumRemoteOperation extends RemoteOperation { + private static final String TAG = CreateNewAlbumRemoteOperation.class.getSimpleName(); + private final String newAlbumName; + private final SessionTimeOut sessionTimeOut; + + public CreateNewAlbumRemoteOperation(String newAlbumName) { + this(newAlbumName, SessionTimeOutKt.getDefaultSessionTimeOut()); + } + + public CreateNewAlbumRemoteOperation(String newAlbumName, SessionTimeOut sessionTimeOut) { + this.newAlbumName = newAlbumName; + this.sessionTimeOut = sessionTimeOut; + } + + public String getNewAlbumName() { + return newAlbumName; + } + + /** + * Performs the operation. + * + * @param client Client object to communicate with the remote ownCloud server. + */ + @Override + protected RemoteOperationResult run(OwnCloudClient client) { + MkColMethod mkCol = null; + RemoteOperationResult result; + try { + mkCol = new MkColMethod(client.getBaseUri() + "/remote.php/dav/photos/" + client.getUserId() + "/albums" + WebdavUtils.encodePath(newAlbumName)); + client.executeMethod(mkCol, sessionTimeOut.getReadTimeOut(), sessionTimeOut.getConnectionTimeOut()); + if (405 == mkCol.getStatusCode()) { + result = new RemoteOperationResult<>(RemoteOperationResult.ResultCode.FOLDER_ALREADY_EXISTS); + } else { + result = new RemoteOperationResult<>(mkCol.succeeded(), mkCol); + result.setResultData(null); + } + + Log_OC.d(TAG, "Create album " + newAlbumName + ": " + result.getLogMessage()); + client.exhaustResponse(mkCol.getResponseBodyAsStream()); + } catch (Exception e) { + result = new RemoteOperationResult<>(e); + Log_OC.e(TAG, "Create album " + newAlbumName + ": " + result.getLogMessage(), e); + } finally { + if (mkCol != null) { + mkCol.releaseConnection(); + } + + } + + return result; + } + +} diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntry.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntry.kt new file mode 100644 index 0000000000..2204c24af8 --- /dev/null +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntry.kt @@ -0,0 +1,106 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2025 TSI-mc + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package com.owncloud.android.lib.resources.albums + +import com.owncloud.android.lib.common.network.WebdavEntry +import org.apache.commons.httpclient.HttpStatus +import org.apache.jackrabbit.webdav.MultiStatusResponse +import org.apache.jackrabbit.webdav.property.DavPropertyName +import org.apache.jackrabbit.webdav.property.DavPropertySet +import org.apache.jackrabbit.webdav.xml.Namespace +import org.json.JSONException +import org.json.JSONObject +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale + +class PhotoAlbumEntry(response: MultiStatusResponse) { + val href: String + val lastPhoto: Long + val nbItems: Int + val location: String? + private val dateRange: String? + + companion object { + val dateFormat = SimpleDateFormat("MMM yyyy", Locale.US) + } + + init { + + href = response.href + + val properties = response.getProperties(HttpStatus.SC_OK) + + this.lastPhoto = parseLong(parseString(properties, WebdavEntry.PROPERTY_LAST_PHOTO)) + this.nbItems = parseInt(parseString(properties, WebdavEntry.PROPERTY_NB_ITEMS)) + this.location = parseString(properties, WebdavEntry.PROPERTY_LOCATION) + this.dateRange = parseString(properties, WebdavEntry.PROPERTY_DATE_RANGE) + } + + private fun parseString(props: DavPropertySet, name: String): String? { + val propName = DavPropertyName.create(name, Namespace.getNamespace("nc", WebdavEntry.NAMESPACE_NC)) + val prop = props[propName] + return if (prop != null && prop.value != null) prop.value.toString() else null + } + + private fun parseInt(value: String?): Int { + return try { + value?.toInt() ?: 0 + } catch (e: NumberFormatException) { + 0 + } + } + + private fun parseLong(value: String?): Long { + return try { + value?.toLong() ?: 0L + } catch (e: NumberFormatException) { + 0L + } + } + + val albumName: String + get() { + var href = href + if (href.isEmpty()) { + return "" + } + + // Remove trailing slash if present + if (href.endsWith("/")) { + href = href.substring(0, href.length - 1) + } + + // Split and return last part + val parts = href.split("/".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + return if (parts.isNotEmpty()) parts[parts.size - 1] else "" + } + + val createdDate: String + get() { + val jsonRange = dateRange + val currentDate = Date(System.currentTimeMillis()) + if (jsonRange.isNullOrEmpty()) { + return dateFormat.format(currentDate) + } + + try { + val obj = JSONObject(jsonRange) + val startTimestamp = obj.optLong("start", 0) + + if (startTimestamp > 0) { + val date = Date(startTimestamp * 1000L) // Convert to milliseconds + return dateFormat.format(date) + } + } catch (e: JSONException) { + e.printStackTrace() + return dateFormat.format(currentDate) + } + return dateFormat.format(currentDate) + } +} \ No newline at end of file diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.java b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.java new file mode 100644 index 0000000000..9e267ff5e4 --- /dev/null +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.java @@ -0,0 +1,99 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2025 TSI-mc + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package com.owncloud.android.lib.resources.albums; + +import com.nextcloud.common.SessionTimeOut; +import com.nextcloud.common.SessionTimeOutKt; +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.network.WebdavUtils; +import com.owncloud.android.lib.common.operations.RemoteOperation; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.lib.common.utils.WebDavFileUtils; +import com.owncloud.android.lib.resources.files.model.RemoteFile; + +import org.apache.commons.httpclient.HttpStatus; +import org.apache.jackrabbit.webdav.DavConstants; +import org.apache.jackrabbit.webdav.MultiStatus; +import org.apache.jackrabbit.webdav.client.methods.PropFindMethod; + +import java.util.ArrayList; +import java.util.List; + +public class ReadAlbumItemsRemoteOperation extends RemoteOperation> { + + private static final String TAG = ReadAlbumItemsRemoteOperation.class.getSimpleName(); + private final String mRemotePath; + private final SessionTimeOut sessionTimeOut; + + public ReadAlbumItemsRemoteOperation(String mRemotePath) { + this(mRemotePath, SessionTimeOutKt.getDefaultSessionTimeOut()); + } + + public ReadAlbumItemsRemoteOperation(String mRemotePath, SessionTimeOut sessionTimeOut) { + this.mRemotePath = mRemotePath; + this.sessionTimeOut = sessionTimeOut; + } + + protected RemoteOperationResult> run(OwnCloudClient client) { + RemoteOperationResult> result = null; + PropFindMethod query = null; + String url = client.getBaseUri() + "/remote.php/dav/photos/" + client.getUserId() + "/albums" + WebdavUtils.encodePath(mRemotePath); + try { + // remote request + query = new PropFindMethod(url, + WebdavUtils.getAllPropSet(), // PropFind Properties + DavConstants.DEPTH_1); + int status = client.executeMethod(query, sessionTimeOut.getReadTimeOut(), sessionTimeOut.getConnectionTimeOut()); + + // check and process response + boolean isSuccess = (status == HttpStatus.SC_MULTI_STATUS || status == HttpStatus.SC_OK); + + if (isSuccess) { + // get data from remote folder + MultiStatus dataInServer = query.getResponseBodyAsMultiStatus(); + ArrayList mFolderAndFiles = new WebDavFileUtils().readAlbumData(dataInServer, client); + + // Result of the operation + result = new RemoteOperationResult<>(true, query); + // Add data to the result + if (result.isSuccess()) { + result.setResultData(mFolderAndFiles); + } + } else { + // synchronization failed + client.exhaustResponse(query.getResponseBodyAsStream()); + result = new RemoteOperationResult<>(false, query); + } + } catch (Exception e) { + result = new RemoteOperationResult<>(e); + } finally { + if (query != null) { + query.releaseConnection(); // let the connection available for other methods + } + + if (result == null) { + result = new RemoteOperationResult(new Exception("unknown error")); + Log_OC.e(TAG, "Synchronized " + mRemotePath + ": failed"); + } else { + if (result.isSuccess()) { + Log_OC.i(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage()); + } else { + if (result.isException()) { + Log_OC.e(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage(), + result.getException()); + } else { + Log_OC.e(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage()); + } + } + } + } + + return result; + } +} diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.java b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.java new file mode 100644 index 0000000000..2a09e243d4 --- /dev/null +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.java @@ -0,0 +1,99 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2025 TSI-mc + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package com.owncloud.android.lib.resources.albums; + +import static org.apache.commons.httpclient.HttpStatus.SC_MULTI_STATUS; +import static org.apache.commons.httpclient.HttpStatus.SC_OK; + +import android.text.TextUtils; + +import androidx.annotation.Nullable; + +import com.nextcloud.common.SessionTimeOut; +import com.nextcloud.common.SessionTimeOutKt; +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.network.WebdavUtils; +import com.owncloud.android.lib.common.operations.RemoteOperation; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.common.utils.Log_OC; + +import org.apache.jackrabbit.webdav.DavConstants; +import org.apache.jackrabbit.webdav.MultiStatus; +import org.apache.jackrabbit.webdav.MultiStatusResponse; +import org.apache.jackrabbit.webdav.client.methods.PropFindMethod; + +import java.util.ArrayList; +import java.util.List; + +public class ReadAlbumsRemoteOperation extends RemoteOperation> { + + private static final String TAG = ReadAlbumsRemoteOperation.class.getSimpleName(); + private final String mAlbumRemotePath; + private final SessionTimeOut sessionTimeOut; + + + public ReadAlbumsRemoteOperation() { + this(null); + } + + public ReadAlbumsRemoteOperation(@Nullable String mAlbumRemotePath) { + this(mAlbumRemotePath, SessionTimeOutKt.getDefaultSessionTimeOut()); + } + + public ReadAlbumsRemoteOperation(@Nullable String mAlbumRemotePath, SessionTimeOut sessionTimeOut) { + this.mAlbumRemotePath = mAlbumRemotePath; + this.sessionTimeOut = sessionTimeOut; + } + + /** + * Performs the operation. + * + * @param client Client object to communicate with the remote ownCloud server. + */ + @Override + protected RemoteOperationResult> run(OwnCloudClient client) { + PropFindMethod propfind = null; + RemoteOperationResult> result; + String url = client.getBaseUri() + "/remote.php/dav/photos/" + client.getUserId() + "/albums"; + if (!TextUtils.isEmpty(mAlbumRemotePath)) { + url += WebdavUtils.encodePath(mAlbumRemotePath); + } + try { + propfind = new PropFindMethod(url, WebdavUtils.getAlbumPropSet(), DavConstants.DEPTH_1); + int status = client.executeMethod(propfind, sessionTimeOut.getReadTimeOut(), sessionTimeOut.getConnectionTimeOut()); + boolean isSuccess = status == SC_MULTI_STATUS || status == SC_OK; + if (isSuccess) { + MultiStatus multiStatus = propfind.getResponseBodyAsMultiStatus(); + List albumsList = new ArrayList<>(); + for (MultiStatusResponse response : multiStatus.getResponses()) { + int st = response.getStatus()[0].getStatusCode(); + if (st == SC_OK) { + PhotoAlbumEntry entry = new PhotoAlbumEntry(response); + albumsList.add(entry); + } + } + result = new RemoteOperationResult(true, propfind); + result.setResultData(albumsList); + } else { + result = new RemoteOperationResult(false, propfind); + client.exhaustResponse(propfind.getResponseBodyAsStream()); + } + } catch (Exception var13) { + Exception e = var13; + result = new RemoteOperationResult(e); + Log_OC.e(TAG, "Read album " + " failed: " + result.getLogMessage(), result.getException()); + } finally { + if (propfind != null) { + propfind.releaseConnection(); + } + + } + + return result; + } +} diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumFileRemoteOperation.java b/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumFileRemoteOperation.java new file mode 100644 index 0000000000..52296a5651 --- /dev/null +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumFileRemoteOperation.java @@ -0,0 +1,62 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2025 TSI-mc + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package com.owncloud.android.lib.resources.albums; + +import android.net.Uri; + +import com.nextcloud.common.SessionTimeOut; +import com.nextcloud.common.SessionTimeOutKt; +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.operations.RemoteOperation; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.lib.resources.files.RemoveFileRemoteOperation; + +import org.apache.commons.httpclient.HttpStatus; +import org.apache.jackrabbit.webdav.client.methods.DeleteMethod; + +public class RemoveAlbumFileRemoteOperation extends RemoteOperation { + private static final String TAG = RemoveFileRemoteOperation.class.getSimpleName(); + private final String mRemotePath; + private final SessionTimeOut sessionTimeOut; + + public RemoveAlbumFileRemoteOperation(String remotePath) { + this(remotePath, SessionTimeOutKt.getDefaultSessionTimeOut()); + } + + public RemoveAlbumFileRemoteOperation(String remotePath, SessionTimeOut sessionTimeOut) { + this.mRemotePath = remotePath; + this.sessionTimeOut = sessionTimeOut; + } + + protected RemoteOperationResult run(OwnCloudClient client) { + RemoteOperationResult result; + DeleteMethod delete = null; + String webDavUrl = client.getDavUri().toString()+"/photos/"; + String encodedPath = (client.getUserId() + Uri.encode(this.mRemotePath)).replace("%2F", "/"); + String fullFilePath = webDavUrl + encodedPath; + + try { + delete = new DeleteMethod(fullFilePath); + int status = client.executeMethod(delete, this.sessionTimeOut.getReadTimeOut(), this.sessionTimeOut.getConnectionTimeOut()); + delete.getResponseBodyAsString(); + result = new RemoteOperationResult(delete.succeeded() || status == HttpStatus.SC_NOT_FOUND, delete); + Log_OC.i(TAG, "Remove " + this.mRemotePath + ": " + result.getLogMessage()); + } catch (Exception e) { + result = new RemoteOperationResult(e); + Log_OC.e(TAG, "Remove " + this.mRemotePath + ": " + result.getLogMessage(), e); + } finally { + if (delete != null) { + delete.releaseConnection(); + } + + } + + return result; + } +} diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.java b/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.java new file mode 100644 index 0000000000..f86e6fc919 --- /dev/null +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.java @@ -0,0 +1,64 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2025 TSI-mc + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package com.owncloud.android.lib.resources.albums; + +import com.nextcloud.common.SessionTimeOut; +import com.nextcloud.common.SessionTimeOutKt; +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.network.WebdavUtils; +import com.owncloud.android.lib.common.operations.RemoteOperation; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.common.utils.Log_OC; + +import org.apache.commons.httpclient.HttpStatus; +import org.apache.jackrabbit.webdav.client.methods.DeleteMethod; + +public class RemoveAlbumRemoteOperation extends RemoteOperation { + private static final String TAG = RemoveAlbumRemoteOperation.class.getSimpleName(); + private final String albumName; + private final SessionTimeOut sessionTimeOut; + + public RemoveAlbumRemoteOperation(String albumName) { + this(albumName, SessionTimeOutKt.getDefaultSessionTimeOut()); + } + + public RemoveAlbumRemoteOperation(String albumName, SessionTimeOut sessionTimeOut) { + this.albumName = albumName; + this.sessionTimeOut = sessionTimeOut; + } + + /** + * Performs the operation. + * + * @param client Client object to communicate with the remote ownCloud server. + */ + @Override + protected RemoteOperationResult run(OwnCloudClient client) { + RemoteOperationResult result; + DeleteMethod delete = null; + + try { + delete = new DeleteMethod(client.getBaseUri() + "/remote.php/dav/photos/" + client.getUserId() + "/albums" + WebdavUtils.encodePath(albumName)); + int status = client.executeMethod(delete, sessionTimeOut.getReadTimeOut(), sessionTimeOut.getConnectionTimeOut()); + delete.getResponseBodyAsString(); + result = new RemoteOperationResult(delete.succeeded() || status == HttpStatus.SC_NOT_FOUND, delete); + Log_OC.i(TAG, "Remove " + this.albumName + ": " + result.getLogMessage()); + } catch (Exception e) { + result = new RemoteOperationResult(e); + Log_OC.e(TAG, "Remove " + this.albumName + ": " + result.getLogMessage(), e); + } finally { + if (delete != null) { + delete.releaseConnection(); + } + + } + + return result; + } + +} diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.java b/library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.java new file mode 100644 index 0000000000..7c17cb0324 --- /dev/null +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.java @@ -0,0 +1,72 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2025 TSI-mc + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package com.owncloud.android.lib.resources.albums; + +import com.nextcloud.common.SessionTimeOut; +import com.nextcloud.common.SessionTimeOutKt; +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.network.WebdavUtils; +import com.owncloud.android.lib.common.operations.RemoteOperation; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.common.utils.Log_OC; + +import org.apache.jackrabbit.webdav.client.methods.MoveMethod; + +public class RenameAlbumRemoteOperation extends RemoteOperation { + private static final String TAG = RenameAlbumRemoteOperation.class.getSimpleName(); + private final String mOldRemotePath; + private final String mNewAlbumName; + private final SessionTimeOut sessionTimeOut; + + public RenameAlbumRemoteOperation(String mOldRemotePath, String mNewAlbumName) { + this(mOldRemotePath, mNewAlbumName, SessionTimeOutKt.getDefaultSessionTimeOut()); + } + + public RenameAlbumRemoteOperation(String mOldRemotePath, String mNewAlbumName, SessionTimeOut sessionTimeOut) { + this.mOldRemotePath = mOldRemotePath; + this.mNewAlbumName = mNewAlbumName; + this.sessionTimeOut = sessionTimeOut; + } + + public String getNewAlbumName() { + return mNewAlbumName; + } + + /** + * Performs the operation. + * + * @param client Client object to communicate with the remote ownCloud server. + */ + @Override + protected RemoteOperationResult run(OwnCloudClient client) { + RemoteOperationResult result = null; + MoveMethod move = null; + String url = client.getBaseUri() + "/remote.php/dav/photos/" + client.getUserId() + "/albums"; + try { + if (!this.mNewAlbumName.equals(this.mOldRemotePath)) { + move = new MoveMethod(url + WebdavUtils.encodePath(mOldRemotePath), url + WebdavUtils.encodePath(mNewAlbumName), true); + client.executeMethod(move, sessionTimeOut.getReadTimeOut(), sessionTimeOut.getConnectionTimeOut()); + result = new RemoteOperationResult(move.succeeded(), move); + Log_OC.i(TAG, "Rename " + this.mOldRemotePath + " to " + this.mNewAlbumName + ": " + result.getLogMessage()); + client.exhaustResponse(move.getResponseBodyAsStream()); + return result; + } + } catch (Exception e) { + result = new RemoteOperationResult(e); + Log_OC.e(TAG, "Rename " + this.mOldRemotePath + " to " + this.mNewAlbumName + ": " + result.getLogMessage(), e); + return result; + } finally { + if (move != null) { + move.releaseConnection(); + } + } + + return result; + } + +} diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/ToggleAlbumFavoriteRemoteOperation.java b/library/src/main/java/com/owncloud/android/lib/resources/albums/ToggleAlbumFavoriteRemoteOperation.java new file mode 100644 index 0000000000..d03d612505 --- /dev/null +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/ToggleAlbumFavoriteRemoteOperation.java @@ -0,0 +1,80 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2025 TSI-mc + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package com.owncloud.android.lib.resources.albums; + +import android.net.Uri; + +import com.nextcloud.common.SessionTimeOut; +import com.nextcloud.common.SessionTimeOutKt; +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.network.WebdavEntry; +import com.owncloud.android.lib.common.operations.RemoteOperation; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; + +import org.apache.commons.httpclient.HttpStatus; +import org.apache.jackrabbit.webdav.client.methods.PropPatchMethod; +import org.apache.jackrabbit.webdav.property.DavPropertyNameSet; +import org.apache.jackrabbit.webdav.property.DavPropertySet; +import org.apache.jackrabbit.webdav.property.DefaultDavProperty; +import org.apache.jackrabbit.webdav.xml.Namespace; + +import java.io.IOException; + +public class ToggleAlbumFavoriteRemoteOperation extends RemoteOperation { + private boolean makeItFavorited; + private String filePath; + private final SessionTimeOut sessionTimeOut; + + public ToggleAlbumFavoriteRemoteOperation(boolean makeItFavorited, String filePath) { + this(makeItFavorited, filePath, SessionTimeOutKt.getDefaultSessionTimeOut()); + } + + public ToggleAlbumFavoriteRemoteOperation(boolean makeItFavorited, String filePath, SessionTimeOut sessionTimeOut) { + this.makeItFavorited = makeItFavorited; + this.filePath = filePath; + this.sessionTimeOut = sessionTimeOut; + } + + protected RemoteOperationResult run(OwnCloudClient client) { + RemoteOperationResult result; + PropPatchMethod propPatchMethod = null; + DavPropertySet newProps = new DavPropertySet(); + DavPropertyNameSet removeProperties = new DavPropertyNameSet(); + if (this.makeItFavorited) { + DefaultDavProperty favoriteProperty = new DefaultDavProperty("oc:favorite", "1", Namespace.getNamespace(WebdavEntry.NAMESPACE_OC)); + newProps.add(favoriteProperty); + } else { + removeProperties.add("oc:favorite", Namespace.getNamespace(WebdavEntry.NAMESPACE_OC)); + } + + String webDavUrl = client.getDavUri().toString() + "/photos/"; + String encodedPath = (client.getUserId() + Uri.encode(this.filePath)).replace("%2F", "/"); + String fullFilePath = webDavUrl + encodedPath; + + try { + propPatchMethod = new PropPatchMethod(fullFilePath, newProps, removeProperties); + int status = client.executeMethod(propPatchMethod, sessionTimeOut.getReadTimeOut(), sessionTimeOut.getConnectionTimeOut()); + boolean isSuccess = (status == HttpStatus.SC_MULTI_STATUS || status == HttpStatus.SC_OK); + if (isSuccess) { + result = new RemoteOperationResult(true, status, propPatchMethod.getResponseHeaders()); + } else { + client.exhaustResponse(propPatchMethod.getResponseBodyAsStream()); + result = new RemoteOperationResult(false, status, propPatchMethod.getResponseHeaders()); + } + } catch (IOException e) { + result = new RemoteOperationResult(e); + } finally { + if (propPatchMethod != null) { + propPatchMethod.releaseConnection(); + } + + } + + return result; + } +} \ No newline at end of file From 277d8ad060d65db1a2f171f1b7e447e0177abb6b Mon Sep 17 00:00:00 2001 From: A117870935 Date: Tue, 3 Jun 2025 19:13:43 +0530 Subject: [PATCH 2/8] Code refactoring and unit test for PhotoAlbumEntry Signed-off-by: Surinder Kumar --- .../lib/common/utils/WebDavFileUtils.java | 26 +++++---- .../lib/resources/albums/PhotoAlbumEntry.kt | 37 ++++-------- .../albums/ReadAlbumItemsRemoteOperation.java | 2 +- .../resources/albums/PhotoAlbumEntryTest.kt | 57 +++++++++++++++++++ 4 files changed, 85 insertions(+), 37 deletions(-) create mode 100644 library/src/test/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntryTest.kt diff --git a/library/src/main/java/com/owncloud/android/lib/common/utils/WebDavFileUtils.java b/library/src/main/java/com/owncloud/android/lib/common/utils/WebDavFileUtils.java index 80bc1c511c..bcfb80c55d 100644 --- a/library/src/main/java/com/owncloud/android/lib/common/utils/WebDavFileUtils.java +++ b/library/src/main/java/com/owncloud/android/lib/common/utils/WebDavFileUtils.java @@ -18,6 +18,8 @@ import org.apache.jackrabbit.webdav.MultiStatusResponse; import java.util.ArrayList; +import java.util.Collections; +import java.util.List; /** * WebDav helper. @@ -72,19 +74,23 @@ public ArrayList readData(MultiStatus remoteData, * retrieved. * @return */ - public ArrayList readAlbumData(MultiStatus remoteData, OwnCloudClient client) { - String url = client.getBaseUri() + "/remote.php/dav/photos/" + client.getUserId(); + public List readAlbumData(MultiStatus remoteData, OwnCloudClient client) { + String baseUrl = client.getBaseUri() + "/remote.php/dav/photos/" + client.getUserId(); + String encodedPath = Uri.parse(baseUrl).getEncodedPath(); + if (encodedPath == null) { + return Collections.emptyList(); + } - ArrayList mFolderAndFiles = new ArrayList<>(); + List files = new ArrayList<>(); + final var responses = remoteData.getResponses(); - // loop to update every child // reading from 1 as 0th item will be just the root album path - for (int i = 1; i < remoteData.getResponses().length; ++i) { - /// new OCFile instance with the data from the server - WebdavEntry we = new WebdavEntry(remoteData.getResponses()[i], Uri.parse(url).getEncodedPath()); - RemoteFile remoteFile = new RemoteFile(we); - mFolderAndFiles.add(remoteFile); + for (int i = 1; i < responses.length; i++) { + WebdavEntry entry = new WebdavEntry(responses[i], encodedPath); + RemoteFile remoteFile = new RemoteFile(entry); + files.add(remoteFile); } - return mFolderAndFiles; + + return files; } } diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntry.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntry.kt index 2204c24af8..ba0b57e83e 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntry.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntry.kt @@ -66,41 +66,26 @@ class PhotoAlbumEntry(response: MultiStatusResponse) { val albumName: String get() { - var href = href - if (href.isEmpty()) { - return "" - } - - // Remove trailing slash if present - if (href.endsWith("/")) { - href = href.substring(0, href.length - 1) - } - - // Split and return last part - val parts = href.split("/".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() - return if (parts.isNotEmpty()) parts[parts.size - 1] else "" + return href + .removeSuffix("/") + .substringAfterLast("/") + .takeIf { it.isNotEmpty() } ?: "" } val createdDate: String get() { - val jsonRange = dateRange val currentDate = Date(System.currentTimeMillis()) - if (jsonRange.isNullOrEmpty()) { - return dateFormat.format(currentDate) - } - try { - val obj = JSONObject(jsonRange) + return try { + val obj = JSONObject(dateRange ?: return dateFormat.format(currentDate)) val startTimestamp = obj.optLong("start", 0) - - if (startTimestamp > 0) { - val date = Date(startTimestamp * 1000L) // Convert to milliseconds - return dateFormat.format(date) - } + if (startTimestamp > 0) + dateFormat.format(Date(startTimestamp * 1000L)) + else + dateFormat.format(currentDate) } catch (e: JSONException) { e.printStackTrace() - return dateFormat.format(currentDate) + dateFormat.format(currentDate) } - return dateFormat.format(currentDate) } } \ No newline at end of file diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.java b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.java index 9e267ff5e4..5459ea807b 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.java +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.java @@ -57,7 +57,7 @@ protected RemoteOperationResult> run(OwnCloudClient client) { if (isSuccess) { // get data from remote folder MultiStatus dataInServer = query.getResponseBodyAsMultiStatus(); - ArrayList mFolderAndFiles = new WebDavFileUtils().readAlbumData(dataInServer, client); + List mFolderAndFiles = new WebDavFileUtils().readAlbumData(dataInServer, client); // Result of the operation result = new RemoteOperationResult<>(true, query); diff --git a/library/src/test/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntryTest.kt b/library/src/test/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntryTest.kt new file mode 100644 index 0000000000..f7757395d8 --- /dev/null +++ b/library/src/test/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntryTest.kt @@ -0,0 +1,57 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2025 TSI-mc + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package com.owncloud.android.lib.resources.albums + +import org.apache.jackrabbit.webdav.MultiStatusResponse +import org.junit.Assert.assertEquals +import org.junit.Test + +class PhotoAlbumEntryTest { + + @Test + fun testAlbumName_withTrailingSlash() { + val entry = createTestEntry("/remote.php/dav/photos/user_id/albums/vacation2024/") + assertEquals("vacation2024", entry.albumName) + } + + @Test + fun testAlbumName_withoutTrailingSlash() { + val entry = createTestEntry("/remote.php/dav/photos/user_id/albums/vacation2024") + assertEquals("vacation2024", entry.albumName) + } + + @Test + fun testAlbumName_nestedPath() { + val entry = createTestEntry("/remote.php/dav/photos/user_id/albums/travel/europe/") + assertEquals("europe", entry.albumName) + } + + @Test + fun testAlbumName_singleSlash() { + val entry = createTestEntry("/") + assertEquals("", entry.albumName) + } + + @Test + fun testAlbumName_onlySlashes() { + val entry = createTestEntry("///") + assertEquals("", entry.albumName) + } + + @Test + fun testAlbumName_noSlash() { + val entry = createTestEntry("holiday") + assertEquals("holiday", entry.albumName) + } + + // Helper method to create a stub entry + private fun createTestEntry(href: String): PhotoAlbumEntry { + val response = MultiStatusResponse(href, 200) + return PhotoAlbumEntry(response) + } +} \ No newline at end of file From 2e62124b8ffc45501e35e7fe65b8010fa997d699 Mon Sep 17 00:00:00 2001 From: A117870935 Date: Wed, 4 Jun 2025 11:32:12 +0530 Subject: [PATCH 3/8] Rename .java to .kt Signed-off-by: Surinder Kumar --- ...lbumRemoteOperation.java => CopyFileToAlbumRemoteOperation.kt} | 0 ...AlbumRemoteOperation.java => CreateNewAlbumRemoteOperation.kt} | 0 ...ItemsRemoteOperation.java => ReadAlbumItemsRemoteOperation.kt} | 0 ...eadAlbumsRemoteOperation.java => ReadAlbumsRemoteOperation.kt} | 0 ...FileRemoteOperation.java => RemoveAlbumFileRemoteOperation.kt} | 0 ...oveAlbumRemoteOperation.java => RemoveAlbumRemoteOperation.kt} | 0 ...ameAlbumRemoteOperation.java => RenameAlbumRemoteOperation.kt} | 0 ...RemoteOperation.java => ToggleAlbumFavoriteRemoteOperation.kt} | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename library/src/main/java/com/owncloud/android/lib/resources/albums/{CopyFileToAlbumRemoteOperation.java => CopyFileToAlbumRemoteOperation.kt} (100%) rename library/src/main/java/com/owncloud/android/lib/resources/albums/{CreateNewAlbumRemoteOperation.java => CreateNewAlbumRemoteOperation.kt} (100%) rename library/src/main/java/com/owncloud/android/lib/resources/albums/{ReadAlbumItemsRemoteOperation.java => ReadAlbumItemsRemoteOperation.kt} (100%) rename library/src/main/java/com/owncloud/android/lib/resources/albums/{ReadAlbumsRemoteOperation.java => ReadAlbumsRemoteOperation.kt} (100%) rename library/src/main/java/com/owncloud/android/lib/resources/albums/{RemoveAlbumFileRemoteOperation.java => RemoveAlbumFileRemoteOperation.kt} (100%) rename library/src/main/java/com/owncloud/android/lib/resources/albums/{RemoveAlbumRemoteOperation.java => RemoveAlbumRemoteOperation.kt} (100%) rename library/src/main/java/com/owncloud/android/lib/resources/albums/{RenameAlbumRemoteOperation.java => RenameAlbumRemoteOperation.kt} (100%) rename library/src/main/java/com/owncloud/android/lib/resources/albums/{ToggleAlbumFavoriteRemoteOperation.java => ToggleAlbumFavoriteRemoteOperation.kt} (100%) diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.java b/library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.kt similarity index 100% rename from library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.java rename to library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.kt diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.java b/library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.kt similarity index 100% rename from library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.java rename to library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.kt diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.java b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.kt similarity index 100% rename from library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.java rename to library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.kt diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.java b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.kt similarity index 100% rename from library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.java rename to library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.kt diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumFileRemoteOperation.java b/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumFileRemoteOperation.kt similarity index 100% rename from library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumFileRemoteOperation.java rename to library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumFileRemoteOperation.kt diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.java b/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.kt similarity index 100% rename from library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.java rename to library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.kt diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.java b/library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.kt similarity index 100% rename from library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.java rename to library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.kt diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/ToggleAlbumFavoriteRemoteOperation.java b/library/src/main/java/com/owncloud/android/lib/resources/albums/ToggleAlbumFavoriteRemoteOperation.kt similarity index 100% rename from library/src/main/java/com/owncloud/android/lib/resources/albums/ToggleAlbumFavoriteRemoteOperation.java rename to library/src/main/java/com/owncloud/android/lib/resources/albums/ToggleAlbumFavoriteRemoteOperation.kt From 74c2b2919af3209530b696aae84228ae813c011d Mon Sep 17 00:00:00 2001 From: A117870935 Date: Wed, 4 Jun 2025 11:32:14 +0530 Subject: [PATCH 4/8] Operations migrated to kotlin. Signed-off-by: Surinder Kumar --- .../albums/CopyFileToAlbumRemoteOperation.kt | 193 +++++++++--------- .../albums/CreateNewAlbumRemoteOperation.kt | 96 +++++---- .../albums/ReadAlbumItemsRemoteOperation.kt | 131 ++++++------ .../albums/ReadAlbumsRemoteOperation.kt | 128 +++++------- .../albums/RemoveAlbumFileRemoteOperation.kt | 94 ++++----- .../albums/RemoveAlbumRemoteOperation.kt | 89 ++++---- .../albums/RenameAlbumRemoteOperation.kt | 105 +++++----- .../ToggleAlbumFavoriteRemoteOperation.kt | 109 +++++----- 8 files changed, 456 insertions(+), 489 deletions(-) diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.kt index 15e23a9e1e..0af703b924 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.kt @@ -4,156 +4,149 @@ * SPDX-FileCopyrightText: 2025 TSI-mc * SPDX-License-Identifier: AGPL-3.0-or-later */ - -package com.owncloud.android.lib.resources.albums; - -import android.util.Log; - -import com.nextcloud.common.SessionTimeOut; -import com.nextcloud.common.SessionTimeOutKt; -import com.owncloud.android.lib.common.OwnCloudClient; -import com.owncloud.android.lib.common.network.WebdavUtils; -import com.owncloud.android.lib.common.operations.RemoteOperation; -import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; - -import org.apache.commons.httpclient.HttpStatus; -import org.apache.jackrabbit.webdav.DavException; -import org.apache.jackrabbit.webdav.MultiStatusResponse; -import org.apache.jackrabbit.webdav.Status; -import org.apache.jackrabbit.webdav.client.methods.CopyMethod; - -import java.io.IOException; - +package com.owncloud.android.lib.resources.albums + +import android.util.Log +import com.nextcloud.common.SessionTimeOut +import com.nextcloud.common.defaultSessionTimeOut +import com.owncloud.android.lib.common.OwnCloudClient +import com.owncloud.android.lib.common.network.WebdavUtils +import com.owncloud.android.lib.common.operations.RemoteOperation +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode +import com.owncloud.android.lib.resources.albums.CopyFileToAlbumRemoteOperation +import org.apache.commons.httpclient.HttpStatus +import org.apache.jackrabbit.webdav.DavException +import org.apache.jackrabbit.webdav.Status +import org.apache.jackrabbit.webdav.client.methods.CopyMethod +import java.io.IOException /** * Remote operation moving a remote file or folder in the ownCloud server to a different folder * in the same account. - *

+ * + * * Allows renaming the moving file/folder at the same time. */ -public class CopyFileToAlbumRemoteOperation extends RemoteOperation { - private static final String TAG = CopyFileToAlbumRemoteOperation.class.getSimpleName(); - - private final String mSrcRemotePath; - private final String mTargetRemotePath; - - private final SessionTimeOut sessionTimeOut; - - public CopyFileToAlbumRemoteOperation(String srcRemotePath, String targetRemotePath) { - this(srcRemotePath, targetRemotePath, SessionTimeOutKt.getDefaultSessionTimeOut()); - } - - public CopyFileToAlbumRemoteOperation(String srcRemotePath, String targetRemotePath, SessionTimeOut sessionTimeOut) { - mSrcRemotePath = srcRemotePath; - mTargetRemotePath = targetRemotePath; - this.sessionTimeOut = sessionTimeOut; - } - +class CopyFileToAlbumRemoteOperation @JvmOverloads constructor( + private val mSrcRemotePath: String, + private val mTargetRemotePath: String, + private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut +) : + RemoteOperation() { /** * Performs the operation. * * @param client Client object to communicate with the remote ownCloud server. */ - @Override - protected RemoteOperationResult run(OwnCloudClient client) { + @Deprecated("Deprecated in Java") + override fun run(client: OwnCloudClient): RemoteOperationResult { + /** check parameters */ - /// check parameters - if (mTargetRemotePath.equals(mSrcRemotePath)) { + if (mTargetRemotePath == mSrcRemotePath) { // nothing to do! - return new RemoteOperationResult<>(ResultCode.OK); + return RemoteOperationResult(ResultCode.OK) } if (mTargetRemotePath.startsWith(mSrcRemotePath)) { - return new RemoteOperationResult<>(ResultCode.INVALID_COPY_INTO_DESCENDANT); + return RemoteOperationResult(ResultCode.INVALID_COPY_INTO_DESCENDANT) } - /// perform remote operation - CopyMethod copyMethod = null; - RemoteOperationResult result; + /** perform remote operation */ + var copyMethod: CopyMethod? = null + var result: RemoteOperationResult try { - copyMethod = new CopyMethod( + copyMethod = CopyMethod( client.getFilesDavUri(this.mSrcRemotePath), - client.getBaseUri() + "/remote.php/dav/photos/" + client.getUserId() + "/albums" + WebdavUtils.encodePath(mTargetRemotePath), + "${client.baseUri}/remote.php/dav/photos/${client.userId}/albums${ + WebdavUtils.encodePath( + mTargetRemotePath + ) + }", false - ); - int status = client.executeMethod(copyMethod, sessionTimeOut.getReadTimeOut(), sessionTimeOut.getConnectionTimeOut()); - - /// process response + ) + val status = client.executeMethod( + copyMethod, + sessionTimeOut.readTimeOut, + sessionTimeOut.connectionTimeOut + ) + + /** process response */ if (status == HttpStatus.SC_MULTI_STATUS) { - result = processPartialError(copyMethod); - + result = processPartialError(copyMethod) } else if (status == HttpStatus.SC_PRECONDITION_FAILED) { - - result = new RemoteOperationResult<>(ResultCode.INVALID_OVERWRITE); - client.exhaustResponse(copyMethod.getResponseBodyAsStream()); - + result = RemoteOperationResult(ResultCode.INVALID_OVERWRITE) + client.exhaustResponse(copyMethod.responseBodyAsStream) } else { - result = new RemoteOperationResult<>(isSuccess(status), copyMethod); - client.exhaustResponse(copyMethod.getResponseBodyAsStream()); + result = RemoteOperationResult(isSuccess(status), copyMethod) + client.exhaustResponse(copyMethod.responseBodyAsStream) } - Log.i(TAG, "Copy " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + result.getLogMessage()); - - } catch (Exception e) { - result = new RemoteOperationResult<>(e); - Log.e(TAG, "Copy " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + result.getLogMessage(), e); - + Log.i( + TAG, + "Copy $mSrcRemotePath to $mTargetRemotePath : ${result.logMessage}" + ) + } catch (e: Exception) { + result = RemoteOperationResult(e) + Log.e( + TAG, + "Copy $mSrcRemotePath to $mTargetRemotePath : ${result.logMessage}", e + ) } finally { - if (copyMethod != null) { - copyMethod.releaseConnection(); - } + copyMethod?.releaseConnection() } - return result; + return result } - /** * Analyzes a multistatus response from the OC server to generate an appropriate result. - *

+ * + * * In WebDAV, a COPY request on collections (folders) can be PARTIALLY successful: some * children are copied, some other aren't. - *

+ * + * * According to the WebDAV specification, a multistatus response SHOULD NOT include partial * successes (201, 204) nor for descendants of already failed children (424) in the response * entity. But SHOULD NOT != MUST NOT, so take carefully. * * @param copyMethod Copy operation just finished with a multistatus response - * @return A result for the {@link CopyFileToAlbumRemoteOperation} caller + * @return A result for the [CopyFileToAlbumRemoteOperation] caller * @throws java.io.IOException If the response body could not be parsed * @throws org.apache.jackrabbit.webdav.DavException If the status code is other than MultiStatus or if obtaining - * the response XML document fails + * the response XML document fails */ - private RemoteOperationResult processPartialError(CopyMethod copyMethod) - throws IOException, DavException { + @Throws(IOException::class, DavException::class) + private fun processPartialError(copyMethod: CopyMethod): RemoteOperationResult { // Adding a list of failed descendants to the result could be interesting; or maybe not. // For the moment, let's take the easy way. - - /// check that some error really occurred - MultiStatusResponse[] responses = copyMethod.getResponseBodyAsMultiStatus().getResponses(); - Status[] status; - boolean failFound = false; - for (int i = 0; i < responses.length && !failFound; i++) { - status = responses[i].getStatus(); - failFound = ( - status != null && - status.length > 0 && - status[0].getStatusCode() > 299 - ); + /** check that some error really occurred */ + + val responses = copyMethod.responseBodyAsMultiStatus.responses + var status: Array? + var failFound = false + var i = 0 + while (i < responses.size && !failFound) { + status = responses[i].status + failFound = (!status.isNullOrEmpty() && status[0].statusCode > 299 + ) + i++ } - - RemoteOperationResult result; - if (failFound) { - result = new RemoteOperationResult<>(ResultCode.PARTIAL_COPY_DONE); + val result: RemoteOperationResult = if (failFound) { + RemoteOperationResult(ResultCode.PARTIAL_COPY_DONE) } else { - result = new RemoteOperationResult<>(true, copyMethod); + RemoteOperationResult(true, copyMethod) } - return result; + return result + } + + private fun isSuccess(status: Int): Boolean { + return status == HttpStatus.SC_CREATED || status == HttpStatus.SC_NO_CONTENT } - protected boolean isSuccess(int status) { - return status == HttpStatus.SC_CREATED || status == HttpStatus.SC_NO_CONTENT; + companion object { + private val TAG: String = CopyFileToAlbumRemoteOperation::class.java.simpleName } } diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.kt index dbaa5d5cf7..615384fea6 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.kt @@ -4,69 +4,67 @@ * SPDX-FileCopyrightText: 2025 TSI-mc * SPDX-License-Identifier: AGPL-3.0-or-later */ +package com.owncloud.android.lib.resources.albums -package com.owncloud.android.lib.resources.albums; - -import com.nextcloud.common.SessionTimeOut; -import com.nextcloud.common.SessionTimeOutKt; -import com.owncloud.android.lib.common.OwnCloudClient; -import com.owncloud.android.lib.common.network.WebdavUtils; -import com.owncloud.android.lib.common.operations.RemoteOperation; -import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.utils.Log_OC; - -import org.apache.jackrabbit.webdav.client.methods.MkColMethod; - -public class CreateNewAlbumRemoteOperation extends RemoteOperation { - private static final String TAG = CreateNewAlbumRemoteOperation.class.getSimpleName(); - private final String newAlbumName; - private final SessionTimeOut sessionTimeOut; - - public CreateNewAlbumRemoteOperation(String newAlbumName) { - this(newAlbumName, SessionTimeOutKt.getDefaultSessionTimeOut()); - } - - public CreateNewAlbumRemoteOperation(String newAlbumName, SessionTimeOut sessionTimeOut) { - this.newAlbumName = newAlbumName; - this.sessionTimeOut = sessionTimeOut; - } - - public String getNewAlbumName() { - return newAlbumName; - } +import com.nextcloud.common.SessionTimeOut +import com.nextcloud.common.defaultSessionTimeOut +import com.owncloud.android.lib.common.OwnCloudClient +import com.owncloud.android.lib.common.network.WebdavUtils +import com.owncloud.android.lib.common.operations.RemoteOperation +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.lib.resources.albums.CreateNewAlbumRemoteOperation +import org.apache.commons.httpclient.HttpStatus +import org.apache.jackrabbit.webdav.client.methods.MkColMethod +class CreateNewAlbumRemoteOperation @JvmOverloads constructor( + val newAlbumName: String, + private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut +) : + RemoteOperation() { /** * Performs the operation. * * @param client Client object to communicate with the remote ownCloud server. */ - @Override - protected RemoteOperationResult run(OwnCloudClient client) { - MkColMethod mkCol = null; - RemoteOperationResult result; + @Deprecated("Deprecated in Java") + override fun run(client: OwnCloudClient): RemoteOperationResult { + var mkCol: MkColMethod? = null + var result: RemoteOperationResult try { - mkCol = new MkColMethod(client.getBaseUri() + "/remote.php/dav/photos/" + client.getUserId() + "/albums" + WebdavUtils.encodePath(newAlbumName)); - client.executeMethod(mkCol, sessionTimeOut.getReadTimeOut(), sessionTimeOut.getConnectionTimeOut()); - if (405 == mkCol.getStatusCode()) { - result = new RemoteOperationResult<>(RemoteOperationResult.ResultCode.FOLDER_ALREADY_EXISTS); + mkCol = MkColMethod( + "${client.baseUri}/remote.php/dav/photos/${client.userId}/albums${ + WebdavUtils.encodePath( + newAlbumName + ) + }" + ) + client.executeMethod( + mkCol, + sessionTimeOut.readTimeOut, + sessionTimeOut.connectionTimeOut + ) + if (HttpStatus.SC_METHOD_NOT_ALLOWED == mkCol.statusCode) { + result = + RemoteOperationResult(RemoteOperationResult.ResultCode.FOLDER_ALREADY_EXISTS) } else { - result = new RemoteOperationResult<>(mkCol.succeeded(), mkCol); - result.setResultData(null); + result = RemoteOperationResult(mkCol.succeeded(), mkCol) + result.setResultData(null) } - Log_OC.d(TAG, "Create album " + newAlbumName + ": " + result.getLogMessage()); - client.exhaustResponse(mkCol.getResponseBodyAsStream()); - } catch (Exception e) { - result = new RemoteOperationResult<>(e); - Log_OC.e(TAG, "Create album " + newAlbumName + ": " + result.getLogMessage(), e); + Log_OC.d(TAG, "Create album $newAlbumName : ${result.logMessage}") + client.exhaustResponse(mkCol.responseBodyAsStream) + } catch (e: Exception) { + result = RemoteOperationResult(e) + Log_OC.e(TAG, "Create album $newAlbumName : ${result.logMessage}", e) } finally { - if (mkCol != null) { - mkCol.releaseConnection(); - } - + mkCol?.releaseConnection() } - return result; + return result } + companion object { + private val TAG: String = CreateNewAlbumRemoteOperation::class.java.simpleName + } } diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.kt index 5459ea807b..37b54c14ce 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.kt @@ -4,96 +4,99 @@ * SPDX-FileCopyrightText: 2025 TSI-mc * SPDX-License-Identifier: AGPL-3.0-or-later */ +package com.owncloud.android.lib.resources.albums -package com.owncloud.android.lib.resources.albums; +import com.nextcloud.common.SessionTimeOut +import com.nextcloud.common.defaultSessionTimeOut +import com.owncloud.android.lib.common.OwnCloudClient +import com.owncloud.android.lib.common.network.WebdavUtils +import com.owncloud.android.lib.common.operations.RemoteOperation +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.lib.common.utils.WebDavFileUtils +import com.owncloud.android.lib.resources.albums.ReadAlbumItemsRemoteOperation +import com.owncloud.android.lib.resources.files.model.RemoteFile +import org.apache.commons.httpclient.HttpStatus +import org.apache.jackrabbit.webdav.DavConstants +import org.apache.jackrabbit.webdav.client.methods.PropFindMethod -import com.nextcloud.common.SessionTimeOut; -import com.nextcloud.common.SessionTimeOutKt; -import com.owncloud.android.lib.common.OwnCloudClient; -import com.owncloud.android.lib.common.network.WebdavUtils; -import com.owncloud.android.lib.common.operations.RemoteOperation; -import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.utils.Log_OC; -import com.owncloud.android.lib.common.utils.WebDavFileUtils; -import com.owncloud.android.lib.resources.files.model.RemoteFile; - -import org.apache.commons.httpclient.HttpStatus; -import org.apache.jackrabbit.webdav.DavConstants; -import org.apache.jackrabbit.webdav.MultiStatus; -import org.apache.jackrabbit.webdav.client.methods.PropFindMethod; - -import java.util.ArrayList; -import java.util.List; - -public class ReadAlbumItemsRemoteOperation extends RemoteOperation> { - - private static final String TAG = ReadAlbumItemsRemoteOperation.class.getSimpleName(); - private final String mRemotePath; - private final SessionTimeOut sessionTimeOut; - - public ReadAlbumItemsRemoteOperation(String mRemotePath) { - this(mRemotePath, SessionTimeOutKt.getDefaultSessionTimeOut()); - } - - public ReadAlbumItemsRemoteOperation(String mRemotePath, SessionTimeOut sessionTimeOut) { - this.mRemotePath = mRemotePath; - this.sessionTimeOut = sessionTimeOut; - } - - protected RemoteOperationResult> run(OwnCloudClient client) { - RemoteOperationResult> result = null; - PropFindMethod query = null; - String url = client.getBaseUri() + "/remote.php/dav/photos/" + client.getUserId() + "/albums" + WebdavUtils.encodePath(mRemotePath); +class ReadAlbumItemsRemoteOperation @JvmOverloads constructor( + private val mRemotePath: String, + private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut +) : + RemoteOperation>() { + @Deprecated("Deprecated in Java") + override fun run(client: OwnCloudClient): RemoteOperationResult> { + var result: RemoteOperationResult>? = null + var query: PropFindMethod? = null + val url = "${client.baseUri}/remote.php/dav/photos/${client.userId}/albums${ + WebdavUtils.encodePath( + mRemotePath + ) + }" try { // remote request - query = new PropFindMethod(url, - WebdavUtils.getAllPropSet(), // PropFind Properties - DavConstants.DEPTH_1); - int status = client.executeMethod(query, sessionTimeOut.getReadTimeOut(), sessionTimeOut.getConnectionTimeOut()); + query = PropFindMethod( + url, + WebdavUtils.getAllPropSet(), // PropFind Properties + DavConstants.DEPTH_1 + ) + val status = client.executeMethod( + query, + sessionTimeOut.readTimeOut, + sessionTimeOut.connectionTimeOut + ) // check and process response - boolean isSuccess = (status == HttpStatus.SC_MULTI_STATUS || status == HttpStatus.SC_OK); + val isSuccess = (status == HttpStatus.SC_MULTI_STATUS || status == HttpStatus.SC_OK) if (isSuccess) { // get data from remote folder - MultiStatus dataInServer = query.getResponseBodyAsMultiStatus(); - List mFolderAndFiles = new WebDavFileUtils().readAlbumData(dataInServer, client); + val dataInServer = query.responseBodyAsMultiStatus + val mFolderAndFiles = WebDavFileUtils().readAlbumData(dataInServer, client) // Result of the operation - result = new RemoteOperationResult<>(true, query); + result = RemoteOperationResult(true, query) // Add data to the result - if (result.isSuccess()) { - result.setResultData(mFolderAndFiles); + if (result.isSuccess) { + result.resultData = mFolderAndFiles } } else { // synchronization failed - client.exhaustResponse(query.getResponseBodyAsStream()); - result = new RemoteOperationResult<>(false, query); + client.exhaustResponse(query.responseBodyAsStream) + result = RemoteOperationResult(false, query) } - } catch (Exception e) { - result = new RemoteOperationResult<>(e); + } catch (e: Exception) { + result = RemoteOperationResult(e) } finally { - if (query != null) { - query.releaseConnection(); // let the connection available for other methods - } + query?.releaseConnection() if (result == null) { - result = new RemoteOperationResult(new Exception("unknown error")); - Log_OC.e(TAG, "Synchronized " + mRemotePath + ": failed"); + result = RemoteOperationResult>(Exception("unknown error")) + Log_OC.e( + TAG, + "Synchronized $mRemotePath: failed" + ) } else { - if (result.isSuccess()) { - Log_OC.i(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage()); + if (result.isSuccess) { + Log_OC.i(TAG, "Synchronized $mRemotePath : ${result.logMessage}") } else { - if (result.isException()) { - Log_OC.e(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage(), - result.getException()); + if (result.isException) { + Log_OC.e( + TAG, "Synchronized $mRemotePath : ${result.logMessage}", + result.exception + ) } else { - Log_OC.e(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage()); + Log_OC.e(TAG, "Synchronized $mRemotePath : ${result.logMessage}") } } } } - return result; + return result + } + + companion object { + private val TAG: String = ReadAlbumItemsRemoteOperation::class.java.simpleName } } diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.kt index 2a09e243d4..9ce71d7f77 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.kt @@ -4,96 +4,74 @@ * SPDX-FileCopyrightText: 2025 TSI-mc * SPDX-License-Identifier: AGPL-3.0-or-later */ - -package com.owncloud.android.lib.resources.albums; - -import static org.apache.commons.httpclient.HttpStatus.SC_MULTI_STATUS; -import static org.apache.commons.httpclient.HttpStatus.SC_OK; - -import android.text.TextUtils; - -import androidx.annotation.Nullable; - -import com.nextcloud.common.SessionTimeOut; -import com.nextcloud.common.SessionTimeOutKt; -import com.owncloud.android.lib.common.OwnCloudClient; -import com.owncloud.android.lib.common.network.WebdavUtils; -import com.owncloud.android.lib.common.operations.RemoteOperation; -import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.utils.Log_OC; - -import org.apache.jackrabbit.webdav.DavConstants; -import org.apache.jackrabbit.webdav.MultiStatus; -import org.apache.jackrabbit.webdav.MultiStatusResponse; -import org.apache.jackrabbit.webdav.client.methods.PropFindMethod; - -import java.util.ArrayList; -import java.util.List; - -public class ReadAlbumsRemoteOperation extends RemoteOperation> { - - private static final String TAG = ReadAlbumsRemoteOperation.class.getSimpleName(); - private final String mAlbumRemotePath; - private final SessionTimeOut sessionTimeOut; - - - public ReadAlbumsRemoteOperation() { - this(null); - } - - public ReadAlbumsRemoteOperation(@Nullable String mAlbumRemotePath) { - this(mAlbumRemotePath, SessionTimeOutKt.getDefaultSessionTimeOut()); - } - - public ReadAlbumsRemoteOperation(@Nullable String mAlbumRemotePath, SessionTimeOut sessionTimeOut) { - this.mAlbumRemotePath = mAlbumRemotePath; - this.sessionTimeOut = sessionTimeOut; - } - +package com.owncloud.android.lib.resources.albums + +import android.text.TextUtils +import com.nextcloud.common.SessionTimeOut +import com.nextcloud.common.defaultSessionTimeOut +import com.owncloud.android.lib.common.OwnCloudClient +import com.owncloud.android.lib.common.network.WebdavUtils +import com.owncloud.android.lib.common.operations.RemoteOperation +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.common.utils.Log_OC +import org.apache.commons.httpclient.HttpStatus +import org.apache.jackrabbit.webdav.DavConstants +import org.apache.jackrabbit.webdav.client.methods.PropFindMethod + +class ReadAlbumsRemoteOperation @JvmOverloads constructor( + private val mAlbumRemotePath: String? = null, + private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut +) : + RemoteOperation>() { /** * Performs the operation. * * @param client Client object to communicate with the remote ownCloud server. */ - @Override - protected RemoteOperationResult> run(OwnCloudClient client) { - PropFindMethod propfind = null; - RemoteOperationResult> result; - String url = client.getBaseUri() + "/remote.php/dav/photos/" + client.getUserId() + "/albums"; + @Deprecated("Deprecated in Java") + override fun run(client: OwnCloudClient): RemoteOperationResult> { + var propfind: PropFindMethod? = null + var result: RemoteOperationResult> + var url = "${client.baseUri}/remote.php/dav/photos/${client.userId}/albums" if (!TextUtils.isEmpty(mAlbumRemotePath)) { - url += WebdavUtils.encodePath(mAlbumRemotePath); + url += WebdavUtils.encodePath(mAlbumRemotePath) } try { - propfind = new PropFindMethod(url, WebdavUtils.getAlbumPropSet(), DavConstants.DEPTH_1); - int status = client.executeMethod(propfind, sessionTimeOut.getReadTimeOut(), sessionTimeOut.getConnectionTimeOut()); - boolean isSuccess = status == SC_MULTI_STATUS || status == SC_OK; + propfind = PropFindMethod(url, WebdavUtils.getAlbumPropSet(), DavConstants.DEPTH_1) + val status = client.executeMethod( + propfind, + sessionTimeOut.readTimeOut, + sessionTimeOut.connectionTimeOut + ) + val isSuccess = status == HttpStatus.SC_MULTI_STATUS || status == HttpStatus.SC_OK if (isSuccess) { - MultiStatus multiStatus = propfind.getResponseBodyAsMultiStatus(); - List albumsList = new ArrayList<>(); - for (MultiStatusResponse response : multiStatus.getResponses()) { - int st = response.getStatus()[0].getStatusCode(); - if (st == SC_OK) { - PhotoAlbumEntry entry = new PhotoAlbumEntry(response); - albumsList.add(entry); + val multiStatus = propfind.responseBodyAsMultiStatus + val albumsList: MutableList = ArrayList() + for (response in multiStatus.responses) { + val st = response.status[0].statusCode + if (st == HttpStatus.SC_OK) { + val entry = PhotoAlbumEntry(response) + albumsList.add(entry) } } - result = new RemoteOperationResult(true, propfind); - result.setResultData(albumsList); + result = RemoteOperationResult>(true, propfind) + result.setResultData(albumsList) } else { - result = new RemoteOperationResult(false, propfind); - client.exhaustResponse(propfind.getResponseBodyAsStream()); + result = RemoteOperationResult>(false, propfind) + client.exhaustResponse(propfind.responseBodyAsStream) } - } catch (Exception var13) { - Exception e = var13; - result = new RemoteOperationResult(e); - Log_OC.e(TAG, "Read album " + " failed: " + result.getLogMessage(), result.getException()); + } catch (var13: Exception) { + val e = var13 + result = RemoteOperationResult>(e) + Log_OC.e(TAG, "Read album failed: ${result.logMessage}", result.exception) } finally { - if (propfind != null) { - propfind.releaseConnection(); - } - + propfind?.releaseConnection() } - return result; + return result + } + + companion object { + private val TAG: String = ReadAlbumsRemoteOperation::class.java.simpleName } } diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumFileRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumFileRemoteOperation.kt index 52296a5651..8ffa6f1af5 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumFileRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumFileRemoteOperation.kt @@ -4,59 +4,55 @@ * SPDX-FileCopyrightText: 2025 TSI-mc * SPDX-License-Identifier: AGPL-3.0-or-later */ - -package com.owncloud.android.lib.resources.albums; - -import android.net.Uri; - -import com.nextcloud.common.SessionTimeOut; -import com.nextcloud.common.SessionTimeOutKt; -import com.owncloud.android.lib.common.OwnCloudClient; -import com.owncloud.android.lib.common.operations.RemoteOperation; -import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.utils.Log_OC; -import com.owncloud.android.lib.resources.files.RemoveFileRemoteOperation; - -import org.apache.commons.httpclient.HttpStatus; -import org.apache.jackrabbit.webdav.client.methods.DeleteMethod; - -public class RemoveAlbumFileRemoteOperation extends RemoteOperation { - private static final String TAG = RemoveFileRemoteOperation.class.getSimpleName(); - private final String mRemotePath; - private final SessionTimeOut sessionTimeOut; - - public RemoveAlbumFileRemoteOperation(String remotePath) { - this(remotePath, SessionTimeOutKt.getDefaultSessionTimeOut()); - } - - public RemoveAlbumFileRemoteOperation(String remotePath, SessionTimeOut sessionTimeOut) { - this.mRemotePath = remotePath; - this.sessionTimeOut = sessionTimeOut; - } - - protected RemoteOperationResult run(OwnCloudClient client) { - RemoteOperationResult result; - DeleteMethod delete = null; - String webDavUrl = client.getDavUri().toString()+"/photos/"; - String encodedPath = (client.getUserId() + Uri.encode(this.mRemotePath)).replace("%2F", "/"); - String fullFilePath = webDavUrl + encodedPath; +package com.owncloud.android.lib.resources.albums + +import android.net.Uri +import com.nextcloud.common.SessionTimeOut +import com.nextcloud.common.defaultSessionTimeOut +import com.owncloud.android.lib.common.OwnCloudClient +import com.owncloud.android.lib.common.operations.RemoteOperation +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.lib.resources.files.RemoveFileRemoteOperation +import org.apache.commons.httpclient.HttpStatus +import org.apache.jackrabbit.webdav.client.methods.DeleteMethod + +class RemoveAlbumFileRemoteOperation @JvmOverloads constructor( + private val mRemotePath: String, + private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut +) : + RemoteOperation() { + @Deprecated("Deprecated in Java") + override fun run(client: OwnCloudClient): RemoteOperationResult { + var result: RemoteOperationResult + var delete: DeleteMethod? = null + val webDavUrl = "${client.davUri}/photos/" + val encodedPath = ("${client.userId}${Uri.encode(this.mRemotePath)}").replace("%2F", "/") + val fullFilePath = "$webDavUrl$encodedPath" try { - delete = new DeleteMethod(fullFilePath); - int status = client.executeMethod(delete, this.sessionTimeOut.getReadTimeOut(), this.sessionTimeOut.getConnectionTimeOut()); - delete.getResponseBodyAsString(); - result = new RemoteOperationResult(delete.succeeded() || status == HttpStatus.SC_NOT_FOUND, delete); - Log_OC.i(TAG, "Remove " + this.mRemotePath + ": " + result.getLogMessage()); - } catch (Exception e) { - result = new RemoteOperationResult(e); - Log_OC.e(TAG, "Remove " + this.mRemotePath + ": " + result.getLogMessage(), e); + delete = DeleteMethod(fullFilePath) + val status = client.executeMethod( + delete, + sessionTimeOut.readTimeOut, sessionTimeOut.connectionTimeOut + ) + delete.responseBodyAsString + result = RemoteOperationResult( + delete.succeeded() || status == HttpStatus.SC_NOT_FOUND, + delete + ) + Log_OC.i(TAG, "Remove ${this.mRemotePath} : ${result.logMessage}") + } catch (e: Exception) { + result = RemoteOperationResult(e) + Log_OC.e(TAG, "Remove ${this.mRemotePath} : ${result.logMessage}", e) } finally { - if (delete != null) { - delete.releaseConnection(); - } - + delete?.releaseConnection() } - return result; + return result + } + + companion object { + private val TAG: String = RemoveFileRemoteOperation::class.java.simpleName } } diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.kt index f86e6fc919..bff94b2040 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.kt @@ -4,61 +4,64 @@ * SPDX-FileCopyrightText: 2025 TSI-mc * SPDX-License-Identifier: AGPL-3.0-or-later */ +package com.owncloud.android.lib.resources.albums -package com.owncloud.android.lib.resources.albums; - -import com.nextcloud.common.SessionTimeOut; -import com.nextcloud.common.SessionTimeOutKt; -import com.owncloud.android.lib.common.OwnCloudClient; -import com.owncloud.android.lib.common.network.WebdavUtils; -import com.owncloud.android.lib.common.operations.RemoteOperation; -import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.utils.Log_OC; - -import org.apache.commons.httpclient.HttpStatus; -import org.apache.jackrabbit.webdav.client.methods.DeleteMethod; - -public class RemoveAlbumRemoteOperation extends RemoteOperation { - private static final String TAG = RemoveAlbumRemoteOperation.class.getSimpleName(); - private final String albumName; - private final SessionTimeOut sessionTimeOut; - - public RemoveAlbumRemoteOperation(String albumName) { - this(albumName, SessionTimeOutKt.getDefaultSessionTimeOut()); - } - - public RemoveAlbumRemoteOperation(String albumName, SessionTimeOut sessionTimeOut) { - this.albumName = albumName; - this.sessionTimeOut = sessionTimeOut; - } +import com.nextcloud.common.SessionTimeOut +import com.nextcloud.common.defaultSessionTimeOut +import com.owncloud.android.lib.common.OwnCloudClient +import com.owncloud.android.lib.common.network.WebdavUtils +import com.owncloud.android.lib.common.operations.RemoteOperation +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.lib.resources.albums.RemoveAlbumRemoteOperation +import org.apache.commons.httpclient.HttpStatus +import org.apache.jackrabbit.webdav.client.methods.DeleteMethod +class RemoveAlbumRemoteOperation @JvmOverloads constructor( + private val albumName: String, + private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut +) : + RemoteOperation() { /** * Performs the operation. * * @param client Client object to communicate with the remote ownCloud server. */ - @Override - protected RemoteOperationResult run(OwnCloudClient client) { - RemoteOperationResult result; - DeleteMethod delete = null; + @Deprecated("Deprecated in Java") + override fun run(client: OwnCloudClient): RemoteOperationResult { + var result: RemoteOperationResult + var delete: DeleteMethod? = null try { - delete = new DeleteMethod(client.getBaseUri() + "/remote.php/dav/photos/" + client.getUserId() + "/albums" + WebdavUtils.encodePath(albumName)); - int status = client.executeMethod(delete, sessionTimeOut.getReadTimeOut(), sessionTimeOut.getConnectionTimeOut()); - delete.getResponseBodyAsString(); - result = new RemoteOperationResult(delete.succeeded() || status == HttpStatus.SC_NOT_FOUND, delete); - Log_OC.i(TAG, "Remove " + this.albumName + ": " + result.getLogMessage()); - } catch (Exception e) { - result = new RemoteOperationResult(e); - Log_OC.e(TAG, "Remove " + this.albumName + ": " + result.getLogMessage(), e); + delete = DeleteMethod( + "${client.baseUri}/remote.php/dav/photos/${client.userId}/albums${ + WebdavUtils.encodePath( + albumName + ) + }" + ) + val status = client.executeMethod( + delete, + sessionTimeOut.readTimeOut, + sessionTimeOut.connectionTimeOut + ) + delete.responseBodyAsString + result = RemoteOperationResult( + delete.succeeded() || status == HttpStatus.SC_NOT_FOUND, + delete + ) + Log_OC.i(TAG, "Remove ${this.albumName} : ${result.logMessage}") + } catch (e: Exception) { + result = RemoteOperationResult(e) + Log_OC.e(TAG, "Remove ${this.albumName} : ${result.logMessage}", e) } finally { - if (delete != null) { - delete.releaseConnection(); - } - + delete?.releaseConnection() } - return result; + return result } + companion object { + private val TAG: String = RemoveAlbumRemoteOperation::class.java.simpleName + } } diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.kt index 7c17cb0324..fe1def4129 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.kt @@ -4,69 +4,72 @@ * SPDX-FileCopyrightText: 2025 TSI-mc * SPDX-License-Identifier: AGPL-3.0-or-later */ +package com.owncloud.android.lib.resources.albums -package com.owncloud.android.lib.resources.albums; - -import com.nextcloud.common.SessionTimeOut; -import com.nextcloud.common.SessionTimeOutKt; -import com.owncloud.android.lib.common.OwnCloudClient; -import com.owncloud.android.lib.common.network.WebdavUtils; -import com.owncloud.android.lib.common.operations.RemoteOperation; -import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.utils.Log_OC; - -import org.apache.jackrabbit.webdav.client.methods.MoveMethod; - -public class RenameAlbumRemoteOperation extends RemoteOperation { - private static final String TAG = RenameAlbumRemoteOperation.class.getSimpleName(); - private final String mOldRemotePath; - private final String mNewAlbumName; - private final SessionTimeOut sessionTimeOut; - - public RenameAlbumRemoteOperation(String mOldRemotePath, String mNewAlbumName) { - this(mOldRemotePath, mNewAlbumName, SessionTimeOutKt.getDefaultSessionTimeOut()); - } - - public RenameAlbumRemoteOperation(String mOldRemotePath, String mNewAlbumName, SessionTimeOut sessionTimeOut) { - this.mOldRemotePath = mOldRemotePath; - this.mNewAlbumName = mNewAlbumName; - this.sessionTimeOut = sessionTimeOut; - } - - public String getNewAlbumName() { - return mNewAlbumName; - } +import com.nextcloud.common.SessionTimeOut +import com.nextcloud.common.defaultSessionTimeOut +import com.owncloud.android.lib.common.OwnCloudClient +import com.owncloud.android.lib.common.network.WebdavUtils +import com.owncloud.android.lib.common.operations.RemoteOperation +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.lib.resources.albums.RenameAlbumRemoteOperation +import org.apache.jackrabbit.webdav.client.methods.MoveMethod +class RenameAlbumRemoteOperation @JvmOverloads constructor( + private val mOldRemotePath: String, + val newAlbumName: String, + private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut +) : + RemoteOperation() { /** * Performs the operation. * * @param client Client object to communicate with the remote ownCloud server. */ - @Override - protected RemoteOperationResult run(OwnCloudClient client) { - RemoteOperationResult result = null; - MoveMethod move = null; - String url = client.getBaseUri() + "/remote.php/dav/photos/" + client.getUserId() + "/albums"; + @Deprecated("Deprecated in Java") + override fun run(client: OwnCloudClient): RemoteOperationResult? { + var result: RemoteOperationResult? = null + var move: MoveMethod? = null + val url = "${client.baseUri}/remote.php/dav/photos/${client.userId}/albums" try { - if (!this.mNewAlbumName.equals(this.mOldRemotePath)) { - move = new MoveMethod(url + WebdavUtils.encodePath(mOldRemotePath), url + WebdavUtils.encodePath(mNewAlbumName), true); - client.executeMethod(move, sessionTimeOut.getReadTimeOut(), sessionTimeOut.getConnectionTimeOut()); - result = new RemoteOperationResult(move.succeeded(), move); - Log_OC.i(TAG, "Rename " + this.mOldRemotePath + " to " + this.mNewAlbumName + ": " + result.getLogMessage()); - client.exhaustResponse(move.getResponseBodyAsStream()); - return result; + if (this.newAlbumName != this.mOldRemotePath) { + move = MoveMethod( + "$url${WebdavUtils.encodePath(mOldRemotePath)}", "$url${ + WebdavUtils.encodePath( + newAlbumName + ) + }", true + ) + client.executeMethod( + move, + sessionTimeOut.readTimeOut, + sessionTimeOut.connectionTimeOut + ) + result = RemoteOperationResult(move.succeeded(), move) + Log_OC.i( + TAG, + "Rename ${this.mOldRemotePath} to ${this.newAlbumName} : ${result.logMessage}" + ) + client.exhaustResponse(move.responseBodyAsStream) + return result } - } catch (Exception e) { - result = new RemoteOperationResult(e); - Log_OC.e(TAG, "Rename " + this.mOldRemotePath + " to " + this.mNewAlbumName + ": " + result.getLogMessage(), e); - return result; + } catch (e: Exception) { + result = RemoteOperationResult(e) + Log_OC.e( + TAG, + "Rename ${this.mOldRemotePath} to ${this.newAlbumName} : ${result.logMessage}", + e + ) + return result } finally { - if (move != null) { - move.releaseConnection(); - } + move?.releaseConnection() } - return result; + return result } + companion object { + private val TAG: String = RenameAlbumRemoteOperation::class.java.simpleName + } } diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/ToggleAlbumFavoriteRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/ToggleAlbumFavoriteRemoteOperation.kt index d03d612505..be1952b338 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/ToggleAlbumFavoriteRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/ToggleAlbumFavoriteRemoteOperation.kt @@ -4,77 +4,70 @@ * SPDX-FileCopyrightText: 2025 TSI-mc * SPDX-License-Identifier: AGPL-3.0-or-later */ +package com.owncloud.android.lib.resources.albums -package com.owncloud.android.lib.resources.albums; +import android.net.Uri +import com.nextcloud.common.SessionTimeOut +import com.nextcloud.common.defaultSessionTimeOut +import com.owncloud.android.lib.common.OwnCloudClient +import com.owncloud.android.lib.common.network.WebdavEntry +import com.owncloud.android.lib.common.operations.RemoteOperation +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import org.apache.commons.httpclient.HttpStatus +import org.apache.jackrabbit.webdav.client.methods.PropPatchMethod +import org.apache.jackrabbit.webdav.property.DavPropertyNameSet +import org.apache.jackrabbit.webdav.property.DavPropertySet +import org.apache.jackrabbit.webdav.property.DefaultDavProperty +import org.apache.jackrabbit.webdav.xml.Namespace +import java.io.IOException -import android.net.Uri; - -import com.nextcloud.common.SessionTimeOut; -import com.nextcloud.common.SessionTimeOutKt; -import com.owncloud.android.lib.common.OwnCloudClient; -import com.owncloud.android.lib.common.network.WebdavEntry; -import com.owncloud.android.lib.common.operations.RemoteOperation; -import com.owncloud.android.lib.common.operations.RemoteOperationResult; - -import org.apache.commons.httpclient.HttpStatus; -import org.apache.jackrabbit.webdav.client.methods.PropPatchMethod; -import org.apache.jackrabbit.webdav.property.DavPropertyNameSet; -import org.apache.jackrabbit.webdav.property.DavPropertySet; -import org.apache.jackrabbit.webdav.property.DefaultDavProperty; -import org.apache.jackrabbit.webdav.xml.Namespace; - -import java.io.IOException; - -public class ToggleAlbumFavoriteRemoteOperation extends RemoteOperation { - private boolean makeItFavorited; - private String filePath; - private final SessionTimeOut sessionTimeOut; - - public ToggleAlbumFavoriteRemoteOperation(boolean makeItFavorited, String filePath) { - this(makeItFavorited, filePath, SessionTimeOutKt.getDefaultSessionTimeOut()); - } - - public ToggleAlbumFavoriteRemoteOperation(boolean makeItFavorited, String filePath, SessionTimeOut sessionTimeOut) { - this.makeItFavorited = makeItFavorited; - this.filePath = filePath; - this.sessionTimeOut = sessionTimeOut; - } - - protected RemoteOperationResult run(OwnCloudClient client) { - RemoteOperationResult result; - PropPatchMethod propPatchMethod = null; - DavPropertySet newProps = new DavPropertySet(); - DavPropertyNameSet removeProperties = new DavPropertyNameSet(); +class ToggleAlbumFavoriteRemoteOperation @JvmOverloads constructor( + private val makeItFavorited: Boolean, + private val filePath: String, + private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut +) : + RemoteOperation() { + @Deprecated("Deprecated in Java") + override fun run(client: OwnCloudClient): RemoteOperationResult { + var result: RemoteOperationResult + var propPatchMethod: PropPatchMethod? = null + val newProps = DavPropertySet() + val removeProperties = DavPropertyNameSet() if (this.makeItFavorited) { - DefaultDavProperty favoriteProperty = new DefaultDavProperty("oc:favorite", "1", Namespace.getNamespace(WebdavEntry.NAMESPACE_OC)); - newProps.add(favoriteProperty); + val favoriteProperty = DefaultDavProperty( + "oc:favorite", + "1", + Namespace.getNamespace(WebdavEntry.NAMESPACE_OC) + ) + newProps.add(favoriteProperty) } else { - removeProperties.add("oc:favorite", Namespace.getNamespace(WebdavEntry.NAMESPACE_OC)); + removeProperties.add("oc:favorite", Namespace.getNamespace(WebdavEntry.NAMESPACE_OC)) } - String webDavUrl = client.getDavUri().toString() + "/photos/"; - String encodedPath = (client.getUserId() + Uri.encode(this.filePath)).replace("%2F", "/"); - String fullFilePath = webDavUrl + encodedPath; + val webDavUrl = "${client.davUri}/photos/" + val encodedPath = ("${client.userId}${Uri.encode(this.filePath)}").replace("%2F", "/") + val fullFilePath = "$webDavUrl$encodedPath" try { - propPatchMethod = new PropPatchMethod(fullFilePath, newProps, removeProperties); - int status = client.executeMethod(propPatchMethod, sessionTimeOut.getReadTimeOut(), sessionTimeOut.getConnectionTimeOut()); - boolean isSuccess = (status == HttpStatus.SC_MULTI_STATUS || status == HttpStatus.SC_OK); + propPatchMethod = PropPatchMethod(fullFilePath, newProps, removeProperties) + val status = client.executeMethod( + propPatchMethod, + sessionTimeOut.readTimeOut, + sessionTimeOut.connectionTimeOut + ) + val isSuccess = (status == HttpStatus.SC_MULTI_STATUS || status == HttpStatus.SC_OK) if (isSuccess) { - result = new RemoteOperationResult(true, status, propPatchMethod.getResponseHeaders()); + result = RemoteOperationResult(true, status, propPatchMethod.responseHeaders) } else { - client.exhaustResponse(propPatchMethod.getResponseBodyAsStream()); - result = new RemoteOperationResult(false, status, propPatchMethod.getResponseHeaders()); + client.exhaustResponse(propPatchMethod.responseBodyAsStream) + result = RemoteOperationResult(false, status, propPatchMethod.responseHeaders) } - } catch (IOException e) { - result = new RemoteOperationResult(e); + } catch (e: IOException) { + result = RemoteOperationResult(e) } finally { - if (propPatchMethod != null) { - propPatchMethod.releaseConnection(); - } - + propPatchMethod?.releaseConnection() } - return result; + return result } } \ No newline at end of file From a5999b81b7f344f3c0b638559be2119467988449 Mon Sep 17 00:00:00 2001 From: A117870935 Date: Thu, 5 Jun 2025 22:11:18 +0530 Subject: [PATCH 5/8] Code refactoring Signed-off-by: Surinder Kumar --- .../albums/CopyFileToAlbumRemoteOperation.kt | 1 - .../albums/CreateNewAlbumRemoteOperation.kt | 2 +- .../lib/resources/albums/PhotoAlbumEntry.kt | 6 +++--- .../albums/ReadAlbumItemsRemoteOperation.kt | 1 - .../albums/ReadAlbumsRemoteOperation.kt | 17 +++++------------ .../albums/RemoveAlbumRemoteOperation.kt | 1 - .../albums/RenameAlbumRemoteOperation.kt | 3 --- 7 files changed, 9 insertions(+), 22 deletions(-) diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.kt index 0af703b924..416cae6f8c 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.kt @@ -14,7 +14,6 @@ import com.owncloud.android.lib.common.network.WebdavUtils import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode -import com.owncloud.android.lib.resources.albums.CopyFileToAlbumRemoteOperation import org.apache.commons.httpclient.HttpStatus import org.apache.jackrabbit.webdav.DavException import org.apache.jackrabbit.webdav.Status diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.kt index 615384fea6..946b58e80f 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.kt @@ -49,7 +49,7 @@ class CreateNewAlbumRemoteOperation @JvmOverloads constructor( RemoteOperationResult(RemoteOperationResult.ResultCode.FOLDER_ALREADY_EXISTS) } else { result = RemoteOperationResult(mkCol.succeeded(), mkCol) - result.setResultData(null) + result.resultData = null } Log_OC.d(TAG, "Create album $newAlbumName : ${result.logMessage}") diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntry.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntry.kt index ba0b57e83e..be43aac3f7 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntry.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntry.kt @@ -27,7 +27,7 @@ class PhotoAlbumEntry(response: MultiStatusResponse) { private val dateRange: String? companion object { - val dateFormat = SimpleDateFormat("MMM yyyy", Locale.US) + private val dateFormat = SimpleDateFormat("MMM yyyy", Locale.US) } init { @@ -51,7 +51,7 @@ class PhotoAlbumEntry(response: MultiStatusResponse) { private fun parseInt(value: String?): Int { return try { value?.toInt() ?: 0 - } catch (e: NumberFormatException) { + } catch (_: NumberFormatException) { 0 } } @@ -59,7 +59,7 @@ class PhotoAlbumEntry(response: MultiStatusResponse) { private fun parseLong(value: String?): Long { return try { value?.toLong() ?: 0L - } catch (e: NumberFormatException) { + } catch (_: NumberFormatException) { 0L } } diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.kt index 37b54c14ce..254ec49215 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.kt @@ -14,7 +14,6 @@ import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.utils.Log_OC import com.owncloud.android.lib.common.utils.WebDavFileUtils -import com.owncloud.android.lib.resources.albums.ReadAlbumItemsRemoteOperation import com.owncloud.android.lib.resources.files.model.RemoteFile import org.apache.commons.httpclient.HttpStatus import org.apache.jackrabbit.webdav.DavConstants diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.kt index 9ce71d7f77..92da03c81d 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.kt @@ -45,23 +45,16 @@ class ReadAlbumsRemoteOperation @JvmOverloads constructor( ) val isSuccess = status == HttpStatus.SC_MULTI_STATUS || status == HttpStatus.SC_OK if (isSuccess) { - val multiStatus = propfind.responseBodyAsMultiStatus - val albumsList: MutableList = ArrayList() - for (response in multiStatus.responses) { - val st = response.status[0].statusCode - if (st == HttpStatus.SC_OK) { - val entry = PhotoAlbumEntry(response) - albumsList.add(entry) - } - } + val albumsList = propfind.responseBodyAsMultiStatus.responses + .filter { it.status[0].statusCode == HttpStatus.SC_OK } + .map { res -> PhotoAlbumEntry(res) } result = RemoteOperationResult>(true, propfind) - result.setResultData(albumsList) + result.resultData = albumsList } else { result = RemoteOperationResult>(false, propfind) client.exhaustResponse(propfind.responseBodyAsStream) } - } catch (var13: Exception) { - val e = var13 + } catch (e: Exception) { result = RemoteOperationResult>(e) Log_OC.e(TAG, "Read album failed: ${result.logMessage}", result.exception) } finally { diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.kt index bff94b2040..f1026480d0 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.kt @@ -13,7 +13,6 @@ import com.owncloud.android.lib.common.network.WebdavUtils import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.utils.Log_OC -import com.owncloud.android.lib.resources.albums.RemoveAlbumRemoteOperation import org.apache.commons.httpclient.HttpStatus import org.apache.jackrabbit.webdav.client.methods.DeleteMethod diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.kt index fe1def4129..27fe07c8a0 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.kt @@ -13,7 +13,6 @@ import com.owncloud.android.lib.common.network.WebdavUtils import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.utils.Log_OC -import com.owncloud.android.lib.resources.albums.RenameAlbumRemoteOperation import org.apache.jackrabbit.webdav.client.methods.MoveMethod class RenameAlbumRemoteOperation @JvmOverloads constructor( @@ -52,7 +51,6 @@ class RenameAlbumRemoteOperation @JvmOverloads constructor( "Rename ${this.mOldRemotePath} to ${this.newAlbumName} : ${result.logMessage}" ) client.exhaustResponse(move.responseBodyAsStream) - return result } } catch (e: Exception) { result = RemoteOperationResult(e) @@ -61,7 +59,6 @@ class RenameAlbumRemoteOperation @JvmOverloads constructor( "Rename ${this.mOldRemotePath} to ${this.newAlbumName} : ${result.logMessage}", e ) - return result } finally { move?.releaseConnection() } From cd2f7d721c8f60b28a55ae4f1c983e4665c0a26f Mon Sep 17 00:00:00 2001 From: A117870935 Date: Fri, 6 Jun 2025 14:12:51 +0530 Subject: [PATCH 6/8] Fix Signed-off-by: Surinder Kumar --- .../albums/CopyFileToAlbumRemoteOperation.kt | 95 ++++++------- .../albums/CreateNewAlbumRemoteOperation.kt | 94 ++++++------- .../lib/resources/albums/PhotoAlbumEntry.kt | 29 ++-- .../albums/ReadAlbumItemsRemoteOperation.kt | 130 +++++++++--------- .../albums/ReadAlbumsRemoteOperation.kt | 96 ++++++------- .../albums/RemoveAlbumFileRemoteOperation.kt | 75 +++++----- .../albums/RemoveAlbumRemoteOperation.kt | 91 ++++++------ .../albums/RenameAlbumRemoteOperation.kt | 101 +++++++------- .../ToggleAlbumFavoriteRemoteOperation.kt | 93 +++++++------ .../resources/albums/PhotoAlbumEntryTest.kt | 3 +- 10 files changed, 416 insertions(+), 391 deletions(-) diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.kt index 416cae6f8c..8d7971b91b 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.kt @@ -39,60 +39,62 @@ class CopyFileToAlbumRemoteOperation @JvmOverloads constructor( * @param client Client object to communicate with the remote ownCloud server. */ @Deprecated("Deprecated in Java") + @Suppress("TooGenericExceptionCaught") override fun run(client: OwnCloudClient): RemoteOperationResult { /** check parameters */ + var result: RemoteOperationResult if (mTargetRemotePath == mSrcRemotePath) { // nothing to do! - return RemoteOperationResult(ResultCode.OK) - } + result = RemoteOperationResult(ResultCode.OK) + } else if (mTargetRemotePath.startsWith(mSrcRemotePath)) { + result = RemoteOperationResult(ResultCode.INVALID_COPY_INTO_DESCENDANT) + } else { + /** perform remote operation */ + var copyMethod: CopyMethod? = null + try { + copyMethod = CopyMethod( + client.getFilesDavUri(this.mSrcRemotePath), + "${client.baseUri}/remote.php/dav/photos/${client.userId}/albums${ + WebdavUtils.encodePath( + mTargetRemotePath + ) + }", + false + ) + val status = client.executeMethod( + copyMethod, + sessionTimeOut.readTimeOut, + sessionTimeOut.connectionTimeOut + ) - if (mTargetRemotePath.startsWith(mSrcRemotePath)) { - return RemoteOperationResult(ResultCode.INVALID_COPY_INTO_DESCENDANT) - } + /** process response */ + result = when (status) { + HttpStatus.SC_MULTI_STATUS -> processPartialError(copyMethod) + HttpStatus.SC_PRECONDITION_FAILED -> { + client.exhaustResponse(copyMethod.responseBodyAsStream) + RemoteOperationResult(ResultCode.INVALID_OVERWRITE) + } - /** perform remote operation */ - var copyMethod: CopyMethod? = null - var result: RemoteOperationResult - try { - copyMethod = CopyMethod( - client.getFilesDavUri(this.mSrcRemotePath), - "${client.baseUri}/remote.php/dav/photos/${client.userId}/albums${ - WebdavUtils.encodePath( - mTargetRemotePath - ) - }", - false - ) - val status = client.executeMethod( - copyMethod, - sessionTimeOut.readTimeOut, - sessionTimeOut.connectionTimeOut - ) + else -> { + client.exhaustResponse(copyMethod.responseBodyAsStream) + RemoteOperationResult(isSuccess(status), copyMethod) + } + } - /** process response */ - if (status == HttpStatus.SC_MULTI_STATUS) { - result = processPartialError(copyMethod) - } else if (status == HttpStatus.SC_PRECONDITION_FAILED) { - result = RemoteOperationResult(ResultCode.INVALID_OVERWRITE) - client.exhaustResponse(copyMethod.responseBodyAsStream) - } else { - result = RemoteOperationResult(isSuccess(status), copyMethod) - client.exhaustResponse(copyMethod.responseBodyAsStream) + Log.i( + TAG, + "Copy $mSrcRemotePath to $mTargetRemotePath : ${result.logMessage}" + ) + } catch (e: Exception) { + result = RemoteOperationResult(e) + Log.e( + TAG, + "Copy $mSrcRemotePath to $mTargetRemotePath : ${result.logMessage}", e + ) + } finally { + copyMethod?.releaseConnection() } - - Log.i( - TAG, - "Copy $mSrcRemotePath to $mTargetRemotePath : ${result.logMessage}" - ) - } catch (e: Exception) { - result = RemoteOperationResult(e) - Log.e( - TAG, - "Copy $mSrcRemotePath to $mTargetRemotePath : ${result.logMessage}", e - ) - } finally { - copyMethod?.releaseConnection() } return result @@ -128,7 +130,7 @@ class CopyFileToAlbumRemoteOperation @JvmOverloads constructor( var i = 0 while (i < responses.size && !failFound) { status = responses[i].status - failFound = (!status.isNullOrEmpty() && status[0].statusCode > 299 + failFound = (!status.isNullOrEmpty() && status[0].statusCode > FAILED_STATUS_CODE ) i++ } @@ -147,5 +149,6 @@ class CopyFileToAlbumRemoteOperation @JvmOverloads constructor( companion object { private val TAG: String = CopyFileToAlbumRemoteOperation::class.java.simpleName + private const val FAILED_STATUS_CODE = 299 } } diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.kt index 946b58e80f..23f98b9b95 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.kt @@ -13,58 +13,60 @@ import com.owncloud.android.lib.common.network.WebdavUtils import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.utils.Log_OC -import com.owncloud.android.lib.resources.albums.CreateNewAlbumRemoteOperation import org.apache.commons.httpclient.HttpStatus import org.apache.jackrabbit.webdav.client.methods.MkColMethod -class CreateNewAlbumRemoteOperation @JvmOverloads constructor( - val newAlbumName: String, - private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut -) : - RemoteOperation() { - /** - * Performs the operation. - * - * @param client Client object to communicate with the remote ownCloud server. - */ - @Deprecated("Deprecated in Java") - override fun run(client: OwnCloudClient): RemoteOperationResult { - var mkCol: MkColMethod? = null - var result: RemoteOperationResult - try { - mkCol = MkColMethod( - "${client.baseUri}/remote.php/dav/photos/${client.userId}/albums${ - WebdavUtils.encodePath( - newAlbumName +class CreateNewAlbumRemoteOperation + @JvmOverloads + constructor( + val newAlbumName: String, + private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut + ) : RemoteOperation() { + /** + * Performs the operation. + * + * @param client Client object to communicate with the remote ownCloud server. + */ + @Deprecated("Deprecated in Java") + @Suppress("TooGenericExceptionCaught") + override fun run(client: OwnCloudClient): RemoteOperationResult { + var mkCol: MkColMethod? = null + var result: RemoteOperationResult + try { + mkCol = + MkColMethod( + "${client.baseUri}/remote.php/dav/photos/${client.userId}/albums${ + WebdavUtils.encodePath( + newAlbumName + ) + }" ) - }" - ) - client.executeMethod( - mkCol, - sessionTimeOut.readTimeOut, - sessionTimeOut.connectionTimeOut - ) - if (HttpStatus.SC_METHOD_NOT_ALLOWED == mkCol.statusCode) { - result = - RemoteOperationResult(RemoteOperationResult.ResultCode.FOLDER_ALREADY_EXISTS) - } else { - result = RemoteOperationResult(mkCol.succeeded(), mkCol) - result.resultData = null + client.executeMethod( + mkCol, + sessionTimeOut.readTimeOut, + sessionTimeOut.connectionTimeOut + ) + if (HttpStatus.SC_METHOD_NOT_ALLOWED == mkCol.statusCode) { + result = + RemoteOperationResult(RemoteOperationResult.ResultCode.FOLDER_ALREADY_EXISTS) + } else { + result = RemoteOperationResult(mkCol.succeeded(), mkCol) + result.resultData = null + } + + Log_OC.d(TAG, "Create album $newAlbumName : ${result.logMessage}") + client.exhaustResponse(mkCol.responseBodyAsStream) + } catch (e: Exception) { + result = RemoteOperationResult(e) + Log_OC.e(TAG, "Create album $newAlbumName : ${result.logMessage}", e) + } finally { + mkCol?.releaseConnection() } - Log_OC.d(TAG, "Create album $newAlbumName : ${result.logMessage}") - client.exhaustResponse(mkCol.responseBodyAsStream) - } catch (e: Exception) { - result = RemoteOperationResult(e) - Log_OC.e(TAG, "Create album $newAlbumName : ${result.logMessage}", e) - } finally { - mkCol?.releaseConnection() + return result } - return result - } - - companion object { - private val TAG: String = CreateNewAlbumRemoteOperation::class.java.simpleName + companion object { + private val TAG: String = CreateNewAlbumRemoteOperation::class.java.simpleName + } } -} diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntry.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntry.kt index be43aac3f7..734a9c7f21 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntry.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntry.kt @@ -19,7 +19,9 @@ import java.text.SimpleDateFormat import java.util.Date import java.util.Locale -class PhotoAlbumEntry(response: MultiStatusResponse) { +class PhotoAlbumEntry( + response: MultiStatusResponse +) { val href: String val lastPhoto: Long val nbItems: Int @@ -28,6 +30,7 @@ class PhotoAlbumEntry(response: MultiStatusResponse) { companion object { private val dateFormat = SimpleDateFormat("MMM yyyy", Locale.US) + private const val MILLIS = 1000L } init { @@ -42,27 +45,28 @@ class PhotoAlbumEntry(response: MultiStatusResponse) { this.dateRange = parseString(properties, WebdavEntry.PROPERTY_DATE_RANGE) } - private fun parseString(props: DavPropertySet, name: String): String? { + private fun parseString( + props: DavPropertySet, + name: String + ): String? { val propName = DavPropertyName.create(name, Namespace.getNamespace("nc", WebdavEntry.NAMESPACE_NC)) val prop = props[propName] return if (prop != null && prop.value != null) prop.value.toString() else null } - private fun parseInt(value: String?): Int { - return try { + private fun parseInt(value: String?): Int = + try { value?.toInt() ?: 0 } catch (_: NumberFormatException) { 0 } - } - private fun parseLong(value: String?): Long { - return try { + private fun parseLong(value: String?): Long = + try { value?.toLong() ?: 0L } catch (_: NumberFormatException) { 0L } - } val albumName: String get() { @@ -79,13 +83,14 @@ class PhotoAlbumEntry(response: MultiStatusResponse) { return try { val obj = JSONObject(dateRange ?: return dateFormat.format(currentDate)) val startTimestamp = obj.optLong("start", 0) - if (startTimestamp > 0) - dateFormat.format(Date(startTimestamp * 1000L)) - else + if (startTimestamp > 0) { + dateFormat.format(Date(startTimestamp * MILLIS)) + } else { dateFormat.format(currentDate) + } } catch (e: JSONException) { e.printStackTrace() dateFormat.format(currentDate) } } -} \ No newline at end of file +} diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.kt index 254ec49215..bb586bb04e 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.kt @@ -19,83 +19,77 @@ import org.apache.commons.httpclient.HttpStatus import org.apache.jackrabbit.webdav.DavConstants import org.apache.jackrabbit.webdav.client.methods.PropFindMethod -class ReadAlbumItemsRemoteOperation @JvmOverloads constructor( - private val mRemotePath: String, - private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut -) : - RemoteOperation>() { - @Deprecated("Deprecated in Java") - override fun run(client: OwnCloudClient): RemoteOperationResult> { - var result: RemoteOperationResult>? = null - var query: PropFindMethod? = null - val url = "${client.baseUri}/remote.php/dav/photos/${client.userId}/albums${ - WebdavUtils.encodePath( - mRemotePath - ) - }" - try { - // remote request - query = PropFindMethod( - url, - WebdavUtils.getAllPropSet(), // PropFind Properties - DavConstants.DEPTH_1 - ) - val status = client.executeMethod( - query, - sessionTimeOut.readTimeOut, - sessionTimeOut.connectionTimeOut - ) +class ReadAlbumItemsRemoteOperation + @JvmOverloads + constructor( + private val mRemotePath: String, + private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut + ) : RemoteOperation>() { + @Deprecated("Deprecated in Java") + @Suppress("TooGenericExceptionCaught") + override fun run(client: OwnCloudClient): RemoteOperationResult> { + var result: RemoteOperationResult>? = null + var query: PropFindMethod? = null + val url = "${client.baseUri}/remote.php/dav/photos/${client.userId}/albums${ + WebdavUtils.encodePath( + mRemotePath + ) + }" + try { + // remote request + query = + PropFindMethod( + url, + WebdavUtils.getAllPropSet(), // PropFind Properties + DavConstants.DEPTH_1 + ) + val status = + client.executeMethod( + query, + sessionTimeOut.readTimeOut, + sessionTimeOut.connectionTimeOut + ) - // check and process response - val isSuccess = (status == HttpStatus.SC_MULTI_STATUS || status == HttpStatus.SC_OK) + // check and process response + val isSuccess = (status == HttpStatus.SC_MULTI_STATUS || status == HttpStatus.SC_OK) - if (isSuccess) { - // get data from remote folder - val dataInServer = query.responseBodyAsMultiStatus - val mFolderAndFiles = WebDavFileUtils().readAlbumData(dataInServer, client) + result = + if (isSuccess) { + // get data from remote folder + val dataInServer = query.responseBodyAsMultiStatus + val mFolderAndFiles = WebDavFileUtils().readAlbumData(dataInServer, client) - // Result of the operation - result = RemoteOperationResult(true, query) - // Add data to the result - if (result.isSuccess) { - result.resultData = mFolderAndFiles - } - } else { - // synchronization failed - client.exhaustResponse(query.responseBodyAsStream) - result = RemoteOperationResult(false, query) - } - } catch (e: Exception) { - result = RemoteOperationResult(e) - } finally { - query?.releaseConnection() + // Result of the operation + RemoteOperationResult>(true, query).apply { + // Add data to the result + resultData = mFolderAndFiles + } + } else { + // synchronization failed + client.exhaustResponse(query.responseBodyAsStream) + RemoteOperationResult(false, query) + } + } catch (e: Exception) { + result = RemoteOperationResult(e) + } finally { + query?.releaseConnection() - if (result == null) { - result = RemoteOperationResult>(Exception("unknown error")) - Log_OC.e( - TAG, - "Synchronized $mRemotePath: failed" - ) - } else { + result = result ?: RemoteOperationResult>(Exception("unknown error")).also { + Log_OC.e(TAG, "Synchronized $mRemotePath: failed") + } if (result.isSuccess) { Log_OC.i(TAG, "Synchronized $mRemotePath : ${result.logMessage}") + } else if (result.isException) { + Log_OC.e(TAG, "Synchronized $mRemotePath : ${result.logMessage}", result.exception) } else { - if (result.isException) { - Log_OC.e( - TAG, "Synchronized $mRemotePath : ${result.logMessage}", - result.exception - ) - } else { - Log_OC.e(TAG, "Synchronized $mRemotePath : ${result.logMessage}") - } + Log_OC.e(TAG, "Synchronized $mRemotePath : ${result.logMessage}") } } - } - return result - } + return result + } - companion object { - private val TAG: String = ReadAlbumItemsRemoteOperation::class.java.simpleName + companion object { + private val TAG: String = ReadAlbumItemsRemoteOperation::class.java.simpleName + } } -} diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.kt index 92da03c81d..b7605e1b40 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.kt @@ -18,53 +18,57 @@ import org.apache.commons.httpclient.HttpStatus import org.apache.jackrabbit.webdav.DavConstants import org.apache.jackrabbit.webdav.client.methods.PropFindMethod -class ReadAlbumsRemoteOperation @JvmOverloads constructor( - private val mAlbumRemotePath: String? = null, - private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut -) : - RemoteOperation>() { - /** - * Performs the operation. - * - * @param client Client object to communicate with the remote ownCloud server. - */ - @Deprecated("Deprecated in Java") - override fun run(client: OwnCloudClient): RemoteOperationResult> { - var propfind: PropFindMethod? = null - var result: RemoteOperationResult> - var url = "${client.baseUri}/remote.php/dav/photos/${client.userId}/albums" - if (!TextUtils.isEmpty(mAlbumRemotePath)) { - url += WebdavUtils.encodePath(mAlbumRemotePath) - } - try { - propfind = PropFindMethod(url, WebdavUtils.getAlbumPropSet(), DavConstants.DEPTH_1) - val status = client.executeMethod( - propfind, - sessionTimeOut.readTimeOut, - sessionTimeOut.connectionTimeOut - ) - val isSuccess = status == HttpStatus.SC_MULTI_STATUS || status == HttpStatus.SC_OK - if (isSuccess) { - val albumsList = propfind.responseBodyAsMultiStatus.responses - .filter { it.status[0].statusCode == HttpStatus.SC_OK } - .map { res -> PhotoAlbumEntry(res) } - result = RemoteOperationResult>(true, propfind) - result.resultData = albumsList - } else { - result = RemoteOperationResult>(false, propfind) - client.exhaustResponse(propfind.responseBodyAsStream) +class ReadAlbumsRemoteOperation + @JvmOverloads + constructor( + private val mAlbumRemotePath: String? = null, + private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut + ) : RemoteOperation>() { + /** + * Performs the operation. + * + * @param client Client object to communicate with the remote ownCloud server. + */ + @Deprecated("Deprecated in Java") + @Suppress("TooGenericExceptionCaught") + override fun run(client: OwnCloudClient): RemoteOperationResult> { + var propfind: PropFindMethod? = null + var result: RemoteOperationResult> + var url = "${client.baseUri}/remote.php/dav/photos/${client.userId}/albums" + if (!TextUtils.isEmpty(mAlbumRemotePath)) { + url += WebdavUtils.encodePath(mAlbumRemotePath) + } + try { + propfind = PropFindMethod(url, WebdavUtils.getAlbumPropSet(), DavConstants.DEPTH_1) + val status = + client.executeMethod( + propfind, + sessionTimeOut.readTimeOut, + sessionTimeOut.connectionTimeOut + ) + val isSuccess = status == HttpStatus.SC_MULTI_STATUS || status == HttpStatus.SC_OK + if (isSuccess) { + val albumsList = + propfind.responseBodyAsMultiStatus.responses + .filter { it.status[0].statusCode == HttpStatus.SC_OK } + .map { res -> PhotoAlbumEntry(res) } + result = RemoteOperationResult>(true, propfind) + result.resultData = albumsList + } else { + result = RemoteOperationResult>(false, propfind) + client.exhaustResponse(propfind.responseBodyAsStream) + } + } catch (e: Exception) { + result = RemoteOperationResult>(e) + Log_OC.e(TAG, "Read album failed: ${result.logMessage}", result.exception) + } finally { + propfind?.releaseConnection() } - } catch (e: Exception) { - result = RemoteOperationResult>(e) - Log_OC.e(TAG, "Read album failed: ${result.logMessage}", result.exception) - } finally { - propfind?.releaseConnection() - } - return result - } + return result + } - companion object { - private val TAG: String = ReadAlbumsRemoteOperation::class.java.simpleName + companion object { + private val TAG: String = ReadAlbumsRemoteOperation::class.java.simpleName + } } -} diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumFileRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumFileRemoteOperation.kt index 8ffa6f1af5..843c0913db 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumFileRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumFileRemoteOperation.kt @@ -17,42 +17,47 @@ import com.owncloud.android.lib.resources.files.RemoveFileRemoteOperation import org.apache.commons.httpclient.HttpStatus import org.apache.jackrabbit.webdav.client.methods.DeleteMethod -class RemoveAlbumFileRemoteOperation @JvmOverloads constructor( - private val mRemotePath: String, - private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut -) : - RemoteOperation() { - @Deprecated("Deprecated in Java") - override fun run(client: OwnCloudClient): RemoteOperationResult { - var result: RemoteOperationResult - var delete: DeleteMethod? = null - val webDavUrl = "${client.davUri}/photos/" - val encodedPath = ("${client.userId}${Uri.encode(this.mRemotePath)}").replace("%2F", "/") - val fullFilePath = "$webDavUrl$encodedPath" +class RemoveAlbumFileRemoteOperation + @JvmOverloads + constructor( + private val mRemotePath: String, + private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut + ) : RemoteOperation() { + @Deprecated("Deprecated in Java") + @Suppress("TooGenericExceptionCaught") + override fun run(client: OwnCloudClient): RemoteOperationResult { + var result: RemoteOperationResult + var delete: DeleteMethod? = null + val webDavUrl = "${client.davUri}/photos/" + val encodedPath = ("${client.userId}${Uri.encode(this.mRemotePath)}").replace("%2F", "/") + val fullFilePath = "$webDavUrl$encodedPath" - try { - delete = DeleteMethod(fullFilePath) - val status = client.executeMethod( - delete, - sessionTimeOut.readTimeOut, sessionTimeOut.connectionTimeOut - ) - delete.responseBodyAsString - result = RemoteOperationResult( - delete.succeeded() || status == HttpStatus.SC_NOT_FOUND, - delete - ) - Log_OC.i(TAG, "Remove ${this.mRemotePath} : ${result.logMessage}") - } catch (e: Exception) { - result = RemoteOperationResult(e) - Log_OC.e(TAG, "Remove ${this.mRemotePath} : ${result.logMessage}", e) - } finally { - delete?.releaseConnection() - } + try { + delete = DeleteMethod(fullFilePath) + val status = + client.executeMethod( + delete, + sessionTimeOut.readTimeOut, + sessionTimeOut.connectionTimeOut + ) + delete.responseBodyAsString + result = + RemoteOperationResult( + delete.succeeded() || status == HttpStatus.SC_NOT_FOUND, + delete + ) + Log_OC.i(TAG, "Remove ${this.mRemotePath} : ${result.logMessage}") + } catch (e: Exception) { + result = RemoteOperationResult(e) + Log_OC.e(TAG, "Remove ${this.mRemotePath} : ${result.logMessage}", e) + } finally { + delete?.releaseConnection() + } - return result - } + return result + } - companion object { - private val TAG: String = RemoveFileRemoteOperation::class.java.simpleName + companion object { + private val TAG: String = RemoveFileRemoteOperation::class.java.simpleName + } } -} diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.kt index f1026480d0..c62183c2f8 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.kt @@ -16,51 +16,56 @@ import com.owncloud.android.lib.common.utils.Log_OC import org.apache.commons.httpclient.HttpStatus import org.apache.jackrabbit.webdav.client.methods.DeleteMethod -class RemoveAlbumRemoteOperation @JvmOverloads constructor( - private val albumName: String, - private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut -) : - RemoteOperation() { - /** - * Performs the operation. - * - * @param client Client object to communicate with the remote ownCloud server. - */ - @Deprecated("Deprecated in Java") - override fun run(client: OwnCloudClient): RemoteOperationResult { - var result: RemoteOperationResult - var delete: DeleteMethod? = null +class RemoveAlbumRemoteOperation + @JvmOverloads + constructor( + private val albumName: String, + private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut + ) : RemoteOperation() { + /** + * Performs the operation. + * + * @param client Client object to communicate with the remote ownCloud server. + */ + @Deprecated("Deprecated in Java") + @Suppress("TooGenericExceptionCaught") + override fun run(client: OwnCloudClient): RemoteOperationResult { + var result: RemoteOperationResult + var delete: DeleteMethod? = null - try { - delete = DeleteMethod( - "${client.baseUri}/remote.php/dav/photos/${client.userId}/albums${ - WebdavUtils.encodePath( - albumName + try { + delete = + DeleteMethod( + "${client.baseUri}/remote.php/dav/photos/${client.userId}/albums${ + WebdavUtils.encodePath( + albumName + ) + }" ) - }" - ) - val status = client.executeMethod( - delete, - sessionTimeOut.readTimeOut, - sessionTimeOut.connectionTimeOut - ) - delete.responseBodyAsString - result = RemoteOperationResult( - delete.succeeded() || status == HttpStatus.SC_NOT_FOUND, - delete - ) - Log_OC.i(TAG, "Remove ${this.albumName} : ${result.logMessage}") - } catch (e: Exception) { - result = RemoteOperationResult(e) - Log_OC.e(TAG, "Remove ${this.albumName} : ${result.logMessage}", e) - } finally { - delete?.releaseConnection() - } + val status = + client.executeMethod( + delete, + sessionTimeOut.readTimeOut, + sessionTimeOut.connectionTimeOut + ) + delete.responseBodyAsString + result = + RemoteOperationResult( + delete.succeeded() || status == HttpStatus.SC_NOT_FOUND, + delete + ) + Log_OC.i(TAG, "Remove ${this.albumName} : ${result.logMessage}") + } catch (e: Exception) { + result = RemoteOperationResult(e) + Log_OC.e(TAG, "Remove ${this.albumName} : ${result.logMessage}", e) + } finally { + delete?.releaseConnection() + } - return result - } + return result + } - companion object { - private val TAG: String = RemoveAlbumRemoteOperation::class.java.simpleName + companion object { + private val TAG: String = RemoveAlbumRemoteOperation::class.java.simpleName + } } -} diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.kt index 27fe07c8a0..78ad87671a 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.kt @@ -15,58 +15,63 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.utils.Log_OC import org.apache.jackrabbit.webdav.client.methods.MoveMethod -class RenameAlbumRemoteOperation @JvmOverloads constructor( - private val mOldRemotePath: String, - val newAlbumName: String, - private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut -) : - RemoteOperation() { - /** - * Performs the operation. - * - * @param client Client object to communicate with the remote ownCloud server. - */ - @Deprecated("Deprecated in Java") - override fun run(client: OwnCloudClient): RemoteOperationResult? { - var result: RemoteOperationResult? = null - var move: MoveMethod? = null - val url = "${client.baseUri}/remote.php/dav/photos/${client.userId}/albums" - try { - if (this.newAlbumName != this.mOldRemotePath) { - move = MoveMethod( - "$url${WebdavUtils.encodePath(mOldRemotePath)}", "$url${ - WebdavUtils.encodePath( - newAlbumName +class RenameAlbumRemoteOperation + @JvmOverloads + constructor( + private val mOldRemotePath: String, + val newAlbumName: String, + private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut + ) : RemoteOperation() { + /** + * Performs the operation. + * + * @param client Client object to communicate with the remote ownCloud server. + */ + @Deprecated("Deprecated in Java") + @Suppress("TooGenericExceptionCaught") + override fun run(client: OwnCloudClient): RemoteOperationResult? { + var result: RemoteOperationResult? = null + var move: MoveMethod? = null + val url = "${client.baseUri}/remote.php/dav/photos/${client.userId}/albums" + try { + if (this.newAlbumName != this.mOldRemotePath) { + move = + MoveMethod( + "$url${WebdavUtils.encodePath(mOldRemotePath)}", + "$url${ + WebdavUtils.encodePath( + newAlbumName + ) + }", + true ) - }", true - ) - client.executeMethod( - move, - sessionTimeOut.readTimeOut, - sessionTimeOut.connectionTimeOut - ) - result = RemoteOperationResult(move.succeeded(), move) - Log_OC.i( + client.executeMethod( + move, + sessionTimeOut.readTimeOut, + sessionTimeOut.connectionTimeOut + ) + result = RemoteOperationResult(move.succeeded(), move) + Log_OC.i( + TAG, + "Rename ${this.mOldRemotePath} to ${this.newAlbumName} : ${result.logMessage}" + ) + client.exhaustResponse(move.responseBodyAsStream) + } + } catch (e: Exception) { + result = RemoteOperationResult(e) + Log_OC.e( TAG, - "Rename ${this.mOldRemotePath} to ${this.newAlbumName} : ${result.logMessage}" + "Rename ${this.mOldRemotePath} to ${this.newAlbumName} : ${result.logMessage}", + e ) - client.exhaustResponse(move.responseBodyAsStream) + } finally { + move?.releaseConnection() } - } catch (e: Exception) { - result = RemoteOperationResult(e) - Log_OC.e( - TAG, - "Rename ${this.mOldRemotePath} to ${this.newAlbumName} : ${result.logMessage}", - e - ) - } finally { - move?.releaseConnection() - } - return result - } + return result + } - companion object { - private val TAG: String = RenameAlbumRemoteOperation::class.java.simpleName + companion object { + private val TAG: String = RenameAlbumRemoteOperation::class.java.simpleName + } } -} diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/ToggleAlbumFavoriteRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/ToggleAlbumFavoriteRemoteOperation.kt index be1952b338..c503344007 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/ToggleAlbumFavoriteRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/ToggleAlbumFavoriteRemoteOperation.kt @@ -21,53 +21,56 @@ import org.apache.jackrabbit.webdav.property.DefaultDavProperty import org.apache.jackrabbit.webdav.xml.Namespace import java.io.IOException -class ToggleAlbumFavoriteRemoteOperation @JvmOverloads constructor( - private val makeItFavorited: Boolean, - private val filePath: String, - private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut -) : - RemoteOperation() { - @Deprecated("Deprecated in Java") - override fun run(client: OwnCloudClient): RemoteOperationResult { - var result: RemoteOperationResult - var propPatchMethod: PropPatchMethod? = null - val newProps = DavPropertySet() - val removeProperties = DavPropertyNameSet() - if (this.makeItFavorited) { - val favoriteProperty = DefaultDavProperty( - "oc:favorite", - "1", - Namespace.getNamespace(WebdavEntry.NAMESPACE_OC) - ) - newProps.add(favoriteProperty) - } else { - removeProperties.add("oc:favorite", Namespace.getNamespace(WebdavEntry.NAMESPACE_OC)) - } +class ToggleAlbumFavoriteRemoteOperation + @JvmOverloads + constructor( + private val makeItFavorited: Boolean, + private val filePath: String, + private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut + ) : RemoteOperation() { + @Deprecated("Deprecated in Java") + override fun run(client: OwnCloudClient): RemoteOperationResult { + var result: RemoteOperationResult + var propPatchMethod: PropPatchMethod? = null + val newProps = DavPropertySet() + val removeProperties = DavPropertyNameSet() + if (this.makeItFavorited) { + val favoriteProperty = + DefaultDavProperty( + "oc:favorite", + "1", + Namespace.getNamespace(WebdavEntry.NAMESPACE_OC) + ) + newProps.add(favoriteProperty) + } else { + removeProperties.add("oc:favorite", Namespace.getNamespace(WebdavEntry.NAMESPACE_OC)) + } - val webDavUrl = "${client.davUri}/photos/" - val encodedPath = ("${client.userId}${Uri.encode(this.filePath)}").replace("%2F", "/") - val fullFilePath = "$webDavUrl$encodedPath" + val webDavUrl = "${client.davUri}/photos/" + val encodedPath = ("${client.userId}${Uri.encode(this.filePath)}").replace("%2F", "/") + val fullFilePath = "$webDavUrl$encodedPath" - try { - propPatchMethod = PropPatchMethod(fullFilePath, newProps, removeProperties) - val status = client.executeMethod( - propPatchMethod, - sessionTimeOut.readTimeOut, - sessionTimeOut.connectionTimeOut - ) - val isSuccess = (status == HttpStatus.SC_MULTI_STATUS || status == HttpStatus.SC_OK) - if (isSuccess) { - result = RemoteOperationResult(true, status, propPatchMethod.responseHeaders) - } else { - client.exhaustResponse(propPatchMethod.responseBodyAsStream) - result = RemoteOperationResult(false, status, propPatchMethod.responseHeaders) + try { + propPatchMethod = PropPatchMethod(fullFilePath, newProps, removeProperties) + val status = + client.executeMethod( + propPatchMethod, + sessionTimeOut.readTimeOut, + sessionTimeOut.connectionTimeOut + ) + val isSuccess = (status == HttpStatus.SC_MULTI_STATUS || status == HttpStatus.SC_OK) + if (isSuccess) { + result = RemoteOperationResult(true, status, propPatchMethod.responseHeaders) + } else { + client.exhaustResponse(propPatchMethod.responseBodyAsStream) + result = RemoteOperationResult(false, status, propPatchMethod.responseHeaders) + } + } catch (e: IOException) { + result = RemoteOperationResult(e) + } finally { + propPatchMethod?.releaseConnection() } - } catch (e: IOException) { - result = RemoteOperationResult(e) - } finally { - propPatchMethod?.releaseConnection() - } - return result + return result + } } -} \ No newline at end of file diff --git a/library/src/test/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntryTest.kt b/library/src/test/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntryTest.kt index f7757395d8..ad46c92046 100644 --- a/library/src/test/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntryTest.kt +++ b/library/src/test/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntryTest.kt @@ -12,7 +12,6 @@ import org.junit.Assert.assertEquals import org.junit.Test class PhotoAlbumEntryTest { - @Test fun testAlbumName_withTrailingSlash() { val entry = createTestEntry("/remote.php/dav/photos/user_id/albums/vacation2024/") @@ -54,4 +53,4 @@ class PhotoAlbumEntryTest { val response = MultiStatusResponse(href, 200) return PhotoAlbumEntry(response) } -} \ No newline at end of file +} From 6e2b68fa8e38895ae1a2ce950b177b917469015e Mon Sep 17 00:00:00 2001 From: Surinder Kumar Date: Thu, 19 Jun 2025 20:15:03 +0530 Subject: [PATCH 7/8] Fix Copyright Signed-off-by: Surinder Kumar --- .../lib/resources/albums/CopyFileToAlbumRemoteOperation.kt | 2 +- .../lib/resources/albums/CreateNewAlbumRemoteOperation.kt | 2 +- .../owncloud/android/lib/resources/albums/PhotoAlbumEntry.kt | 2 +- .../lib/resources/albums/ReadAlbumItemsRemoteOperation.kt | 2 +- .../android/lib/resources/albums/ReadAlbumsRemoteOperation.kt | 2 +- .../lib/resources/albums/RemoveAlbumFileRemoteOperation.kt | 2 +- .../android/lib/resources/albums/RemoveAlbumRemoteOperation.kt | 2 +- .../android/lib/resources/albums/RenameAlbumRemoteOperation.kt | 2 +- .../lib/resources/albums/ToggleAlbumFavoriteRemoteOperation.kt | 2 +- .../android/lib/resources/albums/PhotoAlbumEntryTest.kt | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.kt index 8d7971b91b..9272a98208 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/CopyFileToAlbumRemoteOperation.kt @@ -2,7 +2,7 @@ * Nextcloud Android Library * * SPDX-FileCopyrightText: 2025 TSI-mc - * SPDX-License-Identifier: AGPL-3.0-or-later + * SPDX-License-Identifier: MIT */ package com.owncloud.android.lib.resources.albums diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.kt index 23f98b9b95..6d69d53a05 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/CreateNewAlbumRemoteOperation.kt @@ -2,7 +2,7 @@ * Nextcloud Android Library * * SPDX-FileCopyrightText: 2025 TSI-mc - * SPDX-License-Identifier: AGPL-3.0-or-later + * SPDX-License-Identifier: MIT */ package com.owncloud.android.lib.resources.albums diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntry.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntry.kt index 734a9c7f21..168ec0d6be 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntry.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntry.kt @@ -2,7 +2,7 @@ * Nextcloud Android Library * * SPDX-FileCopyrightText: 2025 TSI-mc - * SPDX-License-Identifier: AGPL-3.0-or-later + * SPDX-License-Identifier: MIT */ package com.owncloud.android.lib.resources.albums diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.kt index bb586bb04e..40deed2e70 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumItemsRemoteOperation.kt @@ -2,7 +2,7 @@ * Nextcloud Android Library * * SPDX-FileCopyrightText: 2025 TSI-mc - * SPDX-License-Identifier: AGPL-3.0-or-later + * SPDX-License-Identifier: MIT */ package com.owncloud.android.lib.resources.albums diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.kt index b7605e1b40..c472b34e8c 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/ReadAlbumsRemoteOperation.kt @@ -2,7 +2,7 @@ * Nextcloud Android Library * * SPDX-FileCopyrightText: 2025 TSI-mc - * SPDX-License-Identifier: AGPL-3.0-or-later + * SPDX-License-Identifier: MIT */ package com.owncloud.android.lib.resources.albums diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumFileRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumFileRemoteOperation.kt index 843c0913db..51c5ee2efc 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumFileRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumFileRemoteOperation.kt @@ -2,7 +2,7 @@ * Nextcloud Android Library * * SPDX-FileCopyrightText: 2025 TSI-mc - * SPDX-License-Identifier: AGPL-3.0-or-later + * SPDX-License-Identifier: MIT */ package com.owncloud.android.lib.resources.albums diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.kt index c62183c2f8..b9114ac8f2 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/RemoveAlbumRemoteOperation.kt @@ -2,7 +2,7 @@ * Nextcloud Android Library * * SPDX-FileCopyrightText: 2025 TSI-mc - * SPDX-License-Identifier: AGPL-3.0-or-later + * SPDX-License-Identifier: MIT */ package com.owncloud.android.lib.resources.albums diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.kt index 78ad87671a..6dff04e913 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/RenameAlbumRemoteOperation.kt @@ -2,7 +2,7 @@ * Nextcloud Android Library * * SPDX-FileCopyrightText: 2025 TSI-mc - * SPDX-License-Identifier: AGPL-3.0-or-later + * SPDX-License-Identifier: MIT */ package com.owncloud.android.lib.resources.albums diff --git a/library/src/main/java/com/owncloud/android/lib/resources/albums/ToggleAlbumFavoriteRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/albums/ToggleAlbumFavoriteRemoteOperation.kt index c503344007..b2253c69ca 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/albums/ToggleAlbumFavoriteRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/albums/ToggleAlbumFavoriteRemoteOperation.kt @@ -2,7 +2,7 @@ * Nextcloud Android Library * * SPDX-FileCopyrightText: 2025 TSI-mc - * SPDX-License-Identifier: AGPL-3.0-or-later + * SPDX-License-Identifier: MIT */ package com.owncloud.android.lib.resources.albums diff --git a/library/src/test/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntryTest.kt b/library/src/test/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntryTest.kt index ad46c92046..f80c20d70a 100644 --- a/library/src/test/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntryTest.kt +++ b/library/src/test/java/com/owncloud/android/lib/resources/albums/PhotoAlbumEntryTest.kt @@ -2,7 +2,7 @@ * Nextcloud Android Library * * SPDX-FileCopyrightText: 2025 TSI-mc - * SPDX-License-Identifier: AGPL-3.0-or-later + * SPDX-License-Identifier: MIT */ package com.owncloud.android.lib.resources.albums From 62a46696a9886ebd497866498b8e6ea3934ae1f1 Mon Sep 17 00:00:00 2001 From: Surinder Kumar Date: Thu, 10 Jul 2025 13:56:16 +0530 Subject: [PATCH 8/8] Fix collections presize Signed-off-by: Surinder Kumar --- .../com/owncloud/android/lib/common/utils/WebDavFileUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/src/main/java/com/owncloud/android/lib/common/utils/WebDavFileUtils.java b/library/src/main/java/com/owncloud/android/lib/common/utils/WebDavFileUtils.java index bcfb80c55d..0ca9d16013 100644 --- a/library/src/main/java/com/owncloud/android/lib/common/utils/WebDavFileUtils.java +++ b/library/src/main/java/com/owncloud/android/lib/common/utils/WebDavFileUtils.java @@ -81,8 +81,8 @@ public List readAlbumData(MultiStatus remoteData, OwnCloudClient cli return Collections.emptyList(); } - List files = new ArrayList<>(); final var responses = remoteData.getResponses(); + List files = new ArrayList<>(Math.max(0, responses.length - 1)); // reading from 1 as 0th item will be just the root album path for (int i = 1; i < responses.length; i++) {