From 4615187a7216cc7fabc3f5d6bf31b5f0b40c5d0f Mon Sep 17 00:00:00 2001
From: Kai Reinhard <K.Reinhard@micromata.de>
Date: Tue, 18 Dec 2018 01:06:12 +0000
Subject: [PATCH] Tree view works now perfectly.

---
 borgbutler-core/src/main/java/de/micromata/borgbutler/data/FileSystemFilter.java |   89 ++++++++++++++++----------------------------
 1 files changed, 33 insertions(+), 56 deletions(-)

diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/data/FileSystemFilter.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/data/FileSystemFilter.java
index 97cb406..6ed144b 100644
--- a/borgbutler-core/src/main/java/de/micromata/borgbutler/data/FileSystemFilter.java
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/data/FileSystemFilter.java
@@ -1,6 +1,5 @@
 package de.micromata.borgbutler.data;
 
-import de.micromata.borgbutler.cache.ButlerCache;
 import de.micromata.borgbutler.json.borg.BorgFilesystemItem;
 import lombok.Getter;
 import lombok.Setter;
@@ -8,13 +7,11 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
 public class FileSystemFilter {
-    private  Logger log = LoggerFactory.getLogger(FileSystemFilter.class);
+    private Logger log = LoggerFactory.getLogger(FileSystemFilter.class);
+
     public enum Mode {FLAT, TREE}
 
     @Getter
@@ -24,6 +21,8 @@
     @Getter
     @Setter
     private String currentDirectory;
+    // For storing sub directories of the currentDirectory
+    private Map<String, BorgFilesystemItem> subDirectories;
     @Getter
     @Setter
     private int maxResultSize = -1;
@@ -56,6 +55,17 @@
             }
             return false;
         }
+        if (mode == Mode.TREE) {
+            // In this run only register all direct childs of currentDirectory.
+            String topLevelDir = getTopLevel(item.getPath());
+            if (topLevelDir == null) {
+                // item is not inside the current directory.
+                return false;
+            }
+            if (!subDirectories.containsKey(topLevelDir)) {
+                subDirectories.put(topLevelDir, item);
+            }
+        }
         if (searchKeyWords == null && blackListSearchKeyWords == null) {
             processFinishedFlag();
             return true;
@@ -94,8 +104,10 @@
             List<BorgFilesystemItem> list2 = list;
             list = new ArrayList<>();
             for (BorgFilesystemItem item : list2) {
-                if (matchesDirectoryView(set, item)) {
-                    list.add(item);
+                String topLevel = getTopLevel(item.getPath());
+                if (set.contains(topLevel) == false) {
+                    set.add(topLevel);
+                    list.add(subDirectories.get(topLevel));
                 }
             }
         }
@@ -103,63 +115,27 @@
     }
 
     /**
-     * After processing all files with {@link #matches(BorgFilesystemItem)} you should process the file list again
-     * through this filter (for tree view) for displaying only the sub items of the current directory (not recursive).
-     *
-     * @return
+     * @param path The path of the current item.
+     * @return null if the item is not a child of the current directory otherwise the top level sub directory name of
+     * the current directory.
      */
-    private boolean matchesDirectoryView(Set<String> set, BorgFilesystemItem item) {
-        String path = item.getPath();
+    private String getTopLevel(String path) {
         if (StringUtils.isEmpty(currentDirectory)) {
-            // root dir
-            return checkNotYetAbsent(set, path);
+            int pos = path.indexOf('/');
+            if (pos < 0) {
+                return path;
+            }
+            return path.substring(0, pos);
         }
         if (!path.startsWith(currentDirectory)) {
             // item is not a child of currentDirectory.
-            return false;
+            return null;
         }
         if (path.length() <= currentDirectory.length() + 1) {
             // Don't show the current directory itself.
-            return false;
+            return null;
         }
-        String subPath = path.substring(currentDirectory.length());
-        return checkNotYetAbsent(set, subPath);
-    }
-
-    /**
-     * It's possible, that borg does return something like this:
-     * <ol>
-     * <li>home/user/documents</li>
-     * <li>home/user/fotos/2018</li>
-     * <li>home/user/fotos/2019</li>
-     * <li>home/user/movies</li>
-     * <li>home/user/movies...</li>
-     * </ol>
-     * The entry <tt>home/user/fotos</tt> itself is missed (perhaps while the permissions are not given for the backup script.
-     * This method ensures, that such directories as fotos will be added.
-     * <br>
-     * This method only functioned for ordered lists (by path in ascending order).
-     *
-     * @param set  Already added items.
-     * @param path The path of the current item.
-     * @return true if the path was absent and was added.
-     */
-    private boolean checkNotYetAbsent(Set<String> set, String path) {
-        int pos = path.indexOf('/');
-        if (pos < 0) {
-            if (set.contains(path)) {
-                log.warn("Shouldn't occur! (Reason: unordered list or bug.)");
-                return false;
-            }
-            set.add(path);
-            return true;
-        }
-        String parent = path.substring(0, pos);
-        if (set.contains(parent)) {
-            return false;
-        }
-        set.add(parent);
-        return true;
+        return path.substring(currentDirectory.length());
     }
 
     /**
@@ -204,6 +180,7 @@
     public FileSystemFilter setMode(String mode) {
         if (mode != null && mode.toLowerCase().equals("tree")) {
             this.mode = Mode.TREE;
+            this.subDirectories = new HashMap<>(); // needed only for tree view.
         } else {
             this.mode = Mode.FLAT;
         }

--
Gitblit v1.10.0