Inceptum/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/instance/InstanceListWatcher.java

70 lines
2.4 KiB
Java

package io.gitlab.jfronny.inceptum.launcher.system.instance;
import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.inceptum.common.MetaHolder;
import java.io.Closeable;
import java.io.IOException;
import java.nio.file.*;
import java.util.HashMap;
import java.util.Map;
import static java.nio.file.StandardWatchEventKinds.*;
public class InstanceListWatcher implements Closeable {
private final WatchService watcher = FileSystems.getDefault().newWatchService();
private final Map<WatchKey, Path> keys = new HashMap<>();
private void register(Path dir) throws IOException {
keys.put(dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY), dir);
}
public InstanceListWatcher() throws IOException {
register(MetaHolder.INSTANCE_DIR);
JFiles.listTo(MetaHolder.INSTANCE_DIR, this::register);
}
@Override
public void close() throws IOException {
watcher.close();
}
public boolean poll() throws IOException {
boolean changed = false;
WatchKey key;
while ((key = watcher.poll()) != null) {
Path dir = keys.get(key);
for (WatchEvent<?> event : key.pollEvents()) {
var kind = event.kind();
if (kind == OVERFLOW) continue;
@SuppressWarnings("unchecked") WatchEvent<Path> ev = (WatchEvent<Path>) event;
Path name = ev.context();
Path child = dir.resolve(name);
if (MetaHolder.INSTANCE_DIR.equals(dir)) {
if (kind == ENTRY_CREATE) {
changed = true;
register(child);
}
if (kind == ENTRY_DELETE) changed = true;
} else if (Files.exists(dir.resolve(Instance.CONFIG_NAME))) {
String fn = child.getFileName().toString();
if (fn.equals(Instance.CONFIG_NAME)
|| fn.equals(Instance.LOCK_NAME)
|| fn.equals(Instance.SETUP_LOCK_NAME)) {
changed = true;
}
}
}
if (!key.reset()) {
keys.remove(key);
if (MetaHolder.INSTANCE_DIR.equals(dir)) {
Files.createDirectories(MetaHolder.INSTANCE_DIR);
register(MetaHolder.INSTANCE_DIR);
}
}
}
return changed;
}
}