}
/**
- * 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());
}
}
+ /**
+ * 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);
+ }
+ }
+
}