From: masensio Date: Wed, 18 Dec 2013 09:04:42 +0000 (+0100) Subject: Merge branch 'develop' into refactor_remote_operation_to_download_file X-Git-Tag: oc-android-1.5.5~100^2 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/71430eb7b15c982cb6b634efa5cac8348b2cd22c?hp=1638de66f717c2b4438d92a4259bd2a974b01a7d Merge branch 'develop' into refactor_remote_operation_to_download_file Conflicts: oc_framework-test-project/AndroidManifest.xml oc_framework-test-project/src/com/owncloud/android/oc_framework_test_project/TestActivity.java --- diff --git a/oc_framework-test-project/AndroidManifest.xml b/oc_framework-test-project/AndroidManifest.xml index 2d296ede..3c98ffe1 100644 --- a/oc_framework-test-project/AndroidManifest.xml +++ b/oc_framework-test-project/AndroidManifest.xml @@ -12,8 +12,8 @@ - - diff --git a/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/CreateFolderTest.java b/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/CreateFolderTest.java index 84145022..0c099b15 100644 --- a/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/CreateFolderTest.java +++ b/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/CreateFolderTest.java @@ -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 . + * + */ + package com.owncloud.android.oc_framework_test_project.test; import java.text.SimpleDateFormat; diff --git a/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/DeleteFileTest.java b/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/DeleteFileTest.java index b8ab2b0c..2086257d 100644 --- a/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/DeleteFileTest.java +++ b/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/DeleteFileTest.java @@ -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 . + * + */ + package com.owncloud.android.oc_framework_test_project.test; import com.owncloud.android.oc_framework.operations.RemoteOperationResult; @@ -6,6 +23,12 @@ import com.owncloud.android.oc_framework_test_project.TestActivity; import android.test.ActivityInstrumentationTestCase2; +/** + * Class to test Delete a File Operation + * @author masensio + * + */ + public class DeleteFileTest extends ActivityInstrumentationTestCase2 { /* Folder data to delete. */ diff --git a/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/DownloadFileTest.java b/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/DownloadFileTest.java new file mode 100644 index 00000000..74cfb400 --- /dev/null +++ b/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/DownloadFileTest.java @@ -0,0 +1,125 @@ +/* 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 . + * + */ + +package com.owncloud.android.oc_framework_test_project.test; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import com.owncloud.android.oc_framework.operations.RemoteFile; +import com.owncloud.android.oc_framework.operations.RemoteOperationResult; +import com.owncloud.android.oc_framework_test_project.TestActivity; + +import android.test.ActivityInstrumentationTestCase2; +import android.util.Log; + +/** + * Class to test Download File Operation + * @author masensio + * + */ + +public class DownloadFileTest extends ActivityInstrumentationTestCase2 { + + private final String TAG = DownloadFileTest.class.getSimpleName(); + + /* Files to download. These files must exist on the account */ + private final String mRemoteFilePng = "/fileToDownload.png"; + private final String mRemoteFileChunks = "/fileToDownload.mp4"; + private final String mRemoteFileSpecialChars = "/@file@download.png"; + private final String mRemoteFileSpecialCharsChunks = "/@file@download.mp4"; + private final String mRemoteFileNotFound = "/fileNotFound.png"; /* This file mustn't exist on the account */ + + private String mCurrentDate; + + + private TestActivity mActivity; + + public DownloadFileTest() { + super(TestActivity.class); + + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss"); + mCurrentDate = sdf.format(new Date()); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + setActivityInitialTouchMode(false); + mActivity = getActivity(); + } + + /** + * Test Download a File + */ + public void testDownloadFile() { + String temporalFolder = "/download" + mCurrentDate; + + RemoteFile remoteFile= new RemoteFile(mRemoteFilePng); + + RemoteOperationResult result = mActivity.downloadFile(remoteFile, temporalFolder); + assertTrue(result.isSuccess()); + } + + /** + * Test Download a File with chunks + */ + public void testDownloadFileChunks() { + String temporalFolder = "/download" + mCurrentDate; + + RemoteFile remoteFile= new RemoteFile(mRemoteFileChunks); + + RemoteOperationResult result = mActivity.downloadFile(remoteFile, temporalFolder); + assertTrue(result.isSuccess()); + } + + /** + * Test Download a File with special chars + */ + public void testDownloadFileSpecialChars() { + String temporalFolder = "/download" + mCurrentDate; + + RemoteFile remoteFile= new RemoteFile(mRemoteFileSpecialChars); + + RemoteOperationResult result = mActivity.downloadFile(remoteFile, temporalFolder); + assertTrue(result.isSuccess()); + } + + /** + * Test Download a File with special chars and chunks + */ + public void testDownloadFileSpecialCharsChunks() { + String temporalFolder = "/download" + mCurrentDate; + + RemoteFile remoteFile= new RemoteFile(mRemoteFileSpecialCharsChunks); + + RemoteOperationResult result = mActivity.downloadFile(remoteFile, temporalFolder); + assertTrue(result.isSuccess()); + } + + /** + * Test Download a Not Found File + */ + public void testDownloadFileNotFound() { + String temporalFolder = "/download" + mCurrentDate; + + RemoteFile remoteFile = new RemoteFile(mRemoteFileNotFound); + + RemoteOperationResult result = mActivity.downloadFile(remoteFile, temporalFolder); + assertFalse(result.isSuccess()); + } +} diff --git a/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/ReadFolderTest.java b/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/ReadFolderTest.java index c3399158..ed9ccef6 100644 --- a/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/ReadFolderTest.java +++ b/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/ReadFolderTest.java @@ -1,5 +1,21 @@ -package com.owncloud.android.oc_framework_test_project.test; +/* 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 . + * + */ +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; diff --git a/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/RenameFileTest.java b/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/RenameFileTest.java index e21c6ff8..7de35535 100644 --- a/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/RenameFileTest.java +++ b/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/RenameFileTest.java @@ -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 . + * + */ + package com.owncloud.android.oc_framework_test_project.test; import com.owncloud.android.oc_framework.operations.RemoteOperationResult; diff --git a/oc_framework-test-project/src/com/owncloud/android/oc_framework_test_project/TestActivity.java b/oc_framework-test-project/src/com/owncloud/android/oc_framework_test_project/TestActivity.java index c42aca2e..11f74cf2 100644 --- a/oc_framework-test-project/src/com/owncloud/android/oc_framework_test_project/TestActivity.java +++ b/oc_framework-test-project/src/com/owncloud/android/oc_framework_test_project/TestActivity.java @@ -1,10 +1,31 @@ +/* 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 . + * + */ + package com.owncloud.android.oc_framework_test_project; +import java.io.File; + import com.owncloud.android.oc_framework.network.webdav.OwnCloudClientFactory; import com.owncloud.android.oc_framework.network.webdav.WebdavClient; +import com.owncloud.android.oc_framework.operations.RemoteFile; import com.owncloud.android.oc_framework.operations.RemoteOperationResult; import com.owncloud.android.oc_framework.operations.remote.ChunkedUploadRemoteFileOperation; import com.owncloud.android.oc_framework.operations.remote.CreateRemoteFolderOperation; +import com.owncloud.android.oc_framework.operations.remote.DownloadRemoteFileOperation; 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.RenameRemoteFileOperation; @@ -12,6 +33,7 @@ import com.owncloud.android.oc_framework.operations.remote.UploadRemoteFileOpera import android.net.Uri; import android.os.Bundle; +import android.os.Environment; import android.app.Activity; import android.view.Menu; @@ -20,6 +42,7 @@ import android.view.Menu; * @author masensio * @author David A. Velasco */ + public class TestActivity extends Activity { // This account must exists on the simulator / device @@ -108,6 +131,25 @@ public class TestActivity extends Activity { return result; } + /** + * Access to the library method to Download a File + * @param remotePath + * + * @return + */ + public RemoteOperationResult downloadFile(RemoteFile remoteFile, String temporalFolder) { + // Create folder + String path = "/owncloud/tmp/" + temporalFolder; + File sdCard = Environment.getExternalStorageDirectory(); + File folder = new File(sdCard.getAbsolutePath() + "/" + path); + folder.mkdirs(); + + DownloadRemoteFileOperation downloadOperation = new DownloadRemoteFileOperation(remoteFile, folder.getAbsolutePath()); + RemoteOperationResult result = downloadOperation.execute(mClient); + + return result; + } + /** Access to the library method to Upload a File * @param storagePath * @param remotePath diff --git a/oc_framework/src/com/owncloud/android/oc_framework/operations/remote/DownloadRemoteFileOperation.java b/oc_framework/src/com/owncloud/android/oc_framework/operations/remote/DownloadRemoteFileOperation.java new file mode 100644 index 00000000..e3e7ee07 --- /dev/null +++ b/oc_framework/src/com/owncloud/android/oc_framework/operations/remote/DownloadRemoteFileOperation.java @@ -0,0 +1,169 @@ +/* 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 . + * + */ + +package com.owncloud.android.oc_framework.operations.remote; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.http.HttpStatus; + +import android.util.Log; + +import com.owncloud.android.oc_framework.network.webdav.OnDatatransferProgressListener; +import com.owncloud.android.oc_framework.network.webdav.WebdavClient; +import com.owncloud.android.oc_framework.network.webdav.WebdavUtils; +import com.owncloud.android.oc_framework.operations.OperationCancelledException; +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 download of a remote file in the ownCloud server. + * + * @author David A. Velasco + * @author masensio + */ + +public class DownloadRemoteFileOperation extends RemoteOperation { + + private static final String TAG = DownloadRemoteFileOperation.class.getSimpleName(); + + private Set mDataTransferListeners = new HashSet(); + private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); + private long mModificationTimestamp = 0; + private GetMethod mGet; + + private RemoteFile mRemoteFile; + private String mTemporalFolder; + + public DownloadRemoteFileOperation(RemoteFile remoteFile, String temporalFolder) { + mRemoteFile = remoteFile; + mTemporalFolder = temporalFolder; + } + + @Override + protected RemoteOperationResult run(WebdavClient client) { + RemoteOperationResult result = null; + + /// download will be performed to a temporal file, then moved to the final location + File tmpFile = new File(getTmpPath()); + + /// perform the download + try { + tmpFile.getParentFile().mkdirs(); + int status = downloadFile(client, tmpFile); + result = new RemoteOperationResult(isSuccess(status), status, (mGet != null ? mGet.getResponseHeaders() : null)); + Log.i(TAG, "Download of " + mRemoteFile.getRemotePath() + " to " + getTmpPath() + ": " + result.getLogMessage()); + + } catch (Exception e) { + result = new RemoteOperationResult(e); + Log.e(TAG, "Download of " + mRemoteFile.getRemotePath() + " to " + getTmpPath() + ": " + result.getLogMessage(), e); + } + + return result; + } + + + protected int downloadFile(WebdavClient client, File targetFile) throws HttpException, IOException, OperationCancelledException { + int status = -1; + boolean savedFile = false; + mGet = new GetMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemoteFile.getRemotePath())); + Iterator it = null; + + FileOutputStream fos = null; + try { + status = client.executeMethod(mGet); + if (isSuccess(status)) { + targetFile.createNewFile(); + BufferedInputStream bis = new BufferedInputStream(mGet.getResponseBodyAsStream()); + fos = new FileOutputStream(targetFile); + long transferred = 0; + + byte[] bytes = new byte[4096]; + int readResult = 0; + while ((readResult = bis.read(bytes)) != -1) { + synchronized(mCancellationRequested) { + if (mCancellationRequested.get()) { + mGet.abort(); + throw new OperationCancelledException(); + } + } + fos.write(bytes, 0, readResult); + transferred += readResult; + synchronized (mDataTransferListeners) { + it = mDataTransferListeners.iterator(); + while (it.hasNext()) { + it.next().onTransferProgress(readResult, transferred, mRemoteFile.getLength(), targetFile.getName()); + } + } + } + savedFile = true; + Header modificationTime = mGet.getResponseHeader("Last-Modified"); + if (modificationTime != null) { + Date d = WebdavUtils.parseResponseDate((String) modificationTime.getValue()); + mModificationTimestamp = (d != null) ? d.getTime() : 0; + } + + } else { + client.exhaustResponse(mGet.getResponseBodyAsStream()); + } + + } finally { + if (fos != null) fos.close(); + if (!savedFile && targetFile.exists()) { + targetFile.delete(); + } + mGet.releaseConnection(); // let the connection available for other methods + } + return status; + } + + private boolean isSuccess(int status) { + return (status == HttpStatus.SC_OK); + } + + private String getTmpPath() { + return mTemporalFolder + mRemoteFile.getRemotePath(); + } + + public void addDatatransferProgressListener (OnDatatransferProgressListener listener) { + synchronized (mDataTransferListeners) { + mDataTransferListeners.add(listener); + } + } + + public void removeDatatransferProgressListener(OnDatatransferProgressListener listener) { + synchronized (mDataTransferListeners) { + mDataTransferListeners.remove(listener); + } + } + + public void cancel() { + mCancellationRequested.set(true); // atomic set; there is no need of synchronizing it + } +} diff --git a/src/com/owncloud/android/files/services/FileDownloader.java b/src/com/owncloud/android/files/services/FileDownloader.java index 0e7e91be..5d2a8246 100644 --- a/src/com/owncloud/android/files/services/FileDownloader.java +++ b/src/com/owncloud/android/files/services/FileDownloader.java @@ -440,10 +440,10 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer, String fileName) { int percent = (int)(100.0*((double)totalTransferredSoFar)/((double)totalToTransfer)); if (percent != mLastPercent) { - mNotification.contentView.setProgressBar(R.id.status_progress, 100, percent, totalToTransfer < 0); - String text = String.format(getString(R.string.downloader_download_in_progress_content), percent, fileName); - mNotification.contentView.setTextViewText(R.id.status_text, text); - mNotificationManager.notify(R.string.downloader_download_in_progress_ticker, mNotification); + mNotification.contentView.setProgressBar(R.id.status_progress, 100, percent, totalToTransfer < 0); + String text = String.format(getString(R.string.downloader_download_in_progress_content), percent, fileName); + mNotification.contentView.setTextViewText(R.id.status_text, text); + mNotificationManager.notify(R.string.downloader_download_in_progress_ticker, mNotification); } mLastPercent = percent; } diff --git a/src/com/owncloud/android/operations/DownloadFileOperation.java b/src/com/owncloud/android/operations/DownloadFileOperation.java index eb45d4ba..8d89f636 100644 --- a/src/com/owncloud/android/operations/DownloadFileOperation.java +++ b/src/com/owncloud/android/operations/DownloadFileOperation.java @@ -17,28 +17,18 @@ package com.owncloud.android.operations; -import java.io.BufferedInputStream; import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.apache.commons.httpclient.Header; -import org.apache.commons.httpclient.HttpException; -import org.apache.commons.httpclient.methods.GetMethod; -import org.apache.http.HttpStatus; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.oc_framework.network.webdav.OnDatatransferProgressListener; import com.owncloud.android.oc_framework.network.webdav.WebdavClient; -import com.owncloud.android.oc_framework.network.webdav.WebdavUtils; -import com.owncloud.android.oc_framework.operations.OperationCancelledException; +import com.owncloud.android.oc_framework.operations.RemoteFile; import com.owncloud.android.oc_framework.operations.RemoteOperation; import com.owncloud.android.oc_framework.operations.RemoteOperationResult; +import com.owncloud.android.oc_framework.operations.remote.DownloadRemoteFileOperation; import com.owncloud.android.utils.FileStorageUtils; import com.owncloud.android.utils.Log_OC; @@ -46,9 +36,10 @@ import android.accounts.Account; import android.webkit.MimeTypeMap; /** - * Remote operation performing the download of a file to an ownCloud server + * Remote mDownloadOperation performing the download of a file to an ownCloud server * * @author David A. Velasco + * @author masensio */ public class DownloadFileOperation extends RemoteOperation { @@ -57,9 +48,9 @@ public class DownloadFileOperation extends RemoteOperation { private Account mAccount; private OCFile mFile; private Set mDataTransferListeners = new HashSet(); - private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); private long mModificationTimestamp = 0; - private GetMethod mGet; + + private DownloadRemoteFileOperation mDownloadOperation; public DownloadFileOperation(Account account, OCFile file) { @@ -70,6 +61,7 @@ public class DownloadFileOperation extends RemoteOperation { mAccount = account; mFile = file; + } @@ -93,6 +85,10 @@ public class DownloadFileOperation extends RemoteOperation { return FileStorageUtils.getTemporalPath(mAccount.name) + mFile.getRemotePath(); } + public String getTmpFolder() { + return FileStorageUtils.getTemporalPath(mAccount.name); + } + public String getRemotePath() { return mFile.getRemotePath(); } @@ -121,19 +117,6 @@ public class DownloadFileOperation extends RemoteOperation { public long getModificationTimestamp() { return (mModificationTimestamp > 0) ? mModificationTimestamp : mFile.getModificationTimestamp(); } - - - public void addDatatransferProgressListener (OnDatatransferProgressListener listener) { - synchronized (mDataTransferListeners) { - mDataTransferListeners.add(listener); - } - } - - public void removeDatatransferProgressListener(OnDatatransferProgressListener listener) { - synchronized (mDataTransferListeners) { - mDataTransferListeners.remove(listener); - } - } @Override protected RemoteOperationResult run(WebdavClient client) { @@ -144,93 +127,46 @@ public class DownloadFileOperation extends RemoteOperation { /// download will be performed to a temporal file, then moved to the final location File tmpFile = new File(getTmpPath()); + String tmpFolder = getTmpFolder(); + RemoteFile remoteFile = FileStorageUtils.fillRemoteFile(mFile); + /// perform the download - try { - tmpFile.getParentFile().mkdirs(); - int status = downloadFile(client, tmpFile); - if (isSuccess(status)) { - newFile = new File(getSavePath()); - newFile.getParentFile().mkdirs(); - moved = tmpFile.renameTo(newFile); - } + mDownloadOperation = new DownloadRemoteFileOperation(remoteFile, tmpFolder); + Iterator listener = mDataTransferListeners.iterator(); + while (listener.hasNext()) { + mDownloadOperation.addDatatransferProgressListener(listener.next()); + } + result = mDownloadOperation.execute(client); + + if (result.isSuccess()) { + newFile = new File(getSavePath()); + newFile.getParentFile().mkdirs(); + moved = tmpFile.renameTo(newFile); + if (!moved) result = new RemoteOperationResult(RemoteOperationResult.ResultCode.LOCAL_STORAGE_NOT_MOVED); - else - result = new RemoteOperationResult(isSuccess(status), status, (mGet != null ? mGet.getResponseHeaders() : null)); - Log_OC.i(TAG, "Download of " + mFile.getRemotePath() + " to " + getSavePath() + ": " + result.getLogMessage()); - - } catch (Exception e) { - result = new RemoteOperationResult(e); - Log_OC.e(TAG, "Download of " + mFile.getRemotePath() + " to " + getSavePath() + ": " + result.getLogMessage(), e); } + Log_OC.i(TAG, "Download of " + mFile.getRemotePath() + " to " + getSavePath() + ": " + result.getLogMessage()); + return result; } - - public boolean isSuccess(int status) { - return (status == HttpStatus.SC_OK); + public void cancel() { + mDownloadOperation.cancel(); } - - - protected int downloadFile(WebdavClient client, File targetFile) throws HttpException, IOException, OperationCancelledException { - int status = -1; - boolean savedFile = false; - mGet = new GetMethod(client.getBaseUri() + WebdavUtils.encodePath(mFile.getRemotePath())); - Iterator it = null; - - FileOutputStream fos = null; - try { - status = client.executeMethod(mGet); - if (isSuccess(status)) { - targetFile.createNewFile(); - BufferedInputStream bis = new BufferedInputStream(mGet.getResponseBodyAsStream()); - fos = new FileOutputStream(targetFile); - long transferred = 0; - byte[] bytes = new byte[4096]; - int readResult = 0; - while ((readResult = bis.read(bytes)) != -1) { - synchronized(mCancellationRequested) { - if (mCancellationRequested.get()) { - mGet.abort(); - throw new OperationCancelledException(); - } - } - fos.write(bytes, 0, readResult); - transferred += readResult; - synchronized (mDataTransferListeners) { - it = mDataTransferListeners.iterator(); - while (it.hasNext()) { - it.next().onTransferProgress(readResult, transferred, mFile.getFileLength(), targetFile.getName()); - } - } - } - savedFile = true; - Header modificationTime = mGet.getResponseHeader("Last-Modified"); - if (modificationTime != null) { - Date d = WebdavUtils.parseResponseDate((String) modificationTime.getValue()); - mModificationTimestamp = (d != null) ? d.getTime() : 0; - } - - } else { - client.exhaustResponse(mGet.getResponseBodyAsStream()); - } - - } finally { - if (fos != null) fos.close(); - if (!savedFile && targetFile.exists()) { - targetFile.delete(); - } - mGet.releaseConnection(); // let the connection available for other methods + + public void addDatatransferProgressListener (OnDatatransferProgressListener listener) { + synchronized (mDataTransferListeners) { + mDataTransferListeners.add(listener); } - return status; } - - public void cancel() { - mCancellationRequested.set(true); // atomic set; there is no need of synchronizing it + public void removeDatatransferProgressListener(OnDatatransferProgressListener listener) { + synchronized (mDataTransferListeners) { + mDataTransferListeners.remove(listener); + } } - - + } diff --git a/src/com/owncloud/android/utils/FileStorageUtils.java b/src/com/owncloud/android/utils/FileStorageUtils.java index 25206443..16812c65 100644 --- a/src/com/owncloud/android/utils/FileStorageUtils.java +++ b/src/com/owncloud/android/utils/FileStorageUtils.java @@ -22,6 +22,7 @@ import java.io.File; import com.owncloud.android.MainApp; import com.owncloud.android.R; import com.owncloud.android.datamodel.OCFile; +import com.owncloud.android.oc_framework.operations.RemoteFile; import android.annotation.SuppressLint; import android.content.Context; @@ -82,5 +83,22 @@ public class FileStorageUtils { parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : parentPath + OCFile.PATH_SEPARATOR; return parentPath; } + + + /** + * Creates and populates a new {@link RemoteFile} object with the data read from an {@link OCFile}. + * + * @param oCFile OCFile + * @return New RemoteFile instance representing the resource described by ocFile. + */ + public static RemoteFile fillRemoteFile(OCFile ocFile){ + RemoteFile file = new RemoteFile(ocFile.getRemotePath()); + file.setCreationTimestamp(ocFile.getCreationTimestamp()); + file.setLength(ocFile.getFileLength()); + file.setMimeType(ocFile.getMimetype()); + file.setModifiedTimestamp(ocFile.getModificationTimestamp()); + file.setEtag(ocFile.getEtag()); + return file; + } } \ No newline at end of file