X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/8fef772af40a8eb328105c13a102b62c64d16773..ab3bcf6fe6f62add623a60405ef96ea77839f7a4:/src/com/owncloud/android/operations/SynchronizeFolderOperation.java diff --git a/src/com/owncloud/android/operations/SynchronizeFolderOperation.java b/src/com/owncloud/android/operations/SynchronizeFolderOperation.java index 82b024d2..7f22bb7a 100644 --- a/src/com/owncloud/android/operations/SynchronizeFolderOperation.java +++ b/src/com/owncloud/android/operations/SynchronizeFolderOperation.java @@ -35,10 +35,13 @@ import org.apache.jackrabbit.webdav.client.methods.PropFindMethod; import android.accounts.Account; import android.content.Context; +import android.content.Intent; + import com.owncloud.android.Log_OC; import com.owncloud.android.datamodel.DataStorageManager; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.operations.RemoteOperationResult.ResultCode; +import com.owncloud.android.syncadapter.FileSyncService; import com.owncloud.android.utils.FileStorageUtils; import eu.alefzero.webdav.WebdavClient; @@ -63,6 +66,9 @@ public class SynchronizeFolderOperation extends RemoteOperation { /** Id of the folder to synchronize in the local database */ private long mParentId; + + /** Boolean to indicate if is mandatory to update the folder */ + private boolean mEnforceMetadataUpdate; /** Access to the local database */ private DataStorageManager mStorageManager; @@ -82,16 +88,22 @@ public class SynchronizeFolderOperation extends RemoteOperation { private Map mForgottenLocalFiles; + private boolean mSyncFullAccount; + public SynchronizeFolderOperation( String remotePath, long currentSyncTime, - long parentId, + long parentId, + boolean enforceMetadataUpdate, + boolean syncFullAccount, DataStorageManager dataStorageManager, Account account, Context context ) { mRemotePath = remotePath; mCurrentSyncTime = currentSyncTime; mParentId = parentId; + mEnforceMetadataUpdate = enforceMetadataUpdate; + mSyncFullAccount = syncFullAccount; mStorageManager = dataStorageManager; mAccount = account; mContext = context; @@ -134,7 +146,7 @@ public class SynchronizeFolderOperation extends RemoteOperation { mFailsInFavouritesFound = 0; mConflictsFound = 0; mForgottenLocalFiles.clear(); - boolean fileChanged = false; + boolean dirChanged = false; // code before in FileSyncAdapter.fetchData PropFindMethod query = null; @@ -149,53 +161,57 @@ public class SynchronizeFolderOperation extends RemoteOperation { if (isMultiStatus(status)) { MultiStatus resp = query.getResponseBodyAsMultiStatus(); - // synchronize properties of the parent folder, if necessary - if (mParentId == DataStorageManager.ROOT_PARENT_ID) { - WebdavEntry we = new WebdavEntry(resp.getResponses()[0], client.getBaseUri().getPath()); + // synchronize properties of the parent folder, if necessary + WebdavEntry we = new WebdavEntry(resp.getResponses()[0], client.getBaseUri().getPath()); - // Properties of server folder - OCFile parent = fillOCFile(we); - // Properties of local folder - OCFile localParent = mStorageManager.getFileById(1); - if (localParent == null || parent.getEtag() != localParent.getEtag()) { - mStorageManager.saveFile(parent); - mParentId = parent.getFileId(); + // Properties of server folder + OCFile parent = fillOCFile(we); + // Properties of local folder + OCFile localParent = mStorageManager.getFileByPath(mRemotePath); + if (localParent == null || !(parent.getEtag().equalsIgnoreCase(localParent.getEtag())) || mEnforceMetadataUpdate) { + if (localParent != null) { + parent.setParentId(localParent.getParentId()); } + mStorageManager.saveFile(parent); + if (mParentId == DataStorageManager.ROOT_PARENT_ID) + mParentId = parent.getFileId(); + dirChanged = true; } + if (dirChanged) { + // read contents in folder + List filesOnServer = new ArrayList (); // Contains the lists of files on server + List updatedFiles = new Vector(resp.getResponses().length - 1); + List filesToSyncContents = new Vector(); + for (int i = 1; i < resp.getResponses().length; ++i) { + /// new OCFile instance with the data from the server + we = new WebdavEntry(resp.getResponses()[i], client.getBaseUri().getPath()); + OCFile file = fillOCFile(we); - // read contents in folder - List filesOnServer = new ArrayList (); // Contains the lists of files on server - List updatedFiles = new Vector(resp.getResponses().length - 1); - List filesToSyncContents = new Vector(); - for (int i = 1; i < resp.getResponses().length; ++i) { - /// new OCFile instance with the data from the server - WebdavEntry we = new WebdavEntry(resp.getResponses()[i], client.getBaseUri().getPath()); - OCFile file = fillOCFile(we); + filesOnServer.add(file.getRemotePath()); // Registry the file in the list - filesOnServer.add(file.getRemotePath()); // Registry the file in the list + /// set data about local state, keeping unchanged former data if existing + file.setLastSyncDateForProperties(mCurrentSyncTime); + OCFile oldFile = mStorageManager.getFileByPath(file.getRemotePath()); - /// set data about local state, keeping unchanged former data if existing - file.setLastSyncDateForProperties(mCurrentSyncTime); - OCFile oldFile = mStorageManager.getFileByPath(file.getRemotePath()); + // Check if it is needed to synchronize the folder + if (oldFile != null) { + if (!file.getEtag().equalsIgnoreCase(oldFile.getEtag())) { + } + } - // Check if it is needed to synchronize the folder - fileChanged = false; - if (oldFile != null) { - if (!file.getEtag().equalsIgnoreCase(oldFile.getEtag())) { - fileChanged = true; - } - } else - fileChanged= true; - - if (fileChanged){ if (oldFile != null) { file.setKeepInSync(oldFile.keepInSync()); file.setLastSyncDateForData(oldFile.getLastSyncDateForData()); file.setModificationTimestampAtLastSyncForData(oldFile.getModificationTimestampAtLastSyncForData()); // must be kept unchanged when the file contents are not updated checkAndFixForeignStoragePath(oldFile); file.setStoragePath(oldFile.getStoragePath()); - } + if (file.isDirectory()) + file.setEtag(oldFile.getEtag()); + } else + if (file.isDirectory()) + file.setEtag(""); + /// scan default location if local copy of file is not linked in OCFile instance if (file.getStoragePath() == null && !file.isDirectory()) { File f = new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, file)); @@ -220,70 +236,72 @@ public class SynchronizeFolderOperation extends RemoteOperation { updatedFiles.add(file); } - } - // save updated contents in local database; all at once, trying to get a best performance in database update (not a big deal, indeed) - mStorageManager.saveFiles(updatedFiles); - - // request for the synchronization of files AFTER saving last properties - //SynchronizeFileOperation op = null; - RemoteOperationResult contentsResult = null; - for (SynchronizeFileOperation op: filesToSyncContents) {//int i=0; i < filesToSyncContents.size(); i++) { - //op = filesToSyncContents.get(i); - contentsResult = op.execute(client); // returns without waiting for upload or download finishes - if (!contentsResult.isSuccess()) { - if (contentsResult.getCode() == ResultCode.SYNC_CONFLICT) { - mConflictsFound++; - } else { - mFailsInFavouritesFound++; - if (contentsResult.getException() != null) { - Log_OC.e(TAG, "Error while synchronizing favourites : " + contentsResult.getLogMessage(), contentsResult.getException()); + // save updated contents in local database; all at once, trying to get a best performance in database update (not a big deal, indeed) + mStorageManager.saveFiles(updatedFiles); + + // request for the synchronization of files AFTER saving last properties + RemoteOperationResult contentsResult = null; + for (SynchronizeFileOperation op: filesToSyncContents) { + contentsResult = op.execute(client); // returns without waiting for upload or download finishes + if (!contentsResult.isSuccess()) { + if (contentsResult.getCode() == ResultCode.SYNC_CONFLICT) { + mConflictsFound++; } else { - Log_OC.e(TAG, "Error while synchronizing favourites : " + contentsResult.getLogMessage()); + mFailsInFavouritesFound++; + if (contentsResult.getException() != null) { + Log_OC.e(TAG, "Error while synchronizing favourites : " + contentsResult.getLogMessage(), contentsResult.getException()); + } else { + Log_OC.e(TAG, "Error while synchronizing favourites : " + contentsResult.getLogMessage()); + } } + } // won't let these fails break the synchronization process + } + + // removal of obsolete files + mChildren = mStorageManager.getDirectoryContent(mStorageManager.getFileById(mParentId)); + OCFile file; + String currentSavePath = FileStorageUtils.getSavePath(mAccount.name); + for (int i=0; i < mChildren.size(); ) { + file = mChildren.get(i); + if (file.getLastSyncDateForProperties() != mCurrentSyncTime) { + Log_OC.d(TAG, "removing file: " + file); + mStorageManager.removeFile(file, (file.isDown() && file.getStoragePath().startsWith(currentSavePath))); + mChildren.remove(i); + } else { + i++; } - } // won't let these fails break the synchronization process + } + + } else { + client.exhaustResponse(query.getResponseBodyAsStream()); } + + + // prepare result object + if (!dirChanged) { + result = new RemoteOperationResult(ResultCode.OK_NO_CHANGES_ON_DIR); + mChildren = mStorageManager.getDirectoryContent(mStorageManager.getFileById(mParentId)); + } else { + if (mConflictsFound > 0 || mFailsInFavouritesFound > 0) { + result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT); // should be different result, but will do the job - // removal of obsolete files - mChildren = mStorageManager.getDirectoryContent(mStorageManager.getFileById(mParentId)); - //OCFile file; - String currentSavePath = FileStorageUtils.getSavePath(mAccount.name); - for (OCFile fileChild: mChildren) { - //file = mChildren.get(i); - //if (file.getLastSyncDateForProperties() != mCurrentSyncTime) { - if (!filesOnServer.contains(fileChild.getRemotePath())) { - Log_OC.d(TAG, "removing file: " + fileChild.getFileName()); - mStorageManager.removeFile(fileChild, (fileChild.isDown() && fileChild.getStoragePath().startsWith(currentSavePath))); - mChildren.remove(fileChild); //.remove(i); + } else { + result = new RemoteOperationResult(true, status, query.getResponseHeaders()); } - // } else { - // i++; - // } } - // } - //} - + } else { - client.exhaustResponse(query.getResponseBodyAsStream()); - } - - // prepare result object - if (!fileChanged) { - result = new RemoteOperationResult(ResultCode.OK_NO_CHANGES_ON_DIR); - - } else if (isMultiStatus(status)) { - 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()); + if (status == HttpStatus.SC_NOT_FOUND) { + OCFile dir = mStorageManager.getFileByPath(mRemotePath); + if (dir != null) { + String currentSavePath = FileStorageUtils.getSavePath(mAccount.name); + mStorageManager.removeFile(dir, (dir.isDown() && dir.getStoragePath().startsWith(currentSavePath))); + } } - } else { result = new RemoteOperationResult(false, status, query.getResponseHeaders()); } - Log_OC.i(TAG, "Synchronizing " + mAccount.name + ", folder " + mRemotePath + ": " + result.getLogMessage()); } catch (Exception e) { result = new RemoteOperationResult(e); @@ -293,14 +311,18 @@ public class SynchronizeFolderOperation extends RemoteOperation { if (query != null) query.releaseConnection(); // let the connection available for other methods if (result.isSuccess()) { - Log_OC.i(TAG, "Synchronizing " + mAccount.name + ", folder " + mRemotePath + ": " + result.getLogMessage()); + Log_OC.i(TAG, "Synchroned " + mAccount.name + ", folder " + mRemotePath + ": " + result.getLogMessage()); } else { if (result.isException()) { - Log_OC.e(TAG, "Synchronizing " + mAccount.name + ", folder " + mRemotePath + ": " + result.getLogMessage(), result.getException()); + Log_OC.e(TAG, "Synchroned " + mAccount.name + ", folder " + mRemotePath + ": " + result.getLogMessage(), result.getException()); } else { - Log_OC.e(TAG, "Synchronizing " + mAccount.name + ", folder " + mRemotePath + ": " + result.getLogMessage()); + Log_OC.e(TAG, "Synchroned " + mAccount.name + ", folder " + mRemotePath + ": " + result.getLogMessage()); } } + + if (!mSyncFullAccount) { + sendStickyBroadcast(false, mRemotePath, result); + } } return result; @@ -393,5 +415,23 @@ public class SynchronizeFolderOperation extends RemoteOperation { } } + /** + * Sends a message to any application component interested in the progress of the synchronization. + * + * @param inProgress 'True' when the synchronization progress is not finished. + * @param dirRemotePath Remote path of a folder that was just synchronized (with or without success) + */ + private void sendStickyBroadcast(boolean inProgress, String dirRemotePath, RemoteOperationResult result) { + Intent i = new Intent(FileSyncService.SYNC_MESSAGE); + i.putExtra(FileSyncService.IN_PROGRESS, inProgress); + i.putExtra(FileSyncService.ACCOUNT_NAME, mAccount.name); + if (dirRemotePath != null) { + i.putExtra(FileSyncService.SYNC_FOLDER_REMOTE_PATH, dirRemotePath); + } + if (result != null) { + i.putExtra(FileSyncService.SYNC_RESULT, result); + } + mContext.sendStickyBroadcast(i); + } }