From caf233c0080057c51e2eaad02f8118853ddd205b Mon Sep 17 00:00:00 2001
From: Kai Reinhard <K.Reinhard@micromata.de>
Date: Tue, 18 Dec 2018 00:31:21 +0000
Subject: [PATCH] First approach of tree view (doesn't work perfectly).

---
 borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ArchiveFilelistCache.java |    5 ++
 borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ButlerCache.java          |    5 ++
 borgbutler-core/src/main/java/de/micromata/borgbutler/data/FileSystemFilter.java      |   52 ++++++++++++++++++++++++--
 3 files changed, 56 insertions(+), 6 deletions(-)

diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ArchiveFilelistCache.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ArchiveFilelistCache.java
index 2a21a76..36527fd 100644
--- a/borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ArchiveFilelistCache.java
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ArchiveFilelistCache.java
@@ -129,7 +129,10 @@
             log.error("Error while reading file list '" + file.getAbsolutePath() + "': " + ex.getMessage(), ex);
         }
         log.info("Loading done.");
-        return filter.reduce(list);
+        if (filter != null) {
+            return filter.reduce(list);
+        }
+        return list;
     }
 
     /**
diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ButlerCache.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ButlerCache.java
index b0c9362..53b5630 100644
--- a/borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ButlerCache.java
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ButlerCache.java
@@ -249,12 +249,15 @@
                         if (filter != null && filter.isFinished()) break;
                     }
                 }
+                if (filter != null) {
+                    items = filter.reduce(items);
+                }
             }
         }
         if (items == null && forceLoad) {
             log.warn("Repo::archiv with name '" + archive.getBorgIdentifier() + "' not found.");
         }
-        return filter.reduce(items);
+        return items;
     }
 
     public List<BorgFilesystemItem> getArchiveContent(File file) {
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 02febc5..97cb406 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,14 +1,20 @@
 package de.micromata.borgbutler.data;
 
+import de.micromata.borgbutler.cache.ButlerCache;
 import de.micromata.borgbutler.json.borg.BorgFilesystemItem;
 import lombok.Getter;
 import lombok.Setter;
 import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 public class FileSystemFilter {
+    private  Logger log = LoggerFactory.getLogger(FileSystemFilter.class);
     public enum Mode {FLAT, TREE}
 
     @Getter
@@ -78,15 +84,17 @@
      * After processing a list by using {@link #matches(BorgFilesystemItem)} you should call finally this method with
      * your result list to reduce the files and directories for mode {@link Mode#TREE}. For the mode {@link Mode#FLAT}
      * nothing is done.
+     *
      * @param list
      * @return The original list for mode {@link Mode#FLAT} or the reduced list for the tree view.
      */
     public List reduce(List<BorgFilesystemItem> list) {
         if (mode == FileSystemFilter.Mode.TREE) {
+            Set<String> set = new HashSet<>();
             List<BorgFilesystemItem> list2 = list;
             list = new ArrayList<>();
             for (BorgFilesystemItem item : list2) {
-                if (matchesDirectoryView(item)) {
+                if (matchesDirectoryView(set, item)) {
                     list.add(item);
                 }
             }
@@ -100,11 +108,11 @@
      *
      * @return
      */
-    private boolean matchesDirectoryView(BorgFilesystemItem item) {
+    private boolean matchesDirectoryView(Set<String> set, BorgFilesystemItem item) {
         String path = item.getPath();
         if (StringUtils.isEmpty(currentDirectory)) {
             // root dir
-            return path.indexOf('/') == -1; // Show only top level items.
+            return checkNotYetAbsent(set, path);
         }
         if (!path.startsWith(currentDirectory)) {
             // item is not a child of currentDirectory.
@@ -115,7 +123,43 @@
             return false;
         }
         String subPath = path.substring(currentDirectory.length());
-        return subPath.indexOf('/') < 0;
+        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;
     }
 
     /**

--
Gitblit v1.10.0