From: Svjatoslav Agejenko Date: Mon, 30 Jun 2025 15:42:53 +0000 (+0300) Subject: Properly handle task file deletions and modifications. X-Git-Url: http://www2.svjatoslav.eu/gitweb/?a=commitdiff_plain;h=750dbca3a29829cc5be90952470bda8d1819b564;p=alyverkko-cli.git Properly handle task file deletions and modifications. --- diff --git a/src/main/java/eu/svjatoslav/alyverkko_cli/commands/mail_correspondant/MailCorrespondentCommand.java b/src/main/java/eu/svjatoslav/alyverkko_cli/commands/mail_correspondant/MailCorrespondentCommand.java index 422d2d5..4ddf27e 100644 --- a/src/main/java/eu/svjatoslav/alyverkko_cli/commands/mail_correspondant/MailCorrespondentCommand.java +++ b/src/main/java/eu/svjatoslav/alyverkko_cli/commands/mail_correspondant/MailCorrespondentCommand.java @@ -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 ev = (WatchEvent) 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 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); + } + } + }