Skip to content
This repository was archived by the owner on Mar 19, 2024. It is now read-only.

Commit 0e9f9c6

Browse files
authored
Merge pull request #530 from owncloud/spaces/main
[SPACES] Main features
2 parents e30246c + 159dcd6 commit 0e9f9c6

27 files changed

+615
-169
lines changed

owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CheckPathExistenceRemoteOperation.kt

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* ownCloud Android Library is available under MIT license
2-
* Copyright (C) 2020 ownCloud GmbH.
2+
* Copyright (C) 2023 ownCloud GmbH.
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy
55
* of this software and associated documentation files (the "Software"), to deal
@@ -41,28 +41,30 @@ import java.util.concurrent.TimeUnit
4141
* @author David A. Velasco
4242
* @author David González Verdugo
4343
* @author Abel García de Prada
44+
* @author Juan Carlos Garrote Gascón
4445
*
4546
* @param remotePath Path to append to the URL owned by the client instance.
4647
* @param isUserLoggedIn When `true`, the username won't be added at the end of the PROPFIND url since is not
4748
* needed to check user credentials
4849
*/
4950
class CheckPathExistenceRemoteOperation(
5051
val remotePath: String? = "",
51-
val isUserLoggedIn: Boolean
52+
val isUserLoggedIn: Boolean,
53+
val spaceWebDavUrl: String? = null,
5254
) : RemoteOperation<Boolean>() {
5355

5456
override fun run(client: OwnCloudClient): RemoteOperationResult<Boolean> {
55-
return try {
56-
val stringUrl =
57-
if (isUserLoggedIn) client.baseFilesWebDavUri.toString()
58-
else client.userFilesWebDavUri.toString() + WebdavUtils.encodePath(remotePath)
57+
val baseStringUrl = spaceWebDavUrl ?: if (isUserLoggedIn) client.baseFilesWebDavUri.toString()
58+
else client.userFilesWebDavUri.toString()
59+
val stringUrl = baseStringUrl + WebdavUtils.encodePath(remotePath)
5960

61+
return try {
6062
val propFindMethod = PropfindMethod(URL(stringUrl), 0, allPropset).apply {
6163
setReadTimeout(TIMEOUT.toLong(), TimeUnit.SECONDS)
6264
setConnectionTimeout(TIMEOUT.toLong(), TimeUnit.SECONDS)
6365
}
6466

65-
var status = client.executeHttpMethod(propFindMethod)
67+
val status = client.executeHttpMethod(propFindMethod)
6668
/* PROPFIND method
6769
* 404 NOT FOUND: path doesn't exist,
6870
* 207 MULTI_STATUS: path exists.
@@ -77,7 +79,7 @@ class CheckPathExistenceRemoteOperation(
7779
val result = RemoteOperationResult<Boolean>(e)
7880
Timber.e(
7981
e,
80-
"Existence check for ${client.userFilesWebDavUri}${WebdavUtils.encodePath(remotePath)} : ${result.logMessage}"
82+
"Existence check for $stringUrl : ${result.logMessage}"
8183
)
8284
result
8385
}

owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.kt

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* ownCloud Android Library is available under MIT license
2-
* Copyright (C) 2022 ownCloud GmbH.
2+
* Copyright (C) 2023 ownCloud GmbH.
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy
55
* of this software and associated documentation files (the "Software"), to deal
@@ -44,34 +44,38 @@ import java.util.concurrent.TimeUnit
4444
* @author David A. Velasco
4545
* @author Christian Schabesberger
4646
* @author David González V.
47+
* @author Juan Carlos Garrote Gascón
4748
*
48-
* @param srcRemotePath Remote path of the file/folder to copy.
49+
* @param sourceRemotePath Remote path of the file/folder to copy.
4950
* @param targetRemotePath Remote path desired for the file/folder to copy it.
5051
*/
5152
class CopyRemoteFileOperation(
52-
private val srcRemotePath: String,
53+
private val sourceRemotePath: String,
5354
private val targetRemotePath: String,
55+
private val sourceSpaceWebDavUrl: String? = null,
56+
private val targetSpaceWebDavUrl: String? = null,
5457
) : RemoteOperation<String>() {
58+
5559
/**
5660
* Performs the rename operation.
5761
*
5862
* @param client Client object to communicate with the remote ownCloud server.
5963
*/
6064
override fun run(client: OwnCloudClient): RemoteOperationResult<String> {
61-
if (targetRemotePath == srcRemotePath) {
65+
if (targetRemotePath == sourceRemotePath && sourceSpaceWebDavUrl == targetSpaceWebDavUrl) {
6266
// nothing to do!
6367
return RemoteOperationResult(ResultCode.OK)
6468
}
65-
if (targetRemotePath.startsWith(srcRemotePath)) {
69+
if (targetRemotePath.startsWith(sourceRemotePath) && sourceSpaceWebDavUrl == targetSpaceWebDavUrl) {
6670
return RemoteOperationResult(ResultCode.INVALID_COPY_INTO_DESCENDANT)
6771
}
6872

6973
/// perform remote operation
7074
var result: RemoteOperationResult<String>
7175
try {
7276
val copyMethod = CopyMethod(
73-
URL(client.userFilesWebDavUri.toString() + WebdavUtils.encodePath(srcRemotePath)),
74-
client.userFilesWebDavUri.toString() + WebdavUtils.encodePath(targetRemotePath),
77+
URL((sourceSpaceWebDavUrl ?: client.userFilesWebDavUri.toString()) + WebdavUtils.encodePath(sourceRemotePath)),
78+
(targetSpaceWebDavUrl ?: client.userFilesWebDavUri.toString()) + WebdavUtils.encodePath(targetRemotePath),
7579
).apply {
7680
setReadTimeout(COPY_READ_TIMEOUT, TimeUnit.SECONDS)
7781
setConnectionTimeout(COPY_CONNECTION_TIMEOUT, TimeUnit.SECONDS)
@@ -95,10 +99,10 @@ class CopyRemoteFileOperation(
9599
client.exhaustResponse(copyMethod.getResponseBodyAsStream())
96100
}
97101
}
98-
Timber.i("Copy $srcRemotePath to $targetRemotePath: ${result.logMessage}")
102+
Timber.i("Copy $sourceRemotePath to $targetRemotePath: ${result.logMessage}")
99103
} catch (e: Exception) {
100104
result = RemoteOperationResult(e)
101-
Timber.e(e, "Copy $srcRemotePath to $targetRemotePath: ${result.logMessage}")
105+
Timber.e(e, "Copy $sourceRemotePath to $targetRemotePath: ${result.logMessage}")
102106
}
103107
return result
104108
}

owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ import java.util.concurrent.TimeUnit
4646
class CreateRemoteFolderOperation(
4747
val remotePath: String,
4848
private val createFullPath: Boolean,
49-
private val isChunksFolder: Boolean = false
49+
private val isChunksFolder: Boolean = false,
50+
val spaceWebDavUrl: String? = null,
5051
) : RemoteOperation<Unit>() {
5152

5253
override fun run(client: OwnCloudClient): RemoteOperationResult<Unit> {
@@ -67,13 +68,13 @@ class CreateRemoteFolderOperation(
6768
var result: RemoteOperationResult<Unit>
6869
try {
6970
val webDavUri = if (isChunksFolder) {
70-
client.uploadsWebDavUri
71+
client.uploadsWebDavUri.toString()
7172
} else {
72-
client.userFilesWebDavUri
73+
spaceWebDavUrl ?: client.userFilesWebDavUri.toString()
7374
}
7475

7576
val mkCol = MkColMethod(
76-
URL(webDavUri.toString() + WebdavUtils.encodePath(remotePath))
77+
URL(webDavUri + WebdavUtils.encodePath(remotePath))
7778
).apply {
7879
setReadTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
7980
setConnectionTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS)

owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ import java.io.BufferedInputStream
3636
import java.io.File
3737
import java.io.FileOutputStream
3838
import java.net.URL
39-
import java.util.HashSet
4039
import java.util.concurrent.atomic.AtomicBoolean
4140

4241
/**
@@ -47,7 +46,8 @@ import java.util.concurrent.atomic.AtomicBoolean
4746
*/
4847
class DownloadRemoteFileOperation(
4948
private val remotePath: String,
50-
localFolderPath: String
49+
localFolderPath: String,
50+
private val spaceWebDavUrl: String? = null,
5151
) : RemoteOperation<Unit>() {
5252

5353
private val cancellationRequested = AtomicBoolean(false)
@@ -84,7 +84,8 @@ class DownloadRemoteFileOperation(
8484
var bis: BufferedInputStream? = null
8585
var savedFile = false
8686

87-
val getMethod = GetMethod(URL(client.userFilesWebDavUri.toString() + WebdavUtils.encodePath(remotePath)))
87+
val webDavUri = spaceWebDavUrl ?: client.userFilesWebDavUri.toString()
88+
val getMethod = GetMethod(URL(webDavUri + WebdavUtils.encodePath(remotePath)))
8889

8990
try {
9091
val status = client.executeHttpMethod(getMethod)

owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.kt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* ownCloud Android Library is available under MIT license
2-
* Copyright (C) 2021 ownCloud GmbH.
2+
* Copyright (C) 2023 ownCloud GmbH.
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy
55
* of this software and associated documentation files (the "Software"), to deal
@@ -38,17 +38,22 @@ import java.util.concurrent.TimeUnit
3838

3939
/**
4040
* Remote operation moving a remote file or folder in the ownCloud server to a different folder
41-
* in the same account.
41+
* in the same account and space.
4242
*
4343
* Allows renaming the moving file/folder at the same time.
4444
*
4545
* @author David A. Velasco
4646
* @author David González Verdugo
4747
* @author Abel García de Prada
48+
* @author Juan Carlos Garrote Gascón
49+
*
50+
* @param sourceRemotePath Remote path of the file/folder to copy.
51+
* @param targetRemotePath Remote path desired for the file/folder to copy it.
4852
*/
4953
open class MoveRemoteFileOperation(
5054
private val sourceRemotePath: String,
5155
private val targetRemotePath: String,
56+
private val spaceWebDavUrl: String? = null,
5257
) : RemoteOperation<Unit>() {
5358

5459
/**
@@ -73,8 +78,8 @@ open class MoveRemoteFileOperation(
7378
// so this uri has to be customizable
7479
val srcWebDavUri = getSrcWebDavUriForClient(client)
7580
val moveMethod = MoveMethod(
76-
url = URL(srcWebDavUri.toString() + WebdavUtils.encodePath(sourceRemotePath)),
77-
destinationUrl = client.userFilesWebDavUri.toString() + WebdavUtils.encodePath(targetRemotePath),
81+
url = URL((spaceWebDavUrl ?: srcWebDavUri.toString()) + WebdavUtils.encodePath(sourceRemotePath)),
82+
destinationUrl = (spaceWebDavUrl ?: client.userFilesWebDavUri.toString()) + WebdavUtils.encodePath(targetRemotePath),
7883
).apply {
7984
addRequestHeaders(this)
8085
setReadTimeout(MOVE_READ_TIMEOUT, TimeUnit.SECONDS)

owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFileOperation.kt

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ import java.util.concurrent.TimeUnit
4646
* @author David González Verdugo
4747
*/
4848

49-
class ReadRemoteFileOperation(val remotePath: String) : RemoteOperation<RemoteFile>() {
49+
class ReadRemoteFileOperation(
50+
val remotePath: String,
51+
val spaceWebDavUrl: String? = null,
52+
) : RemoteOperation<RemoteFile>() {
5053

5154
/**
5255
* Performs the read operation.
@@ -57,7 +60,7 @@ class ReadRemoteFileOperation(val remotePath: String) : RemoteOperation<RemoteFi
5760
override fun run(client: OwnCloudClient): RemoteOperationResult<RemoteFile> {
5861
try {
5962
val propFind = PropfindMethod(
60-
url = URL("${client.userFilesWebDavUri}${WebdavUtils.encodePath(remotePath)}"),
63+
url = getFinalWebDavUrl(),
6164
depth = DEPTH_0,
6265
propertiesToRequest = DavUtils.allPropset
6366
).apply {
@@ -69,10 +72,11 @@ class ReadRemoteFileOperation(val remotePath: String) : RemoteOperation<RemoteFi
6972
Timber.i("Read remote file $remotePath with status ${propFind.statusCode}")
7073

7174
return if (isSuccess(status)) {
72-
// TODO: Remove that !!
7375
val remoteFile = RemoteFile.getRemoteFileFromDav(
74-
propFind.root!!,
75-
AccountUtils.getUserId(mAccount, mContext), mAccount.name
76+
davResource = propFind.root!!,
77+
userId = AccountUtils.getUserId(mAccount, mContext),
78+
userName = mAccount.name,
79+
spaceWebDavUrl = spaceWebDavUrl,
7680
)
7781

7882
RemoteOperationResult<RemoteFile>(RemoteOperationResult.ResultCode.OK).apply {
@@ -88,6 +92,12 @@ class ReadRemoteFileOperation(val remotePath: String) : RemoteOperation<RemoteFi
8892
}
8993
}
9094

95+
private fun getFinalWebDavUrl(): URL {
96+
val baseWebDavUrl = spaceWebDavUrl ?: client.userFilesWebDavUri.toString()
97+
98+
return URL(baseWebDavUrl + WebdavUtils.encodePath(remotePath))
99+
}
100+
91101
private fun isSuccess(status: Int) = status.isOneOf(HTTP_MULTI_STATUS, HTTP_OK)
92102

93103
companion object {

owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.kt

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ import java.net.URL
4848
* @author David González Verdugo
4949
*/
5050
class ReadRemoteFolderOperation(
51-
val remotePath: String
51+
val remotePath: String,
52+
val spaceWebDavUrl: String? = null,
5253
) : RemoteOperation<ArrayList<RemoteFile>>() {
5354

5455
/**
@@ -61,7 +62,7 @@ class ReadRemoteFolderOperation(
6162
PropertyRegistry.register(OCShareTypes.Factory())
6263

6364
val propfindMethod = PropfindMethod(
64-
URL(client.userFilesWebDavUri.toString() + WebdavUtils.encodePath(remotePath)),
65+
getFinalWebDavUrl(),
6566
DavConstants.DEPTH_1,
6667
DavUtils.allPropset
6768
)
@@ -71,12 +72,11 @@ class ReadRemoteFolderOperation(
7172
if (isSuccess(status)) {
7273
val mFolderAndFiles = ArrayList<RemoteFile>()
7374

74-
// parse data from remote folder
75-
// TODO: Remove that !!
7675
val remoteFolder = RemoteFile.getRemoteFileFromDav(
7776
davResource = propfindMethod.root!!,
7877
userId = AccountUtils.getUserId(mAccount, mContext),
79-
userName = mAccount.name
78+
userName = mAccount.name,
79+
spaceWebDavUrl = spaceWebDavUrl,
8080
)
8181
mFolderAndFiles.add(remoteFolder)
8282

@@ -85,7 +85,8 @@ class ReadRemoteFolderOperation(
8585
val remoteFile = RemoteFile.getRemoteFileFromDav(
8686
davResource = resource,
8787
userId = AccountUtils.getUserId(mAccount, mContext),
88-
userName = mAccount.name
88+
userName = mAccount.name,
89+
spaceWebDavUrl = spaceWebDavUrl,
8990
)
9091
mFolderAndFiles.add(remoteFile)
9192
}
@@ -107,5 +108,11 @@ class ReadRemoteFolderOperation(
107108
}
108109
}
109110

111+
private fun getFinalWebDavUrl(): URL {
112+
val baseWebDavUrl = spaceWebDavUrl ?: client.userFilesWebDavUri.toString()
113+
114+
return URL(baseWebDavUrl + WebdavUtils.encodePath(remotePath))
115+
}
116+
110117
private fun isSuccess(status: Int): Boolean = status.isOneOf(HTTP_OK, HTTP_MULTI_STATUS)
111118
}

owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoteFile.kt

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ package com.owncloud.android.lib.resources.files
2626

2727
import android.net.Uri
2828
import android.os.Parcelable
29+
import androidx.annotation.VisibleForTesting
2930
import at.bitfire.dav4jvm.PropStat
3031
import at.bitfire.dav4jvm.Property
3132
import at.bitfire.dav4jvm.Response
@@ -100,8 +101,13 @@ data class RemoteFile(
100101
const val MIME_DIR = "DIR"
101102
const val MIME_DIR_UNIX = "httpd/unix-directory"
102103

103-
fun getRemoteFileFromDav(davResource: Response, userId: String, userName: String): RemoteFile {
104-
val remotePath = getRemotePathFromUrl(davResource.href, userId)
104+
fun getRemoteFileFromDav(
105+
davResource: Response,
106+
userId: String,
107+
userName: String,
108+
spaceWebDavUrl: String? = null
109+
): RemoteFile {
110+
val remotePath = getRemotePathFromUrl(davResource.href, userId, spaceWebDavUrl)
105111
val remoteFile = RemoteFile(remotePath = remotePath, owner = userName)
106112
val properties = getPropertiesEvenIfPostProcessing(davResource)
107113

@@ -164,15 +170,25 @@ data class RemoteFile(
164170
* Retrieves a relative path from a remote file url
165171
*
166172
*
167-
* Example: url:port/remote.php/dav/files/username/Documents/text.txt => /Documents/text.txt
173+
* Example legacy:
174+
* /remote.php/dav/files/username/Documents/text.txt => /Documents/text.txt
175+
*
176+
* Example spaces:
177+
* /dav/spaces/8871f4f3-fc6f-4a66-8bed-62f175f76f38$05bca744-d89f-4e9c-a990-25a0d7f03fe9/Documents/text.txt => /Documents/text.txt
168178
*
169179
* @param url remote file url
170180
* @param userId file owner
181+
* @param spaceWebDavUrl custom web dav url for space
171182
* @return remote relative path of the file
172183
*/
173-
private fun getRemotePathFromUrl(url: HttpUrl, userId: String): String {
174-
val davFilesPath = OwnCloudClient.WEBDAV_FILES_PATH_4_0 + userId
175-
val absoluteDavPath = Uri.decode(url.encodedPath)
184+
@VisibleForTesting
185+
fun getRemotePathFromUrl(
186+
url: HttpUrl,
187+
userId: String,
188+
spaceWebDavUrl: String? = null,
189+
): String {
190+
val davFilesPath = spaceWebDavUrl ?: (OwnCloudClient.WEBDAV_FILES_PATH_4_0 + userId)
191+
val absoluteDavPath = if (spaceWebDavUrl != null) Uri.decode(url.toString()) else Uri.decode(url.encodedPath)
176192
val pathToOc = absoluteDavPath.split(davFilesPath).first()
177193
return absoluteDavPath.replace(pathToOc + davFilesPath, "")
178194
}

0 commit comments

Comments
 (0)