From c99af66f5f5366d97f047a6044960cefdd46c64a Mon Sep 17 00:00:00 2001 From: ghidra1 Date: Mon, 15 Sep 2025 10:06:20 -0400 Subject: [PATCH] GP-5908 Corrected excessive folder change notifications on first visit to parent --- .../data/DefaultProjectDataTest.java | 41 ++++++------------- .../framework/data/GhidraFolderData.java | 23 +++++++---- 2 files changed, 29 insertions(+), 35 deletions(-) diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/data/DefaultProjectDataTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/data/DefaultProjectDataTest.java index 4f468c2d00..9be87dcce7 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/data/DefaultProjectDataTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/data/DefaultProjectDataTest.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -339,11 +339,7 @@ public class DefaultProjectDataTest extends AbstractGhidraHeadedIntegrationTest sharedFS.createFolder("/", "b"); flushFileSystemEvents(); // wait for FileSystemListener callback to update folder assertEquals(3, root.getFolders().length); - assertEventsSize(3); - - checkEvent(events.get(0), "Folder Added", null, "/a", null, null, null); - checkEvent(events.get(1), "Folder Added", null, "/b", null, null, null); - checkEvent(events.get(2), "Folder Added", null, "/c", null, null, null); + assertEventsSize(0); sharedFS.createFolder("/b", "subB"); flushFileSystemEvents(); // wait for FileSystemListener callback to update folder @@ -487,12 +483,9 @@ public class DefaultProjectDataTest extends AbstractGhidraHeadedIntegrationTest root.getFolders(); // visit root folder to receive change events for it sharedFS.renameFolder("/", "a", "bigA"); flushFileSystemEvents(); // wait for FileSystemListener callback to update folder - assertEventsSize(4); + assertEventsSize(1); - checkEvent(events.get(0), "Folder Added", null, "/a", null, null, null); - checkEvent(events.get(1), "Folder Added", null, "/b", null, null, null); - checkEvent(events.get(2), "Folder Added", null, "/c", null, null, null); - checkEvent(events.get(3), "Folder Added", null, "/bigA", null, null, null); + checkEvent(events.get(0), "Folder Added", null, "/bigA", null, null, null); // versioned folder was renamed to /bigA, but private folder /a should still exist @@ -516,11 +509,9 @@ public class DefaultProjectDataTest extends AbstractGhidraHeadedIntegrationTest sharedFS.renameFolder("/a", "y", "bigY"); flushFileSystemEvents(); // wait for FileSystemListener callback to update folder - assertEventsSize(4); - checkEvent(events.get(0), "Folder Added", null, "/a/x", null, null, null); - checkEvent(events.get(1), "Folder Added", null, "/a/y", null, null, null); - checkEvent(events.get(2), "Folder Removed", "/a", null, null, null, "y"); - checkEvent(events.get(3), "Folder Added", null, "/a/bigY", null, null, null); + assertEventsSize(2); + checkEvent(events.get(0), "Folder Removed", "/a", null, null, null, "y"); + checkEvent(events.get(1), "Folder Added", null, "/a/bigY", null, null, null); } @@ -532,12 +523,9 @@ public class DefaultProjectDataTest extends AbstractGhidraHeadedIntegrationTest assertNull(root.getFolder("c")); assertNotNull(root.getFolder("bigC")); - assertEventsSize(5); - checkEvent(events.get(0), "Folder Added", null, "/a", null, null, null); - checkEvent(events.get(1), "Folder Added", null, "/b", null, null, null); - checkEvent(events.get(2), "Folder Added", null, "/c", null, null, null); - checkEvent(events.get(3), "Folder Removed", "/", null, null, null, "c"); - checkEvent(events.get(4), "Folder Added", null, "/bigC", null, null, null); + assertEventsSize(2); + checkEvent(events.get(0), "Folder Removed", "/", null, null, null, "c"); + checkEvent(events.get(1), "Folder Added", null, "/bigC", null, null, null); } @Test @@ -614,12 +602,9 @@ public class DefaultProjectDataTest extends AbstractGhidraHeadedIntegrationTest sharedFS.moveFolder("/", "a", "/c"); flushFileSystemEvents(); // wait for FileSystemListener callback to update folder - assertEventsSize(4); + assertEventsSize(1); - checkEvent(events.get(0), "Folder Added", null, "/a", null, null, null); - checkEvent(events.get(1), "Folder Added", null, "/b", null, null, null); - checkEvent(events.get(2), "Folder Added", null, "/c", null, null, null); - checkEvent(events.get(3), "Folder Added", null, "/c/a", null, null, null); + checkEvent(events.get(0), "Folder Added", null, "/c/a", null, null, null); // versioned folder was moved to /c/a, but private folder /a should still exist diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/GhidraFolderData.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/GhidraFolderData.java index b23e02aa08..d7685ee830 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/GhidraFolderData.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/GhidraFolderData.java @@ -558,12 +558,14 @@ class GhidraFolderData { } /** - * Refresh set of sub-folder names and identify added/removed folders. + * Refresh set of sub-folder names and notify about adds/removes if appropriate * @param recursive recurse into visited subfolders if true + * @param notifyAdd true if listener should be notified about newly discovered subfolders * @param monitor recursion task monitor - break from recursion if cancelled * @throws IOException if an IO error occurs during the refresh */ - private void refreshFolders(boolean recursive, TaskMonitor monitor) throws IOException { + private void refreshFolders(boolean recursive, boolean notifyAdd, TaskMonitor monitor) + throws IOException { // FIXME: inconsistent use of forced-recursive refresh and cached folderList @@ -630,7 +632,7 @@ class GhidraFolderData { GhidraFolderData folderData = addFolderData(folderName); if (folderData != null) { folderList.add(folderName); - if (visited) { + if (notifyAdd) { listener.domainFolderAdded(folderData.getDomainFolder()); } } @@ -678,7 +680,13 @@ class GhidraFolderData { return map; } - private void refreshFiles(TaskMonitor monitor) throws IOException { + /** + * Refresh set of files and notify about adds/removes if appropriate + * @param notifyAdd true if listener should be notified about newly discovered files + * @param monitor return immediately if cancelled + * @throws IOException if an IO error occurs during the refresh + */ + private void refreshFiles(boolean notifyAdd, TaskMonitor monitor) throws IOException { String path = getPathname(); @@ -744,7 +752,7 @@ class GhidraFolderData { FolderItem versionedFolderItem = versionedItemMap.get(fileName); GhidraFileData fileData = addFileData(fileName, localFolderItem, versionedFolderItem); - if (visited) { + if (notifyAdd) { listener.domainFileAdded(fileData.getDomainFile()); } } @@ -791,6 +799,7 @@ class GhidraFolderData { return; } + boolean notifyAdd = visited; visited = true; try { @@ -812,13 +821,13 @@ class GhidraFolderData { // FIXME: If forced we should be refreshing folder/file lists - refreshFiles(monitor); + refreshFiles(notifyAdd, monitor); if (monitor != null && monitor.isCancelled()) { return; // break-out from recursion on cancel } - refreshFolders(recursive, monitor); + refreshFolders(recursive, notifyAdd, monitor); } }