From a0478826b4d87ac7b7d0070a10f60be37027a5bf Mon Sep 17 00:00:00 2001 From: davigonz Date: Tue, 12 Jun 2018 12:19:38 +0200 Subject: [PATCH] Update GetRemoteUserQuotaOperation to use the recent wrapper with propfind --- .../lib/common/http/HttpConstants.java | 3 + .../http/methods/webdav/DavConstants.java | 33 ++++++ .../common/http/methods/webdav/DavUtils.java | 15 +++ .../http/methods/webdav/PropfindMethod.java | 8 +- .../files/ExistenceCheckRemoteOperation.java | 59 +++++----- .../files/ReadRemoteFolderOperation.java | 11 +- .../users/GetRemoteUserQuotaOperation.java | 104 ++++++++---------- 7 files changed, 138 insertions(+), 95 deletions(-) create mode 100644 src/com/owncloud/android/lib/common/http/methods/webdav/DavConstants.java create mode 100644 src/com/owncloud/android/lib/common/http/methods/webdav/DavUtils.java diff --git a/src/com/owncloud/android/lib/common/http/HttpConstants.java b/src/com/owncloud/android/lib/common/http/HttpConstants.java index 563ea923..a8f7cfa9 100644 --- a/src/com/owncloud/android/lib/common/http/HttpConstants.java +++ b/src/com/owncloud/android/lib/common/http/HttpConstants.java @@ -24,6 +24,9 @@ package com.owncloud.android.lib.common.http; +/** + * @author David González Verdugo + */ public class HttpConstants { /** diff --git a/src/com/owncloud/android/lib/common/http/methods/webdav/DavConstants.java b/src/com/owncloud/android/lib/common/http/methods/webdav/DavConstants.java new file mode 100644 index 00000000..7017e4fa --- /dev/null +++ b/src/com/owncloud/android/lib/common/http/methods/webdav/DavConstants.java @@ -0,0 +1,33 @@ +/* ownCloud Android Library is available under MIT license + * Copyright (C) 2018 ownCloud GmbH. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +package com.owncloud.android.lib.common.http.methods.webdav; + +/** + * @author David González Verdugo + */ +public class DavConstants { + public static final int DEPTH_0 = 0; + public static final int DEPTH_1 = 1; +} diff --git a/src/com/owncloud/android/lib/common/http/methods/webdav/DavUtils.java b/src/com/owncloud/android/lib/common/http/methods/webdav/DavUtils.java new file mode 100644 index 00000000..484c4ec1 --- /dev/null +++ b/src/com/owncloud/android/lib/common/http/methods/webdav/DavUtils.java @@ -0,0 +1,15 @@ +package com.owncloud.android.lib.common.http.methods.webdav; + +import at.bitfire.dav4android.Property; +import at.bitfire.dav4android.PropertyUtils; + +public class DavUtils { + + public static final Property.Name[] getAllPropset() { + return PropertyUtils.INSTANCE.getAllPropSet(); + } + + public static final Property.Name[] getQuotaPropSet() { + return PropertyUtils.INSTANCE.getQuotaPropset(); + } +} \ No newline at end of file diff --git a/src/com/owncloud/android/lib/common/http/methods/webdav/PropfindMethod.java b/src/com/owncloud/android/lib/common/http/methods/webdav/PropfindMethod.java index 8e788f6c..0f4f5ad4 100644 --- a/src/com/owncloud/android/lib/common/http/methods/webdav/PropfindMethod.java +++ b/src/com/owncloud/android/lib/common/http/methods/webdav/PropfindMethod.java @@ -28,7 +28,7 @@ import java.io.IOException; import java.util.Set; import at.bitfire.dav4android.DavResource; -import at.bitfire.dav4android.PropertyUtils; +import at.bitfire.dav4android.Property; import at.bitfire.dav4android.exception.DavException; import at.bitfire.dav4android.exception.HttpException; import at.bitfire.dav4android.exception.UnauthorizedException; @@ -41,17 +41,19 @@ import okhttp3.HttpUrl; public class PropfindMethod extends DavMethod { private int mDepth; + private Property.Name[] mProperties; private Set mMembers; - public PropfindMethod(HttpUrl httpUrl, int depth) { + public PropfindMethod(HttpUrl httpUrl, int depth, Property.Name[] properties) { super(httpUrl); mDepth = depth; + mProperties = properties; }; @Override public int execute() throws IOException, HttpException, DavException { try { - mDavResource.propfind(mDepth, PropertyUtils.INSTANCE.getAllPropSet()); + mDavResource.propfind(mDepth, mProperties); mMembers = mDavResource.getMembers(); } catch (UnauthorizedException davException) { // Do nothing, we will use the 401 code to handle the situation diff --git a/src/com/owncloud/android/lib/resources/files/ExistenceCheckRemoteOperation.java b/src/com/owncloud/android/lib/resources/files/ExistenceCheckRemoteOperation.java index a71f941b..5be03204 100644 --- a/src/com/owncloud/android/lib/resources/files/ExistenceCheckRemoteOperation.java +++ b/src/com/owncloud/android/lib/resources/files/ExistenceCheckRemoteOperation.java @@ -1,22 +1,22 @@ /* ownCloud Android Library is available under MIT license * Copyright (C) 2016 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, + * + * 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 + * 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. * @@ -27,6 +27,7 @@ package com.owncloud.android.lib.resources.files; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.http.HttpConstants; import com.owncloud.android.lib.common.http.HttpUtils; +import com.owncloud.android.lib.common.http.methods.webdav.DavUtils; import com.owncloud.android.lib.common.http.methods.webdav.PropfindMethod; import com.owncloud.android.lib.common.network.RedirectionPath; import com.owncloud.android.lib.common.network.WebdavUtils; @@ -34,37 +35,40 @@ 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 okhttp3.HttpUrl; - import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK; /** * Operation to check the existence or absence of a path in a remote server. - * + * * @author David A. Velasco * @author David GonzálezVerdugo */ public class ExistenceCheckRemoteOperation extends RemoteOperation { - - /** Maximum time to wait for a response from the server in MILLISECONDs. */ + + /** + * Maximum time to wait for a response from the server in MILLISECONDs. + */ public static final int TIMEOUT = 10000; - + private static final String TAG = ExistenceCheckRemoteOperation.class.getSimpleName(); private static final int FORBIDDEN_ERROR = 403; private static final int SERVICE_UNAVAILABLE_ERROR = 503; - + private String mPath; private boolean mSuccessIfAbsent; - /** Sequence of redirections followed. Available only after executing the operation */ + /** + * Sequence of redirections followed. Available only after executing the operation + */ private RedirectionPath mRedirectionPath = null; + /** * Full constructor. Success of the operation will depend upon the value of successIfAbsent. * - * @param remotePath Path to append to the URL owned by the client instance. - * @param successIfAbsent When 'true', the operation finishes in success if the path does - * NOT exist in the remote server (HTTP 404). + * @param remotePath Path to append to the URL owned by the client instance. + * @param successIfAbsent When 'true', the operation finishes in success if the path does + * NOT exist in the remote server (HTTP 404). */ public ExistenceCheckRemoteOperation(String remotePath, boolean successIfAbsent) { mPath = (remotePath != null) ? remotePath : ""; @@ -72,7 +76,7 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation { } @Override - protected RemoteOperationResult run(OwnCloudClient client) { + protected RemoteOperationResult run(OwnCloudClient client) { RemoteOperationResult result; // TODO Complete redirection stuff, although OkHttp should follow redirections by default @@ -83,7 +87,8 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation { // client.setFollowRedirects(false); PropfindMethod propfindMethod = new PropfindMethod( HttpUtils.stringUrlToHttpUrl(client.getNewWebDavUri() + WebdavUtils.encodePath(mPath)), - 0); + 0, + DavUtils.getAllPropset()); int status = client.executeHttpMethod(propfindMethod); @@ -108,32 +113,32 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation { Log_OC.d(TAG, "Existence check for " + client.getWebdavUri() + WebdavUtils.encodePath(mPath) + " targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + - "finished with HTTP status " + status + (!isSuccess(status)?"(FAIL)":"")); - + "finished with HTTP status " + status + (!isSuccess(status) ? "(FAIL)" : "")); + } catch (Exception e) { result = new RemoteOperationResult(e); Log_OC.e(TAG, "Existence check for " + client.getWebdavUri() + WebdavUtils.encodePath(mPath) + " targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + ": " + result.getLogMessage(), result.getException()); - + } finally { // client.setFollowRedirects(previousFollowRedirects); } return result; - } + } /** * Gets the sequence of redirections followed during the execution of the operation. * - * @return Sequence of redirections followed, if any, or NULL if the operation was not executed. + * @return Sequence of redirections followed, if any, or NULL if the operation was not executed. */ public RedirectionPath getRedirectionPath() { return mRedirectionPath; } /** - * @return 'True' if the operation was executed and at least one redirection was followed. + * @return 'True' if the operation was executed and at least one redirection was followed. */ public boolean wasRedirected() { return (mRedirectionPath != null && mRedirectionPath.getRedirectionsCount() > 0); diff --git a/src/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java b/src/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java index f90a654d..5da8c2df 100644 --- a/src/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java +++ b/src/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java @@ -26,6 +26,9 @@ package com.owncloud.android.lib.resources.files; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.http.HttpConstants; +import com.owncloud.android.lib.common.http.HttpUtils; +import com.owncloud.android.lib.common.http.methods.webdav.DavConstants; +import com.owncloud.android.lib.common.http.methods.webdav.DavUtils; import com.owncloud.android.lib.common.http.methods.webdav.PropfindMethod; import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.RemoteOperation; @@ -35,7 +38,6 @@ import com.owncloud.android.lib.common.utils.Log_OC; import java.util.ArrayList; import at.bitfire.dav4android.DavResource; -import okhttp3.HttpUrl; import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK; @@ -72,15 +74,14 @@ public class ReadRemoteFolderOperation extends RemoteOperation { RemoteOperationResult result = null; try { - PropfindMethod propfindMethod = new PropfindMethod( - HttpUrl.parse(client.getNewWebDavUri() + WebdavUtils.encodePath(mRemotePath)), - 1); + HttpUtils.stringUrlToHttpUrl(client.getNewWebDavUri() + WebdavUtils.encodePath(mRemotePath)), + DavConstants.DEPTH_1, + DavUtils.getAllPropset()); int status = client.executeHttpMethod(propfindMethod); if (isSuccess(status)) { - ArrayList mFolderAndFiles = new ArrayList<>(); // parse data from remote folder diff --git a/src/com/owncloud/android/lib/resources/users/GetRemoteUserQuotaOperation.java b/src/com/owncloud/android/lib/resources/users/GetRemoteUserQuotaOperation.java index 0ae91a43..9cdb9e1c 100644 --- a/src/com/owncloud/android/lib/resources/users/GetRemoteUserQuotaOperation.java +++ b/src/com/owncloud/android/lib/resources/users/GetRemoteUserQuotaOperation.java @@ -28,42 +28,36 @@ package com.owncloud.android.lib.resources.users; import com.owncloud.android.lib.common.OwnCloudClient; -import com.owncloud.android.lib.common.network.WebdavEntry; +import com.owncloud.android.lib.common.http.HttpConstants; +import com.owncloud.android.lib.common.http.HttpUtils; +import com.owncloud.android.lib.common.http.methods.webdav.DavUtils; +import com.owncloud.android.lib.common.http.methods.webdav.PropfindMethod; 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.MultiStatus; -import org.apache.jackrabbit.webdav.client.methods.PropFindMethod; - -import java.math.BigDecimal; -import java.math.RoundingMode; import java.util.ArrayList; +import at.bitfire.dav4android.PropertyCollection; +import at.bitfire.dav4android.property.QuotaAvailableBytes; +import at.bitfire.dav4android.property.QuotaUsedBytes; + +import static com.owncloud.android.lib.common.http.methods.webdav.DavConstants.DEPTH_0; +import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK; + /** * @author marcello * @author David González Verdugo */ public class GetRemoteUserQuotaOperation extends RemoteOperation { - static public class Quota { - - // Not computed yet, e.g. external storage mounted but folder sizes need scanning - public static final int PENDING_FREE_QUOTA = -1; - - // Storage not accessible, e.g. external storage with no API to ask for the free space - public static final int UNKNOWN_FREE_QUOTA = -2; - - // Quota using all the storage - public static final int UNLIMITED_FREE_QUOTA = -3; + static public class RemoteQuota { long mFree, mUsed, mTotal; double mRelative; - public Quota(long free, long used, long total, double relative) { + public RemoteQuota(long free, long used, long total, double relative) { mFree = free; mUsed = used; mTotal = total; @@ -92,34 +86,31 @@ public class GetRemoteUserQuotaOperation extends RemoteOperation { @Override protected RemoteOperationResult run(OwnCloudClient client) { RemoteOperationResult result = null; - PropFindMethod query = null; try { - // remote request - query = new PropFindMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath), - WebdavUtils.getQuotaPropSet(), - DavConstants.DEPTH_0); + PropfindMethod propfindMethod = new PropfindMethod( + HttpUtils.stringUrlToHttpUrl(client.getNewWebDavUri() + WebdavUtils.encodePath(mRemotePath)), + DEPTH_0, + DavUtils.getQuotaPropSet() + ); - int status = client.executeMethod(query); + int status = client.executeHttpMethod(propfindMethod); if (isSuccess(status)) { - // get data from remote folder - MultiStatus dataInServer = query.getResponseBodyAsMultiStatus(); - Quota quota = readData(dataInServer, client); + RemoteQuota remoteQuota = readData(propfindMethod.getDavResource().getProperties()); - // Result of the operation - result = new RemoteOperationResult(true, query); + result = new RemoteOperationResult(OK); ArrayList data = new ArrayList<>(); - data.add(quota); + data.add(remoteQuota); // Add data to the result if (result.isSuccess()) { result.setData(data); } - } else { - // synchronization failed - result = new RemoteOperationResult(false, query); + + } else { // synchronization failed + result = new RemoteOperationResult(propfindMethod); } } catch (Exception e) { @@ -127,8 +118,6 @@ public class GetRemoteUserQuotaOperation extends RemoteOperation { } finally { - if (query != null) - query.releaseConnection(); // let the connection available for other methods if (result.isSuccess()) { Log_OC.i(TAG, "Get quota from " + mRemotePath + ": " + result.getLogMessage()); } else { @@ -145,46 +134,41 @@ public class GetRemoteUserQuotaOperation extends RemoteOperation { } private boolean isSuccess(int status) { - return status == HttpStatus.SC_MULTI_STATUS || status == HttpStatus.SC_OK; + return status == HttpConstants.HTTP_MULTI_STATUS || status == HttpConstants.HTTP_OK; } /** * Read the data retrieved from the server about the quota * - * @param remoteData Full response got from the server with the data of the quota - * @param client Client instance to the remote server where the data were retrieved - * @return new Quota instance representing the data read from the server + * @param properties WebDAV properties containing quota data + * @return new {@link RemoteQuota} instance representing the data read from the server */ - private Quota readData(MultiStatus remoteData, OwnCloudClient client) { + private RemoteQuota readData(PropertyCollection properties) { - // parse data from remote folder - WebdavEntry we = new WebdavEntry(remoteData.getResponses()[0], client.getWebdavUri().getPath()); + long quotaAvailable = properties.get(QuotaAvailableBytes.class).getQuotaAvailableBytes(); + long quotaUsed = properties.get(QuotaUsedBytes.class).getQuotaUsedBytes(); - // If there's a special case, available bytes will contain a negative code + // If there's a special case, quota available will contain a negative code // -1, PENDING: Not computed yet, e.g. external storage mounted but folder sizes need scanning // -2, UNKNOWN: Storage not accessible, e.g. external storage with no API to ask for the free space // -3, UNLIMITED: Quota using all the storage - if (we.quotaAvailableBytes().compareTo(new BigDecimal(1)) == -1) { - return new Quota( - we.quotaAvailableBytes().longValue(), - we.quotaUsedBytes().longValue(), + if (quotaAvailable < 0) { + return new RemoteQuota( + quotaAvailable, + quotaUsed, 0, 0 ); - } else { + long totalQuota = quotaAvailable + quotaUsed; + double relativeQuota = (double)(quotaUsed * 100)/totalQuota; + double roundedRelativeQuota = Math.round(relativeQuota * 100)/100.0d; - BigDecimal totalQuota = we.quotaAvailableBytes().add(we.quotaUsedBytes()); - - BigDecimal relativeQuota = we.quotaUsedBytes() - .multiply(new BigDecimal(100)) - .divide(totalQuota, 2, RoundingMode.HALF_UP); - - return new Quota( - we.quotaAvailableBytes().longValue(), - we.quotaUsedBytes().longValue(), - totalQuota.longValue(), - relativeQuota.doubleValue() + return new RemoteQuota( + quotaAvailable, + quotaUsed, + totalQuota, + roundedRelativeQuota ); } }