package net.filebot.ui.filter;
import static java.util.Collections.*;
import static java.util.stream.Collectors.*;
import static net.filebot.Logging.*;
import static net.filebot.util.ExceptionUtilities.*;
import static net.filebot.util.FileUtilities.*;
import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.logging.Level;
import javax.swing.JComponent;
import javax.swing.SwingWorker;
import javax.swing.tree.TreeNode;
import net.filebot.ui.filter.FileTree.FileNode;
import net.filebot.ui.filter.FileTree.FolderNode;
import net.filebot.util.FileUtilities;
import net.filebot.util.ui.LoadingOverlayPane;
abstract class Tool<M> extends JComponent {
private List<File> root = emptyList();
private UpdateModelTask updateTask;
public Tool(String name) {
setName(name);
}
public List<File> getRoot() {
return root;
}
public void setRoot(List<File> root) {
this.root = root;
if (updateTask != null) {
updateTask.cancel(true);
}
setLoading(true);
updateTask = new UpdateModelTask(root);
updateTask.execute();
}
protected void setLoading(boolean loading) {
firePropertyChange(LoadingOverlayPane.LOADING_PROPERTY, !loading, loading);
}
protected abstract M createModelInBackground(List<File> root) throws Exception;
protected abstract void setModel(M model);
private class UpdateModelTask extends SwingWorker<M, Void> {
private final List<File> root;
public UpdateModelTask(List<File> root) {
this.root = root;
}
@Override
protected M doInBackground() throws Exception {
return createModelInBackground(root);
}
@Override
protected void done() {
if (this == updateTask) {
setLoading(false);
}
// update task will only be cancelled if a newer update task has been started
if (this == updateTask && !isCancelled()) {
try {
setModel(get());
} catch (Exception e) {
Throwable cause = getRootCause(e);
if (cause instanceof InterruptedException || cause instanceof CancellationException) {
debug.log(Level.FINEST, e, e::toString); // if it happens, it is supposed to
} else {
debug.log(Level.WARNING, e, e::toString); // should not happen
}
}
}
}
}
protected List<TreeNode> createFileNodes(Collection<File> files) {
return files.stream().map(FileNode::new).collect(toList());
}
protected FolderNode createStatisticsNode(String name, List<File> files) {
List<File> selection = listFiles(files, FILES, null);
long size = selection.stream().mapToLong(File::length).sum();
// set node text (e.g. txt (1 file, 42 Byte))
String title = String.format("%s (%,d %s, %s)", name, selection.size(), selection.size() == 1 ? "file" : "files", FileUtilities.formatSize(size));
return new FolderNode(title, createFileNodes(files));
}
}