mirror of
https://github.com/nextcloud/android.git
synced 2024-11-27 17:46:37 +03:00
OC-2256: New RemoteFile class
This commit is contained in:
parent
5aaa4e10e8
commit
007ca522ec
4 changed files with 265 additions and 90 deletions
|
@ -0,0 +1,148 @@
|
|||
package com.owncloud.android.oc_framework.operations;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.owncloud.android.oc_framework.utils.FileUtils;
|
||||
|
||||
|
||||
public class RemoteFile implements Parcelable, Serializable{
|
||||
|
||||
/** Generated - should be refreshed every time the class changes!! */
|
||||
private static final long serialVersionUID = 7256606476031992757L;
|
||||
|
||||
private String mRemotePath;
|
||||
private String mMimeType;
|
||||
private long mLength;
|
||||
private long mCreationTimestamp;
|
||||
private long mModifiedTimestamp;
|
||||
private String mEtag;
|
||||
|
||||
/**
|
||||
* Getters and Setters
|
||||
*/
|
||||
|
||||
public String getRemotePath() {
|
||||
return mRemotePath;
|
||||
}
|
||||
|
||||
public void setRemotePath(String remotePath) {
|
||||
this.mRemotePath = remotePath;
|
||||
}
|
||||
|
||||
public String getMimeType() {
|
||||
return mMimeType;
|
||||
}
|
||||
|
||||
public void setMimeType(String mimeType) {
|
||||
this.mMimeType = mimeType;
|
||||
}
|
||||
|
||||
public long getLength() {
|
||||
return mLength;
|
||||
}
|
||||
|
||||
public void setLength(long length) {
|
||||
this.mLength = length;
|
||||
}
|
||||
|
||||
public long getCreationTimestamp() {
|
||||
return mCreationTimestamp;
|
||||
}
|
||||
|
||||
public void setCreationTimestamp(long creationTimestamp) {
|
||||
this.mCreationTimestamp = creationTimestamp;
|
||||
}
|
||||
|
||||
public long getModifiedTimestamp() {
|
||||
return mModifiedTimestamp;
|
||||
}
|
||||
|
||||
public void setModifiedTimestamp(long modifiedTimestamp) {
|
||||
this.mModifiedTimestamp = modifiedTimestamp;
|
||||
}
|
||||
|
||||
public String getEtag() {
|
||||
return mEtag;
|
||||
}
|
||||
|
||||
public void setEtag(String etag) {
|
||||
this.mEtag = etag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new {@link RemoteFile} with given path.
|
||||
*
|
||||
* The path received must be URL-decoded. Path separator must be OCFile.PATH_SEPARATOR, and it must be the first character in 'path'.
|
||||
*
|
||||
* @param path The remote path of the file.
|
||||
*/
|
||||
public RemoteFile(String path) {
|
||||
resetData();
|
||||
if (path == null || path.length() <= 0 || !path.startsWith(FileUtils.PATH_SEPARATOR)) {
|
||||
throw new IllegalArgumentException("Trying to create a OCFile with a non valid remote path: " + path);
|
||||
}
|
||||
mRemotePath = path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used internally. Reset all file properties
|
||||
*/
|
||||
private void resetData() {
|
||||
mRemotePath = null;
|
||||
mMimeType = null;
|
||||
mLength = 0;
|
||||
mCreationTimestamp = 0;
|
||||
mModifiedTimestamp = 0;
|
||||
mEtag = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parcelable Methods
|
||||
*/
|
||||
public static final Parcelable.Creator<RemoteFile> CREATOR = new Parcelable.Creator<RemoteFile>() {
|
||||
@Override
|
||||
public RemoteFile createFromParcel(Parcel source) {
|
||||
return new RemoteFile(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoteFile[] newArray(int size) {
|
||||
return new RemoteFile[size];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reconstruct from parcel
|
||||
*
|
||||
* @param source The source parcel
|
||||
*/
|
||||
private RemoteFile(Parcel source) {
|
||||
mRemotePath = source.readString();
|
||||
mMimeType = source.readString();
|
||||
mLength = source.readLong();
|
||||
mCreationTimestamp = source.readLong();
|
||||
mModifiedTimestamp = source.readLong();
|
||||
mEtag = source.readString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return this.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(mRemotePath);
|
||||
dest.writeString(mMimeType);
|
||||
dest.writeLong(mLength);
|
||||
dest.writeLong(mCreationTimestamp);
|
||||
dest.writeLong(mModifiedTimestamp);
|
||||
dest.writeString(mEtag);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -24,6 +24,7 @@ import java.net.MalformedURLException;
|
|||
import java.net.SocketException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.net.ssl.SSLException;
|
||||
|
||||
|
@ -51,10 +52,8 @@ import android.util.Log;
|
|||
*/
|
||||
public class RemoteOperationResult implements Serializable {
|
||||
|
||||
/** Generated - should be refreshed every time the class changes!! */
|
||||
private static final long serialVersionUID = -4415103901492836870L;
|
||||
|
||||
|
||||
/** Generated - should be refreshed every time the class changes!! */
|
||||
private static final long serialVersionUID = -2469951225222759283L;
|
||||
|
||||
private static final String TAG = "RemoteOperationResult";
|
||||
|
||||
|
@ -99,9 +98,14 @@ public class RemoteOperationResult implements Serializable {
|
|||
private ResultCode mCode = ResultCode.UNKNOWN_ERROR;
|
||||
private String mRedirectedLocation;
|
||||
|
||||
private RemoteFile mFile;
|
||||
private ArrayList<RemoteFile> mFiles;
|
||||
|
||||
public RemoteOperationResult(ResultCode code) {
|
||||
mCode = code;
|
||||
mSuccess = (code == ResultCode.OK || code == ResultCode.OK_SSL || code == ResultCode.OK_NO_SSL);
|
||||
mFile= null;
|
||||
mFiles = null;
|
||||
}
|
||||
|
||||
private RemoteOperationResult(boolean success, int httpCode) {
|
||||
|
@ -196,6 +200,21 @@ public class RemoteOperationResult implements Serializable {
|
|||
|
||||
}
|
||||
|
||||
|
||||
public void setFile(RemoteFile file){
|
||||
mFile = file;
|
||||
}
|
||||
public RemoteFile getFile(){
|
||||
return mFile;
|
||||
}
|
||||
public void setData(ArrayList<RemoteFile> files){
|
||||
mFiles = files;
|
||||
}
|
||||
|
||||
public ArrayList<RemoteFile> getData(){
|
||||
return mFiles;
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return mSuccess;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.owncloud.android.oc_framework.operations.remote;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.jackrabbit.webdav.DavConstants;
|
||||
import org.apache.jackrabbit.webdav.MultiStatus;
|
||||
|
@ -8,7 +10,9 @@ import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
|
|||
import android.util.Log;
|
||||
|
||||
import com.owncloud.android.oc_framework.network.webdav.WebdavClient;
|
||||
import com.owncloud.android.oc_framework.network.webdav.WebdavEntry;
|
||||
import com.owncloud.android.oc_framework.network.webdav.WebdavUtils;
|
||||
import com.owncloud.android.oc_framework.operations.RemoteFile;
|
||||
import com.owncloud.android.oc_framework.operations.RemoteOperation;
|
||||
import com.owncloud.android.oc_framework.operations.RemoteOperationResult;
|
||||
|
||||
|
@ -24,12 +28,8 @@ public class ReadRemoteFileOperation extends RemoteOperation {
|
|||
private static final String TAG = ReadRemoteFileOperation.class.getSimpleName();
|
||||
|
||||
private String mRemotePath;
|
||||
private MultiStatus mDataInServer;
|
||||
|
||||
public MultiStatus getDataInServer() {
|
||||
return mDataInServer;
|
||||
}
|
||||
|
||||
private RemoteFile mFolder;
|
||||
private ArrayList<RemoteFile> mFiles;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -38,7 +38,6 @@ public class ReadRemoteFileOperation extends RemoteOperation {
|
|||
*/
|
||||
public ReadRemoteFileOperation(String remotePath) {
|
||||
mRemotePath = remotePath;
|
||||
mDataInServer = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -61,8 +60,16 @@ public class ReadRemoteFileOperation extends RemoteOperation {
|
|||
// check and process response
|
||||
if (isMultiStatus(status)) {
|
||||
// get data from remote folder
|
||||
mDataInServer = query.getResponseBodyAsMultiStatus();
|
||||
MultiStatus dataInServer = query.getResponseBodyAsMultiStatus();
|
||||
readData(dataInServer, client);
|
||||
|
||||
// Result of the operation
|
||||
result = new RemoteOperationResult(true, status, query.getResponseHeaders());
|
||||
// Add data to the result
|
||||
if (result.isSuccess()) {
|
||||
result.setFile(mFolder);
|
||||
result.setData(mFiles);
|
||||
}
|
||||
} else {
|
||||
// synchronization failed
|
||||
client.exhaustResponse(query.getResponseBodyAsStream());
|
||||
|
@ -93,5 +100,51 @@ public class ReadRemoteFileOperation extends RemoteOperation {
|
|||
public boolean isMultiStatus(int status) {
|
||||
return (status == HttpStatus.SC_MULTI_STATUS);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read the data retrieved from the server about the contents of the target folder
|
||||
*
|
||||
*
|
||||
* @param dataInServer Full response got from the server with the data of the target
|
||||
* folder and its direct children.
|
||||
* @param client Client instance to the remote server where the data were
|
||||
* retrieved.
|
||||
* @return
|
||||
*/
|
||||
private void readData(MultiStatus dataInServer, WebdavClient client) {
|
||||
// parse data from remote folder
|
||||
WebdavEntry we = new WebdavEntry(dataInServer.getResponses()[0], client.getBaseUri().getPath());
|
||||
mFolder = fillOCFile(we);
|
||||
|
||||
Log.d(TAG, "Remote folder " + mRemotePath + " changed - starting update of local data ");
|
||||
|
||||
|
||||
// loop to update every child
|
||||
RemoteFile remoteFile = null;
|
||||
mFiles = new ArrayList<RemoteFile>();
|
||||
for (int i = 1; i < dataInServer.getResponses().length; ++i) {
|
||||
/// new OCFile instance with the data from the server
|
||||
we = new WebdavEntry(dataInServer.getResponses()[i], client.getBaseUri().getPath());
|
||||
remoteFile = fillOCFile(we);
|
||||
|
||||
mFiles.add(remoteFile);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and populates a new {@link RemoteFile} object with the data read from the server.
|
||||
*
|
||||
* @param we WebDAV entry read from the server for a WebDAV resource (remote file or folder).
|
||||
* @return New OCFile instance representing the remote resource described by we.
|
||||
*/
|
||||
private RemoteFile fillOCFile(WebdavEntry we) {
|
||||
RemoteFile file = new RemoteFile(we.decodedPath());
|
||||
file.setCreationTimestamp(we.createTimestamp());
|
||||
file.setLength(we.contentLength());
|
||||
file.setMimeType(we.contentType());
|
||||
file.setModifiedTimestamp(we.modifiedTimestamp());
|
||||
file.setEtag(we.etag());
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.io.FileOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -30,7 +31,6 @@ import java.util.Vector;
|
|||
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.jackrabbit.webdav.DavConstants;
|
||||
import org.apache.jackrabbit.webdav.MultiStatus;
|
||||
import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
|
||||
|
||||
import android.accounts.Account;
|
||||
|
@ -46,6 +46,7 @@ import com.owncloud.android.oc_framework.operations.RemoteOperation;
|
|||
import com.owncloud.android.oc_framework.operations.RemoteOperationResult;
|
||||
import com.owncloud.android.oc_framework.operations.RemoteOperationResult.ResultCode;
|
||||
import com.owncloud.android.oc_framework.operations.remote.ReadRemoteFileOperation;
|
||||
import com.owncloud.android.oc_framework.operations.RemoteFile;
|
||||
import com.owncloud.android.syncadapter.FileSyncService;
|
||||
import com.owncloud.android.utils.FileStorageUtils;
|
||||
import com.owncloud.android.utils.Log_OC;
|
||||
|
@ -248,8 +249,9 @@ public class SynchronizeFolderOperation extends RemoteOperation {
|
|||
Log_OC.d(TAG, "Synchronizing " + mAccount.name + remotePath);
|
||||
|
||||
if (result.isSuccess()) {
|
||||
MultiStatus dataInServer = ((ReadRemoteFileOperation) operation).getDataInServer();
|
||||
synchronizeData(dataInServer, client);
|
||||
RemoteFile folder = result.getFile();
|
||||
ArrayList<RemoteFile> files = result.getData();
|
||||
synchronizeData(folder, files, client);
|
||||
if (mConflictsFound > 0 || mFailsInFavouritesFound > 0) {
|
||||
result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT); // should be different result, but will do the job
|
||||
}
|
||||
|
@ -258,72 +260,9 @@ public class SynchronizeFolderOperation extends RemoteOperation {
|
|||
removeLocalFolder();
|
||||
}
|
||||
|
||||
// RemoteOperationResult result = null;
|
||||
// String remotePath = null;
|
||||
// PropFindMethod query = null;
|
||||
// try {
|
||||
// remotePath = mLocalFolder.getRemotePath();
|
||||
// Log_OC.d(TAG, "Synchronizing " + mAccount.name + remotePath);
|
||||
//
|
||||
// // remote request
|
||||
// query = new PropFindMethod(client.getBaseUri() + WebdavUtils.encodePath(remotePath),
|
||||
// DavConstants.PROPFIND_ALL_PROP,
|
||||
// DavConstants.DEPTH_1);
|
||||
// int status = client.executeMethod(query);
|
||||
//
|
||||
// // check and process response
|
||||
// if (isMultiStatus(status)) {
|
||||
// synchronizeData(query.getResponseBodyAsMultiStatus(), client);
|
||||
// if (mConflictsFound > 0 || mFailsInFavouritesFound > 0) {
|
||||
// result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT); // should be different result, but will do the job
|
||||
// } else {
|
||||
// result = new RemoteOperationResult(true, status, query.getResponseHeaders());
|
||||
// }
|
||||
//
|
||||
// } else {
|
||||
// // synchronization failed
|
||||
// client.exhaustResponse(query.getResponseBodyAsStream());
|
||||
// if (status == HttpStatus.SC_NOT_FOUND) {
|
||||
// removeLocalFolder();
|
||||
// }
|
||||
// result = new RemoteOperationResult(false, status, query.getResponseHeaders());
|
||||
// }
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// result = new RemoteOperationResult(e);
|
||||
//
|
||||
//
|
||||
// } finally {
|
||||
// if (query != null)
|
||||
// query.releaseConnection(); // let the connection available for other methods
|
||||
// if (result.isSuccess()) {
|
||||
// Log_OC.i(TAG, "Synchronized " + mAccount.name + remotePath + ": " + result.getLogMessage());
|
||||
// } else {
|
||||
// if (result.isException()) {
|
||||
// Log_OC.e(TAG, "Synchronized " + mAccount.name + remotePath + ": " + result.getLogMessage(), result.getException());
|
||||
// } else {
|
||||
// Log_OC.e(TAG, "Synchronized " + mAccount.name + remotePath + ": " + result.getLogMessage());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// @Override
|
||||
// public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
|
||||
// if (operation instanceof ReadRemoteFileOperation) {
|
||||
// if (result.isSuccess()) {
|
||||
// MultiStatus dataInServer = ((ReadRemoteFileOperation) operation).getDataInServer();
|
||||
// synchronizeData(dataInServer, client)
|
||||
// } else {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
private void removeLocalFolder() {
|
||||
if (mStorageManager.fileExists(mLocalFolder.getFileId())) {
|
||||
|
@ -338,26 +277,27 @@ public class SynchronizeFolderOperation extends RemoteOperation {
|
|||
* with the current data in the local database.
|
||||
*
|
||||
* Grants that mChildren is updated with fresh data after execution.
|
||||
*
|
||||
* @param dataInServer Full response got from the server with the data of the target
|
||||
* folder and its direct children.
|
||||
*
|
||||
* @param folder Remote Folder to synchronize
|
||||
*
|
||||
* @param files Remote Files in Folder
|
||||
*
|
||||
* @param client Client instance to the remote server where the data were
|
||||
* retrieved.
|
||||
* @return 'True' when any change was made in the local data, 'false' otherwise.
|
||||
*/
|
||||
private void synchronizeData(MultiStatus dataInServer, WebdavClient client) {
|
||||
private void synchronizeData(RemoteFile folder, ArrayList<RemoteFile> files, WebdavClient client) {
|
||||
// get 'fresh data' from the database
|
||||
mLocalFolder = mStorageManager.getFileByPath(mLocalFolder.getRemotePath());
|
||||
|
||||
// parse data from remote folder
|
||||
WebdavEntry we = new WebdavEntry(dataInServer.getResponses()[0], client.getBaseUri().getPath());
|
||||
OCFile remoteFolder = fillOCFile(we);
|
||||
OCFile remoteFolder = fillOCFile(folder);
|
||||
remoteFolder.setParentId(mLocalFolder.getParentId());
|
||||
remoteFolder.setFileId(mLocalFolder.getFileId());
|
||||
|
||||
Log_OC.d(TAG, "Remote folder " + mLocalFolder.getRemotePath() + " changed - starting update of local data ");
|
||||
|
||||
List<OCFile> updatedFiles = new Vector<OCFile>(dataInServer.getResponses().length - 1);
|
||||
List<OCFile> updatedFiles = new Vector<OCFile>(files.size());
|
||||
List<SynchronizeFileOperation> filesToSyncContents = new Vector<SynchronizeFileOperation>();
|
||||
|
||||
// get current data about local contents of the folder to synchronize
|
||||
|
@ -369,10 +309,9 @@ public class SynchronizeFolderOperation extends RemoteOperation {
|
|||
|
||||
// loop to update every child
|
||||
OCFile remoteFile = null, localFile = null;
|
||||
for (int i = 1; i < dataInServer.getResponses().length; ++i) {
|
||||
for (RemoteFile file: files) {
|
||||
/// new OCFile instance with the data from the server
|
||||
we = new WebdavEntry(dataInServer.getResponses()[i], client.getBaseUri().getPath());
|
||||
remoteFile = fillOCFile(we);
|
||||
remoteFile = fillOCFile(file);
|
||||
remoteFile.setParentId(mLocalFolder.getFileId());
|
||||
|
||||
/// retrieve local data for the read file
|
||||
|
@ -463,7 +402,7 @@ public class SynchronizeFolderOperation extends RemoteOperation {
|
|||
return (status == HttpStatus.SC_MULTI_STATUS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates and populates a new {@link OCFile} object with the data read from the server.
|
||||
*
|
||||
|
@ -479,6 +418,22 @@ public class SynchronizeFolderOperation extends RemoteOperation {
|
|||
file.setEtag(we.etag());
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and populates a new {@link OCFile} object with the data read from the server.
|
||||
*
|
||||
* @param remote remote file read from the server (remote file or folder).
|
||||
* @return New OCFile instance representing the remote resource described by we.
|
||||
*/
|
||||
private OCFile fillOCFile(RemoteFile remote) {
|
||||
OCFile file = new OCFile(remote.getRemotePath());
|
||||
file.setCreationTimestamp(remote.getCreationTimestamp());
|
||||
file.setFileLength(remote.getLength());
|
||||
file.setMimetype(remote.getMimeType());
|
||||
file.setModificationTimestamp(remote.getModifiedTimestamp());
|
||||
file.setEtag(remote.getEtag());
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue