Fix various HistorySpooler issues

This commit is contained in:
Reinhard Pointner 2016-09-24 19:51:03 +08:00
parent 5e3cce10f4
commit 9e70409ab2
4 changed files with 41 additions and 48 deletions

View File

@ -210,10 +210,10 @@ public class History {
return ((History) unmarshaller.unmarshal(stream)); return ((History) unmarshaller.unmarshal(stream));
} catch (Exception e) { } catch (Exception e) {
debug.log(Level.SEVERE, "Failed to read history", e); debug.log(Level.SEVERE, "Failed to read history", e);
// fail-safe => default to empty history
return new History();
} }
// default to empty history
return new History();
} }
} }

View File

@ -1,10 +1,10 @@
package net.filebot; package net.filebot;
import static java.nio.channels.Channels.*;
import static net.filebot.Logging.*; import static net.filebot.Logging.*;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.channels.FileLock; import java.nio.channels.FileLock;
import java.nio.file.StandardOpenOption; import java.nio.file.StandardOpenOption;
@ -27,22 +27,16 @@ public final class HistorySpooler {
return instance; return instance;
} }
// commit session history on shutdown
static { static {
Runtime.getRuntime().addShutdownHook(new Thread() { Runtime.getRuntime().addShutdownHook(new Thread(HistorySpooler.getInstance()::commit, "HistorySpoolerShutdownHook")); // commit session history on shutdown
@Override
public void run() {
HistorySpooler.getInstance().commit();
}
});
} }
private File persistentHistoryFile = ApplicationFolder.AppData.resolve("history.xml"); private final File persistentHistoryFile = ApplicationFolder.AppData.resolve("history.xml");
private int persistentHistoryTotalSize = -1; private int persistentHistoryTotalSize = -1;
private boolean persistentHistoryEnabled = true; private boolean persistentHistoryEnabled = true;
private History sessionHistory = new History(); private final History sessionHistory = new History();
public synchronized History getCompleteHistory() throws IOException { public synchronized History getCompleteHistory() throws IOException {
if (persistentHistoryFile.length() <= 0) { if (persistentHistoryFile.length() <= 0) {
@ -51,7 +45,7 @@ public final class HistorySpooler {
try (FileChannel channel = FileChannel.open(persistentHistoryFile.toPath(), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE)) { try (FileChannel channel = FileChannel.open(persistentHistoryFile.toPath(), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE)) {
try (FileLock lock = channel.lock()) { try (FileLock lock = channel.lock()) {
History history = History.importHistory(new CloseShieldInputStream(Channels.newInputStream(channel))); // keep JAXB from closing the stream History history = History.importHistory(new CloseShieldInputStream(newInputStream(channel))); // keep JAXB from closing the stream
history.addAll(sessionHistory.sequences()); history.addAll(sessionHistory.sequences());
return history; return history;
} }
@ -59,7 +53,7 @@ public final class HistorySpooler {
} }
public synchronized void commit() { public synchronized void commit() {
if (!persistentHistoryEnabled || sessionHistory.sequences().isEmpty()) { if (sessionHistory.sequences().isEmpty() || !persistentHistoryEnabled) {
return; return;
} }
@ -72,9 +66,9 @@ public final class HistorySpooler {
if (channel.size() > 0) { if (channel.size() > 0) {
try { try {
channel.position(0); channel.position(0);
history = History.importHistory(new CloseShieldInputStream(Channels.newInputStream(channel))); // keep JAXB from closing the stream history = History.importHistory(new CloseShieldInputStream(newInputStream(channel))); // keep JAXB from closing the stream
} catch (Exception e) { } catch (Exception e) {
debug.log(Level.SEVERE, "Failed to load rename history", e); debug.log(Level.SEVERE, "Failed to read history file", e);
} }
} }
@ -82,14 +76,15 @@ public final class HistorySpooler {
history.addAll(sessionHistory.sequences()); history.addAll(sessionHistory.sequences());
channel.position(0); channel.position(0);
History.exportHistory(history, new CloseShieldOutputStream(Channels.newOutputStream(channel))); // keep JAXB from closing the stream History.exportHistory(history, new CloseShieldOutputStream(newOutputStream(channel))); // keep JAXB from closing the stream
channel.truncate(channel.position());
sessionHistory.clear(); sessionHistory.clear();
persistentHistoryTotalSize = history.totalSize(); persistentHistoryTotalSize = history.totalSize();
} }
} }
} catch (Exception e) { } catch (Exception e) {
debug.log(Level.SEVERE, "Failed to write rename history", e); debug.log(Level.SEVERE, "Failed to write history file", e);
} }
} }
@ -104,21 +99,28 @@ public final class HistorySpooler {
sequence.add(new Element(element.getKey().getName(), element.getValue().getPath(), element.getKey().getParentFile())); sequence.add(new Element(element.getKey().getName(), element.getValue().getPath(), element.getKey().getParentFile()));
} }
// append to session history
if (sequence.size() > 0) { if (sequence.size() > 0) {
sessionHistory.add(sequence); sessionHistory.add(sequence); // append to session history
} }
} }
public History getSessionHistory() { public synchronized void append(History importHistory) {
return sessionHistory; sessionHistory.merge(importHistory);
} }
public int getPersistentHistoryTotalSize() { public synchronized History getSessionHistory() {
return new History(sessionHistory.sequences());
}
public synchronized int getSessionHistoryTotalSize() {
return sessionHistory.totalSize();
}
public synchronized int getPersistentHistoryTotalSize() {
return persistentHistoryTotalSize; return persistentHistoryTotalSize;
} }
public void setPersistentHistoryEnabled(boolean persistentHistoryEnabled) { public synchronized void setPersistentHistoryEnabled(boolean persistentHistoryEnabled) {
this.persistentHistoryEnabled = persistentHistoryEnabled; this.persistentHistoryEnabled = persistentHistoryEnabled;
} }

