mirror of
https://github.com/owncloud/android-library.git
synced 2025-06-07 16:06:08 +00:00
The ShareXMLParser has been removed from UpdateRemoteShareOperation.kt class.
This commit is contained in:
parent
7baf3e43a5
commit
91bd322b68
@ -1,120 +0,0 @@
|
||||
/* ownCloud Android Library is available under MIT license
|
||||
* @author David A. Velasco
|
||||
* @author David González Verdugo
|
||||
* @author Christian Schabesberger
|
||||
* Copyright (C) 2020 ownCloud GmbH.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.owncloud.android.lib.resources.shares
|
||||
|
||||
import android.net.Uri
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult
|
||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion
|
||||
import org.xmlpull.v1.XmlPullParserException
|
||||
import timber.log.Timber
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.IOException
|
||||
import java.util.ArrayList
|
||||
|
||||
class ShareToRemoteOperationResultParser(private var shareXmlParser: ShareXMLParser?) {
|
||||
var oneOrMoreSharesRequired = false
|
||||
var ownCloudVersion: OwnCloudVersion? = null
|
||||
var serverBaseUri: Uri? = null
|
||||
|
||||
fun parse(serverResponse: String?): RemoteOperationResult<ShareResponse> {
|
||||
if (serverResponse.isNullOrEmpty()) {
|
||||
return RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE)
|
||||
}
|
||||
|
||||
var result: RemoteOperationResult<ShareResponse>
|
||||
val resultData: List<RemoteShare>?
|
||||
|
||||
try {
|
||||
// Parse xml response and obtain the list of shares
|
||||
val byteArrayServerResponse = ByteArrayInputStream(serverResponse.toByteArray())
|
||||
if (shareXmlParser == null) {
|
||||
Timber.w("No ShareXmlParser provided, creating new instance")
|
||||
shareXmlParser = ShareXMLParser()
|
||||
}
|
||||
val shares = shareXmlParser?.parseXMLResponse(byteArrayServerResponse)
|
||||
|
||||
when {
|
||||
shareXmlParser?.isSuccess!! -> {
|
||||
if (!shares.isNullOrEmpty() || !oneOrMoreSharesRequired) {
|
||||
result = RemoteOperationResult(RemoteOperationResult.ResultCode.OK)
|
||||
|
||||
resultData = shares?.map { share ->
|
||||
if (share.shareType != ShareType.PUBLIC_LINK ||
|
||||
share.shareLink.isNotEmpty() ||
|
||||
share.token.isEmpty()
|
||||
) {
|
||||
return@map share
|
||||
}
|
||||
|
||||
if (serverBaseUri != null) {
|
||||
val sharingLinkPath = ShareUtils.SHARING_LINK_PATH
|
||||
share.shareLink = serverBaseUri.toString() + sharingLinkPath + share.token
|
||||
} else {
|
||||
Timber.e("Couldn't build link for public share :(")
|
||||
}
|
||||
|
||||
share
|
||||
}
|
||||
|
||||
if (resultData != null) {
|
||||
result.setData(ShareResponse(ArrayList(resultData.toMutableList())))
|
||||
}
|
||||
|
||||
} else {
|
||||
result = RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE)
|
||||
Timber.e("Successful status with no share in the response")
|
||||
}
|
||||
}
|
||||
shareXmlParser?.isWrongParameter!! -> {
|
||||
result = RemoteOperationResult(RemoteOperationResult.ResultCode.SHARE_WRONG_PARAMETER)
|
||||
result.httpPhrase = shareXmlParser?.message
|
||||
}
|
||||
shareXmlParser?.isNotFound!! -> {
|
||||
result = RemoteOperationResult(RemoteOperationResult.ResultCode.SHARE_NOT_FOUND)
|
||||
result.httpPhrase = shareXmlParser?.message
|
||||
}
|
||||
shareXmlParser?.isForbidden!! -> {
|
||||
result = RemoteOperationResult(RemoteOperationResult.ResultCode.SHARE_FORBIDDEN)
|
||||
result.httpPhrase = shareXmlParser?.message
|
||||
}
|
||||
else -> {
|
||||
result = RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE)
|
||||
}
|
||||
}
|
||||
} catch (e: XmlPullParserException) {
|
||||
Timber.e(e, "Error parsing response from server")
|
||||
result = RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE)
|
||||
|
||||
} catch (e: IOException) {
|
||||
Timber.e(e, "Error reading response from server")
|
||||
result = RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
/* ownCloud Android Library is available under MIT license
|
||||
* Copyright (C) 2020 ownCloud GmbH.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.owncloud.android.lib.resources.shares;
|
||||
|
||||
/**
|
||||
* Contains Constants for Share Operation
|
||||
*
|
||||
* @author masensio
|
||||
* @author David González Verdugo
|
||||
*/
|
||||
|
||||
public class ShareUtils {
|
||||
|
||||
// OCS Route
|
||||
public static final String SHARING_API_PATH = "ocs/v2.php/apps/files_sharing/api/v1/shares";
|
||||
|
||||
// String to build the link with the token of a share:
|
||||
public static final String SHARING_LINK_PATH = "/index.php/s/";
|
||||
}
|
@ -1,420 +0,0 @@
|
||||
/* ownCloud Android Library is available under MIT license
|
||||
* Copyright (C) 2020 ownCloud GmbH.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.owncloud.android.lib.resources.shares
|
||||
|
||||
import android.util.Xml
|
||||
import com.owncloud.android.lib.common.network.WebdavUtils
|
||||
import org.xmlpull.v1.XmlPullParser
|
||||
import org.xmlpull.v1.XmlPullParserException
|
||||
import org.xmlpull.v1.XmlPullParserFactory
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.util.ArrayList
|
||||
|
||||
/**
|
||||
* Parser for Share API Response
|
||||
*
|
||||
* @author masensio
|
||||
* @author David González Verdugo
|
||||
*/
|
||||
|
||||
class ShareXMLParser {
|
||||
// Getters and Setters
|
||||
var status: String? = null
|
||||
var statusCode: Int = 0
|
||||
var message: String? = null
|
||||
|
||||
val isSuccess: Boolean
|
||||
get() = statusCode == SUCCESS
|
||||
|
||||
val isForbidden: Boolean
|
||||
get() = statusCode == ERROR_FORBIDDEN
|
||||
|
||||
val isNotFound: Boolean
|
||||
get() = statusCode == ERROR_NOT_FOUND
|
||||
|
||||
val isWrongParameter: Boolean
|
||||
get() = statusCode == ERROR_WRONG_PARAMETER
|
||||
|
||||
// Constructor
|
||||
init {
|
||||
statusCode = INIT
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse is as response of Share API
|
||||
* @param inputStream
|
||||
* @return List of ShareRemoteFiles
|
||||
* @throws XmlPullParserException
|
||||
* @throws IOException
|
||||
*/
|
||||
@Throws(XmlPullParserException::class, IOException::class)
|
||||
fun parseXMLResponse(inputStream: InputStream): ArrayList<RemoteShare> {
|
||||
|
||||
try {
|
||||
// XMLPullParser
|
||||
val factory = XmlPullParserFactory.newInstance()
|
||||
factory.isNamespaceAware = true
|
||||
|
||||
val parser = Xml.newPullParser()
|
||||
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false)
|
||||
parser.setInput(inputStream, null)
|
||||
parser.nextTag()
|
||||
return readOCS(parser)
|
||||
|
||||
} finally {
|
||||
inputStream.close()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse OCS node
|
||||
* @param parser
|
||||
* @return List of ShareRemoteFiles
|
||||
* @throws XmlPullParserException
|
||||
* @throws IOException
|
||||
*/
|
||||
@Throws(XmlPullParserException::class, IOException::class)
|
||||
private fun readOCS(parser: XmlPullParser): ArrayList<RemoteShare> {
|
||||
var shares = ArrayList<RemoteShare>()
|
||||
parser.require(XmlPullParser.START_TAG, ns, NODE_OCS)
|
||||
while (parser.next() != XmlPullParser.END_TAG) {
|
||||
if (parser.eventType != XmlPullParser.START_TAG) {
|
||||
continue
|
||||
}
|
||||
val name = parser.name
|
||||
// read NODE_META and NODE_DATA
|
||||
when {
|
||||
name.equals(NODE_META, ignoreCase = true) -> {
|
||||
readMeta(parser)
|
||||
}
|
||||
name.equals(NODE_DATA, ignoreCase = true) -> {
|
||||
shares = readData(parser)
|
||||
}
|
||||
else -> {
|
||||
skip(parser)
|
||||
}
|
||||
}
|
||||
}
|
||||
return shares
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse Meta node
|
||||
* @param parser
|
||||
* @throws XmlPullParserException
|
||||
* @throws IOException
|
||||
*/
|
||||
@Throws(XmlPullParserException::class, IOException::class)
|
||||
private fun readMeta(parser: XmlPullParser) {
|
||||
parser.require(XmlPullParser.START_TAG, ns, NODE_META)
|
||||
while (parser.next() != XmlPullParser.END_TAG) {
|
||||
if (parser.eventType != XmlPullParser.START_TAG) {
|
||||
continue
|
||||
}
|
||||
val name = parser.name
|
||||
|
||||
when {
|
||||
name.equals(NODE_STATUS, ignoreCase = true) -> {
|
||||
status = readNode(parser, NODE_STATUS)
|
||||
}
|
||||
name.equals(NODE_STATUS_CODE, ignoreCase = true) -> {
|
||||
statusCode = Integer.parseInt(readNode(parser, NODE_STATUS_CODE))
|
||||
}
|
||||
name.equals(NODE_MESSAGE, ignoreCase = true) -> {
|
||||
message = readNode(parser, NODE_MESSAGE)
|
||||
}
|
||||
else -> {
|
||||
skip(parser)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse Data node
|
||||
* @param parser
|
||||
* @return
|
||||
* @throws XmlPullParserException
|
||||
* @throws IOException
|
||||
*/
|
||||
@Throws(XmlPullParserException::class, IOException::class)
|
||||
private fun readData(parser: XmlPullParser): ArrayList<RemoteShare> {
|
||||
val shares = ArrayList<RemoteShare>()
|
||||
var share: RemoteShare? = null
|
||||
|
||||
parser.require(XmlPullParser.START_TAG, ns, NODE_DATA)
|
||||
while (parser.next() != XmlPullParser.END_TAG) {
|
||||
if (parser.eventType != XmlPullParser.START_TAG) {
|
||||
continue
|
||||
}
|
||||
val name = parser.name
|
||||
when {
|
||||
name.equals(NODE_ELEMENT, ignoreCase = true) -> {
|
||||
readElement(parser, shares)
|
||||
}
|
||||
name.equals(NODE_ID, ignoreCase = true) -> { // Parse Create XML Response
|
||||
share = RemoteShare()
|
||||
val value = readNode(parser, NODE_ID)
|
||||
share.id = value
|
||||
}
|
||||
name.equals(NODE_URL, ignoreCase = true) -> {
|
||||
// NOTE: this field is received in all the public shares from OC 9.0.0
|
||||
// in previous versions, it's received in the result of POST requests, but not
|
||||
// in GET requests
|
||||
share!!.shareType = ShareType.PUBLIC_LINK
|
||||
val value = readNode(parser, NODE_URL)
|
||||
share.shareLink = value
|
||||
}
|
||||
name.equals(NODE_TOKEN, ignoreCase = true) -> {
|
||||
share!!.token = readNode(parser, NODE_TOKEN)
|
||||
}
|
||||
else -> {
|
||||
skip(parser)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (share != null) {
|
||||
// this is the response of a request for creation; don't pass to isValidShare()
|
||||
shares.add(share)
|
||||
}
|
||||
|
||||
return shares
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse Element node
|
||||
* @param parser
|
||||
* @return
|
||||
* @throws XmlPullParserException
|
||||
* @throws IOException
|
||||
*/
|
||||
@Throws(XmlPullParserException::class, IOException::class)
|
||||
private fun readElement(parser: XmlPullParser, shares: ArrayList<RemoteShare>) {
|
||||
parser.require(XmlPullParser.START_TAG, ns, NODE_ELEMENT)
|
||||
|
||||
val remoteShare = RemoteShare()
|
||||
|
||||
while (parser.next() != XmlPullParser.END_TAG) {
|
||||
if (parser.eventType != XmlPullParser.START_TAG) {
|
||||
continue
|
||||
}
|
||||
|
||||
val name = parser.name
|
||||
|
||||
when {
|
||||
name.equals(NODE_ELEMENT, ignoreCase = true) -> {
|
||||
// patch to work around servers responding with extra <element> surrounding all
|
||||
// the shares on the same file before
|
||||
// https://github.com/owncloud/core/issues/6992 was fixed
|
||||
readElement(parser, shares)
|
||||
}
|
||||
|
||||
name.equals(NODE_ID, ignoreCase = true) -> {
|
||||
remoteShare.id = readNode(parser, NODE_ID)
|
||||
}
|
||||
|
||||
name.equals(NODE_ITEM_TYPE, ignoreCase = true) -> {
|
||||
remoteShare.isFolder = readNode(parser, NODE_ITEM_TYPE).equals(TYPE_FOLDER, ignoreCase = true)
|
||||
fixPathForFolder(remoteShare)
|
||||
}
|
||||
|
||||
name.equals(NODE_PARENT, ignoreCase = true) -> {
|
||||
readNode(parser, NODE_PARENT)
|
||||
}
|
||||
|
||||
name.equals(NODE_SHARE_TYPE, ignoreCase = true) -> {
|
||||
val value = Integer.parseInt(readNode(parser, NODE_SHARE_TYPE))
|
||||
remoteShare.shareType = ShareType.fromValue(value)
|
||||
}
|
||||
|
||||
name.equals(NODE_SHARE_WITH, ignoreCase = true) -> {
|
||||
remoteShare.shareWith = readNode(parser, NODE_SHARE_WITH)
|
||||
}
|
||||
|
||||
name.equals(NODE_PATH, ignoreCase = true) -> {
|
||||
remoteShare.path = readNode(parser, NODE_PATH)
|
||||
fixPathForFolder(remoteShare)
|
||||
}
|
||||
|
||||
name.equals(NODE_PERMISSIONS, ignoreCase = true) -> {
|
||||
remoteShare.permissions = Integer.parseInt(readNode(parser, NODE_PERMISSIONS))
|
||||
}
|
||||
|
||||
name.equals(NODE_STIME, ignoreCase = true) -> {
|
||||
remoteShare.sharedDate = java.lang.Long.parseLong(readNode(parser, NODE_STIME))
|
||||
}
|
||||
|
||||
name.equals(NODE_EXPIRATION, ignoreCase = true) -> {
|
||||
val value = readNode(parser, NODE_EXPIRATION)
|
||||
if (value.isNotEmpty()) {
|
||||
remoteShare.expirationDate = WebdavUtils.parseResponseDate(value)!!.time
|
||||
}
|
||||
}
|
||||
|
||||
name.equals(NODE_TOKEN, ignoreCase = true) -> {
|
||||
remoteShare.token = readNode(parser, NODE_TOKEN)
|
||||
}
|
||||
|
||||
name.equals(NODE_STORAGE, ignoreCase = true) -> {
|
||||
readNode(parser, NODE_STORAGE)
|
||||
}
|
||||
|
||||
name.equals(NODE_MAIL_SEND, ignoreCase = true) -> {
|
||||
readNode(parser, NODE_MAIL_SEND)
|
||||
}
|
||||
|
||||
name.equals(NODE_SHARE_WITH_DISPLAY_NAME, ignoreCase = true) -> {
|
||||
remoteShare.sharedWithDisplayName = readNode(parser, NODE_SHARE_WITH_DISPLAY_NAME)
|
||||
}
|
||||
|
||||
name.equals(NODE_SHARE_WITH_ADDITIONAL_INFO, ignoreCase = true) -> {
|
||||
remoteShare.sharedWithAdditionalInfo = readNode(parser, NODE_SHARE_WITH_ADDITIONAL_INFO)
|
||||
}
|
||||
|
||||
name.equals(NODE_URL, ignoreCase = true) -> {
|
||||
val value = readNode(parser, NODE_URL)
|
||||
remoteShare.shareLink = value
|
||||
}
|
||||
|
||||
name.equals(NODE_NAME, ignoreCase = true) -> {
|
||||
remoteShare.name = readNode(parser, NODE_NAME)
|
||||
}
|
||||
|
||||
else -> {
|
||||
skip(parser)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shares.add(remoteShare)
|
||||
}
|
||||
|
||||
private fun fixPathForFolder(share: RemoteShare) {
|
||||
if (share.isFolder && share.path.isNotEmpty() &&
|
||||
!share.path.endsWith(File.separator)
|
||||
) {
|
||||
share.path = share.path + File.separator
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a node, to obtain its text. Needs readText method
|
||||
* @param parser
|
||||
* @param node
|
||||
* @return Text of the node
|
||||
* @throws XmlPullParserException
|
||||
* @throws IOException
|
||||
*/
|
||||
@Throws(XmlPullParserException::class, IOException::class)
|
||||
private fun readNode(parser: XmlPullParser, node: String): String {
|
||||
parser.require(XmlPullParser.START_TAG, ns, node)
|
||||
val value = readText(parser)
|
||||
parser.require(XmlPullParser.END_TAG, ns, node)
|
||||
return value
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the text from a node
|
||||
* @param parser
|
||||
* @return Text of the node
|
||||
* @throws IOException
|
||||
* @throws XmlPullParserException
|
||||
*/
|
||||
@Throws(IOException::class, XmlPullParserException::class)
|
||||
private fun readText(parser: XmlPullParser): String {
|
||||
var result = ""
|
||||
if (parser.next() == XmlPullParser.TEXT) {
|
||||
result = parser.text
|
||||
parser.nextTag()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip tags in parser procedure
|
||||
* @param parser
|
||||
* @throws XmlPullParserException
|
||||
* @throws IOException
|
||||
*/
|
||||
@Throws(XmlPullParserException::class, IOException::class)
|
||||
private fun skip(parser: XmlPullParser) {
|
||||
if (parser.eventType != XmlPullParser.START_TAG) {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
var depth = 1
|
||||
while (depth != 0) {
|
||||
when (parser.next()) {
|
||||
XmlPullParser.END_TAG -> depth--
|
||||
XmlPullParser.START_TAG -> depth++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
// No namespaces
|
||||
private val ns: String? = null
|
||||
|
||||
// NODES for XML Parser
|
||||
private const val NODE_OCS = "ocs"
|
||||
|
||||
private const val NODE_META = "meta"
|
||||
private const val NODE_STATUS = "status"
|
||||
private const val NODE_STATUS_CODE = "statuscode"
|
||||
private const val NODE_MESSAGE = "message"
|
||||
|
||||
private const val NODE_DATA = "data"
|
||||
private const val NODE_ELEMENT = "element"
|
||||
private const val NODE_ID = "id"
|
||||
private const val NODE_ITEM_TYPE = "item_type"
|
||||
private const val NODE_PARENT = "parent"
|
||||
private const val NODE_SHARE_TYPE = "share_type"
|
||||
private const val NODE_SHARE_WITH = "share_with"
|
||||
private const val NODE_PATH = "path"
|
||||
private const val NODE_PERMISSIONS = "permissions"
|
||||
private const val NODE_STIME = "stime"
|
||||
private const val NODE_EXPIRATION = "expiration"
|
||||
private const val NODE_TOKEN = "token"
|
||||
private const val NODE_STORAGE = "storage"
|
||||
private const val NODE_MAIL_SEND = "mail_send"
|
||||
private const val NODE_SHARE_WITH_DISPLAY_NAME = "share_with_displayname"
|
||||
private const val NODE_SHARE_WITH_ADDITIONAL_INFO = "share_with_additional_info"
|
||||
private const val NODE_NAME = "name"
|
||||
|
||||
private const val NODE_URL = "url"
|
||||
|
||||
private const val TYPE_FOLDER = "folder"
|
||||
|
||||
private const val SUCCESS = 200
|
||||
private const val ERROR_WRONG_PARAMETER = 400
|
||||
private const val ERROR_FORBIDDEN = 403
|
||||
private const val ERROR_NOT_FOUND = 404
|
||||
private const val INIT = -1
|
||||
}
|
||||
}
|
@ -1,38 +1,45 @@
|
||||
/* ownCloud Android Library is available under MIT license
|
||||
/*
|
||||
* ownCloud Android client application
|
||||
*
|
||||
* Copyright (C) 2020 ownCloud GmbH.
|
||||
* @author David A. Velasco
|
||||
* @author David González Verdugo
|
||||
* @author Fernando Sanz Velasco
|
||||
* Copyright (C) 2021 ownCloud GmbH.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.owncloud.android.lib.resources.shares
|
||||
|
||||
import android.net.Uri
|
||||
import com.owncloud.android.lib.common.OwnCloudClient
|
||||
import com.owncloud.android.lib.common.http.HttpConstants
|
||||
import com.owncloud.android.lib.common.http.methods.nonwebdav.PutMethod
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperation
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult
|
||||
import com.owncloud.android.lib.resources.CommonOcsResponse
|
||||
import com.owncloud.android.lib.resources.shares.RemoteShare.Companion.DEFAULT_PERMISSION
|
||||
import com.owncloud.android.lib.resources.shares.responses.ShareItem
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.Types
|
||||
import okhttp3.FormBody
|
||||
import timber.log.Timber
|
||||
import java.lang.reflect.Type
|
||||
import java.net.URL
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Calendar
|
||||
@ -40,12 +47,7 @@ import java.util.Locale
|
||||
|
||||
/**
|
||||
* Updates parameters of an existing Share resource, known its remote ID.
|
||||
*
|
||||
*
|
||||
* Allow updating several parameters, triggering a request to the server per parameter.
|
||||
*
|
||||
* @author David A. Velasco
|
||||
* @author David González Verdugo
|
||||
*/
|
||||
class UpdateRemoteShareOperation
|
||||
/**
|
||||
@ -99,10 +101,51 @@ class UpdateRemoteShareOperation
|
||||
|
||||
var retrieveShareDetails = false // To retrieve more info about the just updated share
|
||||
|
||||
override fun run(client: OwnCloudClient): RemoteOperationResult<ShareResponse> {
|
||||
var result: RemoteOperationResult<ShareResponse>
|
||||
private fun buildRequestUri(baseUri: Uri) =
|
||||
baseUri.buildUpon()
|
||||
.appendEncodedPath(OCS_ROUTE)
|
||||
.appendEncodedPath(remoteId)
|
||||
.appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT)
|
||||
.build()
|
||||
|
||||
try {
|
||||
private fun parseResponse(response: String): ShareResponse? {
|
||||
val moshi = Moshi.Builder().build()
|
||||
val commonOcsType: Type = Types.newParameterizedType(CommonOcsResponse::class.java, ShareItem::class.java)
|
||||
val adapter: JsonAdapter<CommonOcsResponse<ShareItem>> = moshi.adapter(commonOcsType)
|
||||
val remoteShare = adapter.fromJson(response)?.ocs?.data?.toRemoteShare()
|
||||
return ShareResponse(remoteShare?.let { listOf(it) } ?: listOf())
|
||||
}
|
||||
|
||||
private fun onResultUnsuccessful(
|
||||
method: PutMethod,
|
||||
response: String?,
|
||||
status: Int
|
||||
): RemoteOperationResult<ShareResponse> {
|
||||
Timber.e("Failed response while while updating remote shares ")
|
||||
if (response != null) {
|
||||
Timber.e("*** status code: $status; response message: $response")
|
||||
} else {
|
||||
Timber.e("*** status code: $status")
|
||||
}
|
||||
return RemoteOperationResult(method)
|
||||
}
|
||||
|
||||
private fun onRequestSuccessful(response: String?): RemoteOperationResult<ShareResponse> {
|
||||
val result = RemoteOperationResult<ShareResponse>(RemoteOperationResult.ResultCode.OK)
|
||||
Timber.d("Successful response: $response")
|
||||
result.data = parseResponse(response!!)
|
||||
Timber.d("*** Retrieve the index of the new share completed ")
|
||||
val emptyShare = result.data.shares.first()
|
||||
|
||||
return if (retrieveShareDetails) {
|
||||
// retrieve more info - PUT only returns the index of the new share
|
||||
GetRemoteShareOperation(emptyShare.id).execute(client)
|
||||
} else {
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
private fun createFormBodyBuilder(): FormBody.Builder {
|
||||
val formBodyBuilder = FormBody.Builder()
|
||||
|
||||
// Parameters to update
|
||||
@ -138,61 +181,53 @@ class UpdateRemoteShareOperation
|
||||
formBodyBuilder.add(PARAM_PERMISSIONS, permissions.toString())
|
||||
}
|
||||
|
||||
val requestUri = client.baseUri
|
||||
val uriBuilder = requestUri.buildUpon()
|
||||
uriBuilder.appendEncodedPath(ShareUtils.SHARING_API_PATH)
|
||||
uriBuilder.appendEncodedPath(remoteId.toString())
|
||||
return formBodyBuilder
|
||||
}
|
||||
|
||||
val putMethod = PutMethod(URL(uriBuilder.build().toString()), formBodyBuilder.build())
|
||||
override fun run(client: OwnCloudClient): RemoteOperationResult<ShareResponse> {
|
||||
val requestUri = buildRequestUri(client.baseUri)
|
||||
|
||||
putMethod.setRequestHeader(HttpConstants.CONTENT_TYPE_HEADER, HttpConstants.CONTENT_TYPE_URLENCODED_UTF8)
|
||||
putMethod.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE)
|
||||
val formBodyBuilder = createFormBodyBuilder()
|
||||
|
||||
val putMethod = PutMethod(URL(requestUri.toString()), formBodyBuilder.build()).apply {
|
||||
setRequestHeader(HttpConstants.CONTENT_TYPE_HEADER, HttpConstants.CONTENT_TYPE_URLENCODED_UTF8)
|
||||
addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE)
|
||||
}
|
||||
|
||||
|
||||
return try {
|
||||
val status = client.executeHttpMethod(putMethod)
|
||||
|
||||
// Parse xml response
|
||||
val parser = ShareToRemoteOperationResultParser(
|
||||
ShareXMLParser()
|
||||
)
|
||||
val response = putMethod.getResponseBodyAsString()
|
||||
|
||||
if (!isSuccess(status)) {
|
||||
return parser.parse(putMethod.getResponseBodyAsString())
|
||||
onResultUnsuccessful(putMethod, response, status)
|
||||
} else {
|
||||
onRequestSuccessful(response)
|
||||
}
|
||||
|
||||
parser.ownCloudVersion = client.ownCloudVersion
|
||||
parser.serverBaseUri = client.baseUri
|
||||
result = parser.parse(putMethod.getResponseBodyAsString())
|
||||
|
||||
if (result.isSuccess && retrieveShareDetails) {
|
||||
// retrieve more info - PUT only returns the index of the new share
|
||||
val emptyShare = result.data.shares.first()
|
||||
val getShares = GetRemoteShareOperation(
|
||||
emptyShare.id
|
||||
)
|
||||
result = getShares.execute(client)
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
result = RemoteOperationResult(e)
|
||||
Timber.e(e, "Exception while Creating New Share")
|
||||
Timber.e(e, "Exception while updating remote share")
|
||||
RemoteOperationResult(e)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun isSuccess(status: Int): Boolean = status == HttpConstants.HTTP_OK
|
||||
|
||||
companion object {
|
||||
|
||||
//OCS Route
|
||||
private const val OCS_ROUTE = "ocs/v2.php/apps/files_sharing/api/v1/shares"
|
||||
|
||||
//Arguments - names
|
||||
private const val PARAM_FORMAT = "format"
|
||||
private const val PARAM_NAME = "name"
|
||||
private const val PARAM_PASSWORD = "password"
|
||||
private const val PARAM_EXPIRATION_DATE = "expireDate"
|
||||
private const val PARAM_PERMISSIONS = "permissions"
|
||||
private const val PARAM_PUBLIC_UPLOAD = "publicUpload"
|
||||
private const val FORMAT_EXPIRATION_DATE = "yyyy-MM-dd"
|
||||
private const val ENTITY_CONTENT_TYPE = "application/x-www-form-urlencoded"
|
||||
private const val ENTITY_CHARSET = "UTF-8"
|
||||
|
||||
//Arguments - constant values
|
||||
private const val VALUE_FORMAT = "json"
|
||||
private const val FORMAT_EXPIRATION_DATE = "yyyy-MM-dd"
|
||||
private const val INITIAL_EXPIRATION_DATE_IN_MILLIS: Long = 0
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user