OC-2332: rewrite getAvailableRemotePath from UpdateFileOperation, using ExistenceCehe...
[pub/Android/ownCloud.git] / src / com / owncloud / android / datamodel / FileDataStorageManager.java
index cd793b6..042709a 100644 (file)
@@ -20,21 +20,23 @@ package com.owncloud.android.datamodel;
 
 import java.io.File;
 import java.util.ArrayList;
 
 import java.io.File;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.Collections;
 import java.util.Iterator;
-import java.util.List;
 import java.util.Vector;
 
 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.utils.FileStorageUtils;
 import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
 import com.owncloud.android.utils.FileStorageUtils;
+import com.owncloud.android.utils.Log_OC;
+
 
 import android.accounts.Account;
 import android.content.ContentProviderClient;
 import android.content.ContentProviderOperation;
 import android.content.ContentProviderResult;
 import android.content.ContentResolver;
 
 import android.accounts.Account;
 import android.content.ContentProviderClient;
 import android.content.ContentProviderOperation;
 import android.content.ContentProviderResult;
 import android.content.ContentResolver;
+import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.OperationApplicationException;
 import android.database.Cursor;
 import android.content.ContentValues;
 import android.content.OperationApplicationException;
 import android.database.Cursor;
@@ -181,7 +183,6 @@ public class FileDataStorageManager {
         cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag());
 
         boolean sameRemotePath = fileExists(file.getRemotePath());
         cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag());
 
         boolean sameRemotePath = fileExists(file.getRemotePath());
-        boolean changesSizeOfAncestors = false;
         if (sameRemotePath ||
                 fileExists(file.getFileId())        ) {           // for renamed files; no more delete and create
 
         if (sameRemotePath ||
                 fileExists(file.getFileId())        ) {           // for renamed files; no more delete and create
 
@@ -192,7 +193,6 @@ public class FileDataStorageManager {
             } else {
                 oldFile = getFileById(file.getFileId());
             }
             } else {
                 oldFile = getFileById(file.getFileId());
             }
-            changesSizeOfAncestors = (oldFile.getFileLength() != file.getFileLength());
 
             overriden = true;
             if (getContentResolver() != null) {
 
             overriden = true;
             if (getContentResolver() != null) {
@@ -211,7 +211,6 @@ public class FileDataStorageManager {
                 }
             }
         } else {
                 }
             }
         } else {
-            changesSizeOfAncestors = true;
             Uri result_uri = null;
             if (getContentResolver() != null) {
                 result_uri = getContentResolver().insert(
             Uri result_uri = null;
             if (getContentResolver() != null) {
                 result_uri = getContentResolver().insert(
@@ -234,30 +233,33 @@ public class FileDataStorageManager {
         }
 
         if (file.isFolder()) {
         }
 
         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;
     }
 
 
         }
         
         return overriden;
     }
 
 
-    public void saveFiles(List<OCFile> files) {
+    /**
+     * 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
+     */
+    public void saveFolder(OCFile folder, Collection<OCFile> updatedFiles, Collection<OCFile> filesToRemove) {
+        
+        Log_OC.d(TAG,  "Saving folder " + folder.getRemotePath() + " with " + updatedFiles.size() + " children and " + filesToRemove.size() + " files to remove");
 
 
-        Iterator<OCFile> filesIt = files.iterator();
-        ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(files.size());
-        OCFile file = null;
+        ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(updatedFiles.size());
 
 
-        // prepare operations to perform
-        while (filesIt.hasNext()) {
-            file = filesIt.next();
+        // prepare operations to insert or update files to save in the given folder
+        for (OCFile file : updatedFiles) {
             ContentValues cv = new ContentValues();
             cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
             cv.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, file.getModificationTimestampAtLastSyncForData());
             ContentValues cv = new ContentValues();
             cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
             cv.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, file.getModificationTimestampAtLastSyncForData());
@@ -265,44 +267,21 @@ public class FileDataStorageManager {
             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_CONTENT_LENGTH, file.getFileLength());
             cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
             cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
-            if (file.getParentId() != FileDataStorageManager.ROOT_PARENT_ID)
-                cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
+            //cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
+            cv.put(ProviderTableMeta.FILE_PARENT, folder.getFileId());
             cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
             cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
-            if (!file.isFolder())
+            if (!file.isFolder()) {
                 cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
                 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_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());
 
-            if (fileExists(file.getRemotePath())) {
-                OCFile oldFile = getFileByPath(file.getRemotePath());
-                file.setFileId(oldFile.getFileId());
-               
-                if (file.isFolder()) {
-                    cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, oldFile.getFileLength());
-                    file.setFileLength(oldFile.getFileLength());
-                }
-                
-                operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
-                        withValues(cv).
-                        withSelection(  ProviderTableMeta._ID + "=?", 
-                                new String[] { String.valueOf(file.getFileId()) })
-                                .build());
-
-            } else if (fileExists(file.getFileId())) {
-                OCFile oldFile = getFileById(file.getFileId());
-                if (file.getStoragePath() == null && oldFile.getStoragePath() != null)
-                    file.setStoragePath(oldFile.getStoragePath());
-                
-                if (!file.isFolder())
-                    cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
-                else {
-                    cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, oldFile.getFileLength());
-                    file.setFileLength(oldFile.getFileLength());
-                }
-                
+            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 + "=?", 
                 operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
                         withValues(cv).
                         withSelection(  ProviderTableMeta._ID + "=?", 
@@ -310,127 +289,208 @@ public class FileDataStorageManager {
                                 .build());
 
             } else {
                                 .build());
 
             } else {
+                // adding a new file
                 operations.add(ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI).withValues(cv).build());
             }
         }
                 operations.add(ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI).withValues(cv).build());
             }
         }
