/* blizzy's Backup - Easy to use personal file backup application Copyright (C) 2011-2012 Maik Schreiber This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.blizzy.backup; import java.io.File; import java.util.Calendar; import java.util.Timer; import java.util.TimerTask; import org.apache.commons.lang3.StringUtils; import org.eclipse.equinox.app.IApplication; import org.eclipse.equinox.app.IApplicationContext; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.plugin.AbstractUIPlugin; import de.blizzy.backup.backup.BackupEndedEvent; import de.blizzy.backup.backup.BackupRun; import de.blizzy.backup.backup.BackupRunAdapter; import de.blizzy.backup.check.CheckRun; import de.blizzy.backup.settings.ISettingsListener; import de.blizzy.backup.settings.Settings; import de.blizzy.backup.settings.SettingsManager; public class BackupApplication implements IApplication { private static boolean running = true; private static Display display; private static BackupShell backupShell; private static Timer timer; private static TimerTask backupTimerTask; private static BackupRun backupRun; private static long nextBackupRunTime; private static Image[] windowImages; private static SettingsManager settingsManager; private static TrayIcon trayIcon; @Override public Object start(IApplicationContext context) { display = Display.getDefault(); boolean restartNecessary = false; File runLockFile = new File(BackupPlugin.getDefault().getStateLocation().toFile(), "runLock"); //$NON-NLS-1$ RunLock runLock = new RunLock(runLockFile); if (runLock.tryLock()) { setupDefaultPreferences(); Image image16 = AbstractUIPlugin.imageDescriptorFromPlugin( BackupPlugin.ID, "etc/logo/logo_16.png").createImage(display); //$NON-NLS-1$ Image image32 = AbstractUIPlugin.imageDescriptorFromPlugin( BackupPlugin.ID, "etc/logo/logo_32.png").createImage(display); //$NON-NLS-1$ Image image48 = AbstractUIPlugin.imageDescriptorFromPlugin( BackupPlugin.ID, "etc/logo/logo_48.png").createImage(display); //$NON-NLS-1$ windowImages = new Image[] { image16, image32, image48 }; settingsManager = new SettingsManager(); settingsManager.addListener(new ISettingsListener() { @Override public void settingsChanged() { if (backupRun == null) { scheduleBackupRun(false); } } }); timer = new Timer(); scheduleBackupRun(false); trayIcon = new TrayIcon(display); context.applicationRunning(); if (!BackupPlugin.getDefault().isHidden()) { showShell(); } try { Shell shell = (backupShell != null) ? backupShell.getShell() : null; if (new Updater(false, false).update(shell)) { running = false; restartNecessary = true; } } catch (Throwable e) { BackupPlugin.getDefault().logError("error while updating application", e); //$NON-NLS-1$ } while (running && !display.isDisposed()) { try { if (!display.readAndDispatch()) { display.sleep(); } } catch (RuntimeException e) { BackupPlugin.getDefault().logError("error in event loop", e); //$NON-NLS-1$ } } trayIcon.dispose(); timer.cancel(); timer = null; image16.dispose(); image32.dispose(); image48.dispose(); if (backupRun != null) { backupRun.stopBackupAndWait(); } } else { new MessageDialog(null, Messages.Title_ProgramRunning, null, Messages.ProgramRunning, MessageDialog.ERROR, new String[] { IDialogConstants.CLOSE_LABEL }, 0).open(); } return restartNecessary ? EXIT_RESTART : EXIT_OK; } private void setupDefaultPreferences() { IDialogSettings backupSection = Utils.getSection("backup"); //$NON-NLS-1$ if (backupSection.get("lastRun") == null) { //$NON-NLS-1$ // fake last run as happened 50 min ago backupSection.put("lastRun", System.currentTimeMillis() - 50L * 60L * 1000L); //$NON-NLS-1$ } } static void scheduleBackupRun(boolean forceRunNow) { if (timer != null) { if (backupTimerTask != null) { backupTimerTask.cancel(); backupTimerTask = null; } backupTimerTask = new TimerTask() { @Override public void run() { runBackup(); } }; if (forceRunNow) { timer.schedule(backupTimerTask, 0); } else { IDialogSettings backupSection = Utils.getSection("backup"); //$NON-NLS-1$ long lastRun = backupSection.getLong("lastRun"); //$NON-NLS-1$ Settings settings = settingsManager.getSettings(); if (settings.isRunHourly()) { nextBackupRunTime = lastRun; } else { Calendar c = Calendar.getInstance(); c.setTimeInMillis(lastRun); c.set(Calendar.HOUR_OF_DAY, settings.getDailyHours()); c.set(Calendar.MINUTE, settings.getDailyMinutes()); nextBackupRunTime = c.getTimeInMillis(); } long now = System.currentTimeMillis(); for (;;) { nextBackupRunTime = clearSeconds(nextBackupRunTime); if (nextBackupRunTime > now) { break; } nextBackupRunTime += settings.isRunHourly() ? 60L * 60L * 1000L : 24L * 60L * 60L * 1000L; } timer.schedule(backupTimerTask, Math.max(nextBackupRunTime - now, 0)); } } } private static long clearSeconds(long time) { return (time / 1000L / 60L) * 60L * 1000L; } private static void runBackup() { if (areSettingsOkayToRunBackup()) { Settings settings = settingsManager.getSettings(); long now = System.currentTimeMillis(); IDialogSettings backupSection = Utils.getSection("backup"); //$NON-NLS-1$ backupSection.put("lastRun", now); //$NON-NLS-1$ backupRun = new BackupRun(settings); backupRun.addListener(new BackupRunAdapter() { @Override public void backupEnded(BackupEndedEvent e) { backupRun = null; scheduleBackupRun(false); } }); if (backupShell != null) { backupShell.setBackupRun(backupRun); } trayIcon.setBackupRun(backupRun); backupRun.runBackup(); } } static boolean areSettingsOkayToRunBackup() { Settings settings = settingsManager.getSettings(); return !settings.getLocations().isEmpty() && StringUtils.isNotBlank(settings.getOutputFolder()) && new File(settings.getOutputFolder()).exists(); } @Override public void stop() { quit(); } public static void quit() { running = false; display.wake(); } static void showShell() { if (backupShell == null) { backupShell = new BackupShell(display); if (backupRun != null) { backupShell.setBackupRun(backupRun); } backupShell.open(); } else { backupShell.setVisible(true); backupShell.forceActive(); } } static void hideShell() { if (backupShell != null) { backupShell.setVisible(false); } } static long getNextScheduledBackupRunTime() { return nextBackupRunTime; } public static Image[] getWindowImages() { return windowImages; } public static SettingsManager getSettingsManager() { return settingsManager; } static void runCheck() { new CheckRun(settingsManager.getSettings(), backupShell.getShell()).runCheck(); } public static Shell getBackupShellWindow() { return (backupShell != null) ? backupShell.getShell() : null; } static void resetTrayIconErrors() { trayIcon.resetImage(); } }