Browse Source

refactor data synchronization for better read-ability

AndyScherzinger 6 years ago
parent
commit
9de93de141
1 changed files with 102 additions and 80 deletions
  1. 102 80
      src/main/java/com/owncloud/android/operations/RefreshFolderOperation.java

+ 102 - 80
src/main/java/com/owncloud/android/operations/RefreshFolderOperation.java

@@ -22,6 +22,8 @@ package com.owncloud.android.operations;
 import android.accounts.Account;
 import android.content.Context;
 import android.content.Intent;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 import android.util.Log;
 
 import com.owncloud.android.datamodel.DecryptedFolderMetadata;
@@ -147,13 +149,12 @@ public class RefreshFolderOperation extends RemoteOperation {
         mStorageManager = dataStorageManager;
         mAccount = account;
         mContext = context;
-        mForgottenLocalFiles = new HashMap<String, String>();
+        mForgottenLocalFiles = new HashMap<>();
         mRemoteFolderChanged = false;
         mIgnoreETag = ignoreETag;
-        mFilesToSyncContents = new Vector<SynchronizeFileOperation>();
+        mFilesToSyncContents = new Vector<>();
     }
 
-
     public int getConflictsFound() {
         return mConflictsFound;
     }
@@ -183,7 +184,7 @@ public class RefreshFolderOperation extends RemoteOperation {
      */
     @Override
     protected RemoteOperationResult run(OwnCloudClient client) {
-        RemoteOperationResult result = null;
+        RemoteOperationResult result;
         mFailsInKeptInSyncFound = 0;
         mConflictsFound = 0;
         mForgottenLocalFiles.clear();
@@ -267,7 +268,7 @@ public class RefreshFolderOperation extends RemoteOperation {
 
     private RemoteOperationResult checkForChanges(OwnCloudClient client) {
         mRemoteFolderChanged = true;
-        RemoteOperationResult result = null;
+        RemoteOperationResult result;
         String remotePath = mLocalFolder.getRemotePath();
 
         Log_OC.d(TAG, "Checking changes in " + mAccount.name + remotePath);
@@ -368,32 +369,18 @@ public class RefreshFolderOperation extends RemoteOperation {
 
         Log_OC.d(TAG, "Remote folder " + mLocalFolder.getRemotePath() + " changed - starting update of local data ");
 
-        List<OCFile> updatedFiles = new Vector<OCFile>(folderAndFiles.size() - 1);
+        List<OCFile> updatedFiles = new Vector<>(folderAndFiles.size() - 1);
         mFilesToSyncContents.clear();
 
         // if local folder is encrypted, download fresh metadata
-        DecryptedFolderMetadata metadata;
         boolean encryptedAncestor = FileStorageUtils.checkEncryptionStatus(mLocalFolder, mStorageManager);
         mLocalFolder.setEncrypted(encryptedAncestor);
-        
-        if (encryptedAncestor && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
-            metadata = EncryptionUtils.downloadFolderMetadata(mLocalFolder, getClient(), mContext, mAccount);
-        } else {
-            metadata = null;
-        }
 
-        // get current data about local contents of the folder to synchronize
-        List<OCFile> localFiles = mStorageManager.getFolderContent(mLocalFolder, false);
-        Map<String, OCFile> localFilesMap = new HashMap<String, OCFile>(localFiles.size());
-
-        for (OCFile file : localFiles) {
-            String remotePath = file.getRemotePath();
+        DecryptedFolderMetadata metadata = getDecryptedFolderMetadata(encryptedAncestor);
 
-            if (metadata != null && !file.isFolder()) {
-                remotePath = file.getParentRemotePath() + file.getEncryptedFileName();
-            }
-            localFilesMap.put(remotePath, file);
-        }
+        // get current data about local contents of the folder to synchronize
+        Map<String, OCFile> localFilesMap = prefillLocalFilesMap(metadata,
+                mStorageManager.getFolderContent(mLocalFolder, false));
 
         // loop to update every child
         OCFile remoteFile;
@@ -416,36 +403,8 @@ public class RefreshFolderOperation extends RemoteOperation {
             // add to updatedFile data about LOCAL STATE (not existing in server)
             updatedFile.setLastSyncDateForProperties(mCurrentSyncTime);
 
-            if (localFile != null) {
-                updatedFile.setFileId(localFile.getFileId());
-                updatedFile.setAvailableOffline(localFile.isAvailableOffline());
-                updatedFile.setLastSyncDateForData(localFile.getLastSyncDateForData());
-                updatedFile.setModificationTimestampAtLastSyncForData(
-                        localFile.getModificationTimestampAtLastSyncForData()
-                );
-                updatedFile.setStoragePath(localFile.getStoragePath());
-                // eTag will not be updated unless file CONTENTS are synchronized
-                if (!updatedFile.isFolder() && localFile.isDown() &&
-                        !updatedFile.getEtag().equals(localFile.getEtag())) {
-                    updatedFile.setEtagInConflict(updatedFile.getEtag());
-                }
-                updatedFile.setEtag(localFile.getEtag());
-                if (updatedFile.isFolder()) {
-                    updatedFile.setFileLength(remoteFile.getFileLength());
-                    updatedFile.setMountType(remoteFile.getMountType());
-                } else if (mRemoteFolderChanged && MimeTypeUtil.isImage(remoteFile) &&
-                        remoteFile.getModificationTimestamp() !=
-                                localFile.getModificationTimestamp()) {
-                    updatedFile.setNeedsUpdateThumbnail(true);
-                    Log.d(TAG, "Image " + remoteFile.getFileName() + " updated on the server");
-                }
-                updatedFile.setPublicLink(localFile.getPublicLink());
-                updatedFile.setShareViaLink(localFile.isSharedViaLink());
-                updatedFile.setShareWithSharee(localFile.isSharedWithSharee());
-            } else {
-                // remote eTag will not be updated unless file CONTENTS are synchronized
-                updatedFile.setEtag("");
-            }
+            // add to updatedFile data from local and remote file
+            setLocalFileDataOnUpdatedFile(remoteFile, localFile, updatedFile, mRemoteFolderChanged);
 
             // check and fix, if needed, local storage path
             FileStorageUtils.searchForLocalFileInDefaultPath(updatedFile, mAccount);
@@ -460,21 +419,7 @@ public class RefreshFolderOperation extends RemoteOperation {
 
             // update file name for encrypted files
             if (metadata != null) {
-                updatedFile.setEncryptedFileName(updatedFile.getFileName());
-                try {
-                    String decryptedFileName = metadata.getFiles().get(updatedFile.getFileName()).getEncrypted()
-                            .getFilename();
-                    String mimetype = metadata.getFiles().get(updatedFile.getFileName()).getEncrypted().getMimetype();
-                    updatedFile.setFileName(decryptedFileName);
-
-                    if (mimetype == null || mimetype.isEmpty()) {
-                        updatedFile.setMimetype("application/octet-stream");
-                    } else {
-                        updatedFile.setMimetype(mimetype);
-                    }
-                } catch (NullPointerException e) {
-                    Log_OC.e(TAG, "Metadata for file " + updatedFile.getFileId() + " not found!");
-                }
+                updateFileNameForEncryptedFile(metadata, updatedFile);
             }
 
             // we parse content, so either the folder itself or its direct parent (which we check) must be encrypted
@@ -490,6 +435,87 @@ public class RefreshFolderOperation extends RemoteOperation {
         mChildren = updatedFiles;
     }
 
+    @Nullable
+    private DecryptedFolderMetadata getDecryptedFolderMetadata(boolean encryptedAncestor) {
+        DecryptedFolderMetadata metadata;
+        if (encryptedAncestor && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
+            metadata = EncryptionUtils.downloadFolderMetadata(mLocalFolder, getClient(), mContext, mAccount);
+        } else {
+            metadata = null;
+        }
+        return metadata;
+    }
+
+    private void updateFileNameForEncryptedFile(@NonNull DecryptedFolderMetadata metadata, OCFile updatedFile) {
+        updatedFile.setEncryptedFileName(updatedFile.getFileName());
+        try {
+            String decryptedFileName = metadata.getFiles().get(updatedFile.getFileName()).getEncrypted()
+                    .getFilename();
+            String mimetype = metadata.getFiles().get(updatedFile.getFileName()).getEncrypted().getMimetype();
+            updatedFile.setFileName(decryptedFileName);
+
+            if (mimetype == null || mimetype.isEmpty()) {
+                updatedFile.setMimetype("application/octet-stream");
+            } else {
+                updatedFile.setMimetype(mimetype);
+            }
+        } catch (NullPointerException e) {
+            Log_OC.e(TAG, "Metadata for file " + updatedFile.getFileId() + " not found!");
+        }
+    }
+
+    private void setLocalFileDataOnUpdatedFile(OCFile remoteFile, OCFile localFile, OCFile updatedFile, boolean remoteFolderChanged) {
+        if (localFile != null) {
+            updatedFile.setFileId(localFile.getFileId());
+            updatedFile.setAvailableOffline(localFile.isAvailableOffline());
+            updatedFile.setLastSyncDateForData(localFile.getLastSyncDateForData());
+            updatedFile.setModificationTimestampAtLastSyncForData(
+                    localFile.getModificationTimestampAtLastSyncForData()
+            );
+            updatedFile.setStoragePath(localFile.getStoragePath());
+
+            // eTag will not be updated unless file CONTENTS are synchronized
+            if (!updatedFile.isFolder() && localFile.isDown() &&
+                    !updatedFile.getEtag().equals(localFile.getEtag())) {
+                updatedFile.setEtagInConflict(updatedFile.getEtag());
+            }
+
+            updatedFile.setEtag(localFile.getEtag());
+
+            if (updatedFile.isFolder()) {
+                updatedFile.setFileLength(remoteFile.getFileLength());
+                updatedFile.setMountType(remoteFile.getMountType());
+            } else if (remoteFolderChanged && MimeTypeUtil.isImage(remoteFile) &&
+                    remoteFile.getModificationTimestamp() !=
+                            localFile.getModificationTimestamp()) {
+                updatedFile.setNeedsUpdateThumbnail(true);
+                Log.d(TAG, "Image " + remoteFile.getFileName() + " updated on the server");
+            }
+
+            updatedFile.setPublicLink(localFile.getPublicLink());
+            updatedFile.setShareViaLink(localFile.isSharedViaLink());
+            updatedFile.setShareWithSharee(localFile.isSharedWithSharee());
+        } else {
+            // remote eTag will not be updated unless file CONTENTS are synchronized
+            updatedFile.setEtag("");
+        }
+    }
+
+    @NonNull
+    private Map<String, OCFile> prefillLocalFilesMap(DecryptedFolderMetadata metadata, List<OCFile> localFiles) {
+        Map<String, OCFile> localFilesMap = new HashMap<>(localFiles.size());
+
+        for (OCFile file : localFiles) {
+            String remotePath = file.getRemotePath();
+
+            if (metadata != null && !file.isFolder()) {
+                remotePath = file.getParentRemotePath() + file.getEncryptedFileName();
+            }
+            localFilesMap.put(remotePath, file);
+        }
+        return localFilesMap;
+    }
+
     /**
      * Performs a list of synchronization operations, determining if a download or upload is needed
      * or if exists conflict due to changes both in local and remote contents of the each file.
@@ -520,7 +546,6 @@ public class RefreshFolderOperation extends RemoteOperation {
         }
     }
 
-
     /**
      * Syncs the Share resources for the files contained in the folder refreshed (children, not deeper descendants).
      *
@@ -538,7 +563,7 @@ public class RefreshFolderOperation extends RemoteOperation {
 
         if (result.isSuccess()) {
             // update local database
-            ArrayList<OCShare> shares = new ArrayList<OCShare>();
+            ArrayList<OCShare> shares = new ArrayList<>();
             for (Object obj : result.getData()) {
                 shares.add((OCShare) obj);
             }
@@ -548,19 +573,16 @@ public class RefreshFolderOperation extends RemoteOperation {
         return result;
     }
 
-
     /**
-     * Sends a message to any application component interested in the progress 
+     * Sends a message to any application component interested in the progress
      * of the synchronization.
      *
-     * @param event
-     * @param dirRemotePath     Remote path of a folder that was just synchronized 
-     *                          (with or without success)
-     * @param result
+     * @param event         broadcast event (Intent Action)
+     * @param dirRemotePath Remote path of a folder that was just synchronized
+     *                      (with or without success)
+     * @param result        remote operation result
      */
-    private void sendLocalBroadcast(
-            String event, String dirRemotePath, RemoteOperationResult result
-    ) {
+    private void sendLocalBroadcast(String event, String dirRemotePath, RemoteOperationResult result) {
         Log_OC.d(TAG, "Send broadcast " + event);
         Intent intent = new Intent(event);
         intent.putExtra(FileSyncAdapter.EXTRA_ACCOUNT_NAME, mAccount.name);