Remove conflict badge from ancestors when conflict is solved there are no more confli...
[pub/Android/ownCloud.git] / src / com / owncloud / android / datamodel / FileDataStorageManager.java
index febb3b6..2f5f7e0 100644 (file)
@@ -24,8 +24,10 @@ import java.io.File;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 import java.util.Vector;
 
 import android.accounts.Account;
@@ -43,6 +45,7 @@ import android.os.RemoteException;
 import android.provider.MediaStore;
 
 import com.owncloud.android.MainApp;
+import com.owncloud.android.db.ProviderMeta;
 import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.resources.files.FileUtils;
@@ -158,7 +161,7 @@ public class FileDataStorageManager {
         }
     }
 
-    
+
     public Vector<OCFile> getFolderImages(OCFile folder/*, boolean onlyOnDevice*/) {
         Vector<OCFile> ret = new Vector<OCFile>(); 
         if (folder != null) {
@@ -204,10 +207,10 @@ public class FileDataStorageManager {
         cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId());
         cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, file.needsUpdateThumbnail());
         cv.put(ProviderTableMeta.FILE_IS_DOWNLOADING, file.isDownloading());
-        
+        cv.put(ProviderTableMeta.FILE_IN_CONFLICT, file.isInConflict());
+
         boolean sameRemotePath = fileExists(file.getRemotePath());
-        if (sameRemotePath ||
-                fileExists(file.getFileId())        ) {  // for renamed files
+        if (sameRemotePath ||                fileExists(file.getFileId())) {           // for renamed files; no more delete and create
 
             OCFile oldFile = null;
             if (sameRemotePath) {
@@ -314,6 +317,7 @@ public class FileDataStorageManager {
             cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId());
             cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, file.needsUpdateThumbnail());
             cv.put(ProviderTableMeta.FILE_IS_DOWNLOADING, file.isDownloading());
+            cv.put(ProviderTableMeta.FILE_IN_CONFLICT, file.isInConflict());
 
             boolean existsByPath = fileExists(file.getRemotePath());
             if (existsByPath || fileExists(file.getFileId())) {
@@ -357,7 +361,7 @@ public class FileDataStorageManager {
                                     ProviderTableMeta.CONTENT_URI_FILE, file.getFileId()
                             )
                     ).withSelection(where, whereArgs).build());
-                    
+
                     if (file.isDown()) {
                         String path = file.getStoragePath();
                         new File(path).delete();
@@ -480,13 +484,10 @@ public class FileDataStorageManager {
 
             } else {
                 if (removeDBData) {
-                    Uri file_uri = ContentUris.withAppendedId(
-                        ProviderTableMeta.CONTENT_URI_FILE, 
-                        file.getFileId()
-                    );
-                    String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " + 
-                            ProviderTableMeta.FILE_PATH + "=?";
-                    String [] whereArgs = new String[]{mAccount.name, file.getRemotePath()};
+                    //Uri file_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, ""+file.getFileId());
+                    Uri file_uri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE, file.getFileId());
+                    String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " + ProviderTableMeta.FILE_PATH + "=?";
+                    String[] whereArgs = new String[]{mAccount.name, file.getRemotePath()};
                     int deleted = 0;
                     if (getContentProviderClient() != null) {
                         try {
@@ -509,6 +510,7 @@ public class FileDataStorageManager {
                         // maybe unnecessary, but should be checked TODO remove if unnecessary
                         file.setStoragePath(null);
                         saveFile(file);
+                        saveConflict(file, false);
                     }
                 }
             }
@@ -758,7 +760,7 @@ public class FileDataStorageManager {
         }
     }
 
-    private static boolean copyFile(File src, File target) {
+    private boolean copyFile(File src, File target) {
         boolean ret = true;
 
         InputStream in = null;
@@ -946,7 +948,9 @@ public class FileDataStorageManager {
                     c.getColumnIndex(ProviderTableMeta.FILE_UPDATE_THUMBNAIL)) == 1 ? true : false);
             file.setDownloading(c.getInt(
                     c.getColumnIndex(ProviderTableMeta.FILE_IS_DOWNLOADING)) == 1 ? true : false);
-                    
+            file.setInConflict(c.getInt(
+                    c.getColumnIndex(ProviderTableMeta.FILE_IN_CONFLICT)) == 1 ? true : false);
+
         }
         return file;
     }
@@ -1006,8 +1010,7 @@ public class FileDataStorageManager {
         cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getIdRemoteShared());
         cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name);
 
-        if (shareExists(share.getIdRemoteShared())) {   // for renamed files
-
+        if (shareExists(share.getIdRemoteShared())) {           // for renamed files; no more delete and create
             overriden = true;
             if (getContentResolver() != null) {
                 getContentResolver().update(ProviderTableMeta.CONTENT_URI_SHARE, cv,
@@ -1106,12 +1109,9 @@ public class FileDataStorageManager {
             share.setSharedWithDisplayName(c.getString(c
                     .getColumnIndex(ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME)));
             share.setIsFolder(c.getInt(
-                    c.getColumnIndex(ProviderTableMeta.OCSHARES_IS_DIRECTORY)) == 1 ? true : false);
+                    c.getColumnIndex(ProviderTableMeta.OCSHARES_IS_DIRECTORY)) == 1);
             share.setUserId(c.getLong(c.getColumnIndex(ProviderTableMeta.OCSHARES_USER_ID)));
-            share.setIdRemoteShared(
-                c.getLong(c.getColumnIndex(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED))
-            );
-                    
+            share.setIdRemoteShared(c.getLong(c.getColumnIndex(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED)));
         }
         return share;
     }
@@ -1162,10 +1162,7 @@ public class FileDataStorageManager {
 
         } else {
             try {
-                getContentProviderClient().update(
-                        ProviderTableMeta.CONTENT_URI, cv, where, whereArgs
-                );
-                
+                getContentProviderClient().update(ProviderTableMeta.CONTENT_URI, cv, where, whereArgs);
             } catch (RemoteException e) {
                 Log_OC.e(TAG, "Exception in cleanSharedFiles" + e.getMessage());
             }
@@ -1185,10 +1182,7 @@ public class FileDataStorageManager {
 
         } else {
             try {
-                getContentProviderClient().update(
-                        ProviderTableMeta.CONTENT_URI, cv, where, whereArgs
-                );
-                
+                getContentProviderClient().update(ProviderTableMeta.CONTENT_URI, cv, where, whereArgs);
             } catch (RemoteException e) {
                 Log_OC.e(TAG, "Exception in cleanSharedFilesInFolder " + e.getMessage());
             }
@@ -1204,10 +1198,7 @@ public class FileDataStorageManager {
 
         } else {
             try {
-                getContentProviderClient().delete(
-                        ProviderTableMeta.CONTENT_URI_SHARE, where, whereArgs
-                );
-                
+                getContentProviderClient().delete(ProviderTableMeta.CONTENT_URI_SHARE, where, whereArgs);
             } catch (RemoteException e) {
                 Log_OC.e(TAG, "Exception in cleanShares" + e.getMessage());
             }
@@ -1246,13 +1237,9 @@ public class FileDataStorageManager {
                     operations.add(
                             ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI_SHARE).
                             withValues(cv).
-                            withSelection(
-                                    ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + "=?", 
-                                    new String[] { String.valueOf(share.getIdRemoteShared()) }
-                            ).
-                            build()
-                    );
-
+                            withSelection(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + "=?",
+                                    new String[]{String.valueOf(share.getIdRemoteShared())})
+                            .build());
                 } else {
                     // adding a new file
                     operations.add(
@@ -1271,10 +1258,7 @@ public class FileDataStorageManager {
                         " operations to FileContentProvider");
                 try {
                     if (getContentResolver() != null) {
-                        results = getContentResolver().applyBatch(
-                                MainApp.getAuthority(), operations
-                        );
-    
+                        results = getContentResolver().applyBatch(MainApp.getAuthority(), operations);
                     } else {
                         results = getContentProviderClient().applyBatch(operations);
                     }
@@ -1334,6 +1318,10 @@ public class FileDataStorageManager {
                         ProviderTableMeta.FILE_IS_DOWNLOADING,
                         file.isDownloading() ? 1 : 0
                 );
+                cv.put(
+                        ProviderTableMeta.FILE_IN_CONFLICT,
+                        file.isInConflict() ? 1 : 0
+                );
 
                 boolean existsByPath = fileExists(file.getRemotePath());
                 if (existsByPath || fileExists(file.getFileId())) {
@@ -1341,11 +1329,9 @@ public class FileDataStorageManager {
                     operations.add(
                             ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
                             withValues(cv).
-                            withSelection(
-                                    ProviderTableMeta._ID + "=?", 
-                                    new String[] { String.valueOf(file.getFileId()) }
-                            ).build()
-                    );
+                            withSelection(ProviderTableMeta._ID + "=?",
+                                    new String[]{String.valueOf(file.getFileId())})
+                            .build());
 
                 } else {
                     // adding a new file
@@ -1365,10 +1351,7 @@ public class FileDataStorageManager {
                         " operations to FileContentProvider");
                 try {
                     if (getContentResolver() != null) {
-                        results = getContentResolver().applyBatch(
-                                MainApp.getAuthority(), operations
-                        );
-    
+                        results = getContentResolver().applyBatch(MainApp.getAuthority(), operations);
                     } else {
                         results = getContentProviderClient().applyBatch(operations);
                     }
@@ -1607,4 +1590,136 @@ public class FileDataStorageManager {
 
     }
 
+    public void saveConflict(OCFile file, boolean inConflict) {
+        if (!file.isDown()) {
+            inConflict = false;
+        }
+        ContentValues cv = new ContentValues();
+        cv.put(ProviderTableMeta.FILE_IN_CONFLICT, inConflict ? 1 : 0);
+        int updated = 0;
+        if (getContentResolver() != null) {
+            updated = getContentResolver().update(
+                    ProviderTableMeta.CONTENT_URI_FILE,
+                    cv,
+                    ProviderTableMeta._ID + "=?",
+                    new String[] { String.valueOf(file.getFileId())}
+            );
+        } else {
+            try {
+                updated = getContentProviderClient().update(
+                        ProviderTableMeta.CONTENT_URI_FILE,
+                        cv,
+                        ProviderTableMeta._ID + "=?",
+                        new String[]{String.valueOf(file.getFileId())}
+                );
+            } catch (RemoteException e) {
+                Log_OC.e(TAG, "Failed saving conflict in database " + e.getMessage());
+            }
+        }
+
+        Log_OC.d(TAG, "Number of files updated with CONFLICT: " + updated);
+
+        if (updated > 0) {
+            if (inConflict) {
+                /// set conflict in all ancestor folders
+
+                long parentId = file.getParentId();
+                Set<String> ancestorIds = new HashSet<String>();
+                while (parentId != FileDataStorageManager.ROOT_PARENT_ID) {
+                    ancestorIds.add(Long.toString(parentId));
+                    parentId = getFileById(parentId).getParentId();
+                }
+
+                if (ancestorIds.size() > 0) {
+                    StringBuffer whereBuffer = new StringBuffer();
+                    whereBuffer.append(ProviderTableMeta._ID).append(" IN (");
+                    for (int i = 0; i < ancestorIds.size() - 1; i++) {
+                        whereBuffer.append("?,");
+                    }
+                    whereBuffer.append("?");
+                    whereBuffer.append(")");
+
+                    if (getContentResolver() != null) {
+                        updated = getContentResolver().update(
+                                ProviderTableMeta.CONTENT_URI_FILE,
+                                cv,
+                                whereBuffer.toString(),
+                                ancestorIds.toArray(new String[]{})
+                        );
+                    } else {
+                        try {
+                            updated = getContentProviderClient().update(
+                                    ProviderTableMeta.CONTENT_URI_FILE,
+                                    cv,
+                                    whereBuffer.toString(),
+                                    ancestorIds.toArray(new String[]{})
+                            );
+                        } catch (RemoteException e) {
+                            Log_OC.e(TAG, "Failed saving conflict in database " + e.getMessage());
+                        }
+                    }
+                } // else file is ROOT folder, no parent to set in conflict
+
+            } else {
+                /// update conflict in ancestor folders
+                // (not directly unset; maybe there are more conflicts below them)
+                String parentPath = file.getRemotePath();
+                if (parentPath.endsWith(OCFile.PATH_SEPARATOR)) {
+                    parentPath = parentPath.substring(0, parentPath.length() - 1);
+                }
+                parentPath = parentPath.substring(0, parentPath.lastIndexOf(OCFile.PATH_SEPARATOR) + 1);
+
+                Log_OC.d(TAG, "checking parents to remove conflict; STARTING with " + parentPath);
+                while (parentPath.length() > 0) {
+
+                    String where =
+                            ProviderTableMeta.FILE_IN_CONFLICT + " = 1 AND " +
+                                    ProviderTableMeta.FILE_CONTENT_TYPE + " != 'DIR' AND " +
+                                    ProviderTableMeta.FILE_ACCOUNT_OWNER + " = ? AND " +
+                                    ProviderTableMeta.FILE_PATH + " LIKE ?";
+                    Cursor descendentsInConflict = getContentResolver().query(
+                            ProviderTableMeta.CONTENT_URI_FILE,
+                            new String[]{ProviderTableMeta._ID},
+                            where,
+                            new String[]{mAccount.name, parentPath + "%"},
+                            null
+                    );
+                    if (descendentsInConflict == null || descendentsInConflict.getCount() == 0) {
+                        Log_OC.d(TAG, "NO MORE conflicts in " + parentPath);
+                        if (getContentResolver() != null) {
+                            updated = getContentResolver().update(
+                                    ProviderTableMeta.CONTENT_URI_FILE,
+                                    cv,
+                                    ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + ProviderTableMeta.FILE_PATH + "=?",
+                                    new String[]{mAccount.name, parentPath}
+                            );
+                        } else {
+                            try {
+                                updated = getContentProviderClient().update(
+                                        ProviderTableMeta.CONTENT_URI_FILE,
+                                        cv,
+                                        ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + ProviderTableMeta.FILE_PATH + "=?"
+                                        , new String[]{mAccount.name, parentPath}
+                                );
+                            } catch (RemoteException e) {
+                                Log_OC.e(TAG, "Failed saving conflict in database " + e.getMessage());
+                            }
+                        }
+
+                    } else {
+                        Log_OC.d(TAG, "STILL " + descendentsInConflict.getCount() + " in " + parentPath);
+                    }
+
+                    if (descendentsInConflict != null) {
+                        descendentsInConflict.close();
+                    }
+
+                    parentPath = parentPath.substring(0, parentPath.length() - 1);  // trim last /
+                    parentPath = parentPath.substring(0, parentPath.lastIndexOf(OCFile.PATH_SEPARATOR) + 1);
+                    Log_OC.d(TAG, "checking parents to remove conflict; NEXT " + parentPath);
+                }
+            }
+        }
+
+    }
 }