+        
+        // prepare operations to remove files in the given folder
+        String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " + ProviderTableMeta.FILE_PATH + "=?";
+        String [] whereArgs = null;
+        for (OCFile file : filesToRemove) {
+            if (file.getParentId() == folder.getFileId()) {
+                whereArgs = new String[]{mAccount.name, file.getRemotePath()};
+                //Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, "" + file.getFileId());
+                if (file.isFolder()) {
+                    operations.add(ContentProviderOperation
+                                    .newDelete(ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_DIR, file.getFileId())).withSelection(where, whereArgs)
+                                        .build());
+                    // TODO remove local folder
+                } else {
+                    operations.add(ContentProviderOperation
+                                    .newDelete(ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE, file.getFileId())).withSelection(where, whereArgs)
+                                        .build());
+                    if (file.isDown()) {
+                        new File(file.getStoragePath()).delete();
+                        // TODO move the deletion of local contents after success of deletions
+                    }
+                }
+            }
+        }
+        
+        // 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, 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());
+        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());
+        operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
+                withValues(cv).
+                withSelection(  ProviderTableMeta._ID + "=?", 
+                        new String[] { String.valueOf(folder.getFileId()) })
+                        .build());
 
         // apply operations in batch
         ContentProviderResult[] results = null;
 
         // apply operations in batch
         ContentProviderResult[] results = null;
