Fixed update of shares database - grant that shares are removed after removing all...
[pub/Android/ownCloud.git] / src / com / owncloud / android / datamodel / FileDataStorageManager.java
index d43de6a..76e3e5c 100644 (file)
@@ -25,10 +25,13 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.Vector;
 
-import com.owncloud.android.Log_OC;
-import com.owncloud.android.db.ProviderMeta;
+import com.owncloud.android.MainApp;
 import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
+import com.owncloud.android.lib.operations.common.OCShare;
+import com.owncloud.android.lib.operations.common.ShareType;
 import com.owncloud.android.utils.FileStorageUtils;
+import com.owncloud.android.utils.Log_OC;
+
 
 import android.accounts.Account;
 import android.content.ContentProviderClient;
@@ -180,9 +183,10 @@ public class FileDataStorageManager {
         cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, file.getLastSyncDateForData());
         cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0);
         cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag());
-
+        cv.put(ProviderTableMeta.FILE_SHARE_BY_LINK, file.isShareByLink() ? 1 : 0);
+        cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, file.getPublicLink());
+        
         boolean sameRemotePath = fileExists(file.getRemotePath());
-        boolean changesSizeOfAncestors = false;
         if (sameRemotePath ||
                 fileExists(file.getFileId())        ) {           // for renamed files; no more delete and create
 
@@ -193,7 +197,6 @@ public class FileDataStorageManager {
             } else {
                 oldFile = getFileById(file.getFileId());
             }
-            changesSizeOfAncestors = (oldFile.getFileLength() != file.getFileLength());
 
             overriden = true;
             if (getContentResolver() != null) {
@@ -212,7 +215,6 @@ public class FileDataStorageManager {
                 }
             }
         } else {
-            changesSizeOfAncestors = true;
             Uri result_uri = null;
             if (getContentResolver() != null) {
                 result_uri = getContentResolver().insert(
@@ -235,15 +237,9 @@ public class FileDataStorageManager {
         }
 
         if (file.isFolder()) {
-            calculateFolderSize(file.getFileId());
-            if (file.needsUpdatingWhileSaving()) {
-                for (OCFile f : getFolderContent(file))
-                    saveFile(f);
-            }
-        }
-        
-        if (changesSizeOfAncestors || file.isFolder()) {
-            updateSizesToTheRoot(file.getParentId());
+            updateFolderSize(file.getFileId());
+        } else {
+            updateFolderSize(file.getParentId());
         }
         
         return overriden;
@@ -253,6 +249,9 @@ public class FileDataStorageManager {
     /**
      * Inserts or updates the list of files contained in a given folder.
      * 
+     * CALLER IS THE RESPONSIBLE FOR GRANTING RIGHT UPDATE OF INFORMATION, NOT THIS METHOD.
+     * HERE ONLY DATA CONSISTENCY SHOULD BE GRANTED
+     *  
      * @param folder
      * @param files
      * @param removeNotUpdated
@@ -283,37 +282,12 @@ public class FileDataStorageManager {
             cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, file.getLastSyncDateForData());
             cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0);
             cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag());
+            cv.put(ProviderTableMeta.FILE_SHARE_BY_LINK, file.isShareByLink() ? 1 : 0);
+            cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, file.getPublicLink());
 
             boolean existsByPath = fileExists(file.getRemotePath());
             if (existsByPath || fileExists(file.getFileId())) {
                 // updating an existing file
-                
-                /* CALLER IS THE RESPONSIBLE FOR GRANTING RIGHT UPDATE OF INFORMATION, NOT THIS METHOD.
-                 * 
-                 * HERE ONLY DATA CONSISTENCY SHOULD BE GRANTED 
-                 */
-                /*
-                OCFile oldFile = null;
-                if (existsByPath) {
-                    // grant same id
-                    oldFile = getFileByPath(file.getRemotePath());
-                    file.setFileId(oldFile.getFileId());
-                } else {
-                    oldFile = getFileById(file.getFileId());
-                }
-                
-                if (file.isFolder()) {
-                    // folders keep size information, since it's calculated
-                    file.setFileLength(oldFile.getFileLength());
-                    cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, oldFile.getFileLength());
-                    
-                } else if (file.getStoragePath() == null && oldFile.getStoragePath() != null) {
-                    // regular files keep access to local contents, although it's lost in the new OCFile
-                    file.setStoragePath(oldFile.getStoragePath());
-                    cv.put(ProviderTableMeta.FILE_STORAGE_PATH, oldFile.getStoragePath());
-                }
-                */
-                
                 operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
                         withValues(cv).
                         withSelection(  ProviderTableMeta._ID + "=?", 
@@ -350,24 +324,24 @@ public class FileDataStorageManager {
             }
         }
         
-        // update metadata of folder --> TODO  MOVE UPDATE OF SIZE TO CONTENTPROVIDER
+        // update metadata of folder
         ContentValues cv = new ContentValues();
         cv.put(ProviderTableMeta.FILE_MODIFIED, folder.getModificationTimestamp());
         cv.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, folder.getModificationTimestampAtLastSyncForData());
         cv.put(ProviderTableMeta.FILE_CREATION, folder.getCreationTimestamp());
-        cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, folder.getFileLength());
+        cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, 0);   // FileContentProvider calculates the right size
         cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, folder.getMimetype());
         cv.put(ProviderTableMeta.FILE_NAME, folder.getFileName());
         cv.put(ProviderTableMeta.FILE_PARENT, folder.getParentId());
         cv.put(ProviderTableMeta.FILE_PATH, folder.getRemotePath());
