borgbutler-core/src/main/java/de/micromata/borgbutler/data/DiffFileSystemFilter.java
File was renamed from borgbutler-core/src/main/java/de/micromata/borgbutler/DiffTool.java @@ -1,4 +1,4 @@ package de.micromata.borgbutler; package de.micromata.borgbutler.data; import de.micromata.borgbutler.json.borg.BorgFilesystemItem; import org.slf4j.Logger; @@ -11,15 +11,15 @@ /** * Extracts the differences between two archives of one repo. */ public class DiffTool { private static Logger log = LoggerFactory.getLogger(DiffTool.class); public class DiffFileSystemFilter extends FileSystemFilter { private Logger log = LoggerFactory.getLogger(DiffFileSystemFilter.class); /** * @param items Sorted list of items from the current archive. * @param otherItems Sorted list of items of the archive to extract differences. * @return A list of differing items (new, removed and modified ones). */ public static List<BorgFilesystemItem> extractDifferences(List<BorgFilesystemItem> items, List<BorgFilesystemItem> otherItems) { public List<BorgFilesystemItem> extractDifferences(List<BorgFilesystemItem> items, List<BorgFilesystemItem> otherItems) { List<BorgFilesystemItem> currentList = items != null ? items : new ArrayList<>(); List<BorgFilesystemItem> otherList = otherItems != null ? otherItems : new ArrayList<>(); List<BorgFilesystemItem> result = new ArrayList<>(); @@ -37,7 +37,8 @@ } int cmp = current.compareTo(other); if (cmp == 0) { // Items represents both the same file system item. if (current.equals(other)) { if (!checkDirectoryMatchAndRegisterSubDirectories(current) || current.equals(other)) { current = other = null; // increment both iterators. continue; } @@ -48,10 +49,14 @@ result.add(current); current = other = null; // increment both iterators. } else if (cmp < 0) { result.add(current.setDiffStatus(BorgFilesystemItem.DiffStatus.NEW)); if (checkDirectoryMatchAndRegisterSubDirectories(current)) { result.add(current.setDiffStatus(BorgFilesystemItem.DiffStatus.NEW)); } current = currentIt.hasNext() ? currentIt.next() : null; } else { result.add(other.setDiffStatus(BorgFilesystemItem.DiffStatus.REMOVED)); if (checkDirectoryMatchAndRegisterSubDirectories(other)) { result.add(other.setDiffStatus(BorgFilesystemItem.DiffStatus.REMOVED)); } other = otherIt.hasNext() ? otherIt.next() : null; } } borgbutler-core/src/main/java/de/micromata/borgbutler/data/FileSystemFilter.java
@@ -83,35 +83,6 @@ } /** * This method has only effect in FLAT view. This method has to be called for every item of the list before * {@link #reduce(List)} may work, because this method registers sub directories of the current directory needed * by {@link #reduce(List)}. * * @param item * @return false, if the given item is not a sub item of the current directory. You may skip further checkings for this * item. If true, this item might be part of the result. */ boolean checkDirectoryMatchAndRegisterSubDirectories(BorgFilesystemItem item) { if (mode != Mode.TREE) { return true; } if (StringUtils.isNotEmpty(currentDirectory) && !item.getPath().startsWith(currentDirectory)) { // item is not inside the current directory. return false; } // 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); } return true; } /** * 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. @@ -136,8 +107,12 @@ if (set.contains(topLevel) == false) { set.add(topLevel); BorgFilesystemItem topItem = subDirectories.get(topLevel); topItem.setDisplayPath(StringUtils.removeStart(topItem.getPath(), currentDirectory)); list.add(topItem); if (topItem == null) { log.error("Internal error, can't find subDirectory: " + topLevel); } else { topItem.setDisplayPath(StringUtils.removeStart(topItem.getPath(), currentDirectory)); list.add(topItem); } } } list2 = list; @@ -194,6 +169,36 @@ } /** * This method has only effect in FLAT view. This method has to be called for every item of the list before * {@link #reduce(List)} may work, because this method registers sub directories of the current directory needed * by {@link #reduce(List)}. * * @param item * @return false, if the given item is not a sub item of the current directory. You may skip further checkings for this * item. If true, this item might be part of the result. */ protected boolean checkDirectoryMatchAndRegisterSubDirectories(BorgFilesystemItem item) { if (mode != Mode.TREE) { return true; } if (StringUtils.isNotEmpty(currentDirectory) && !item.getPath().startsWith(currentDirectory)) { // item is not inside the current directory. return false; } // 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); } return true; } /** * currentDirectory '': <tt>home</tt> -> <tt>home</tt><br> * currentDirectory '': <tt>home/kai</tt> -> <tt>home</tt><br> * currentDirectory 'home': <tt>home</tt> -> <tt>null</tt><br> borgbutler-core/src/test/java/de/micromata/borgbutler/DiffFileSystemFilterTest.java
File was renamed from borgbutler-core/src/test/java/de/micromata/borgbutler/DiffToolTest.java @@ -1,5 +1,6 @@ package de.micromata.borgbutler; import de.micromata.borgbutler.data.DiffFileSystemFilter; import de.micromata.borgbutler.json.borg.BorgFilesystemItem; import org.junit.jupiter.api.Test; @@ -9,7 +10,7 @@ import static org.junit.jupiter.api.Assertions.*; public class DiffToolTest { public class DiffFileSystemFilterTest { @Test void differencesTest() { BorgFilesystemItem i1 = create("etc", true, "drwx------", 0, "2018-11-21"); @@ -28,33 +29,34 @@ List<BorgFilesystemItem> l1 = null; List<BorgFilesystemItem> l2 = null; List<BorgFilesystemItem> result; assertEquals(0, DiffTool.extractDifferences(l1, l2).size()); DiffFileSystemFilter filter = new DiffFileSystemFilter(); assertEquals(0, filter.extractDifferences(l1, l2).size()); l1 = create(); result = DiffTool.extractDifferences(l1, l2); result = filter.extractDifferences(l1, l2); assertEquals(7, result.size()); assertEquals(BorgFilesystemItem.DiffStatus.NEW, result.get(0).getDiffStatus()); assertEquals(BorgFilesystemItem.DiffStatus.NEW, result.get(1).getDiffStatus()); result = DiffTool.extractDifferences(l2, l1); result = filter.extractDifferences(l2, l1); assertEquals(7, result.size()); assertEquals(BorgFilesystemItem.DiffStatus.REMOVED, result.get(0).getDiffStatus()); assertEquals(BorgFilesystemItem.DiffStatus.REMOVED, result.get(1).getDiffStatus()); l1 = create(); l2 = create(); result = DiffTool.extractDifferences(l2, l1); result = filter.extractDifferences(l2, l1); assertEquals(0, result.size()); remove(l2, "etc"); // 0 remove(l2, "etc/passwd"); // 1 remove(l1, "home/kai/.borgbutler/borgbutler-config-bak.json"); // 2 get(l1, "home/kai/.borgbutler/borgbutler-config.json").setSize(712).setMtime("2018-11-22"); // 3 result = DiffTool.extractDifferences(l1, l2); result = filter.extractDifferences(l1, l2); assertEquals(4, result.size()); assertEquals(BorgFilesystemItem.DiffStatus.NEW, result.get(0).getDiffStatus()); assertEquals(BorgFilesystemItem.DiffStatus.NEW, result.get(1).getDiffStatus()); assertEquals(BorgFilesystemItem.DiffStatus.REMOVED, result.get(2).getDiffStatus()); assertEquals(BorgFilesystemItem.DiffStatus.MODIFIED, result.get(3).getDiffStatus()); result = DiffTool.extractDifferences(l2, l1); result = filter.extractDifferences(l2, l1); assertEquals(4, result.size()); assertEquals(BorgFilesystemItem.DiffStatus.REMOVED, result.get(0).getDiffStatus()); assertEquals(BorgFilesystemItem.DiffStatus.REMOVED, result.get(1).getDiffStatus()); @@ -66,12 +68,12 @@ remove(l2, "etc"); // 0 remove(l2, "etc/passwd"); // 1 remove(l1, "home/kai/.borgbutler/borgbutler-config.json"); // 2 result = DiffTool.extractDifferences(l1, l2); result = filter.extractDifferences(l1, l2); assertEquals(3, result.size()); assertEquals(BorgFilesystemItem.DiffStatus.NEW, result.get(0).getDiffStatus()); assertEquals(BorgFilesystemItem.DiffStatus.NEW, result.get(1).getDiffStatus()); assertEquals(BorgFilesystemItem.DiffStatus.REMOVED, result.get(2).getDiffStatus()); result = DiffTool.extractDifferences(l2, l1); result = filter.extractDifferences(l2, l1); assertEquals(3, result.size()); assertEquals(BorgFilesystemItem.DiffStatus.REMOVED, result.get(0).getDiffStatus()); assertEquals(BorgFilesystemItem.DiffStatus.REMOVED, result.get(1).getDiffStatus()); @@ -82,11 +84,11 @@ l2 = create(); remove(l1, "home/kai/.borgbutler/borgbutler-config-bak.json"); remove(l2, "home/kai/.borgbutler/borgbutler-config.json"); result = DiffTool.extractDifferences(l1, l2); result = filter.extractDifferences(l1, l2); assertEquals(2, result.size()); assertEquals(BorgFilesystemItem.DiffStatus.REMOVED, result.get(0).getDiffStatus()); assertEquals(BorgFilesystemItem.DiffStatus.NEW, result.get(1).getDiffStatus()); result = DiffTool.extractDifferences(l2, l1); result = filter.extractDifferences(l2, l1); assertEquals(2, result.size()); assertEquals(BorgFilesystemItem.DiffStatus.NEW, result.get(0).getDiffStatus()); assertEquals(BorgFilesystemItem.DiffStatus.REMOVED, result.get(1).getDiffStatus()); @@ -96,12 +98,12 @@ remove(l1, "home/kai"); remove(l1, "home/kai/.borgbutler"); remove(l2, "home/kai/.borgbutler/borgbutler-config-bak.json"); result = DiffTool.extractDifferences(l1, l2); result = filter.extractDifferences(l1, l2); assertEquals(3, result.size()); assertEquals(BorgFilesystemItem.DiffStatus.REMOVED, result.get(0).getDiffStatus()); assertEquals(BorgFilesystemItem.DiffStatus.REMOVED, result.get(1).getDiffStatus()); assertEquals(BorgFilesystemItem.DiffStatus.NEW, result.get(2).getDiffStatus()); result = DiffTool.extractDifferences(l2, l1); result = filter.extractDifferences(l2, l1); assertEquals(3, result.size()); assertEquals(BorgFilesystemItem.DiffStatus.NEW, result.get(0).getDiffStatus()); assertEquals(BorgFilesystemItem.DiffStatus.NEW, result.get(1).getDiffStatus()); borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/ArchivesRest.java
@@ -1,11 +1,11 @@ package de.micromata.borgbutler.server.rest; import de.micromata.borgbutler.BorgCommands; import de.micromata.borgbutler.DiffTool; import de.micromata.borgbutler.cache.ButlerCache; import de.micromata.borgbutler.config.BorgRepoConfig; import de.micromata.borgbutler.config.ConfigurationHandler; import de.micromata.borgbutler.data.Archive; import de.micromata.borgbutler.data.DiffFileSystemFilter; import de.micromata.borgbutler.data.FileSystemFilter; import de.micromata.borgbutler.data.Repository; import de.micromata.borgbutler.json.JsonUtils; @@ -77,29 +77,30 @@ @QueryParam("diffArchiveId") String diffArchiveId, @QueryParam("force") boolean force, @QueryParam("prettyPrinter") boolean prettyPrinter) { boolean diffMode = StringUtils.isNotBlank(diffArchiveId); int maxSize = NumberUtils.toInt(maxResultSize, 50); FileSystemFilter filter = new FileSystemFilter() .setSearchString(searchString) .setMaxResultSize(maxSize) .setMode(mode) FileSystemFilter filter = diffMode ? new DiffFileSystemFilter() : new FileSystemFilter(); filter.setSearchString(searchString) .setCurrentDirectory(currentDirectory); List<BorgFilesystemItem> items = null; if (StringUtils.isBlank(diffArchiveId)) { if (diffMode) { filter.setMode(FileSystemFilter.Mode.FLAT); items = ButlerCache.getInstance().getArchiveContent(archiveId, true, filter); List<BorgFilesystemItem> diffItems = ButlerCache.getInstance().getArchiveContent(diffArchiveId, true, filter); filter.setMaxResultSize(maxSize) .setMode(mode); items = ((DiffFileSystemFilter) filter).extractDifferences(items, diffItems); items = filter.reduce(items); } else { filter.setMode(mode) .setMaxResultSize(maxSize); // Get file list (without running diff). items = ButlerCache.getInstance().getArchiveContent(archiveId, force, filter); if (items == null) { return "[{\"mode\": \"notLoaded\"}]"; } } else { filter.setMode(FileSystemFilter.Mode.FLAT).setMaxResultSize(-1); items = ButlerCache.getInstance().getArchiveContent(archiveId, true, filter); List<BorgFilesystemItem> diffItems = ButlerCache.getInstance().getArchiveContent(diffArchiveId, true, filter); items = DiffTool.extractDifferences(items, diffItems); filter.setMaxResultSize(maxSize) .setMode(mode); items = filter.reduce(items); } return JsonUtils.toJson(items, prettyPrinter); }