+        Log_OC.d(TAG, "Sending " + operations.size() + " operations to FileContentProvider");
         try {
             if (getContentResolver() != null) {
         try {
             if (getContentResolver() != null) {
-                results = getContentResolver().applyBatch(ProviderMeta.AUTHORITY_FILES, operations);
+                results = getContentResolver().applyBatch(MainApp.getAuthority(), operations);
 
             } else {
                 results = getContentProviderClient().applyBatch(operations);
             }
 
         } catch (OperationApplicationException e) {
 
             } else {
                 results = getContentProviderClient().applyBatch(operations);
             }
 
         } catch (OperationApplicationException e) {
-            Log_OC.e(TAG, "Fail to update/insert list of files to database " + e.getMessage());
+            Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage());
 
         } catch (RemoteException e) {
 
         } catch (RemoteException e) {
-            Log_OC.e(TAG, "Fail to update/insert list of files to database " + e.getMessage());
+            Log_OC.e(TAG, "Exception in batch of operations  " + e.getMessage());
         }
 
         // update new id in file objects for insertions
         if (results != null) {
             long newId;
         }
 
         // update new id in file objects for insertions
         if (results != null) {
             long newId;
+            Iterator<OCFile> filesIt = updatedFiles.iterator();
+            OCFile file = null;
             for (int i=0; i<results.length; i++) {
             for (int i=0; i<results.length; i++) {
+                if (filesIt.hasNext()) {
+                    file = filesIt.next();
+                } else {
+                    file = null;
+                }
                 if (results[i].uri != null) {
                     newId = Long.parseLong(results[i].uri.getPathSegments().get(1));
                 if (results[i].uri != null) {
                     newId = Long.parseLong(results[i].uri.getPathSegments().get(1));
-                    files.get(i).setFileId(newId);
-                    //Log_OC.v(TAG, "Found and added id in insertion for " + files.get(i).getRemotePath());
+                    //updatedFiles.get(i).setFileId(newId);
+                    if (file != null) {
+                        file.setFileId(newId);
+                    }
                 }
             }
         }
                 }
             }
         }
-
-        for (OCFile aFile : files) {
-            if (aFile.isFolder() && aFile.needsUpdatingWhileSaving())
-                saveFiles(getFolderContent(aFile));
-        }
-
+        
+        updateFolderSize(folder.getFileId());
+        
     }
 
 
     /**
     }
 
 
     /**
-     * Calculate and save the folderSize on DB
+     * 
      * @param id
      */
      * @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()) {
+                removeFolder(file, removeDBData, removeLocalCopy);
+                
+            } else {
+                if (removeDBData) {
+                    //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()};
+                    if (getContentProviderClient() != null) {
+                        try {
+                            getContentProviderClient().delete(file_uri, where, whereArgs);
+                        } catch (RemoteException e) {
+                            e.printStackTrace();
+                        }
+                    } else {
+                        getContentResolver().delete(file_uri, where, whereArgs);
+                    }
+                    updateFolderSize(file.getParentId());
+                }
+                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
+                        file.setStoragePath(null);
+                        saveFile(file);
+                    }
+                }
+            }
+        }
+    }
     
     
-    public void removeFile(OCFile file, boolean removeLocalCopy) {
-        Uri file_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, ""+file.getFileId());
+
+    public void removeFolder(OCFile folder, boolean removeDBData, boolean removeLocalContent) {
+        if (folder != null && folder.isFolder()) {
+            if (removeDBData &&  folder.getFileId() != -1) {
+                removeFolderInDb(folder);
+            }
+            if (removeLocalContent) {
+                File localFolder = new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, folder));
+                removeLocalFolder(localFolder);
+            }
+        }
+    }
+
+    private void removeFolderInDb(OCFile folder) {
+        Uri folder_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, ""+ folder.getFileId());   // URI for recursive deletion
+        String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " + ProviderTableMeta.FILE_PATH + "=?";
+        String [] whereArgs = new String[]{mAccount.name, folder.getRemotePath()};
         if (getContentProviderClient() != null) {
             try {
         if (getContentProviderClient() != null) {
             try {
-                getContentProviderClient().delete(file_uri,
-                        ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",
-                        new String[]{mAccount.name});
+                getContentProviderClient().delete(folder_uri, where, whereArgs);
             } catch (RemoteException e) {
                 e.printStackTrace();
             }
         } else {
             } catch (RemoteException e) {
                 e.printStackTrace();
             }
         } else {
-            getContentResolver().delete(file_uri,
-                    ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",
-                    new String[]{mAccount.name});
-        }
-        if (file.isDown() && removeLocalCopy) {
-            new File(file.getStoragePath()).delete();
-        }
-        if (file.isFolder() && removeLocalCopy) {
-            File f = new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, file));
-            if (f.exists() && f.isDirectory() && (f.list() == null || f.list().length == 0)) {
-                f.delete();
-            }
-        }
-        
-        if (file.getFileLength() > 0) {
-            updateSizesToTheRoot(file.getParentId());
+            getContentResolver().delete(folder_uri, where, whereArgs); 
         }
         }
