Properly handle task file deletions and modifications. master
authorSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Mon, 30 Jun 2025 15:42:53 +0000 (18:42 +0300)
committerSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Mon, 30 Jun 2025 15:42:53 +0000 (18:42 +0300)
src/main/java/eu/svjatoslav/alyverkko_cli/commands/mail_correspondant/MailCorrespondentCommand.java

index 422d2d5..4ddf27e 100644 (file)
@@ -371,42 +371,56 @@ public class MailCorrespondentCommand implements Command {
     }
 
     /**
-     * Handles the filesystem events from the WatchService (e.g., file
-     * creation or modification), then adds the file to the task queue
-     * if it needs processing.
+     * Handles the filesystem events from the WatchService (e.g., file creation, modification, or deletion),
+     * and updates the task queue accordingly.
      *
      * @param key the watch key containing the events.
      * @throws IOException if file processing fails.
      */
     private void processDetectedFilesystemEvents(WatchKey key) throws IOException {
-
-        Path dir = (Path) key.watchable();   // ★ new line
+        Path dir = (Path) key.watchable();
 
         for (WatchEvent<?> event : key.pollEvents()) {
-
             WatchEvent.Kind<?> kind = event.kind();
-            if (kind != ENTRY_CREATE && kind != ENTRY_MODIFY) continue;
+
+            if (kind != ENTRY_CREATE && kind != ENTRY_MODIFY && kind != ENTRY_DELETE) {
+                continue;
+            }
 
             @SuppressWarnings("unchecked")
             WatchEvent<Path> ev = (WatchEvent<Path>) event;
             Path filename = ev.context();
-
             Path fullPath = dir.resolve(filename);
+
             System.out.printf("Event: %s – %s%n", kind.name(), fullPath);
 
-            // If the entry is a *new directory* we need to start watching it, too:
-            if (kind == ENTRY_CREATE && Files.isDirectory(fullPath)) {
-                registerAllSubdirectories(fullPath);
+            if (kind == ENTRY_DELETE) {
+                // Remove any existing tasks for this file
+                removeTasksForFile(fullPath);
+                continue;
+            }
+
+            // Handle directory creation
+            if (Files.isDirectory(fullPath)) {
+                if (kind == ENTRY_CREATE) {
+                    registerAllSubdirectories(fullPath);
+                }
+                continue;
+            }
+
+            // Handle file events
+            if (kind == ENTRY_MODIFY) {
+                // Remove existing tasks for this file before adding new ones
+                removeTasksForFile(fullPath);
             }
 
-            // And finally queue the file if it’s a regular, non-hidden file:
+            // Check if it's a regular, non-hidden file and needs processing
             if (Files.isRegularFile(fullPath) && !Files.isHidden(fullPath)) {
                 considerFileForQueuing(fullPath);
             }
         }
     }
 
-
     private void initializeFileWatcher() throws IOException {
         this.directoryWatcher = FileSystems.getDefault().newWatchService();
         registerAllSubdirectories(mailDir.toPath());
@@ -491,4 +505,28 @@ public class MailCorrespondentCommand implements Command {
         }
     }
 
+    /**
+     * Removes all tasks from the queue that match the given file path.
+     * This is done by draining the queue into a list, filtering out the matching entries,
+     * and re-adding the remaining ones back into the queue.
+     *
+     * @param filePath the file path to match and remove from the queue.
+     */
+    private void removeTasksForFile(Path filePath) {
+        List<TaskQueueEntry> remaining = new ArrayList<>();
+
+        // Drain all elements into a list
+        while (!taskQueue.isEmpty()) {
+            TaskQueueEntry entry = taskQueue.poll();
+            if (!entry.getFilePath().equals(filePath)) {
+                remaining.add(entry);
+            }
+        }
+
+        // Re-add all remaining entries back to the queue
+        for (TaskQueueEntry entry : remaining) {
+            taskQueue.offer(entry);
+        }
+    }
+
 }