com.swoval.files.FileTreeRepositoryImpl Maven / Gradle / Ivy
package com.swoval.files;
import com.swoval.files.FileTreeDataViews.CacheObserver;
import com.swoval.files.FileTreeDataViews.Entry;
import com.swoval.files.FileTreeViews.Observer;
import com.swoval.functional.Either;
import com.swoval.functional.Filter;
import com.swoval.logging.Logger;
import com.swoval.logging.Loggers;
import com.swoval.logging.Loggers.Level;
import com.swoval.runtime.ShutdownHooks;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
class FileTreeRepositoryImpl implements FileTreeRepository {
private final AtomicBoolean closed = new AtomicBoolean(false);
private final FileCacheDirectoryTree directoryTree;
private final FileCachePathWatcher watcher;
private final Runnable closeRunnable =
new Runnable() {
@Override
@SuppressWarnings("EmptyCatchBlock")
public void run() {
if (closed.compareAndSet(false, true)) {
ShutdownHooks.removeHook(shutdownHookId);
watcher.close();
directoryTree.close();
}
}
};
private final int shutdownHookId;
private final Logger logger;
FileTreeRepositoryImpl(
final FileCacheDirectoryTree directoryTree,
final FileCachePathWatcher watcher,
final Logger logger) {
this.shutdownHookId = ShutdownHooks.addHook(1, closeRunnable);
this.directoryTree = directoryTree;
this.watcher = watcher;
this.logger = logger;
}
FileTreeRepositoryImpl(
final FileCacheDirectoryTree directoryTree, final FileCachePathWatcher watcher) {
this(directoryTree, watcher, Loggers.getLogger());
}
/** Cleans up the path watcher and clears the directory cache. */
@Override
public void close() {
closeRunnable.run();
}
@Override
public int addObserver(final Observer super FileTreeDataViews.Entry> observer) {
return addCacheObserver(
new CacheObserver() {
@Override
public void onCreate(final Entry newEntry) {
observer.onNext(newEntry);
}
@Override
public void onDelete(final Entry oldEntry) {
observer.onNext(oldEntry);
}
@Override
public void onUpdate(final Entry oldEntry, final Entry newEntry) {
observer.onNext(newEntry);
}
@Override
public void onError(final IOException exception) {
observer.onError(exception);
}
});
}
@Override
public void removeObserver(int handle) {
directoryTree.removeObserver(handle);
}
@Override
public List> listEntries(
final Path path,
final int maxDepth,
final Filter super FileTreeDataViews.Entry> filter) {
return directoryTree.listEntries(path, maxDepth, filter);
}
@Override
public Either register(final Path path, final int maxDepth) {
try {
final Path absolutePath = path.isAbsolute() ? path : path.toAbsolutePath();
final Either res =
Either.right(watcher.register(absolutePath, maxDepth));
if (Loggers.shouldLog(logger, Level.DEBUG))
logger.debug(this + " registered " + path + " with max depth " + maxDepth);
return res;
} catch (final IOException e) {
return Either.left(e);
}
}
@Override
@SuppressWarnings("EmptyCatchBlock")
public void unregister(final Path path) {
final Path absolutePath = path.isAbsolute() ? path : path.toAbsolutePath();
watcher.unregister(absolutePath);
}
@Override
public List list(Path path, int maxDepth, Filter super TypedPath> filter) {
return directoryTree.list(path, maxDepth, filter);
}
@Override
public int addCacheObserver(final CacheObserver observer) {
return directoryTree.addCacheObserver(observer);
}
abstract static class Callback implements Runnable, Comparable {
private final Path path;
Callback(final Path path) {
this.path = path;
}
@Override
public int compareTo(final Callback that) {
return this.path.compareTo(that.path);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy