From: David A. Velasco Date: Wed, 8 Jan 2014 17:12:06 +0000 (-0800) Subject: Merge pull request #345 from owncloud/fix_pincode_in_instant_uploads X-Git-Tag: oc-android-1.5.5~83 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/56fa4445e857d224398b2ebb8fadb37c6f1325c8?hp=5bab662e90b1f58a9ffee4923433a3e0ee2dac71 Merge pull request #345 from owncloud/fix_pincode_in_instant_uploads Fixed pincode request in instant uploads --- diff --git a/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/ReadFileTest.java b/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/ReadFileTest.java new file mode 100644 index 00000000..b75732b1 --- /dev/null +++ b/oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/ReadFileTest.java @@ -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 . + * + */ + +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 { + + /* 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()); + } + + +} diff --git a/oc_framework/src/com/owncloud/android/oc_framework/operations/RemoteFile.java b/oc_framework/src/com/owncloud/android/oc_framework/operations/RemoteFile.java index 07f45b7b..922b270a 100644 --- a/oc_framework/src/com/owncloud/android/oc_framework/operations/RemoteFile.java +++ b/oc_framework/src/com/owncloud/android/oc_framework/operations/RemoteFile.java @@ -22,6 +22,7 @@ import java.io.Serializable; import android.os.Parcel; import android.os.Parcelable; +import com.owncloud.android.oc_framework.network.webdav.WebdavEntry; import com.owncloud.android.oc_framework.utils.FileUtils; /** @@ -33,7 +34,7 @@ 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 static final long serialVersionUID = 532139091191390616L; private String mRemotePath; private String mMimeType; @@ -108,6 +109,15 @@ public class RemoteFile implements Parcelable, Serializable { } mRemotePath = path; } + + public RemoteFile(WebdavEntry we) { + this(we.decodedPath()); + this.setCreationTimestamp(we.createTimestamp()); + this.setLength(we.contentLength()); + this.setMimeType(we.contentType()); + this.setModifiedTimestamp(we.modifiedTimestamp()); + this.setEtag(we.etag()); + } /** * Used internally. Reset all file properties diff --git a/oc_framework/src/com/owncloud/android/oc_framework/operations/RemoteOperationResult.java b/oc_framework/src/com/owncloud/android/oc_framework/operations/RemoteOperationResult.java index 666e3129..58accf9f 100644 --- a/oc_framework/src/com/owncloud/android/oc_framework/operations/RemoteOperationResult.java +++ b/oc_framework/src/com/owncloud/android/oc_framework/operations/RemoteOperationResult.java @@ -99,7 +99,7 @@ public class RemoteOperationResult implements Serializable { private String mRedirectedLocation; private ArrayList mFiles; - + public RemoteOperationResult(ResultCode code) { mCode = code; mSuccess = (code == ResultCode.OK || code == ResultCode.OK_SSL || code == ResultCode.OK_NO_SSL); @@ -320,7 +320,7 @@ public class RemoteOperationResult implements Serializable { } else if (mCode == ResultCode.ACCOUNT_NOT_THE_SAME) { return "Authenticated with a different account than the one updating"; } else if (mCode == ResultCode.INVALID_CHARACTER_IN_NAME) { - return "The file name contains an forbidden character"; + return "The file name contains an forbidden character"; } return "Operation finished with HTTP status code " + mHttpCode + " (" + (isSuccess() ? "success" : "fail") + ")"; diff --git a/oc_framework/src/com/owncloud/android/oc_framework/operations/remote/ReadRemoteFileOperation.java b/oc_framework/src/com/owncloud/android/oc_framework/operations/remote/ReadRemoteFileOperation.java new file mode 100644 index 00000000..6cdacad8 --- /dev/null +++ b/oc_framework/src/com/owncloud/android/oc_framework/operations/remote/ReadRemoteFileOperation.java @@ -0,0 +1,108 @@ +/* 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.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 a file from the ownCloud server. + * + * @author David A. Velasco + * @author masensio + */ + +public class ReadRemoteFileOperation extends RemoteOperation { + + private static final String TAG = ReadRemoteFileOperation.class.getSimpleName(); + private static final int SYNC_READ_TIMEOUT = 10000; + private static final int SYNC_CONNECTION_TIMEOUT = 5000; + + private String mRemotePath; + + + /** + * Constructor + * + * @param remotePath Remote path of the file. + */ + public ReadRemoteFileOperation(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) { + PropFindMethod propfind = null; + RemoteOperationResult result = null; + + /// take the duty of check the server for the current state of the file there + try { + propfind = new PropFindMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemotePath), + DavConstants.PROPFIND_ALL_PROP, + DavConstants.DEPTH_0); + int status; + status = client.executeMethod(propfind, SYNC_READ_TIMEOUT, SYNC_CONNECTION_TIMEOUT); + + boolean isMultiStatus = status == HttpStatus.SC_MULTI_STATUS; + if (isMultiStatus) { + // Parse response + MultiStatus resp = propfind.getResponseBodyAsMultiStatus(); + WebdavEntry we = new WebdavEntry(resp.getResponses()[0], client.getBaseUri().getPath()); + RemoteFile remoteFile = new RemoteFile(we); + ArrayList files = new ArrayList(); + files.add(remoteFile); + + // Result of the operation + result = new RemoteOperationResult(true, status, propfind.getResponseHeaders()); + result.setData(files); + + } else { + client.exhaustResponse(propfind.getResponseBodyAsStream()); + result = new RemoteOperationResult(false, status, propfind.getResponseHeaders()); + } + + } catch (Exception e) { + result = new RemoteOperationResult(e); + e.printStackTrace(); + Log.e(TAG, "Synchronizing file " + mRemotePath + ": " + result.getLogMessage(), result.getException()); + } finally { + if (propfind != null) + propfind.releaseConnection(); + } + return result; + } + +} diff --git a/oc_framework/src/com/owncloud/android/oc_framework/utils/FileUtils.java b/oc_framework/src/com/owncloud/android/oc_framework/utils/FileUtils.java index a7674e4f..192c267b 100644 --- a/oc_framework/src/com/owncloud/android/oc_framework/utils/FileUtils.java +++ b/oc_framework/src/com/owncloud/android/oc_framework/utils/FileUtils.java @@ -66,4 +66,6 @@ public class FileUtils { } return result; } + + } diff --git a/res/values-id/strings.xml b/res/values-id/strings.xml index 697ce72a..bd151ad1 100644 --- a/res/values-id/strings.xml +++ b/res/values-id/strings.xml @@ -1,18 +1,39 @@ + %1$s Apl Android + versi %1$s + Segarkan akun Unggah + Konten dari apl lain Berkas + Bukan dengan Buat folder pengaturan - Detail + Rincian umum Lainnya Akun - Kolola Akun + Kelola Akun + PIN Apl + Lindungi klien Anda + Aktifkan unggah instan + Unggah langsung foto yang diambil oleh kamera + Aktifkan Pencatatan + Ini digunakan untuk mencatat masalah + Riwayat Catatan + Ini menampilkan catatan yang disimpan + Riwayat Hapus Bantuan + Rekomendasikan ke teman + Umpan balik Imprint - nama pengguna - kata kunci + Coba %1$s pada smartphone Anda! + Saya mengundang Anda untuk menggunakan %1$s pada smartphone Anda!\nUnduh di sini: %2$s + Periksa Server + Alamat server https://… + Nama Pengguna + Sandi + Baru di %1$s? Berkas Sambungkan Unggah @@ -21,22 +42,27 @@ Belum ada akun %1$s pada perangkat Anda. Silahkan buat akun terlebih dahulu. Pengaturan Keluar + Tidak ada konten untuk diunggah + Tidak ada konten yang diterima. Tidak ada yang diunggah + %1$s tidak diizinkan mengakses konten berbagi Mengunggah + Tidak ada berkas dalam folder ini.\nBerkas baru dapat ditambahkan dengan opsi menu \"Unggah\". Sentuh pada berkas untuk menampilkan informasi tambahan Ukuran: Tipe: Dibuat: Diubah: - unduh + Unduh + Segarkan berkas Berkas diubah namanya menjadi %1$s saat pengunggahan Ya Tidak Oke Batal mengunduh Batal mengunggah - batal + Batal Simpan & Keluar - kesalahan + Kesalahan Memuat ... Galat tidak diketahui Tentang @@ -55,21 +81,32 @@ %1$d%% Mengunduh %2$s Berhasil mengunduh %1$s berhasil diunduh + Gagal Mengunduh + Mengunduh %1$s tidak selesai Belum diunduh Pilih akun + Sinkronisasi gagal + Sinkronisasi %1$s tidak selesai + Sandi salah untuk %1$s Konflik ditemukan + Konten berkas %1$d tidak dapat disinkronasikan (%2$d konflik) + Beberapa berkas lokal terlupakan + %1$d berkas dari direktori %2$s tidak dapat disalin ke + Folder %1$s tidak ada lagi Pindahkan semua Semua berkas sudah dipindahkan Beberapa berkas tidak dapat dipindahkan Lokal: %1$s - Silakan masukkan App PIN - Masukkan App PIN - Silakan masukkan ulang App PIN - Hapus App PIN - App PIN tidak sama - App PIN salah - App PIN dihapus - App PIN disimpan + Jauh: %1$s + Silakan masukkan PIN Apl + Masukkan PIN Apl + PIN akan selalu diminta setiap kali apl dijalankan + Silakan masukkan ulang PIN Apl + Hapus PIN Apl + PIN Apl tidak sama + PIN Apl salah + PIN Apl dihapus + PIN Apl disimpan Pemutar musik %1$s %1$s (dimainkan) %1$s (sedang dimuat) @@ -78,25 +115,114 @@ Brkas tidak didalam akun yang sah Kodek media tidak didukung Berkas media tidak dapat dibaca + Berkas media tidak di enkode dengan benar + Waktu habis saat mencoba untuk main + Berkas media tidak bisa dialirkan + Berkas media tidak dapat dimainkan dengan pemutar media + Kesalahan keamanan saat mencoba memutar %1$s + Kesalahan masukkan saat mencoba memutar %1$s + Kesalahan tak terduga saat mencoba memutar %1$s + Tombol mundur + Tombol main dan jeda + Tombol maju + Mencoba untuk masuk... Tidak ada koneksi internet Sambungan aman tidak tersedia Sambungan dibuat + Pengetesan koneksi ... Konfigurasi server cacat + Akun untuk pengguna dan server yang sama sudah ada dalam perangkat + Pengguna yang dimasukkan tidak cocok dengan pengguna akun ini Terjadi kesalahan yang tidak diketahui! + Tidak menemukan host + Instansi server tidak ditemukan + Server terlalu lama merespon + Format URL salah + Menginisiasi SSL gagal + Tidak dapat memverifikasi identitas server SSL + Versi server tidak dikenal + Tidak dapat membuat koneksi Sambungan aman dibuat + Nama pengguna dan sandi salah + Otorisasi tidak berhasil + Akses ditolak oleh server otorisasi + Keadaan tak terduga, silahkan masukkan URL server yang lagi + Otorisasi Anda telah berakhir. Silakan mengotorisasi lagi + Silakan mesukkan sandi saat ini + Sesi Anda telah berakhir. Silakan masuk kembali + Menyambungkan ke server otentikasi... + Server tidak mendukung medote otentikasi ini + %1$s tidak mendukung banyak akun + Biarkan berkas tetap terbaru Ubah nama - hilangkan + Hapus Apakah Anda yakin ingin menghapus %1$s ? + Apakah Anda benar-benar ingin menghapus %1$s beserta isinya? + Lokal saja + Konten lokal saja + Hapus dari server + Jarak jauh dan lokal Penghapusan berhasil Penghapusan gagal Masukkan nama baru + Salinan lokal tidak dapat diubah nama, coba dengan nama yang berbeda + Mengubah nama tidak selesai + Berkas jauh tidak dapat diperiksa Isi berkas sudah diselaraskan - Masalah tidak terduga, silahkan pilih berkas dari aplikasi yang berbeda - Detail - sembunyikan + Folder tidak dapat dibuat + Karakter yang dilarang: / \\ < > : \" | ? * + Tunggu sejenak + Masalah tidak terduga, silahkan pilih berkas dari apl yang berbeda + Tidak ada berkas yang terpilih + Masuk dengan oAuth2 + Menyambungkan ke server oAuth2... + Identitas situs tidak dapat diverfikasi + - Sertifikat server tidak terpercaya + - Sertifikat server kadaluarsa + - Tanggal sertifikat server yang valid adalah di masa depan + - URL tidak cocok dengan nama host dalam sertifikat + Apakah Anda percaya dengan sertifikat ini? + Sertifikat tidak dapat disimpan + Rincian + Sembunyikan + Diterbitkan untuk: + Diterbitkan oleh: + Nama panggilan: + Organisasi: + Unit Organisasi: + Negara: + Negara bagian: + Lokasi: + Masa berlaku: + Dari: + Untuk: Tanda tangan: Algoritma: + Ini adalah placeholder + placeholder.txt + Gambar PNG + 389 KB + 18/05/2012 12:23 PM + 12:23:45 + Hanya unggah gambar via WiFi + /UnggahInstan Perbarui benturan - Tindih + Berkas jauh %s tidak sinkron dengan berkas lokal. Melanjutkan akan menggantikan konten berkas di server. + Biarkan keduannya + Timpa Jangan mengunggah + Pratilik gambar + Gambar ini tidak dapat ditampilkan + %1$s tidak dapat disalin ke direktori lokal %2$s + UnggahInsatan Gagal + Unggahan instan gagal + Ringkasan dari semua unggahan instan yang gagal + pilih semua + Ulangi semua yang terpilih + hapus semua yang terpilih dari antrian unggahan + ulangi unggah gambar: + Muat Gambar selengkapnya + Tidak melakukan apapun, Anda tidak sedang online + Pesan Kegagalan: + Silakan periksa konfigurasi server Anda, kemungkinan kuota terlampaui. diff --git a/src/com/owncloud/android/files/services/FileUploader.java b/src/com/owncloud/android/files/services/FileUploader.java index 5fa27511..35952634 100644 --- a/src/com/owncloud/android/files/services/FileUploader.java +++ b/src/com/owncloud/android/files/services/FileUploader.java @@ -28,29 +28,24 @@ import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -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 com.owncloud.android.R; import com.owncloud.android.authentication.AuthenticatorActivity; import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.db.DbHandler; import com.owncloud.android.operations.CreateFolderOperation; +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.operations.UploadFileOperation; import com.owncloud.android.oc_framework.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.oc_framework.operations.remote.ExistenceCheckRemoteOperation; +import com.owncloud.android.oc_framework.operations.remote.ReadRemoteFileOperation; import com.owncloud.android.oc_framework.utils.OwnCloudVersion; import com.owncloud.android.oc_framework.network.webdav.OnDatatransferProgressListener; import com.owncloud.android.oc_framework.accounts.OwnCloudAccount; 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.WebdavEntry; -import com.owncloud.android.oc_framework.network.webdav.WebdavUtils; import com.owncloud.android.ui.activity.FailedUploadActivity; import com.owncloud.android.ui.activity.FileActivity; import com.owncloud.android.ui.activity.FileDisplayActivity; @@ -610,40 +605,15 @@ public class FileUploader extends Service implements OnDatatransferProgressListe long syncDate = System.currentTimeMillis(); file.setLastSyncDateForData(syncDate); - // / new PROPFIND to keep data consistent with server in theory, should - // return the same we already have - PropFindMethod propfind = null; - RemoteOperationResult result = null; - try { - propfind = new PropFindMethod(mUploadClient.getBaseUri() + WebdavUtils.encodePath(mCurrentUpload.getRemotePath()), - DavConstants.PROPFIND_ALL_PROP, - DavConstants.DEPTH_0); - int status = mUploadClient.executeMethod(propfind); - boolean isMultiStatus = (status == HttpStatus.SC_MULTI_STATUS); - if (isMultiStatus) { - MultiStatus resp = propfind.getResponseBodyAsMultiStatus(); - WebdavEntry we = new WebdavEntry(resp.getResponses()[0], mUploadClient.getBaseUri().getPath()); - updateOCFile(file, we); - file.setLastSyncDateForProperties(syncDate); - - } else { - mUploadClient.exhaustResponse(propfind.getResponseBodyAsStream()); - } - - result = new RemoteOperationResult(isMultiStatus, status, propfind.getResponseHeaders()); - Log_OC.i(TAG, "Update: synchronizing properties for uploaded " + mCurrentUpload.getRemotePath() + ": " - + result.getLogMessage()); - - } catch (Exception e) { - result = new RemoteOperationResult(e); - Log_OC.e(TAG, "Update: synchronizing properties for uploaded " + mCurrentUpload.getRemotePath() + ": " - + result.getLogMessage(), e); - - } finally { - if (propfind != null) - propfind.releaseConnection(); + // new PROPFIND to keep data consistent with server + // in theory, should return the same we already have + ReadRemoteFileOperation operation = new ReadRemoteFileOperation(mCurrentUpload.getRemotePath()); + RemoteOperationResult result = operation.execute(mUploadClient); + if (result.isSuccess()) { + updateOCFile(file, result.getData().get(0)); + file.setLastSyncDateForProperties(syncDate); } - + // / maybe this would be better as part of UploadFileOperation... or // maybe all this method if (mCurrentUpload.wasRenamed()) { @@ -660,13 +630,13 @@ public class FileUploader extends Service implements OnDatatransferProgressListe mStorageManager.saveFile(file); } - private void updateOCFile(OCFile file, WebdavEntry we) { - file.setCreationTimestamp(we.createTimestamp()); - file.setFileLength(we.contentLength()); - file.setMimetype(we.contentType()); - file.setModificationTimestamp(we.modifiedTimestamp()); - file.setModificationTimestampAtLastSyncForData(we.modifiedTimestamp()); - // file.setEtag(mCurrentUpload.getEtag()); // TODO Etag, where available + private void updateOCFile(OCFile file, RemoteFile remoteFile) { + file.setCreationTimestamp(remoteFile.getCreationTimestamp()); + file.setFileLength(remoteFile.getLength()); + file.setMimetype(remoteFile.getMimeType()); + file.setModificationTimestamp(remoteFile.getModifiedTimestamp()); + file.setModificationTimestampAtLastSyncForData(remoteFile.getModifiedTimestamp()); + // file.setEtag(remoteFile.getEtag()); // TODO Etag, where available } private OCFile obtainNewOCFileToUpload(String remotePath, String localPath, String mimeType, diff --git a/src/com/owncloud/android/operations/SynchronizeFileOperation.java b/src/com/owncloud/android/operations/SynchronizeFileOperation.java index f087aa5e..71d7f721 100644 --- a/src/com/owncloud/android/operations/SynchronizeFileOperation.java +++ b/src/com/owncloud/android/operations/SynchronizeFileOperation.java @@ -18,33 +18,32 @@ package com.owncloud.android.operations; -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 com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.files.services.FileDownloader; import com.owncloud.android.files.services.FileUploader; 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.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.utils.FileStorageUtils; import com.owncloud.android.utils.Log_OC; import android.accounts.Account; import android.content.Context; import android.content.Intent; +/** + * Remote operation performing the read of remote file in the ownCloud server. + * + * @author David A. Velasco + * @author masensio + */ public class SynchronizeFileOperation extends RemoteOperation { private String TAG = SynchronizeFileOperation.class.getSimpleName(); - private static final int SYNC_READ_TIMEOUT = 10000; - private static final int SYNC_CONNECTION_TIMEOUT = 5000; private OCFile mLocalFile; private OCFile mServerFile; @@ -74,103 +73,83 @@ public class SynchronizeFileOperation extends RemoteOperation { @Override protected RemoteOperationResult run(WebdavClient client) { - - PropFindMethod propfind = null; + RemoteOperationResult result = null; mTransferWasRequested = false; - try { - if (!mLocalFile.isDown()) { - /// easy decision - requestForDownload(mLocalFile); - result = new RemoteOperationResult(ResultCode.OK); - - } else { - /// local copy in the device -> need to think a bit more before do anything - - if (mServerFile == null) { - /// take the duty of check the server for the current state of the file there - propfind = new PropFindMethod(client.getBaseUri() + WebdavUtils.encodePath(mLocalFile.getRemotePath()), - DavConstants.PROPFIND_ALL_PROP, - DavConstants.DEPTH_0); - int status = client.executeMethod(propfind, SYNC_READ_TIMEOUT, SYNC_CONNECTION_TIMEOUT); - boolean isMultiStatus = status == HttpStatus.SC_MULTI_STATUS; - if (isMultiStatus) { - MultiStatus resp = propfind.getResponseBodyAsMultiStatus(); - WebdavEntry we = new WebdavEntry(resp.getResponses()[0], - client.getBaseUri().getPath()); - mServerFile = fillOCFile(we); - mServerFile.setLastSyncDateForProperties(System.currentTimeMillis()); - - } else { - client.exhaustResponse(propfind.getResponseBodyAsStream()); - result = new RemoteOperationResult(false, status, propfind.getResponseHeaders()); - } + if (!mLocalFile.isDown()) { + /// easy decision + requestForDownload(mLocalFile); + result = new RemoteOperationResult(ResultCode.OK); + + } else { + /// local copy in the device -> need to think a bit more before do anything + + if (mServerFile == null) { + String remotePath = mLocalFile.getRemotePath(); + ReadRemoteFileOperation operation = new ReadRemoteFileOperation(remotePath); + result = operation.execute(client); + if (result.isSuccess()){ + mServerFile = FileStorageUtils.fillOCFile(result.getData().get(0)); + mServerFile.setLastSyncDateForProperties(System.currentTimeMillis()); } - - if (result == null) { // true if the server was not checked. nothing was wrong with the remote request - - /// check changes in server and local file - boolean serverChanged = false; - /* time for eTag is coming, but not yet + } + + if (result.isSuccess()) { + + /// check changes in server and local file + boolean serverChanged = false; + /* time for eTag is coming, but not yet if (mServerFile.getEtag() != null) { serverChanged = (!mServerFile.getEtag().equals(mLocalFile.getEtag())); // TODO could this be dangerous when the user upgrades the server from non-tagged to tagged? } else { */ - // server without etags - serverChanged = (mServerFile.getModificationTimestamp() > mLocalFile.getModificationTimestampAtLastSyncForData()); - //} - boolean localChanged = (mLocalFile.getLocalModificationTimestamp() > mLocalFile.getLastSyncDateForData()); - // TODO this will be always true after the app is upgraded to database version 2; will result in unnecessary uploads - - /// decide action to perform depending upon changes - //if (!mLocalFile.getEtag().isEmpty() && localChanged && serverChanged) { - if (localChanged && serverChanged) { - result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT); - - } else if (localChanged) { - if (mSyncFileContents) { - requestForUpload(mLocalFile); - // the local update of file properties will be done by the FileUploader service when the upload finishes - } else { - // NOTHING TO DO HERE: updating the properties of the file in the server without uploading the contents would be stupid; - // So, an instance of SynchronizeFileOperation created with syncFileContents == false is completely useless when we suspect - // that an upload is necessary (for instance, in FileObserverService). - } - result = new RemoteOperationResult(ResultCode.OK); - - } else if (serverChanged) { - if (mSyncFileContents) { - requestForDownload(mLocalFile); // local, not server; we won't to keep the value of keepInSync! - // the update of local data will be done later by the FileUploader service when the upload finishes - } else { - // TODO CHECK: is this really useful in some point in the code? - mServerFile.setKeepInSync(mLocalFile.keepInSync()); - mServerFile.setLastSyncDateForData(mLocalFile.getLastSyncDateForData()); - mServerFile.setStoragePath(mLocalFile.getStoragePath()); - mServerFile.setParentId(mLocalFile.getParentId()); - mStorageManager.saveFile(mServerFile); - - } - result = new RemoteOperationResult(ResultCode.OK); - + // server without etags + serverChanged = (mServerFile.getModificationTimestamp() != mLocalFile.getModificationTimestampAtLastSyncForData()); + //} + boolean localChanged = (mLocalFile.getLocalModificationTimestamp() > mLocalFile.getLastSyncDateForData()); + // TODO this will be always true after the app is upgraded to database version 2; will result in unnecessary uploads + + /// decide action to perform depending upon changes + //if (!mLocalFile.getEtag().isEmpty() && localChanged && serverChanged) { + if (localChanged && serverChanged) { + result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT); + + } else if (localChanged) { + if (mSyncFileContents) { + requestForUpload(mLocalFile); + // the local update of file properties will be done by the FileUploader service when the upload finishes } else { - // nothing changed, nothing to do - result = new RemoteOperationResult(ResultCode.OK); + // NOTHING TO DO HERE: updating the properties of the file in the server without uploading the contents would be stupid; + // So, an instance of SynchronizeFileOperation created with syncFileContents == false is completely useless when we suspect + // that an upload is necessary (for instance, in FileObserverService). } - - } - - } - - Log_OC.i(TAG, "Synchronizing " + mAccount.name + ", file " + mLocalFile.getRemotePath() + ": " + result.getLogMessage()); - - } catch (Exception e) { - result = new RemoteOperationResult(e); - Log_OC.e(TAG, "Synchronizing " + mAccount.name + ", file " + (mLocalFile != null ? mLocalFile.getRemotePath() : "NULL") + ": " + result.getLogMessage(), result.getException()); - - } finally { - if (propfind != null) - propfind.releaseConnection(); + result = new RemoteOperationResult(ResultCode.OK); + + } else if (serverChanged) { + if (mSyncFileContents) { + requestForDownload(mLocalFile); // local, not server; we won't to keep the value of keepInSync! + // the update of local data will be done later by the FileUploader service when the upload finishes + } else { + // TODO CHECK: is this really useful in some point in the code? + mServerFile.setKeepInSync(mLocalFile.keepInSync()); + mServerFile.setLastSyncDateForData(mLocalFile.getLastSyncDateForData()); + mServerFile.setStoragePath(mLocalFile.getStoragePath()); + mServerFile.setParentId(mLocalFile.getParentId()); + mStorageManager.saveFile(mServerFile); + + } + result = new RemoteOperationResult(ResultCode.OK); + + } else { + // nothing changed, nothing to do + result = new RemoteOperationResult(ResultCode.OK); + } + + } + } + + Log_OC.i(TAG, "Synchronizing " + mAccount.name + ", file " + mLocalFile.getRemotePath() + ": " + result.getLogMessage()); + return result; } @@ -207,24 +186,6 @@ public class SynchronizeFileOperation extends RemoteOperation { } - /** - * Creates and populates a new {@link OCFile} 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 OCFile fillOCFile(WebdavEntry we) { - OCFile file = new OCFile(we.decodedPath()); - file.setCreationTimestamp(we.createTimestamp()); - file.setFileLength(we.contentLength()); - file.setMimetype(we.contentType()); - file.setModificationTimestamp(we.modifiedTimestamp()); - file.setEtag(we.etag()); - - return file; - } - - public boolean transferWasRequested() { return mTransferWasRequested; } diff --git a/src/com/owncloud/android/operations/SynchronizeFolderOperation.java b/src/com/owncloud/android/operations/SynchronizeFolderOperation.java index e93736c4..ff387c0f 100644 --- a/src/com/owncloud/android/operations/SynchronizeFolderOperation.java +++ b/src/com/owncloud/android/operations/SynchronizeFolderOperation.java @@ -30,9 +30,6 @@ import java.util.Map; import java.util.Vector; import org.apache.http.HttpStatus; -import org.apache.jackrabbit.webdav.DavConstants; -import org.apache.jackrabbit.webdav.client.methods.PropFindMethod; - import android.accounts.Account; import android.content.Context; import android.content.Intent; @@ -40,11 +37,10 @@ import android.content.Intent; import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; 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.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.remote.ReadRemoteFolderOperation; import com.owncloud.android.oc_framework.operations.RemoteFile; import com.owncloud.android.syncadapter.FileSyncService; @@ -188,48 +184,27 @@ public class SynchronizeFolderOperation extends RemoteOperation { mRemoteFolderChanged = false; RemoteOperationResult result = null; String remotePath = null; - PropFindMethod query = null; - - try { + remotePath = mLocalFolder.getRemotePath(); Log_OC.d(TAG, "Checking changes in " + mAccount.name + remotePath); // remote request - query = new PropFindMethod(client.getBaseUri() + WebdavUtils.encodePath(remotePath), - DavConstants.PROPFIND_ALL_PROP, - DavConstants.DEPTH_0); - int status = client.executeMethod(query); - - // check and process response - if (isMultiStatus(status)) { - // parse data from remote folder - WebdavEntry we = new WebdavEntry(query.getResponseBodyAsMultiStatus().getResponses()[0], client.getBaseUri().getPath()); - OCFile remoteFolder = fillOCFile(we); - - // check if remote and local folder are different - mRemoteFolderChanged = !(remoteFolder.getEtag().equalsIgnoreCase(mLocalFolder.getEtag())); - - result = new RemoteOperationResult(ResultCode.OK); + ReadRemoteFileOperation operation = new ReadRemoteFileOperation(remotePath); + result = operation.execute(client); + if (result.isSuccess()){ + OCFile remoteFolder = FileStorageUtils.fillOCFile(result.getData().get(0)); + // check if remote and local folder are different + mRemoteFolderChanged = !(remoteFolder.getEtag().equalsIgnoreCase(mLocalFolder.getEtag())); + + result = new RemoteOperationResult(ResultCode.OK); + + Log_OC.i(TAG, "Checked " + mAccount.name + remotePath + " : " + (mRemoteFolderChanged ? "changed" : "not changed")); } else { // check failed - client.exhaustResponse(query.getResponseBodyAsStream()); - if (status == HttpStatus.SC_NOT_FOUND) { + if (result.getCode() == ResultCode.FILE_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, "Checked " + mAccount.name + remotePath + " : " + (mRemoteFolderChanged ? "changed" : "not changed")); - } else { if (result.isException()) { Log_OC.e(TAG, "Checked " + mAccount.name + remotePath + " : " + result.getLogMessage(), result.getException()); } else { @@ -237,7 +212,6 @@ public class SynchronizeFolderOperation extends RemoteOperation { } } - } return result; } @@ -398,23 +372,6 @@ 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. - * - * @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 OCFile fillOCFile(WebdavEntry we) { - OCFile file = new OCFile(we.decodedPath()); - file.setCreationTimestamp(we.createTimestamp()); - file.setFileLength(we.contentLength()); - file.setMimetype(we.contentType()); - file.setModificationTimestamp(we.modifiedTimestamp()); - file.setEtag(we.etag()); - return file; - } - /** * Creates and populates a new {@link OCFile} object with the data read from the server. * diff --git a/src/com/owncloud/android/utils/FileStorageUtils.java b/src/com/owncloud/android/utils/FileStorageUtils.java index 16812c65..d4042f50 100644 --- a/src/com/owncloud/android/utils/FileStorageUtils.java +++ b/src/com/owncloud/android/utils/FileStorageUtils.java @@ -84,6 +84,22 @@ public class FileStorageUtils { return parentPath; } + /** + * 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. + */ + public static 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; + } /** * Creates and populates a new {@link RemoteFile} object with the data read from an {@link OCFile}.