+        updateFolderSize(folder.getParentId());
     }
 
     }
 
-    public void removeFolder(OCFile folder, boolean removeDBData, boolean removeLocalContent) {
-        // TODO consider possible failures
-        if (folder != null && folder.isFolder() && folder.getFileId() != -1) {
-            Vector<OCFile> children = getFolderContent(folder);
-            if (children.size() > 0) {
-                OCFile child = null;
-                for (int i=0; i<children.size(); i++) {
-                    child = children.get(i);
-                    if (child.isFolder()) {
-                        removeFolder(child, removeDBData, removeLocalContent);
+    private void removeLocalFolder(File folder) {
+        if (folder.exists()) {
+            File[] files = folder.listFiles();
+            if (files != null) {
+                for (File file : files) {
+                    if (file.isDirectory()) {
+                        removeLocalFolder(file);
                     } else {
                     } else {
-                        if (removeDBData) {
-                            removeFile(child, removeLocalContent);
-                        } else if (removeLocalContent) {
-                            if (child.isDown()) {
-                                new File(child.getStoragePath()).delete();
-                            }
-                        }
+                        file.delete();
                     }
                 }
             }
                     }
                 }
             }
-            if (removeDBData) {
-                removeFile(folder, true);
-            }
-            
-            if (folder.getFileLength() > 0) {
-                updateSizesToTheRoot(folder.getParentId());
-            }
+            folder.delete();
         }
     }
 
         }
     }
 
-
     /**
      * Updates database for a folder that was moved to a different location.
      * 
     /**
      * Updates database for a folder that was moved to a different location.
      * 
@@ -484,7 +544,7 @@ public class FileDataStorageManager {
             /// 3. apply updates in batch
             try {
                 if (getContentResolver() != null) {
             /// 3. apply updates in batch
             try {
                 if (getContentResolver() != null) {
-                    getContentResolver().applyBatch(ProviderMeta.AUTHORITY_FILES, operations);
+                    getContentResolver().applyBatch(MainApp.getAuthority(), operations);
 
                 } else {
                     getContentProviderClient().applyBatch(operations);
 
                 } else {
                     getContentProviderClient().applyBatch(operations);
@@ -646,46 +706,4 @@ public class FileDataStorageManager {
         return file;
     }
 
         return file;
     }
 
-    /**
-     * Update the size value of an OCFile in DB
-     */
-    private int updateSize(long id, long size) {
-        ContentValues cv = new ContentValues();
-        cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, size);
-        int result = -1;
-        if (getContentResolver() != null) {
-             result = getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv, ProviderTableMeta._ID + "=?", 
-                     new String[] { String.valueOf(id) });
-        } else {
-            try {
-                result = getContentProviderClient().update(ProviderTableMeta.CONTENT_URI, cv, ProviderTableMeta._ID + "=?", 
-                        new String[] { String.valueOf(id) });
-            } catch (RemoteException e) {
-                Log_OC.e(TAG,"Fail to update size column into database " + e.getMessage());
-            }
-        }
-        return result;
-    }
-
-    /** 
-     * 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) {
-        
-        OCFile file; 
-
-        while (parentId != FileDataStorageManager.ROOT_PARENT_ID) {
-            
-            // Update the size of the parent
-            calculateFolderSize(parentId);
-            
-            // search the next parent
-            file = getFileById(parentId);            
-            parentId = file.getParentId();
-            
-        }              
-        
-    }
-    
 }
 }