package net.sf.jabref.export;
import net.sf.jabref.JabRefFrame;
import net.sf.jabref.BasePanel;
import net.sf.jabref.Globals;
import java.util.Timer;
import java.util.TimerTask;
import java.util.List;
import java.util.ArrayList;
import java.io.File;
/**
* Background task and utilities for autosave feature.
*/
public class AutoSaveManager {
private JabRefFrame frame;
private Timer t = null;
private TimerTask task = null;
public AutoSaveManager(JabRefFrame frame) {
this.frame = frame;
}
public void startAutoSaveTimer() {
task = new AutoSaveTask();
t = new Timer();
long interval = (long)(60000*Globals.prefs.getInt("autoSaveInterval"));
t.scheduleAtFixedRate(task, interval, interval);
}
public void stopAutoSaveTimer() {
t.cancel();
}
class AutoSaveTask extends TimerTask {
public void run() {
// Since this method is running in the background, we must be prepared that
// there could be changes done by the user while this method is running.
List<BasePanel> panels = new ArrayList<BasePanel>();
for (int i=0; i<frame.baseCount(); i++)
panels.add(frame.baseAt(i));
int i=0;
for (BasePanel panel : panels) {
if (panel.isBaseChanged()) {
if (panel.getFile() != null) {
autoSave(panel);
}
}
else {
}
i++;
}
}
}
/**
* Get a File object pointing to the autosave file corresponding to the given file.
* @param f The database file.
* @return its corresponding autosave file.
*/
public static File getAutoSaveFile(File f) {
String n = f.getName();
return new File(f.getParentFile(), ".$"+n+"$");
}
/**
* Perform an autosave.
* @param panel The BasePanel to autosave for.
* @return true if successful, false otherwise.
*/
public static boolean autoSave(BasePanel panel) {
File backupFile = getAutoSaveFile(panel.getFile());
try {
SaveSession ss = FileActions.saveDatabase(panel.database(), panel.metaData(),
backupFile, Globals.prefs,
false, false, panel.getEncoding(), true);
ss.commit();
} catch (SaveException e) {
e.printStackTrace();
return false;
} catch (Throwable ex) {
ex.printStackTrace();
return false;
}
return true;
}
/**
* Delete this BasePanel's autosave if it exists.
* @param panel The BasePanel in question.
* @return true if there was no autosave or if the autosave was successfully deleted, false otherwise.
*/
public static boolean deleteAutoSaveFile(BasePanel panel) {
if (panel.getFile() == null)
return true;
File backupFile = getAutoSaveFile(panel.getFile());
if (backupFile.exists()) {
return backupFile.delete();
}
else return true;
}
/**
* Clean up by deleting the autosave files corresponding to all open files,
* if they exist.
*/
public void clearAutoSaves() {
List<BasePanel> panels = new ArrayList<BasePanel>();
for (int i=0; i<frame.baseCount(); i++)
panels.add(frame.baseAt(i));
for (BasePanel panel : panels) {
deleteAutoSaveFile(panel);
}
}
/**
* Check if a newer autosave exists for the given file.
* @param f The file to check.
* @return true if an autosave is found, and if the autosave is newer
* than the given file.
*/
public static boolean newerAutoSaveExists(File f) {
File asFile = getAutoSaveFile(f);
return asFile.exists() && (asFile.lastModified() > f.lastModified());
}
}