View File

@ -133,7 +133,7 @@ public enum SupportDialog {
int lastSupportRevision = supportRevision.stream().max(Integer::compare).orElse(0); int lastSupportRevision = supportRevision.stream().max(Integer::compare).orElse(0);
int currentRevision = getApplicationRevisionNumber(); int currentRevision = getApplicationRevisionNumber();
int sessionRenameCount = HistorySpooler.getInstance().getSessionHistory().totalSize(); int sessionRenameCount = HistorySpooler.getInstance().getSessionHistoryTotalSize();
int totalRenameCount = HistorySpooler.getInstance().getPersistentHistoryTotalSize(); int totalRenameCount = HistorySpooler.getInstance().getPersistentHistoryTotalSize();
// show donation / review reminders to power users // show donation / review reminders to power users

View File

@ -10,6 +10,7 @@ import static net.filebot.Logging.*;
import static net.filebot.Settings.*; import static net.filebot.Settings.*;
import static net.filebot.UserFiles.*; import static net.filebot.UserFiles.*;
import static net.filebot.media.XattrMetaInfo.*; import static net.filebot.media.XattrMetaInfo.*;
import static net.filebot.util.FileUtilities.*;
import static net.filebot.util.RegularExpressions.*; import static net.filebot.util.RegularExpressions.*;
import static net.filebot.util.ui.SwingUI.*; import static net.filebot.util.ui.SwingUI.*;
@ -71,6 +72,7 @@ import javax.swing.table.TableRowSorter;
import net.filebot.History; import net.filebot.History;
import net.filebot.History.Element; import net.filebot.History.Element;
import net.filebot.History.Sequence; import net.filebot.History.Sequence;
import net.filebot.HistorySpooler;
import net.filebot.ResourceManager; import net.filebot.ResourceManager;
import net.filebot.StandardRenameAction; import net.filebot.StandardRenameAction;
import net.filebot.mac.MacAppUtilities; import net.filebot.mac.MacAppUtilities;
@ -79,8 +81,6 @@ import net.filebot.ui.transfer.FileTransferablePolicy;
import net.filebot.ui.transfer.LoadAction; import net.filebot.ui.transfer.LoadAction;
import net.filebot.ui.transfer.SaveAction; import net.filebot.ui.transfer.SaveAction;
import net.filebot.ui.transfer.TransferablePolicy; import net.filebot.ui.transfer.TransferablePolicy;
import net.filebot.ui.transfer.TransferablePolicy.TransferAction;
import net.filebot.util.FileUtilities;
import net.filebot.util.FileUtilities.ExtensionFileFilter; import net.filebot.util.FileUtilities.ExtensionFileFilter;
import net.filebot.util.ui.GradientStyle; import net.filebot.util.ui.GradientStyle;
import net.filebot.util.ui.LazyDocumentListener; import net.filebot.util.ui.LazyDocumentListener;
@ -126,15 +126,7 @@ class HistoryDialog extends JDialog {
content.add(createScrollPaneGroup("Sequences", sequenceTable), "growx, wrap paragraph"); content.add(createScrollPaneGroup("Sequences", sequenceTable), "growx, wrap paragraph");
content.add(createScrollPaneGroup("Elements", elementTable), "growx, wrap paragraph"); content.add(createScrollPaneGroup("Elements", elementTable), "growx, wrap paragraph");
// use ADD by default Action importAction = new LoadAction("Import", ResourceManager.getIcon("action.load"), this::getTransferablePolicy);
Action importAction = new LoadAction("Import", ResourceManager.getIcon("action.load"), this::getTransferablePolicy) {
@Override
public TransferAction getTransferAction(ActionEvent evt) {
// if SHIFT was pressed when the button was clicked, assume PUT action, use ADD by default
return ((evt.getModifiers() & ActionEvent.SHIFT_MASK) != 0) ? TransferAction.PUT : TransferAction.ADD;
}
};
content.add(new JButton(importAction), "wmin button, hmin 25px, gap indent, sg button"); content.add(new JButton(importAction), "wmin button, hmin 25px, gap indent, sg button");
content.add(new JButton(new SaveAction("Export", ResourceManager.getIcon("action.save"), exportHandler)), "gap rel, sg button"); content.add(new JButton(new SaveAction("Export", ResourceManager.getIcon("action.save"), exportHandler)), "gap rel, sg button");
@ -597,26 +589,25 @@ class HistoryDialog extends JDialog {
@Override @Override
protected boolean accept(List<File> files) { protected boolean accept(List<File> files) {
return FileUtilities.containsOnly(files, new ExtensionFileFilter("xml")); return containsOnly(files, new ExtensionFileFilter("xml"));
} }
@Override @Override
protected void clear() { protected void clear() {
setModel(new History()); // do nothing
} }
@Override @Override
protected void load(List<File> files, TransferAction action) throws IOException { protected void load(List<File> files, TransferAction action) throws IOException {
History history = getModel(); for (File file : files) {
try {
try { HistorySpooler.getInstance().append(History.importHistory(new FileInputStream(file)));
for (File file : files) { } catch (Exception e) {
history.merge(History.importHistory(new FileInputStream(file))); log.log(Level.SEVERE, "Failed to import history: " + file, e);
} }
} finally {
// update view
setModel(history);
} }
setModel(HistorySpooler.getInstance().getCompleteHistory()); // update view
} }
@Override @Override