-        if (!folder.isFolder()) {
-            cv.put(ProviderTableMeta.FILE_STORAGE_PATH, folder.getStoragePath());
-        }
         cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
         cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, folder.getLastSyncDateForProperties());
         cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, folder.getLastSyncDateForData());
         cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, folder.keepInSync() ? 1 : 0);
         cv.put(ProviderTableMeta.FILE_ETAG, folder.getEtag());
+        cv.put(ProviderTableMeta.FILE_SHARE_BY_LINK, folder.isShareByLink() ? 1 : 0);
+        cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, folder.getPublicLink());
+        
         operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
                 withValues(cv).
                 withSelection(  ProviderTableMeta._ID + "=?", 
@@ -379,7 +353,7 @@ public class FileDataStorageManager {
         Log_OC.d(TAG, "Sending " + operations.size() + " operations to FileContentProvider");
         try {
             if (getContentResolver() != null) {
-                results = getContentResolver().applyBatch(ProviderMeta.AUTHORITY_FILES, operations);
+                results = getContentResolver().applyBatch(MainApp.getAuthority(), operations);
 
             } else {
                 results = getContentProviderClient().applyBatch(operations);
@@ -413,27 +387,40 @@ public class FileDataStorageManager {
             }
         }
         
+        updateFolderSize(folder.getFileId());
+        
     }
 
 
     /**
-     * Calculate and save the folderSize on DB
+     * 
      * @param id
      */
-    public void calculateFolderSize(long id) {
-        long folderSize = 0;
-        
-        Vector<OCFile> files = getFolderContent(id);
-        
-        for (OCFile f: files)
-        {
-            folderSize = folderSize + f.getFileLength();
+    private void updateFolderSize(long id) {
+        if (id > FileDataStorageManager.ROOT_PARENT_ID) {
+            Log_OC.d(TAG, "Updating size of " + id);
+            if (getContentResolver() != null) {
+                getContentResolver().update(ProviderTableMeta.CONTENT_URI_DIR, 
+                        new ContentValues(),    // won't be used, but cannot be null; crashes in KLP
+                        ProviderTableMeta._ID + "=?",
+                        new String[] { String.valueOf(id) });
+            } else {
+                try {
+                    getContentProviderClient().update(ProviderTableMeta.CONTENT_URI_DIR, 
+                            new ContentValues(),    // won't be used, but cannot be null; crashes in KLP
+                            ProviderTableMeta._ID + "=?",
+                            new String[] { String.valueOf(id) });
+                    
+                } catch (RemoteException e) {
+                    Log_OC.e(TAG, "Exception in update of folder size through compatibility patch " + e.getMessage());
+                }
+            }
+        } else {
+            Log_OC.e(TAG,  "not updating size for folder " + id);
         }
-        
-        updateSize(id, folderSize);
     }
     
-    
+
     public void removeFile(OCFile file, boolean removeDBData, boolean removeLocalCopy) {
         if (file != null) {
             if (file.isFolder()) {
@@ -454,11 +441,9 @@ public class FileDataStorageManager {
                     } else {
                         getContentResolver().delete(file_uri, where, whereArgs);
                     }
-                    if (file.getFileLength() > 0) {
-                        updateSizesToTheRoot(file.getParentId());   // TODO move to content provider
-                    }
+                    updateFolderSize(file.getParentId());
                 }
-                if (removeLocalCopy && file.isDown()) {
+                if (removeLocalCopy && file.isDown() && file.getStoragePath() != null) {
                     boolean success = new File(file.getStoragePath()).delete();
                     if (!removeDBData && success) {
                         // maybe unnecessary, but should be checked TODO remove if unnecessary
@@ -496,9 +481,7 @@ public class FileDataStorageManager {
         } else {
             getContentResolver().delete(folder_uri, where, whereArgs); 
         }
-        if (folder.getFileLength() > 0) {
-            updateSizesToTheRoot(folder.getParentId()); // TODO move to FileContentProvider
-        }
+        updateFolderSize(folder.getParentId());
     }
 
     private void removeLocalFolder(File folder) {
@@ -570,7 +553,7 @@ public class FileDataStorageManager {
             /// 3. apply updates in batch
             try {
                 if (getContentResolver() != null) {
-                    getContentResolver().applyBatch(ProviderMeta.AUTHORITY_FILES, operations);
+                    getContentResolver().applyBatch(MainApp.getAuthority(), operations);
 
                 } else {
                     getContentProviderClient().applyBatch(operations);
@@ -689,6 +672,32 @@ public class FileDataStorageManager {
         }
         return c;
     }
+    
+    private Cursor getShareCursorForValue(String key, String value) {
+        Cursor c = null;
+        if (getContentResolver() != null) {
+            c = getContentResolver()
+                    .query(ProviderTableMeta.CONTENT_URI_SHARE,
+                            null,
+                            key + "=? AND "
+                                    + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER
+                                    + "=?",
+                                    new String[] { value, mAccount.name }, null);
+        } else {
+            try {
+                c = getContentProviderClient().query(
+                        ProviderTableMeta.CONTENT_URI_SHARE,
+                        null,
+                        key + "=? AND " + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER
+                        + "=?", new String[] { value, mAccount.name },
+                        null);
+            } catch (RemoteException e) {
+                Log_OC.e(TAG, "Could not get file details: " + e.getMessage());
+                c = null;
+            }
+        }
+        return c;
+    }
 
     private OCFile createFileInstance(Cursor c) {
         OCFile file = null;
@@ -727,51 +736,367 @@ public class FileDataStorageManager {
             file.setKeepInSync(c.getInt(
                     c.getColumnIndex(ProviderTableMeta.FILE_KEEP_IN_SYNC)) == 1 ? true : false);
             file.setEtag(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_ETAG)));
+            file.setShareByLink(c.getInt(
+                    c.getColumnIndex(ProviderTableMeta.FILE_SHARE_BY_LINK)) == 1 ? true : false);
+            file.setPublicLink(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_PUBLIC_LINK)));
                     
         }
         return file;
     }
-
+    
+    /**
+     * Returns if the file/folder is shared by link or not
+     * @param path  Path of the file/folder
+     * @return
+     */
+    public boolean isShareByLink(String path) {
+        Cursor c = getCursorForValue(ProviderTableMeta.FILE_STORAGE_PATH, path);
+        OCFile file = null;
+        if (c.moveToFirst()) {
+            file = createFileInstance(c);
+        }
+        c.close();
+        return file.isShareByLink();
+    }
+    
     /**
-     * Update the size value of an OCFile in DB
+     * Returns the public link of the file/folder
+     * @param path  Path of the file/folder
+     * @return
      */
-    private int updateSize(long id, long size) {
+    public String getPublicLink(String path) {
+        Cursor c = getCursorForValue(ProviderTableMeta.FILE_STORAGE_PATH, path);
+        OCFile file = null;
+        if (c.moveToFirst()) {
+            file = createFileInstance(c);
+        }
+        c.close();
+        return file.getPublicLink();
+    }
+    
+    
+    // Methods for Shares
+    public boolean saveShare(OCShare share) {
+        boolean overriden = false;
         ContentValues cv = new ContentValues();
-        cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, size);
-        int result = -1;
+        cv.put(ProviderTableMeta.OCSHARES_FILE_SOURCE, share.getFileSource());
+        cv.put(ProviderTableMeta.OCSHARES_ITEM_SOURCE, share.getItemSource());
+        cv.put(ProviderTableMeta.OCSHARES_SHARE_TYPE, share.getShareType().getValue());
+        cv.put(ProviderTableMeta.OCSHARES_SHARE_WITH, share.getShareWith());
+        cv.put(ProviderTableMeta.OCSHARES_PATH, share.getPath());
+        cv.put(ProviderTableMeta.OCSHARES_PERMISSIONS, share.getPermissions());
+        cv.put(ProviderTableMeta.OCSHARES_SHARED_DATE, share.getSharedDate());
+        cv.put(ProviderTableMeta.OCSHARES_EXPIRATION_DATE, share.getExpirationDate());
+        cv.put(ProviderTableMeta.OCSHARES_TOKEN, share.getToken());
+        cv.put(ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME, share.getSharedWithDisplayName());
+        cv.put(ProviderTableMeta.OCSHARES_IS_DIRECTORY, share.isDirectory() ? 1 : 0);
+        cv.put(ProviderTableMeta.OCSHARES_USER_ID, share.getUserId());
+        cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getIdRemoteShared());
+        cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name);
+        
+        boolean samePath = shareExists(share.getPath());
+        if (samePath ||
+                shareExists(share.getId())) {           // for renamed files; no more delete and create
+
+            OCShare oldFile = null;
+            if (samePath) {
+                oldFile = getShareByPath(share.getPath());
+                share.setId(oldFile.getId());
+            } else {
+                oldFile = getShareById(share.getId());
+            }
+
+            overriden = true;
+            if (getContentResolver() != null) {
+                getContentResolver().update(ProviderTableMeta.CONTENT_URI_SHARE, cv,
+                        ProviderTableMeta._ID + "=?",
+                        new String[] { String.valueOf(share.getId()) });
+            } else {
+                try {
+                    getContentProviderClient().update(ProviderTableMeta.CONTENT_URI_SHARE,
+                            cv, ProviderTableMeta._ID + "=?",
+                            new String[] { String.valueOf(share.getId()) });
+                } catch (RemoteException e) {
+                    Log_OC.e(TAG,
+                            "Fail to insert insert file to database "
+                                    + e.getMessage());
+                }
+            }
+        } else {
+            Uri result_uri = null;
+            if (getContentResolver() != null) {
+                result_uri = getContentResolver().insert(
+                        ProviderTableMeta.CONTENT_URI_SHARE, cv);
+            } else {
+                try {
+                    result_uri = getContentProviderClient().insert(
+                            ProviderTableMeta.CONTENT_URI_SHARE, cv);
+                } catch (RemoteException e) {
+                    Log_OC.e(TAG,
+                            "Fail to insert insert file to database "
+                                    + e.getMessage());
+                }
+            }
+            if (result_uri != null) {
+                long new_id = Long.parseLong(result_uri.getPathSegments()
+                        .get(1));
+                share.setId(new_id);
+            }            
+        }
+
+        return overriden;
+    }
+
+    private OCShare getShareById(long id) {
+        Cursor c = getShareCursorForValue(ProviderTableMeta._ID, String.valueOf(id));
+        OCShare share = null;
+        if (c.moveToFirst()) {
+            share = createShareInstance(c);
+        }
+        c.close();
+        return share;
+    }
+
+    public OCShare getShareByPath(String path) {
+        Cursor c = getShareCursorForValue(ProviderTableMeta.OCSHARES_PATH, path);
+        OCShare share = null;
+        if (c.moveToFirst()) {
+            share = createShareInstance(c);
+        }
+        c.close();
+        return share;
+    }
+    
+    private OCShare createShareInstance(Cursor c) {
+        OCShare share = null;
+        if (c != null) {
+            share = new OCShare(c.getString(c
+                    .getColumnIndex(ProviderTableMeta.OCSHARES_PATH)));
+            share.setId(c.getLong(c.getColumnIndex(ProviderTableMeta._ID)));
+            share.setFileSource(c.getLong(c
+                    .getColumnIndex(ProviderTableMeta.OCSHARES_ITEM_SOURCE)));
+            share.setShareType(ShareType.fromValue(c.getInt(c
+                    .getColumnIndex(ProviderTableMeta.OCSHARES_SHARE_TYPE))));
+            share.setPermissions(c.getInt(c
+                    .getColumnIndex(ProviderTableMeta.OCSHARES_PERMISSIONS)));
+            share.setSharedDate(c.getLong(c
+                    .getColumnIndex(ProviderTableMeta.OCSHARES_SHARED_DATE)));
+            share.setExpirationDate(c.getLong(c
+                    .getColumnIndex(ProviderTableMeta.OCSHARES_EXPIRATION_DATE)));
+            share.setToken(c.getString(c
+                    .getColumnIndex(ProviderTableMeta.OCSHARES_TOKEN)));
+            share.setSharedWithDisplayName(c.getString(c
+                    .getColumnIndex(ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME)));
+            share.setIsDirectory(c.getInt(
+                    c.getColumnIndex(ProviderTableMeta.OCSHARES_IS_DIRECTORY)) == 1 ? true : false);
+            share.setUserId(c.getLong(c.getColumnIndex(ProviderTableMeta.OCSHARES_USER_ID)));
+            share.setIdRemoteShared(c.getLong(c.getColumnIndex(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED)));
+                    
+        }
+        return share;
+    }
+
+    private boolean shareExists(String cmp_key, String value) {
+        Cursor c;
         if (getContentResolver() != null) {
-             result = getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv, ProviderTableMeta._ID + "=?", 
-                     new String[] { String.valueOf(id) });
+            c = getContentResolver()
+                    .query(ProviderTableMeta.CONTENT_URI_SHARE,
+                            null,
+                            cmp_key + "=? AND "
+                                    + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER
+                                    + "=?",
+                                    new String[] { value, mAccount.name }, null);
         } else {
             try {
-                result = getContentProviderClient().update(ProviderTableMeta.CONTENT_URI, cv, ProviderTableMeta._ID + "=?", 
-                        new String[] { String.valueOf(id) });
+                c = getContentProviderClient().query(
+                        ProviderTableMeta.CONTENT_URI_SHARE,
+                        null,
+                        cmp_key + "=? AND "
+                                + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?",
+                                new String[] { value, mAccount.name }, null);
             } catch (RemoteException e) {
-                Log_OC.e(TAG,"Fail to update size column into database " + e.getMessage());
+                Log_OC.e(TAG,
+                        "Couldn't determine file existance, assuming non existance: "
+                                + e.getMessage());
+                return false;
             }
         }
-        return result;
+        boolean retval = c.moveToFirst();
+        c.close();
+        return retval;
+    }
+    
+    public boolean shareExists(long id) {
+        return shareExists(ProviderTableMeta._ID, String.valueOf(id));
     }
 
-    /** 
-     * Update the size of a subtree of folder from a file to the root
-     * @param parentId: parent of the file
-     */
-    private void updateSizesToTheRoot(long parentId) {
+    public boolean shareExists(String path) {
+        return shareExists(ProviderTableMeta.OCSHARES_PATH, path);
+    }
+    
+    private void cleanSharedFiles() {
+        ContentValues cv = new ContentValues();
+        cv.put(ProviderTableMeta.FILE_SHARE_BY_LINK, false);
+        cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, "");
+        String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?";
+        String [] whereArgs = new String[]{mAccount.name};
         
-        OCFile file; 
+        if (getContentResolver() != null) {
+            getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv, where, whereArgs);
 
-        while (parentId != FileDataStorageManager.ROOT_PARENT_ID) {
-            
-            // Update the size of the parent
-            calculateFolderSize(parentId);
-            
-            // search the next parent
-            file = getFileById(parentId);            
-            parentId = file.getParentId();
+        } else {
+            try {
+                getContentProviderClient().update(ProviderTableMeta.CONTENT_URI, cv, where, whereArgs);
+                
+            } catch (RemoteException e) {
+                Log_OC.e(TAG, "Exception in cleanSharedFiles" + e.getMessage());
+            }
+        }
+    }
+
+    private void cleanShares() {
+        String where = ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?";
+        String [] whereArgs = new String[]{mAccount.name};
+        
+        if (getContentResolver() != null) {
+            getContentResolver().delete(ProviderTableMeta.CONTENT_URI_SHARE, where, whereArgs);
+
+        } else {
+            try {
+                getContentProviderClient().delete(ProviderTableMeta.CONTENT_URI_SHARE, where, whereArgs);
+                
+            } catch (RemoteException e) {
+                Log_OC.e(TAG, "Exception in cleanShares" + e.getMessage());
+            }
+        }
+    }
+    
+    public void saveShares(Collection<OCShare> shares) {
+        cleanShares();
+        if (shares != null) {
+            ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(shares.size());
+
+            // prepare operations to insert or update files to save in the given folder
+            for (OCShare share : shares) {
+                ContentValues cv = new ContentValues();
+                cv.put(ProviderTableMeta.OCSHARES_FILE_SOURCE, share.getFileSource());
+                cv.put(ProviderTableMeta.OCSHARES_ITEM_SOURCE, share.getItemSource());
+                cv.put(ProviderTableMeta.OCSHARES_SHARE_TYPE, share.getShareType().getValue());
+                cv.put(ProviderTableMeta.OCSHARES_SHARE_WITH, share.getShareWith());
+                cv.put(ProviderTableMeta.OCSHARES_PATH, share.getPath());
+                cv.put(ProviderTableMeta.OCSHARES_PERMISSIONS, share.getPermissions());
+                cv.put(ProviderTableMeta.OCSHARES_SHARED_DATE, share.getSharedDate());
+                cv.put(ProviderTableMeta.OCSHARES_EXPIRATION_DATE, share.getExpirationDate());
+                cv.put(ProviderTableMeta.OCSHARES_TOKEN, share.getToken());
+                cv.put(ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME, share.getSharedWithDisplayName());
+                cv.put(ProviderTableMeta.OCSHARES_IS_DIRECTORY, share.isDirectory() ? 1 : 0);
+                cv.put(ProviderTableMeta.OCSHARES_USER_ID, share.getUserId());
+                cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getIdRemoteShared());
+                cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name);
+
+                boolean existsByPath = shareExists(share.getPath());
+                if (existsByPath || shareExists(share.getId())) {
+                    // updating an existing file
+                    operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI_SHARE).
+                            withValues(cv).
+                            withSelection(  ProviderTableMeta._ID + "=?", 
+                                    new String[] { String.valueOf(share.getId()) })
+                                    .build());
+
+                } else {
+                    // adding a new file
+                    operations.add(ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI_SHARE).withValues(cv).build());
+                }
+            }
             
-        }              
+            // apply operations in batch
+            if (operations.size() > 0) {
+                @SuppressWarnings("unused")
+                ContentProviderResult[] results = null;
+                Log_OC.d(TAG, "Sending " + operations.size() + " operations to FileContentProvider");
+                try {
+                    if (getContentResolver() != null) {
+                        results = getContentResolver().applyBatch(MainApp.getAuthority(), operations);
+    
+                    } else {
+                        results = getContentProviderClient().applyBatch(operations);
+                    }
+    
+                } catch (OperationApplicationException e) {
+                    Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage());
+    
+                } catch (RemoteException e) {
+                    Log_OC.e(TAG, "Exception in batch of operations  " + e.getMessage());
+                }
+            }
+        }
         
     }
     
