Loading build.gradle +1 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ dependencies { implementation 'org.parceler:parceler-api:1.1.6' annotationProcessor 'org.parceler:parceler:1.1.6' implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.0' implementation "com.android.support:support-annotations:27.1.1" } android { Loading src/com/owncloud/android/lib/common/network/WebdavUtils.java +17 −0 Original line number Diff line number Diff line Loading @@ -148,6 +148,23 @@ public class WebdavUtils { return propSet; } /** * Builds a DavPropertyNameSet with properties for versions * @return */ public static DavPropertyNameSet getFileVersionPropSet() { DavPropertyNameSet propSet = new DavPropertyNameSet(); propSet.add(DavPropertyName.GETCONTENTTYPE); propSet.add(DavPropertyName.RESOURCETYPE); propSet.add(DavPropertyName.GETCONTENTLENGTH); propSet.add(DavPropertyName.GETLASTMODIFIED); propSet.add(DavPropertyName.CREATIONDATE); 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; } /** * * @param rawEtag Loading src/com/owncloud/android/lib/resources/files/FileVersion.java 0 → 100644 +158 −0 Original line number Diff line number Diff line /* ownCloud Android Library is available under MIT license * Copyright (C) 2018 Nextcloud 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.files; import android.os.Parcel; import android.os.Parcelable; import com.owncloud.android.lib.common.network.WebdavEntry; import java.io.Serializable; /** * Contains the data of a versioned file from a WebDavEntry. * * @author Tobias Kaminsky */ public class FileVersion implements Parcelable, Serializable, ServerFileInterface { /** * Generated - should be refreshed every time the class changes!! */ private static final long serialVersionUID = 3130865437811248455L; public static final String DIRECTORY = "DIR"; private String mimeType; private long length; private long modifiedTimestamp; private String remoteId; @Override public boolean getIsFavorite() { return false; } @Override public String getFileName() { return String.valueOf(modifiedTimestamp / 1000); } public String getMimeType() { return mimeType; } @Override public String getRemotePath() { return ""; } @Override public String getRemoteId() { return remoteId; } public void setMimeType(String mimeType) { this.mimeType = mimeType; } public long getFileLength() { return length; } public void setFileLength(long length) { this.length = length; } public boolean isFolder() { return mimeType != null && mimeType.equals(DIRECTORY); } public boolean isHidden() { return getFileName().startsWith("."); } public void setModifiedTimestamp(long modifiedTimestamp) { this.modifiedTimestamp = modifiedTimestamp; } public long getModifiedTimestamp() { return modifiedTimestamp; } public FileVersion(String fileId, WebdavEntry we) { remoteId = fileId; setMimeType(we.contentType()); if (isFolder()) { setFileLength(we.size()); } else { setFileLength(we.contentLength()); } setModifiedTimestamp(we.modifiedTimestamp()); } /** * Parcelable Methods */ public static final Creator<FileVersion> CREATOR = new Creator<FileVersion>() { @Override public FileVersion createFromParcel(Parcel source) { return new FileVersion(source); } @Override public FileVersion[] newArray(int size) { return new FileVersion[size]; } }; /** * Reconstruct from parcel * * @param source The source parcel */ protected FileVersion(Parcel source) { readFromParcel(source); } public void readFromParcel(Parcel source) { mimeType = source.readString(); length = source.readLong(); } @Override public int describeContents() { return this.hashCode(); } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(mimeType); dest.writeLong(length); } } src/com/owncloud/android/lib/resources/files/ReadFileVersionsOperation.java 0 → 100644 +154 −0 Original line number Diff line number Diff line /* ownCloud Android Library is available under MIT license * Copyright (C) 2018 Nextcloud 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.files; import android.support.annotation.NonNull; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.network.WebdavEntry; 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 org.apache.jackrabbit.webdav.property.DavPropertyNameSet; import java.util.ArrayList; /** * Remote operation performing the read of remote trashbin folder on Nextcloud server. * * @author Tobias Kaminsky */ public class ReadFileVersionsOperation extends RemoteOperation { private static final String TAG = ReadFileVersionsOperation.class.getSimpleName(); private String fileId; private String userId; private ArrayList<Object> versions; /** * Constructor * * @param fileId FileId of the file. */ public ReadFileVersionsOperation(@NonNull String fileId, @NonNull String userId) { this.fileId = fileId; this.userId = userId; } /** * Performs the read operation. * * @param client Client object to communicate with the remote ownCloud server. */ @Override protected RemoteOperationResult run(OwnCloudClient client) { RemoteOperationResult result = null; PropFindMethod query = null; try { // remote request if (userId.isEmpty()) { throw new IllegalArgumentException("UserId may not be empty!"); } String uri = client.getNewWebdavUri(false) + "/versions/" + userId + "/versions/" + fileId; DavPropertyNameSet propSet = WebdavUtils.getFileVersionPropSet(); query = new PropFindMethod(uri, propSet, DavConstants.DEPTH_1); int status = client.executeMethod(query); // 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(); readData(dataInServer, client); // Result of the operation result = new RemoteOperationResult(true, query); // Add data to the result if (result.isSuccess()) { result.setData(versions); } } 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 file with id " + fileId + ": failed"); } else { if (result.isSuccess()) { Log_OC.i(TAG, "Synchronized file with id " + fileId + ": " + result.getLogMessage()); } else { if (result.isException()) { Log_OC.e(TAG, "Synchronized with id " + fileId + ": " + result.getLogMessage(), result.getException()); } else { Log_OC.e(TAG, "Synchronized with id " + fileId + ": " + result.getLogMessage()); } } } } return result; } /** * Read the data retrieved from the server about the file versions. * * @param remoteData Full response got from the server with the version data. * @param client Client instance to the remote server where the data were retrieved. */ private void readData(MultiStatus remoteData, OwnCloudClient client) { versions = new ArrayList<>(); // parse data from remote folder WebdavEntry we; String splitElement = client.getNewWebdavUri(false).getPath(); // loop to update every child for (int i = 1; i < remoteData.getResponses().length; ++i) { we = new WebdavEntry(remoteData.getResponses()[i], splitElement); versions.add(new FileVersion(fileId, we)); } } } Loading
build.gradle +1 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ dependencies { implementation 'org.parceler:parceler-api:1.1.6' annotationProcessor 'org.parceler:parceler:1.1.6' implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.0' implementation "com.android.support:support-annotations:27.1.1" } android { Loading
src/com/owncloud/android/lib/common/network/WebdavUtils.java +17 −0 Original line number Diff line number Diff line Loading @@ -148,6 +148,23 @@ public class WebdavUtils { return propSet; } /** * Builds a DavPropertyNameSet with properties for versions * @return */ public static DavPropertyNameSet getFileVersionPropSet() { DavPropertyNameSet propSet = new DavPropertyNameSet(); propSet.add(DavPropertyName.GETCONTENTTYPE); propSet.add(DavPropertyName.RESOURCETYPE); propSet.add(DavPropertyName.GETCONTENTLENGTH); propSet.add(DavPropertyName.GETLASTMODIFIED); propSet.add(DavPropertyName.CREATIONDATE); 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; } /** * * @param rawEtag Loading
src/com/owncloud/android/lib/resources/files/FileVersion.java 0 → 100644 +158 −0 Original line number Diff line number Diff line /* ownCloud Android Library is available under MIT license * Copyright (C) 2018 Nextcloud 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.files; import android.os.Parcel; import android.os.Parcelable; import com.owncloud.android.lib.common.network.WebdavEntry; import java.io.Serializable; /** * Contains the data of a versioned file from a WebDavEntry. * * @author Tobias Kaminsky */ public class FileVersion implements Parcelable, Serializable, ServerFileInterface { /** * Generated - should be refreshed every time the class changes!! */ private static final long serialVersionUID = 3130865437811248455L; public static final String DIRECTORY = "DIR"; private String mimeType; private long length; private long modifiedTimestamp; private String remoteId; @Override public boolean getIsFavorite() { return false; } @Override public String getFileName() { return String.valueOf(modifiedTimestamp / 1000); } public String getMimeType() { return mimeType; } @Override public String getRemotePath() { return ""; } @Override public String getRemoteId() { return remoteId; } public void setMimeType(String mimeType) { this.mimeType = mimeType; } public long getFileLength() { return length; } public void setFileLength(long length) { this.length = length; } public boolean isFolder() { return mimeType != null && mimeType.equals(DIRECTORY); } public boolean isHidden() { return getFileName().startsWith("."); } public void setModifiedTimestamp(long modifiedTimestamp) { this.modifiedTimestamp = modifiedTimestamp; } public long getModifiedTimestamp() { return modifiedTimestamp; } public FileVersion(String fileId, WebdavEntry we) { remoteId = fileId; setMimeType(we.contentType()); if (isFolder()) { setFileLength(we.size()); } else { setFileLength(we.contentLength()); } setModifiedTimestamp(we.modifiedTimestamp()); } /** * Parcelable Methods */ public static final Creator<FileVersion> CREATOR = new Creator<FileVersion>() { @Override public FileVersion createFromParcel(Parcel source) { return new FileVersion(source); } @Override public FileVersion[] newArray(int size) { return new FileVersion[size]; } }; /** * Reconstruct from parcel * * @param source The source parcel */ protected FileVersion(Parcel source) { readFromParcel(source); } public void readFromParcel(Parcel source) { mimeType = source.readString(); length = source.readLong(); } @Override public int describeContents() { return this.hashCode(); } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(mimeType); dest.writeLong(length); } }
src/com/owncloud/android/lib/resources/files/ReadFileVersionsOperation.java 0 → 100644 +154 −0 Original line number Diff line number Diff line /* ownCloud Android Library is available under MIT license * Copyright (C) 2018 Nextcloud 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.files; import android.support.annotation.NonNull; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.network.WebdavEntry; 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 org.apache.jackrabbit.webdav.property.DavPropertyNameSet; import java.util.ArrayList; /** * Remote operation performing the read of remote trashbin folder on Nextcloud server. * * @author Tobias Kaminsky */ public class ReadFileVersionsOperation extends RemoteOperation { private static final String TAG = ReadFileVersionsOperation.class.getSimpleName(); private String fileId; private String userId; private ArrayList<Object> versions; /** * Constructor * * @param fileId FileId of the file. */ public ReadFileVersionsOperation(@NonNull String fileId, @NonNull String userId) { this.fileId = fileId; this.userId = userId; } /** * Performs the read operation. * * @param client Client object to communicate with the remote ownCloud server. */ @Override protected RemoteOperationResult run(OwnCloudClient client) { RemoteOperationResult result = null; PropFindMethod query = null; try { // remote request if (userId.isEmpty()) { throw new IllegalArgumentException("UserId may not be empty!"); } String uri = client.getNewWebdavUri(false) + "/versions/" + userId + "/versions/" + fileId; DavPropertyNameSet propSet = WebdavUtils.getFileVersionPropSet(); query = new PropFindMethod(uri, propSet, DavConstants.DEPTH_1); int status = client.executeMethod(query); // 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(); readData(dataInServer, client); // Result of the operation result = new RemoteOperationResult(true, query); // Add data to the result if (result.isSuccess()) { result.setData(versions); } } 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 file with id " + fileId + ": failed"); } else { if (result.isSuccess()) { Log_OC.i(TAG, "Synchronized file with id " + fileId + ": " + result.getLogMessage()); } else { if (result.isException()) { Log_OC.e(TAG, "Synchronized with id " + fileId + ": " + result.getLogMessage(), result.getException()); } else { Log_OC.e(TAG, "Synchronized with id " + fileId + ": " + result.getLogMessage()); } } } } return result; } /** * Read the data retrieved from the server about the file versions. * * @param remoteData Full response got from the server with the version data. * @param client Client instance to the remote server where the data were retrieved. */ private void readData(MultiStatus remoteData, OwnCloudClient client) { versions = new ArrayList<>(); // parse data from remote folder WebdavEntry we; String splitElement = client.getNewWebdavUri(false).getPath(); // loop to update every child for (int i = 1; i < remoteData.getResponses().length; ++i) { we = new WebdavEntry(remoteData.getResponses()[i], splitElement); versions.add(new FileVersion(fileId, we)); } } }