X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/491780ad1db3917aef6763fd2b0420ec9921dcdd..cc77ea37de47ecf8d0261978aa9de924c917deec:/src/com/owncloud/android/operations/SynchronizeFileOperation.java diff --git a/src/com/owncloud/android/operations/SynchronizeFileOperation.java b/src/com/owncloud/android/operations/SynchronizeFileOperation.java index 1614ba1c..72cb22be 100644 --- a/src/com/owncloud/android/operations/SynchronizeFileOperation.java +++ b/src/com/owncloud/android/operations/SynchronizeFileOperation.java @@ -25,10 +25,10 @@ import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.resources.files.RemoteFile; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; +import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.lib.resources.files.ReadRemoteFileOperation; import com.owncloud.android.operations.common.SyncOperation; import com.owncloud.android.utils.FileStorageUtils; -import com.owncloud.android.utils.Log_OC; import android.accounts.Account; import android.content.Context; @@ -53,33 +53,120 @@ public class SynchronizeFileOperation extends SyncOperation { private Context mContext; private boolean mTransferWasRequested = false; + + /** + * When 'false', uploads to the server are not done; only downloads or conflict detection. + * This is a temporal field. + * TODO Remove when 'folder synchronization' replaces 'folder download'. + */ + private boolean mAllowUploads; + + /** + * Constructor for "full synchronization mode". + * + * Uses remotePath to retrieve all the data both in local cache and in the remote OC server when the operation + * is executed, instead of reusing {@link OCFile} instances. + * + * Useful for direct synchronization of a single file. + * + * @param + * @param account ownCloud account holding the file. + * @param syncFileContents When 'true', transference of data will be started by the + * operation if needed and no conflict is detected. + * @param context Android context; needed to start transfers. + */ public SynchronizeFileOperation( - OCFile localFile, - OCFile serverFile, // make this null to let the operation checks the server; added to reuse info from SynchronizeFolderOperation + String remotePath, Account account, boolean syncFileContents, Context context) { - mLocalFile = localFile; - mServerFile = serverFile; + mRemotePath = remotePath; + mLocalFile = null; + mServerFile = null; mAccount = account; mSyncFileContents = syncFileContents; mContext = context; + mAllowUploads = true; } + + /** + * Constructor allowing to reuse {@link OCFile} instances just queried from local cache or from remote OC server. + * + * Useful to include this operation as part of the synchronization of a folder (or a full account), avoiding the + * repetition of fetch operations (both in local database or remote server). + * + * At least one of localFile or serverFile MUST NOT BE NULL. If you don't have none of them, use the other + * constructor. + * + * @param localFile Data of file (just) retrieved from local cache/database. + * @param serverFile Data of file (just) retrieved from a remote server. If null, will be + * retrieved from network by the operation when executed. + * @param account ownCloud account holding the file. + * @param syncFileContents When 'true', transference of data will be started by the + * operation if needed and no conflict is detected. + * @param context Android context; needed to start transfers. + */ public SynchronizeFileOperation( - String remotePath, + OCFile localFile, + OCFile serverFile, Account account, boolean syncFileContents, Context context) { - mRemotePath = remotePath; - mServerFile = null; + mLocalFile = localFile; + mServerFile = serverFile; + if (mLocalFile != null) { + mRemotePath = mLocalFile.getRemotePath(); + if (mServerFile != null && !mServerFile.getRemotePath().equals(mRemotePath)) { + throw new IllegalArgumentException("serverFile and localFile do not correspond to the same OC file"); + } + } else if (mServerFile != null) { + mRemotePath = mServerFile.getRemotePath(); + } else { + throw new IllegalArgumentException("Both serverFile and localFile are NULL"); + } mAccount = account; mSyncFileContents = syncFileContents; mContext = context; + mAllowUploads = true; } + + + /** + * Temporal constructor. + * + * Extends the previous one to allow constrained synchronizations where uploads are never performed - only + * downloads or conflict detection. + * + * Do not use unless you are involved in 'folder synchronization' or 'folder download' work in progress. + * + * TODO Remove when 'folder synchronization' replaces 'folder download'. + * + * @param localFile Data of file (just) retrieved from local cache/database. MUSTN't be null. + * @param serverFile Data of file (just) retrieved from a remote server. If null, will be + * retrieved from network by the operation when executed. + * @param account ownCloud account holding the file. + * @param syncFileContents When 'true', transference of data will be started by the + * operation if needed and no conflict is detected. + * @param allowUploads When 'false', uploads to the server are not done; only downloads or conflict + * detection. + * @param context Android context; needed to start transfers. + */ + public SynchronizeFileOperation( + OCFile localFile, + OCFile serverFile, + Account account, + boolean syncFileContents, + boolean allowUploads, + Context context) { + + this(localFile, serverFile, account, syncFileContents, context); + mAllowUploads = allowUploads; + } + @Override protected RemoteOperationResult run(OwnCloudClient client) { @@ -87,8 +174,10 @@ public class SynchronizeFileOperation extends SyncOperation { RemoteOperationResult result = null; mTransferWasRequested = false; - // Get local file from the DB - mLocalFile = getStorageManager().getFileByPath(mRemotePath); + if (mLocalFile == null) { + // Get local file from the DB + mLocalFile = getStorageManager().getFileByPath(mRemotePath); + } if (!mLocalFile.isDown()) { /// easy decision @@ -99,8 +188,7 @@ public class SynchronizeFileOperation extends SyncOperation { /// 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); + ReadRemoteFileOperation operation = new ReadRemoteFileOperation(mRemotePath); result = operation.execute(client); if (result.isSuccess()){ mServerFile = FileStorageUtils.fillOCFile((RemoteFile) result.getData().get(0)); @@ -114,13 +202,15 @@ public class SynchronizeFileOperation extends SyncOperation { 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? + serverChanged = (!mServerFile.getEtag().equals(mLocalFile.getEtag())); } else { */ - // server without etags - serverChanged = (mServerFile.getModificationTimestamp() != mLocalFile.getModificationTimestampAtLastSyncForData()); + 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 + boolean localChanged = ( + mLocalFile.getLocalModificationTimestamp() > mLocalFile.getLastSyncDateForData() + ); /// decide action to perform depending upon changes //if (!mLocalFile.getEtag().isEmpty() && localChanged && serverChanged) { @@ -128,7 +218,7 @@ public class SynchronizeFileOperation extends SyncOperation { result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT); } else if (localChanged) { - if (mSyncFileContents) { + if (mSyncFileContents && mAllowUploads) { requestForUpload(mLocalFile); // the local update of file properties will be done by the FileUploader service when the upload finishes } else { @@ -139,6 +229,8 @@ public class SynchronizeFileOperation extends SyncOperation { result = new RemoteOperationResult(ResultCode.OK); } else if (serverChanged) { + mLocalFile.setRemoteId(mServerFile.getRemoteId()); + 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 @@ -162,7 +254,8 @@ public class SynchronizeFileOperation extends SyncOperation { } - Log_OC.i(TAG, "Synchronizing " + mAccount.name + ", file " + mLocalFile.getRemotePath() + ": " + result.getLogMessage()); + Log_OC.i(TAG, "Synchronizing " + mAccount.name + ", file " + mLocalFile.getRemotePath() + ": " + + result.getLogMessage()); return result; }