+    public void updateSharedFiles(Collection<OCFile> sharedFiles) {
+        cleanSharedFiles();
+        
+        if (sharedFiles != null) {
+            ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(sharedFiles.size());
+
+            // prepare operations to insert or update files to save in the given folder
+            for (OCFile file : sharedFiles) {
+                ContentValues cv = new ContentValues();
+                cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
+                cv.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, file.getModificationTimestampAtLastSyncForData());
+                cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
+                cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
+                cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
+                cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
+                cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
+                cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
+                if (!file.isFolder()) {
+                    cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
+                }
+                cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
+                cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDateForProperties());
+                cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, file.getLastSyncDateForData());
+                cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0);
+                cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag());
+                cv.put(ProviderTableMeta.FILE_SHARE_BY_LINK, file.isShareByLink() ? 1 : 0);
+                cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, file.getPublicLink());
+
+                boolean existsByPath = fileExists(file.getRemotePath());
+                if (existsByPath || fileExists(file.getFileId())) {
+                    // updating an existing file
+                    operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
+                            withValues(cv).
+                            withSelection(  ProviderTableMeta._ID + "=?", 
+                                    new String[] { String.valueOf(file.getFileId()) })
+                                    .build());
+
+                } else {
+                    // adding a new file
+                    operations.add(ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI).withValues(cv).build());
+                }
+            }
+            
+            // apply operations in batch
+            if (operations.size() > 0) {
+                @SuppressWarnings("unused")
+                ContentProviderResult[] results = null;
+                Log_OC.d(TAG, "Sending " + operations.size() + " operations to FileContentProvider");
+                try {
+                    if (getContentResolver() != null) {
+                        results = getContentResolver().applyBatch(MainApp.getAuthority(), operations);
+    
+                    } else {
+                        results = getContentProviderClient().applyBatch(operations);
+                    }
+    
+                } catch (OperationApplicationException e) {
+                    Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage());
+    
+                } catch (RemoteException e) {
+                    Log_OC.e(TAG, "Exception in batch of operations  " + e.getMessage());
+                }
+            }
+        }
+        
+    } 
 }