mirror of
https://github.com/nextcloud/android.git
synced 2024-11-23 21:55:48 +03:00
Merge branch 'develop' into refactor_remote_operation_to_read_file
Conflicts: oc_framework/src/com/owncloud/android/oc_framework/operations/RemoteFile.java oc_framework/src/com/owncloud/android/oc_framework/operations/RemoteOperationResult.java oc_framework/src/com/owncloud/android/oc_framework/utils/FileUtils.java src/com/owncloud/android/operations/SynchronizeFolderOperation.java
This commit is contained in:
commit
39c2fffbfe
13 changed files with 460 additions and 141 deletions
|
@ -0,0 +1,61 @@
|
||||||
|
/* ownCloud Android client application
|
||||||
|
* Copyright (C) 2012-2013 ownCloud Inc.
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.owncloud.android.oc_framework_test_project.test;
|
||||||
|
|
||||||
|
import com.owncloud.android.oc_framework.operations.RemoteOperationResult;
|
||||||
|
import com.owncloud.android.oc_framework_test_project.TestActivity;
|
||||||
|
|
||||||
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to test Read File Operation
|
||||||
|
* @author masensio
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ReadFileTest extends ActivityInstrumentationTestCase2<TestActivity> {
|
||||||
|
|
||||||
|
/* File data to read. This file must exist on the account */
|
||||||
|
private final String mRemoteFolderPath = "/fileToRead.txt";
|
||||||
|
|
||||||
|
|
||||||
|
private TestActivity mActivity;
|
||||||
|
|
||||||
|
public ReadFileTest() {
|
||||||
|
super(TestActivity.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
setActivityInitialTouchMode(false);
|
||||||
|
mActivity = getActivity();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Read File
|
||||||
|
*/
|
||||||
|
public void testReadFile() {
|
||||||
|
|
||||||
|
RemoteOperationResult result = mActivity.readFile(mRemoteFolderPath);
|
||||||
|
assertTrue(result.getData().size() == 1);
|
||||||
|
assertTrue(result.isSuccess());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.owncloud.android.oc_framework_test_project.test;
|
||||||
|
|
||||||
|
|
||||||
|
import com.owncloud.android.oc_framework.operations.RemoteOperationResult;
|
||||||
|
import com.owncloud.android.oc_framework_test_project.TestActivity;
|
||||||
|
|
||||||
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to test Read Folder Operation
|
||||||
|
* @author masensio
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ReadFolderTest extends ActivityInstrumentationTestCase2<TestActivity> {
|
||||||
|
|
||||||
|
|
||||||
|
/* Folder data to read. This folder must exist on the account */
|
||||||
|
private final String mRemoteFolderPath = "/folderToRead";
|
||||||
|
|
||||||
|
|
||||||
|
private TestActivity mActivity;
|
||||||
|
|
||||||
|
public ReadFolderTest() {
|
||||||
|
super(TestActivity.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
setActivityInitialTouchMode(false);
|
||||||
|
mActivity = getActivity();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Read Folder
|
||||||
|
*/
|
||||||
|
public void testReadFolder() {
|
||||||
|
|
||||||
|
RemoteOperationResult result = mActivity.readFile(mRemoteFolderPath);
|
||||||
|
assertTrue(result.getData().size() > 1);
|
||||||
|
assertTrue(result.getData().size() == 4);
|
||||||
|
assertTrue(result.isSuccess());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,6 +6,12 @@ import com.owncloud.android.oc_framework_test_project.TestActivity;
|
||||||
|
|
||||||
import android.test.ActivityInstrumentationTestCase2;
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to test Rename File Operation
|
||||||
|
* @author masensio
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
public class RenameFileTest extends ActivityInstrumentationTestCase2<TestActivity> {
|
public class RenameFileTest extends ActivityInstrumentationTestCase2<TestActivity> {
|
||||||
|
|
||||||
/* Folder data to rename. This folder must exist on the account */
|
/* Folder data to rename. This folder must exist on the account */
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.owncloud.android.oc_framework.network.webdav.OwnCloudClientFactory;
|
||||||
import com.owncloud.android.oc_framework.network.webdav.WebdavClient;
|
import com.owncloud.android.oc_framework.network.webdav.WebdavClient;
|
||||||
import com.owncloud.android.oc_framework.operations.RemoteOperationResult;
|
import com.owncloud.android.oc_framework.operations.RemoteOperationResult;
|
||||||
import com.owncloud.android.oc_framework.operations.remote.CreateRemoteFolderOperation;
|
import com.owncloud.android.oc_framework.operations.remote.CreateRemoteFolderOperation;
|
||||||
|
import com.owncloud.android.oc_framework.operations.remote.ReadRemoteFolderOperation;
|
||||||
import com.owncloud.android.oc_framework.operations.remote.RemoveRemoteFileOperation;
|
import com.owncloud.android.oc_framework.operations.remote.RemoveRemoteFileOperation;
|
||||||
import com.owncloud.android.oc_framework.operations.remote.RenameRemoteFileOperation;
|
import com.owncloud.android.oc_framework.operations.remote.RenameRemoteFileOperation;
|
||||||
|
|
||||||
|
@ -90,5 +91,18 @@ public class TestActivity extends Activity {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access to the library method to Read a Folder (PROPFIND DEPTH 1)
|
||||||
|
* @param remotePath
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public RemoteOperationResult readFile(String remotePath) {
|
||||||
|
|
||||||
|
ReadRemoteFolderOperation readOperation= new ReadRemoteFolderOperation(remotePath);
|
||||||
|
RemoteOperationResult result = readOperation.execute(mClient);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
package com.owncloud.android.oc_framework.network;
|
|
||||||
/* ownCloud Android client application
|
/* ownCloud Android client application
|
||||||
* Copyright (C) 2012 ownCloud Inc.
|
* Copyright (C) 2012 ownCloud Inc.
|
||||||
*
|
*
|
||||||
|
@ -17,6 +16,7 @@ package com.owncloud.android.oc_framework.network;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package com.owncloud.android.oc_framework.network;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
|
@ -32,84 +32,84 @@ import com.owncloud.android.oc_framework.utils.FileUtils;
|
||||||
|
|
||||||
public class RemoteFile implements Parcelable, Serializable {
|
public class RemoteFile implements Parcelable, Serializable {
|
||||||
|
|
||||||
/** Generated - should be refreshed every time the class changes!! */
|
/** Generated - should be refreshed every time the class changes!! */
|
||||||
private static final long serialVersionUID = 7256606476031992757L;
|
private static final long serialVersionUID = 7256606476031992757L;
|
||||||
|
|
||||||
private String mRemotePath;
|
private String mRemotePath;
|
||||||
private String mMimeType;
|
private String mMimeType;
|
||||||
private long mLength;
|
private long mLength;
|
||||||
private long mCreationTimestamp;
|
private long mCreationTimestamp;
|
||||||
private long mModifiedTimestamp;
|
private long mModifiedTimestamp;
|
||||||
private String mEtag;
|
private String mEtag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Getters and Setters
|
* Getters and Setters
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public String getRemotePath() {
|
public String getRemotePath() {
|
||||||
return mRemotePath;
|
return mRemotePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRemotePath(String remotePath) {
|
public void setRemotePath(String remotePath) {
|
||||||
this.mRemotePath = remotePath;
|
this.mRemotePath = remotePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMimeType() {
|
public String getMimeType() {
|
||||||
return mMimeType;
|
return mMimeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMimeType(String mimeType) {
|
public void setMimeType(String mimeType) {
|
||||||
this.mMimeType = mimeType;
|
this.mMimeType = mimeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getLength() {
|
public long getLength() {
|
||||||
return mLength;
|
return mLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLength(long length) {
|
public void setLength(long length) {
|
||||||
this.mLength = length;
|
this.mLength = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getCreationTimestamp() {
|
public long getCreationTimestamp() {
|
||||||
return mCreationTimestamp;
|
return mCreationTimestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCreationTimestamp(long creationTimestamp) {
|
public void setCreationTimestamp(long creationTimestamp) {
|
||||||
this.mCreationTimestamp = creationTimestamp;
|
this.mCreationTimestamp = creationTimestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getModifiedTimestamp() {
|
public long getModifiedTimestamp() {
|
||||||
return mModifiedTimestamp;
|
return mModifiedTimestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setModifiedTimestamp(long modifiedTimestamp) {
|
public void setModifiedTimestamp(long modifiedTimestamp) {
|
||||||
this.mModifiedTimestamp = modifiedTimestamp;
|
this.mModifiedTimestamp = modifiedTimestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getEtag() {
|
public String getEtag() {
|
||||||
return mEtag;
|
return mEtag;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEtag(String etag) {
|
public void setEtag(String etag) {
|
||||||
this.mEtag = etag;
|
this.mEtag = etag;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new {@link RemoteFile} with given path.
|
* 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'.
|
* 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.
|
* @param path The remote path of the file.
|
||||||
*/
|
*/
|
||||||
public RemoteFile(String path) {
|
public RemoteFile(String path) {
|
||||||
resetData();
|
resetData();
|
||||||
if (path == null || path.length() <= 0 || !path.startsWith(FileUtils.PATH_SEPARATOR)) {
|
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);
|
throw new IllegalArgumentException("Trying to create a OCFile with a non valid remote path: " + path);
|
||||||
}
|
}
|
||||||
mRemotePath = path;
|
mRemotePath = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used internally. Reset all file properties
|
* Used internally. Reset all file properties
|
||||||
*/
|
*/
|
||||||
private void resetData() {
|
private void resetData() {
|
||||||
|
@ -151,20 +151,20 @@ public class RemoteFile implements Parcelable, Serializable {
|
||||||
mEtag = source.readString();
|
mEtag = source.readString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int describeContents() {
|
public int describeContents() {
|
||||||
return this.hashCode();
|
return this.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeToParcel(Parcel dest, int flags) {
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
dest.writeString(mRemotePath);
|
dest.writeString(mRemotePath);
|
||||||
dest.writeString(mMimeType);
|
dest.writeString(mMimeType);
|
||||||
dest.writeLong(mLength);
|
dest.writeLong(mLength);
|
||||||
dest.writeLong(mCreationTimestamp);
|
dest.writeLong(mCreationTimestamp);
|
||||||
dest.writeLong(mModifiedTimestamp);
|
dest.writeLong(mModifiedTimestamp);
|
||||||
dest.writeString(mEtag);
|
dest.writeString(mEtag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,8 +52,8 @@ import android.util.Log;
|
||||||
*/
|
*/
|
||||||
public class RemoteOperationResult implements Serializable {
|
public class RemoteOperationResult implements Serializable {
|
||||||
|
|
||||||
/** Generated - should be refreshed every time the class changes!! */
|
/** Generated - should be refreshed every time the class changes!! */
|
||||||
private static final long serialVersionUID = -2469951225222759283L;
|
private static final long serialVersionUID = -2469951225222759283L;
|
||||||
|
|
||||||
private static final String TAG = "RemoteOperationResult";
|
private static final String TAG = "RemoteOperationResult";
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ public class RemoteOperationResult implements Serializable {
|
||||||
private String mRedirectedLocation;
|
private String mRedirectedLocation;
|
||||||
|
|
||||||
private ArrayList<RemoteFile> mFiles;
|
private ArrayList<RemoteFile> mFiles;
|
||||||
|
|
||||||
public RemoteOperationResult(ResultCode code) {
|
public RemoteOperationResult(ResultCode code) {
|
||||||
mCode = code;
|
mCode = code;
|
||||||
mSuccess = (code == ResultCode.OK || code == ResultCode.OK_SSL || code == ResultCode.OK_NO_SSL);
|
mSuccess = (code == ResultCode.OK || code == ResultCode.OK_SSL || code == ResultCode.OK_NO_SSL);
|
||||||
|
@ -200,12 +200,12 @@ public class RemoteOperationResult implements Serializable {
|
||||||
|
|
||||||
|
|
||||||
public void setData(ArrayList<RemoteFile> files){
|
public void setData(ArrayList<RemoteFile> files){
|
||||||
mFiles = files;
|
mFiles = files;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<RemoteFile> getData(){
|
public ArrayList<RemoteFile> getData(){
|
||||||
return mFiles;
|
return mFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSuccess() {
|
public boolean isSuccess() {
|
||||||
return mSuccess;
|
return mSuccess;
|
||||||
|
@ -349,4 +349,4 @@ public class RemoteOperationResult implements Serializable {
|
||||||
mRedirectedLocation.toLowerCase().contains("wayf")));
|
mRedirectedLocation.toLowerCase().contains("wayf")));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,20 @@
|
||||||
|
/* ownCloud Android client application
|
||||||
|
* Copyright (C) 2012-2013 ownCloud Inc.
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
package com.owncloud.android.oc_framework.operations.remote;
|
package com.owncloud.android.oc_framework.operations.remote;
|
||||||
|
|
||||||
import org.apache.commons.httpclient.HttpStatus;
|
import org.apache.commons.httpclient.HttpStatus;
|
||||||
|
|
|
@ -0,0 +1,162 @@
|
||||||
|
/* ownCloud Android client application
|
||||||
|
* Copyright (C) 2012-2013 ownCloud Inc.
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remote operation performing the read of remote file or folder in the ownCloud server.
|
||||||
|
*
|
||||||
|
* @author David A. Velasco
|
||||||
|
* @author masensio
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ReadRemoteFolderOperation extends RemoteOperation {
|
||||||
|
|
||||||
|
private static final String TAG = ReadRemoteFolderOperation.class.getSimpleName();
|
||||||
|
|
||||||
|
private String mRemotePath;
|
||||||
|
private ArrayList<RemoteFile> mFolderAndFiles;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param remotePath Remote path of the file.
|
||||||
|
*/
|
||||||
|
public ReadRemoteFolderOperation(String remotePath) {
|
||||||
|
mRemotePath = remotePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the read operation.
|
||||||
|
*
|
||||||
|
* @param client Client object to communicate with the remote ownCloud server.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected RemoteOperationResult run(WebdavClient client) {
|
||||||
|
RemoteOperationResult result = null;
|
||||||
|
PropFindMethod query = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// remote request
|
||||||
|
query = new PropFindMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemotePath),
|
||||||
|
DavConstants.PROPFIND_ALL_PROP,
|
||||||
|
DavConstants.DEPTH_1);
|
||||||
|
int status = client.executeMethod(query);
|
||||||
|
|
||||||
|
// check and process response
|
||||||
|
if (isMultiStatus(status)) {
|
||||||
|
// get data from remote folder
|
||||||
|
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.setData(mFolderAndFiles);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// synchronization failed
|
||||||
|
client.exhaustResponse(query.getResponseBodyAsStream());
|
||||||
|
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.i(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage());
|
||||||
|
} else {
|
||||||
|
if (result.isException()) {
|
||||||
|
Log.e(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage(), result.getException());
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
mFolderAndFiles = new ArrayList<RemoteFile>();
|
||||||
|
|
||||||
|
// parse data from remote folder
|
||||||
|
WebdavEntry we = new WebdavEntry(dataInServer.getResponses()[0], client.getBaseUri().getPath());
|
||||||
|
mFolderAndFiles.add(fillOCFile(we));
|
||||||
|
|
||||||
|
// loop to update every child
|
||||||
|
RemoteFile remoteFile = null;
|
||||||
|
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);
|
||||||
|
mFolderAndFiles.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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,20 @@
|
||||||
|
/* ownCloud Android client application
|
||||||
|
* Copyright (C) 2012-2013 ownCloud Inc.
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
package com.owncloud.android.oc_framework.operations.remote;
|
package com.owncloud.android.oc_framework.operations.remote;
|
||||||
|
|
||||||
import org.apache.commons.httpclient.HttpStatus;
|
import org.apache.commons.httpclient.HttpStatus;
|
||||||
|
|
|
@ -1,3 +1,20 @@
|
||||||
|
/* ownCloud Android client application
|
||||||
|
* Copyright (C) 2012-2013 ownCloud Inc.
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
package com.owncloud.android.oc_framework.operations.remote;
|
package com.owncloud.android.oc_framework.operations.remote;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.owncloud.android.oc_framework.utils;
|
package com.owncloud.android.oc_framework.utils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
|
@ -23,16 +23,13 @@ import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
import org.apache.http.HttpStatus;
|
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;
|
import android.accounts.Account;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
@ -41,11 +38,12 @@ import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||||
import com.owncloud.android.datamodel.OCFile;
|
import com.owncloud.android.datamodel.OCFile;
|
||||||
import com.owncloud.android.oc_framework.network.webdav.WebdavClient;
|
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.WebdavEntry;
|
||||||
import com.owncloud.android.oc_framework.network.webdav.WebdavUtils;
|
|
||||||
import com.owncloud.android.oc_framework.operations.RemoteOperation;
|
import com.owncloud.android.oc_framework.operations.RemoteOperation;
|
||||||
import com.owncloud.android.oc_framework.operations.RemoteOperationResult;
|
import com.owncloud.android.oc_framework.operations.RemoteOperationResult;
|
||||||
import com.owncloud.android.oc_framework.operations.RemoteOperationResult.ResultCode;
|
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.remote.ReadRemoteFileOperation;
|
||||||
|
import com.owncloud.android.oc_framework.operations.remote.ReadRemoteFolderOperation;
|
||||||
|
import com.owncloud.android.oc_framework.operations.RemoteFile;
|
||||||
import com.owncloud.android.syncadapter.FileSyncService;
|
import com.owncloud.android.syncadapter.FileSyncService;
|
||||||
import com.owncloud.android.utils.FileStorageUtils;
|
import com.owncloud.android.utils.FileStorageUtils;
|
||||||
import com.owncloud.android.utils.Log_OC;
|
import com.owncloud.android.utils.Log_OC;
|
||||||
|
@ -220,59 +218,25 @@ public class SynchronizeFolderOperation extends RemoteOperation {
|
||||||
|
|
||||||
|
|
||||||
private RemoteOperationResult fetchAndSyncRemoteFolder(WebdavClient client) {
|
private RemoteOperationResult fetchAndSyncRemoteFolder(WebdavClient client) {
|
||||||
RemoteOperationResult result = null;
|
String remotePath = mLocalFolder.getRemotePath();
|
||||||
String remotePath = null;
|
ReadRemoteFolderOperation operation = new ReadRemoteFolderOperation(remotePath);
|
||||||
PropFindMethod query = null;
|
RemoteOperationResult result = operation.execute(client);
|
||||||
try {
|
Log_OC.d(TAG, "Synchronizing " + mAccount.name + remotePath);
|
||||||
remotePath = mLocalFolder.getRemotePath();
|
|
||||||
Log_OC.d(TAG, "Synchronizing " + mAccount.name + remotePath);
|
if (result.isSuccess()) {
|
||||||
|
synchronizeData(result.getData(), client);
|
||||||
// remote request
|
if (mConflictsFound > 0 || mFailsInFavouritesFound > 0) {
|
||||||
query = new PropFindMethod(client.getBaseUri() + WebdavUtils.encodePath(remotePath),
|
result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT); // should be different result, but will do the job
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
} catch (Exception e) {
|
if (result.getCode() == ResultCode.FILE_NOT_FOUND)
|
||||||
result = new RemoteOperationResult(e);
|
removeLocalFolder();
|
||||||
|
|
||||||
|
|
||||||
} 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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void removeLocalFolder() {
|
private void removeLocalFolder() {
|
||||||
if (mStorageManager.fileExists(mLocalFolder.getFileId())) {
|
if (mStorageManager.fileExists(mLocalFolder.getFileId())) {
|
||||||
String currentSavePath = FileStorageUtils.getSavePath(mAccount.name);
|
String currentSavePath = FileStorageUtils.getSavePath(mAccount.name);
|
||||||
|
@ -286,26 +250,25 @@ public class SynchronizeFolderOperation extends RemoteOperation {
|
||||||
* with the current data in the local database.
|
* with the current data in the local database.
|
||||||
*
|
*
|
||||||
* Grants that mChildren is updated with fresh data after execution.
|
* Grants that mChildren is updated with fresh data after execution.
|
||||||
*
|
*
|
||||||
* @param dataInServer Full response got from the server with the data of the target
|
* @param folderAndFiles Remote folder and children files in Folder
|
||||||
* folder and its direct children.
|
*
|
||||||
* @param client Client instance to the remote server where the data were
|
* @param client Client instance to the remote server where the data were
|
||||||
* retrieved.
|
* retrieved.
|
||||||
* @return 'True' when any change was made in the local data, 'false' otherwise.
|
* @return 'True' when any change was made in the local data, 'false' otherwise.
|
||||||
*/
|
*/
|
||||||
private void synchronizeData(MultiStatus dataInServer, WebdavClient client) {
|
private void synchronizeData(ArrayList<RemoteFile> folderAndFiles, WebdavClient client) {
|
||||||
// get 'fresh data' from the database
|
// get 'fresh data' from the database
|
||||||
mLocalFolder = mStorageManager.getFileByPath(mLocalFolder.getRemotePath());
|
mLocalFolder = mStorageManager.getFileByPath(mLocalFolder.getRemotePath());
|
||||||
|
|
||||||
// parse data from remote folder
|
// parse data from remote folder
|
||||||
WebdavEntry we = new WebdavEntry(dataInServer.getResponses()[0], client.getBaseUri().getPath());
|
OCFile remoteFolder = fillOCFile(folderAndFiles.get(0));
|
||||||
OCFile remoteFolder = fillOCFile(we);
|
|
||||||
remoteFolder.setParentId(mLocalFolder.getParentId());
|
remoteFolder.setParentId(mLocalFolder.getParentId());
|
||||||
remoteFolder.setFileId(mLocalFolder.getFileId());
|
remoteFolder.setFileId(mLocalFolder.getFileId());
|
||||||
|
|
||||||
Log_OC.d(TAG, "Remote folder " + mLocalFolder.getRemotePath() + " changed - starting update of local data ");
|
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>(folderAndFiles.size() - 1);
|
||||||
List<SynchronizeFileOperation> filesToSyncContents = new Vector<SynchronizeFileOperation>();
|
List<SynchronizeFileOperation> filesToSyncContents = new Vector<SynchronizeFileOperation>();
|
||||||
|
|
||||||
// get current data about local contents of the folder to synchronize
|
// get current data about local contents of the folder to synchronize
|
||||||
|
@ -317,10 +280,9 @@ public class SynchronizeFolderOperation extends RemoteOperation {
|
||||||
|
|
||||||
// loop to update every child
|
// loop to update every child
|
||||||
OCFile remoteFile = null, localFile = null;
|
OCFile remoteFile = null, localFile = null;
|
||||||
for (int i = 1; i < dataInServer.getResponses().length; ++i) {
|
for (int i=1; i<folderAndFiles.size(); i++) {
|
||||||
/// new OCFile instance with the data from the server
|
/// new OCFile instance with the data from the server
|
||||||
we = new WebdavEntry(dataInServer.getResponses()[i], client.getBaseUri().getPath());
|
remoteFile = fillOCFile(folderAndFiles.get(i));
|
||||||
remoteFile = fillOCFile(we);
|
|
||||||
remoteFile.setParentId(mLocalFolder.getFileId());
|
remoteFile.setParentId(mLocalFolder.getFileId());
|
||||||
|
|
||||||
/// retrieve local data for the read file
|
/// retrieve local data for the read file
|
||||||
|
@ -411,7 +373,7 @@ public class SynchronizeFolderOperation extends RemoteOperation {
|
||||||
return (status == HttpStatus.SC_MULTI_STATUS);
|
return (status == HttpStatus.SC_MULTI_STATUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and populates a new {@link OCFile} object with the data read from the server.
|
* Creates and populates a new {@link OCFile} object with the data read from the server.
|
||||||
*
|
*
|
||||||
|
@ -427,6 +389,22 @@ public class SynchronizeFolderOperation extends RemoteOperation {
|
||||||
file.setEtag(we.etag());
|
file.setEtag(we.etag());
|
||||||
return file;
|
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