X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/97dd59063ba1bf16fa2c176563614a9ce310b158..c2abbaaedb69dba35866a48b745b68f3519cbca1:/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 9923c17e..211ba705 100644 --- a/src/com/owncloud/android/operations/SynchronizeFileOperation.java +++ b/src/com/owncloud/android/operations/SynchronizeFileOperation.java @@ -1,10 +1,10 @@ /* ownCloud Android client application * Copyright (C) 2012 Bartek Przybylski + * 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 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * 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 @@ -19,20 +19,22 @@ 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 android.accounts.Account; -import android.content.Context; -import android.content.Intent; -import android.util.Log; - +import com.owncloud.android.Log_OC; import com.owncloud.android.datamodel.DataStorageManager; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.files.services.FileDownloader; import com.owncloud.android.files.services.FileUploader; import com.owncloud.android.operations.RemoteOperationResult.ResultCode; +import android.accounts.Account; +import android.content.Context; +import android.content.Intent; + + import eu.alefzero.webdav.WebdavClient; import eu.alefzero.webdav.WebdavEntry; import eu.alefzero.webdav.WebdavUtils; @@ -40,8 +42,11 @@ import eu.alefzero.webdav.WebdavUtils; public class SynchronizeFileOperation extends RemoteOperation { private String TAG = SynchronizeFileOperation.class.getSimpleName(); - //private String mRemotePath; + private static final int SYNC_READ_TIMEOUT = 10000; + private static final int SYNC_CONNECTION_TIMEOUT = 5000; + private OCFile mLocalFile; + private OCFile mServerFile; private DataStorageManager mStorageManager; private Account mAccount; private boolean mSyncFileContents; @@ -51,23 +56,24 @@ public class SynchronizeFileOperation extends RemoteOperation { private boolean mTransferWasRequested = false; public SynchronizeFileOperation( - OCFile localFile, - DataStorageManager dataStorageManager, + OCFile localFile, + OCFile serverFile, // make this null to let the operation checks the server; added to reuse info from SynchronizeFolderOperation + DataStorageManager storageManager, Account account, boolean syncFileContents, - boolean localChangeAlreadyKnown, + boolean localChangeAlreadyKnown, Context context) { - //mRemotePath = remotePath; mLocalFile = localFile; - mStorageManager = dataStorageManager; + mServerFile = serverFile; + mStorageManager = storageManager; mAccount = account; mSyncFileContents = syncFileContents; mLocalChangeAlreadyKnown = localChangeAlreadyKnown; mContext = context; } - + @Override protected RemoteOperationResult run(WebdavClient client) { @@ -83,29 +89,41 @@ public class SynchronizeFileOperation extends RemoteOperation { } else { /// local copy in the device -> need to think a bit more before do anything - propfind = new PropFindMethod(client.getBaseUri() + WebdavUtils.encodePath(mLocalFile.getRemotePath())); - int status = client.executeMethod(propfind); - boolean isMultiStatus = status == HttpStatus.SC_MULTI_STATUS; - if (isMultiStatus) { - MultiStatus resp = propfind.getResponseBodyAsMultiStatus(); - WebdavEntry we = new WebdavEntry(resp.getResponses()[0], + 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()); - OCFile serverFile = fillOCFile(we); + mServerFile = fillOCFile(we); + mServerFile.setLastSyncDateForProperties(System.currentTimeMillis()); + + } else { + client.exhaustResponse(propfind.getResponseBodyAsStream()); + result = new RemoteOperationResult(false, status, propfind.getResponseHeaders()); + } + } + + 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; - if (serverFile.getEtag() != null) { - serverChanged = (!serverFile.getEtag().equals(mLocalFile.getEtag())); // TODO could this be dangerous when the user upgrades the server from non-tagged to tagged? + 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 = (serverFile.getModificationTimestamp() > mLocalFile.getModificationTimestamp()); + serverChanged = (mServerFile.getModificationTimestamp() > mLocalFile.getModificationTimestampAtLastSyncForData()); } boolean localChanged = (mLocalChangeAlreadyKnown || mLocalFile.getLocalModificationTimestamp() > mLocalFile.getLastSyncDateForData()); - // TODO this will be always true after the app is upgraded to database version 3; will result in unnecessary uploads + // 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 (localChanged && serverChanged) { - // conflict result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT); } else if (localChanged) { @@ -125,9 +143,11 @@ public class SynchronizeFileOperation extends RemoteOperation { // 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? - serverFile.setKeepInSync(mLocalFile.keepInSync()); - serverFile.setParentId(mLocalFile.getParentId()); - mStorageManager.saveFile(serverFile); + mServerFile.setKeepInSync(mLocalFile.keepInSync()); + mServerFile.setLastSyncDateForData(mLocalFile.getLastSyncDateForData()); + mServerFile.setStoragePath(mLocalFile.getStoragePath()); + mServerFile.setParentId(mLocalFile.getParentId()); + mStorageManager.saveFile(mServerFile); } result = new RemoteOperationResult(ResultCode.OK); @@ -137,18 +157,15 @@ public class SynchronizeFileOperation extends RemoteOperation { result = new RemoteOperationResult(ResultCode.OK); } - } else { - client.exhaustResponse(propfind.getResponseBodyAsStream()); - result = new RemoteOperationResult(false, status); - } + } } - Log.i(TAG, "Synchronizing " + mAccount.name + ", file " + mLocalFile.getRemotePath() + ": " + result.getLogMessage()); + Log_OC.i(TAG, "Synchronizing " + mAccount.name + ", file " + mLocalFile.getRemotePath() + ": " + result.getLogMessage()); } catch (Exception e) { result = new RemoteOperationResult(e); - Log.e(TAG, "Synchronizing " + mAccount.name + ", file " + mLocalFile.getRemotePath() + ": " + result.getLogMessage(), result.getException()); + Log_OC.e(TAG, "Synchronizing " + mAccount.name + ", file " + (mLocalFile != null ? mLocalFile.getRemotePath() : "NULL") + ": " + result.getLogMessage(), result.getException()); } finally { if (propfind != null) @@ -201,9 +218,7 @@ public class SynchronizeFileOperation extends RemoteOperation { file.setCreationTimestamp(we.createTimestamp()); file.setFileLength(we.contentLength()); file.setMimetype(we.contentType()); - file.setModificationTimestamp(we.modifiedTimesamp()); - file.setLastSyncDateForProperties(System.currentTimeMillis()); - file.setLastSyncDateForData(0); + file.setModificationTimestamp(we.modifiedTimestamp()); return file; } @@ -212,4 +227,9 @@ public class SynchronizeFileOperation extends RemoteOperation { return mTransferWasRequested; } + + public OCFile getLocalFile() { + return mLocalFile; + } + }