diff --git a/src/com/owncloud/android/lib/common/network/WebdavEntry.java b/src/com/owncloud/android/lib/common/network/WebdavEntry.java index 82d0c83c..e5c5b764 100644 --- a/src/com/owncloud/android/lib/common/network/WebdavEntry.java +++ b/src/com/owncloud/android/lib/common/network/WebdavEntry.java @@ -37,12 +37,19 @@ import android.net.Uri; import com.owncloud.android.lib.common.utils.Log_OC; public class WebdavEntry { - private static final String NAMESPACE_OC = "http://owncloud.org/ns"; - private static final String EXTENDED_PROPERTY_NAME_PERMISSIONS = "permissions"; - private static final String EXTENDED_PROPERTY_NAME_REMOTE_ID = "id"; + public static final String NAMESPACE_OC = "http://owncloud.org/ns"; + public static final String EXTENDED_PROPERTY_NAME_PERMISSIONS = "permissions"; + public static final String EXTENDED_PROPERTY_NAME_REMOTE_ID = "id"; + public static final String EXTENDED_PROPERTY_NAME_SIZE = "size"; + + public static final String PROPERTY_QUOTA_USED_BYTES = "quota-used-bytes"; + public static final String PROPERTY_QUOTA_AVAILABLE_BYTES = "quota-available-bytes"; + + private static final int CODE_PROP_NOT_FOUND = 404; private String mName, mPath, mUri, mContentType, mEtag, mPermissions, mRemoteId; - private long mContentLength, mCreateTimestamp, mModifiedTimestamp; + private long mContentLength, mCreateTimestamp, mModifiedTimestamp, mSize; + private long mQuotaUsedBytes, mQuotaAvailableBytes; public WebdavEntry(MultiStatusResponse ms, String splitElement) { resetData(); @@ -52,6 +59,9 @@ public class WebdavEntry { mPath = mUri.split(splitElement, 2)[1]; int status = ms.getStatus()[0].getStatusCode(); + if ( status == CODE_PROP_NOT_FOUND ) { + status = ms.getStatus()[1].getStatusCode(); + } DavPropertySet propSet = ms.getProperties(status); @SuppressWarnings("rawtypes") DavProperty prop = propSet.get(DavPropertyName.DISPLAYNAME); @@ -66,29 +76,37 @@ public class WebdavEntry { } // use unknown mimetype as default behavior + // {DAV:}getcontenttype mContentType = "application/octet-stream"; prop = propSet.get(DavPropertyName.GETCONTENTTYPE); if (prop != null) { mContentType = (String) prop.getValue(); - // dvelasco: some builds of ownCloud server 4.0.x added a trailing ';' to the MIME type ; if looks fixed, but let's be cautious + // dvelasco: some builds of ownCloud server 4.0.x added a trailing ';' + // to the MIME type ; if looks fixed, but let's be cautious if (mContentType.indexOf(";") >= 0) { mContentType = mContentType.substring(0, mContentType.indexOf(";")); } } - // check if it's a folder in the standard way: see RFC2518 12.2 . RFC4918 14.3 + // check if it's a folder in the standard way: see RFC2518 12.2 . RFC4918 14.3 + // {DAV:}resourcetype prop = propSet.get(DavPropertyName.RESOURCETYPE); if (prop!= null) { Object value = prop.getValue(); if (value != null) { - mContentType = "DIR"; // a specific attribute would be better, but this is enough; unless while we have no reason to distinguish MIME types for folders + mContentType = "DIR"; // a specific attribute would be better, + // but this is enough; + // unless while we have no reason to distinguish + // MIME types for folders } } + // {DAV:}getcontentlength prop = propSet.get(DavPropertyName.GETCONTENTLENGTH); if (prop != null) mContentLength = Long.parseLong((String) prop.getValue()); + // {DAV:}getlastmodified prop = propSet.get(DavPropertyName.GETLASTMODIFIED); if (prop != null) { Date d = WebdavUtils @@ -102,13 +120,25 @@ public class WebdavEntry { .parseResponseDate((String) prop.getValue()); mCreateTimestamp = (d != null) ? d.getTime() : 0; } - + + // {DAV:}getetag prop = propSet.get(DavPropertyName.GETETAG); if (prop != null) { mEtag = (String) prop.getValue(); mEtag = mEtag.substring(1, mEtag.length()-1); } + // {DAV:}quota-used-bytes + prop = propSet.get(DavPropertyName.create(PROPERTY_QUOTA_USED_BYTES)); + if (prop != null) { + mQuotaUsedBytes = Long.parseLong((String) prop.getValue()); + } + + // {DAV:}quota-available-bytes + prop = propSet.get(DavPropertyName.create(PROPERTY_QUOTA_AVAILABLE_BYTES)); + if (prop != null) { + mQuotaAvailableBytes = Long.parseLong((String) prop.getValue()); + } // OC permissions property prop = propSet.get( EXTENDED_PROPERTY_NAME_PERMISSIONS, Namespace.getNamespace(NAMESPACE_OC) @@ -125,6 +155,15 @@ public class WebdavEntry { mRemoteId = prop.getValue().toString(); } + // TODO: is it necessary? + // OC size property + prop = propSet.get( + EXTENDED_PROPERTY_NAME_SIZE, Namespace.getNamespace(NAMESPACE_OC) + ); + if (prop != null) { + mSize = Long.parseLong((String) prop.getValue()); + } + } else { Log_OC.e("WebdavEntry", "General fuckup, no status for webdav response"); @@ -179,8 +218,23 @@ public class WebdavEntry { return mRemoteId; } + public long size(){ + return mSize; + } + + public long quotaUsedBytes() { + return mQuotaUsedBytes; + } + + public long quotaAvailableBytes() { + return mQuotaAvailableBytes; + } + private void resetData() { mName = mUri = mContentType = mPermissions = null; mRemoteId = null; mContentLength = mCreateTimestamp = mModifiedTimestamp = 0; + mSize = 0; + mQuotaUsedBytes = 0; + mQuotaAvailableBytes = 0; } } diff --git a/src/com/owncloud/android/lib/common/network/WebdavUtils.java b/src/com/owncloud/android/lib/common/network/WebdavUtils.java index 7c2a1bb4..bf2e986d 100644 --- a/src/com/owncloud/android/lib/common/network/WebdavUtils.java +++ b/src/com/owncloud/android/lib/common/network/WebdavUtils.java @@ -1,6 +1,6 @@ /* ownCloud Android Library is available under MIT license * Copyright (C) 2015 ownCloud Inc. - * Copyright (C) 2012 Bartek Przybylski + * Copyright (C) 2012 Bartek Przybylski * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,6 +32,10 @@ import java.util.Locale; import android.net.Uri; +import org.apache.jackrabbit.webdav.property.DavPropertyName; +import org.apache.jackrabbit.webdav.property.DavPropertyNameSet; +import org.apache.jackrabbit.webdav.xml.Namespace; + public class WebdavUtils { public static final SimpleDateFormat DISPLAY_DATE_FORMAT = new SimpleDateFormat( "dd.MM.yyyy hh:mm"); @@ -78,5 +82,53 @@ public class WebdavUtils { encodedPath = "/" + encodedPath; return encodedPath; } - + + /** + * Builds a DavPropertyNameSet with all prop + * For using instead of DavConstants.PROPFIND_ALL_PROP + * @return + */ + public static DavPropertyNameSet getAllPropSet(){ + DavPropertyNameSet propSet = new DavPropertyNameSet(); + propSet.add(DavPropertyName.DISPLAYNAME); + propSet.add(DavPropertyName.GETCONTENTTYPE); + propSet.add(DavPropertyName.RESOURCETYPE); + propSet.add(DavPropertyName.GETCONTENTLENGTH); + propSet.add(DavPropertyName.GETLASTMODIFIED); + propSet.add(DavPropertyName.CREATIONDATE); + propSet.add(DavPropertyName.GETETAG); + propSet.add(DavPropertyName.create(WebdavEntry.PROPERTY_QUOTA_USED_BYTES)); + propSet.add(DavPropertyName.create(WebdavEntry.PROPERTY_QUOTA_AVAILABLE_BYTES)); + propSet.add(WebdavEntry.EXTENDED_PROPERTY_NAME_PERMISSIONS, + Namespace.getNamespace(WebdavEntry.NAMESPACE_OC)); + propSet.add(WebdavEntry.EXTENDED_PROPERTY_NAME_REMOTE_ID, + Namespace.getNamespace(WebdavEntry.NAMESPACE_OC)); + propSet.add(WebdavEntry.EXTENDED_PROPERTY_NAME_SIZE, + Namespace.getNamespace(WebdavEntry.NAMESPACE_OC)); + + return propSet; + } + + /** + * Builds a DavPropertyNameSet with properties for files + * @return + */ + public static DavPropertyNameSet getFilePropSet(){ + DavPropertyNameSet propSet = new DavPropertyNameSet(); + propSet.add(DavPropertyName.DISPLAYNAME); + propSet.add(DavPropertyName.GETCONTENTTYPE); + propSet.add(DavPropertyName.RESOURCETYPE); + propSet.add(DavPropertyName.GETCONTENTLENGTH); + propSet.add(DavPropertyName.GETLASTMODIFIED); + propSet.add(DavPropertyName.CREATIONDATE); + propSet.add(DavPropertyName.GETETAG); + propSet.add(WebdavEntry.EXTENDED_PROPERTY_NAME_PERMISSIONS, + Namespace.getNamespace(WebdavEntry.NAMESPACE_OC)); + propSet.add(WebdavEntry.EXTENDED_PROPERTY_NAME_REMOTE_ID, + Namespace.getNamespace(WebdavEntry.NAMESPACE_OC)); + propSet.add(WebdavEntry.EXTENDED_PROPERTY_NAME_SIZE, + Namespace.getNamespace(WebdavEntry.NAMESPACE_OC)); + + return propSet; + } } diff --git a/src/com/owncloud/android/lib/resources/files/ReadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/ReadRemoteFileOperation.java index 6acb7bf9..12c2017f 100644 --- a/src/com/owncloud/android/lib/resources/files/ReadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/ReadRemoteFileOperation.java @@ -75,8 +75,9 @@ public class ReadRemoteFileOperation extends RemoteOperation { /// take the duty of check the server for the current state of the file there try { + // remote request propfind = new PropFindMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath), - DavConstants.PROPFIND_ALL_PROP, + WebdavUtils.getFilePropSet(), // PropFind Properties DavConstants.DEPTH_0); int status; status = client.executeMethod(propfind, SYNC_READ_TIMEOUT, SYNC_CONNECTION_TIMEOUT); @@ -88,7 +89,8 @@ public class ReadRemoteFileOperation extends RemoteOperation { if (isSuccess) { // Parse response MultiStatus resp = propfind.getResponseBodyAsMultiStatus(); - WebdavEntry we = new WebdavEntry(resp.getResponses()[0], client.getWebdavUri().getPath()); + WebdavEntry we = new WebdavEntry(resp.getResponses()[0], + client.getWebdavUri().getPath()); RemoteFile remoteFile = new RemoteFile(we); ArrayList files = new ArrayList(); files.add(remoteFile); @@ -105,7 +107,8 @@ public class ReadRemoteFileOperation extends RemoteOperation { } catch (Exception e) { result = new RemoteOperationResult(e); e.printStackTrace(); - Log_OC.e(TAG, "Synchronizing file " + mRemotePath + ": " + result.getLogMessage(), result.getException()); + Log_OC.e(TAG, "Synchronizing file " + mRemotePath + ": " + result.getLogMessage(), + result.getException()); } finally { if (propfind != null) propfind.releaseConnection(); diff --git a/src/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java b/src/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java index 2ec1b763..1e93aa22 100644 --- a/src/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java +++ b/src/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java @@ -72,9 +72,9 @@ public class ReadRemoteFolderOperation extends RemoteOperation { PropFindMethod query = null; try { - // remote request + // remote request query = new PropFindMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath), - DavConstants.PROPFIND_ALL_PROP, + WebdavUtils.getAllPropSet(), // PropFind Properties DavConstants.DEPTH_1); int status = client.executeMethod(query); @@ -111,7 +111,8 @@ public class ReadRemoteFolderOperation extends RemoteOperation { Log_OC.i(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage()); } else { if (result.isException()) { - Log_OC.e(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage(), result.getException()); + Log_OC.e(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage(), + result.getException()); } else { Log_OC.e(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage()); } @@ -139,7 +140,8 @@ public class ReadRemoteFolderOperation extends RemoteOperation { mFolderAndFiles = new ArrayList(); // parse data from remote folder - WebdavEntry we = new WebdavEntry(remoteData.getResponses()[0], client.getWebdavUri().getPath()); + WebdavEntry we = new WebdavEntry(remoteData.getResponses()[0], + client.getWebdavUri().getPath()); mFolderAndFiles.add(fillOCFile(we)); // loop to update every child @@ -168,6 +170,9 @@ public class ReadRemoteFolderOperation extends RemoteOperation { file.setEtag(we.etag()); file.setPermissions(we.permissions()); file.setRemoteId(we.remoteId()); + file.setSize(we.size()); + file.setQuotaUsedBytes(we.quotaUsedBytes()); + file.setQuotaAvailableBytes(we.quotaAvailableBytes()); return file; } } diff --git a/src/com/owncloud/android/lib/resources/files/RemoteFile.java b/src/com/owncloud/android/lib/resources/files/RemoteFile.java index fe95949a..1a5d13f9 100644 --- a/src/com/owncloud/android/lib/resources/files/RemoteFile.java +++ b/src/com/owncloud/android/lib/resources/files/RemoteFile.java @@ -39,9 +39,9 @@ import com.owncloud.android.lib.common.network.WebdavEntry; public class RemoteFile implements Parcelable, Serializable { - /** Generated - should be refreshed every time the class changes!! */ - private static final long serialVersionUID = 532139091191390616L; - + /** Generated - should be refreshed every time the class changes!! */ + private static final long serialVersionUID = 3130865437811248451L; + private String mRemotePath; private String mMimeType; private long mLength; @@ -50,6 +50,9 @@ public class RemoteFile implements Parcelable, Serializable { private String mEtag; private String mPermissions; private String mRemoteId; + private long mSize; + private long mQuotaUsedBytes; + private long mQuotaAvailableBytes; /** * Getters and Setters @@ -119,6 +122,22 @@ public class RemoteFile implements Parcelable, Serializable { this.mRemoteId = remoteId; } + public long getSize() { + return mSize; + } + + public void setSize (long size){ + mSize = size; + } + + public void setQuotaUsedBytes (long quotaUsedBytes) { + mQuotaUsedBytes = quotaUsedBytes; + } + + public void setQuotaAvailableBytes (long quotaAvailableBytes) { + mQuotaAvailableBytes = quotaAvailableBytes; + } + public RemoteFile() { resetData(); } @@ -147,6 +166,9 @@ public class RemoteFile implements Parcelable, Serializable { this.setEtag(we.etag()); this.setPermissions(we.permissions()); this.setRemoteId(we.remoteId()); + this.setSize(we.size()); + this.setQuotaUsedBytes(we.quotaUsedBytes()); + this.setQuotaAvailableBytes(we.quotaAvailableBytes()); } /** @@ -161,6 +183,9 @@ public class RemoteFile implements Parcelable, Serializable { mEtag = null; mPermissions = null; mRemoteId = null; + mSize = 0; + mQuotaUsedBytes = 0; + mQuotaAvailableBytes = 0; } /** @@ -197,6 +222,9 @@ public class RemoteFile implements Parcelable, Serializable { mEtag = source.readString(); mPermissions= source.readString(); mRemoteId = source.readString(); + mSize = source.readLong(); + mQuotaUsedBytes = source.readLong(); + mQuotaAvailableBytes = source.readLong(); } @Override @@ -214,7 +242,9 @@ public class RemoteFile implements Parcelable, Serializable { dest.writeString(mEtag); dest.writeString(mPermissions); dest.writeString(mRemoteId); + dest.writeLong(mSize); + dest.writeLong(mQuotaUsedBytes); + dest.writeLong(mQuotaAvailableBytes); } - - + }