blob: d0f40ea82940e93d9380acdc9f52b1512890703a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2007 Mylyn project committers and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.mylyn.internal.tasks.ui.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Queue;
import java.util.Set;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.context.core.ContextCore;
import org.eclipse.mylyn.context.core.IInteractionContextManager;
import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
import org.eclipse.mylyn.internal.tasks.ui.TaskListManager;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.tasks.core.AbstractTask;
import org.eclipse.mylyn.tasks.core.ITaskListChangeListener;
import org.eclipse.mylyn.tasks.core.TaskContainerDelta;
//import org.eclipse.ui.PlatformUI;
/**
* @author Mik Kersten
* @author Eugene Kuleshov
* @author Rob Elves
*/
public class TaskListSaveManager implements ITaskListChangeListener, IBackgroundSaveListener {
private final static int DEFAULT_SAVE_INTERVAL = 1 * 60 * 1000;
private final BackgroundSaveTimer saveTimer;
private final TaskListSaverJob taskListSaverJob;
private final boolean initializationWarningDialogShow = false;
private static final int MAX_TASKLIST_SNAPSHOTS = 8;
public static final Pattern SNAPSHOT_REGEXP = Pattern.compile("^tasklist-.*");
public TaskListSaveManager() {
saveTimer = new BackgroundSaveTimer(this);
saveTimer.setSaveIntervalMillis(DEFAULT_SAVE_INTERVAL);
saveTimer.start();
taskListSaverJob = new TaskListSaverJob();
//taskListSaverJob.setRule(TasksUiPlugin.getTaskList());
taskListSaverJob.schedule();
}
/**
* Called periodically by the save timer
*/
public void saveRequested() {
if (TasksUiPlugin.getDefault() != null && Platform.isRunning()) {// &&
// TasksUiPlugin.getDefault().isShellActive()
try {
taskListSaverJob.runRequested();
} catch (Exception e) {
StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Could not auto save task list", e));
}
}
}
/**
* Should only be used by TaskListManager and unit tests
*
* @param saveContext
* @param async
*/
public void saveTaskList(boolean saveContext, boolean async) {
if (TasksUiPlugin.getDefault() != null && TasksUiPlugin.getDefault().isInitialized()) {
TaskListManager taskListManager = TasksUiPlugin.getTaskListManager();
if (async) {
if (saveContext) {
AbstractTask task = taskListManager.getActiveTask();
if (task != null) {
taskListSaverJob.addTaskContext(task);
}
}
taskListSaverJob.requestSave();
} else {
taskListSaverJob.waitSaveCompleted();
IInteractionContextManager contextManager = ContextCore.getContextManager();
if (saveContext) {
AbstractTask task = taskListManager.getActiveTask();
if (task != null) {
contextManager.saveContext(task.getHandleIdentifier());
}
}
internalSaveTaskList();
}
} /*else if (PlatformUI.getWorkbench() != null && !PlatformUI.getWorkbench().isClosing()) {
StatusHandler.fail(new Status(IStatus.WARNING, TasksUiPlugin.ID_PLUGIN,
"Possible task list initialization failure, not saving list"));
if (!initializationWarningDialogShow) {
initializationWarningDialogShow = true;
PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
public void run() {
if (PlatformUI.getWorkbench() != null && PlatformUI.getWorkbench().getDisplay() != null) {
MessageDialog.openInformation(
PlatformUI.getWorkbench().getDisplay().getActiveShell(),
ITasksUiConstants.TITLE_DIALOG,
"If task list is blank, Mylyn Task List may have failed to initialize.\n\n"
+ "First, try restarting to see if that corrects the problem.\n\n"
+ "Then, check the Error Log view for messages, and the FAQ for solutions.\n\n"
+ ITasksUiConstants.URL_HOMEPAGE);
}
}
});
}*/
//}
}
private synchronized void internalSaveTaskList() {
TaskListManager taskListManager = TasksUiPlugin.getTaskListManager();
File current = taskListManager.getTaskListFile();
SimpleDateFormat format = new SimpleDateFormat(ITasksCoreConstants.TIMESTAMP_FORMAT, Locale.ENGLISH);
String date = format.format(new Date());
String backupFileName = ITasksCoreConstants.PREFIX_TASKLIST + "-" + date + ITasksCoreConstants.FILE_EXTENSION;
String destination = TasksUiPlugin.getDefault().getBackupFolderPath();
File backupFolder = new File(destination);
if (!backupFolder.exists()) {
backupFolder.mkdir();
}
File backup = new File(backupFolder, backupFileName);
if (current.renameTo(backup)) {
TasksUiPlugin.getBackupManager().removeOldBackups();
String newTasklistPath = TasksUiPlugin.getDefault().getDataDirectory() + File.separator
+ ITasksCoreConstants.DEFAULT_TASK_LIST_FILE;
File newTaskListFile = new File(newTasklistPath);
taskListManager.setTaskListFile(newTaskListFile);
} else {
StatusHandler.log(new Status(IStatus.WARNING, TasksUiPlugin.ID_PLUGIN,
"Unable to create task list snapshot " + backup.getAbsolutePath()));
}
taskListManager.getTaskListWriter().writeTaskList(taskListManager.getTaskList(),
taskListManager.getTaskListFile());
}
/**
* Copies all files in the current data directory to the specified folder. Will overwrite.
*/
public void copyDataDirContentsTo(String targetFolderPath) {
saveTaskList(true, false);
File mainDataDir = new File(TasksUiPlugin.getDefault().getDataDirectory());
for (File currFile : mainDataDir.listFiles()) {
if (currFile.isFile()) {
File destFile = new File(targetFolderPath + File.separator + currFile.getName());
copy(currFile, destFile);
} else if (currFile.isDirectory()) {
File destDir = new File(targetFolderPath + File.separator + currFile.getName());
if (!destDir.exists()) {
if (!destDir.mkdir()) {
StatusHandler.log(new Status(IStatus.WARNING, TasksUiPlugin.ID_PLUGIN,
"Unable to create destination context folder: " + destDir.getAbsolutePath()));
continue;
}
}
for (File file : currFile.listFiles()) {
File destFile = new File(destDir, file.getName());
if (destFile.exists()) {
destFile.delete();
}
copy(file, destFile);
}
}
}
}
// public void createTaskListBackupFile() {
// String path = TasksUiPlugin.getDefault().getDataDirectory() +
// File.separator
// + TasksUiPlugin.DEFAULT_TASK_LIST_FILE;
// File taskListFile = new File(path);
// String backup = path.substring(0, path.indexOf('.')) +
// FILE_SUFFIX_BACKUP;
// copy(taskListFile, new File(backup));
// }
//
// public String getBackupFilePath() {
// String path = TasksUiPlugin.getDefault().getDataDirectory() +
// File.separator
// + TasksUiPlugin.DEFAULT_TASK_LIST_FILE;
// return path.substring(0, path.indexOf('.')) + FILE_SUFFIX_BACKUP;
// }
//
// public void reverseBackup() {
// String path = TasksUiPlugin.getDefault().getBackupFolderPath() +
// File.separator
// + TasksUiPlugin.DEFAULT_TASK_LIST_FILE;
// File taskListFile = new File(path);
// String backup = path.substring(0, path.indexOf('.')) +
// FILE_SUFFIX_BACKUP;
// copy(new File(backup), taskListFile);
// }
private boolean copy(File src, File dst) {
try {
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
return true;
} catch (IOException ioe) {
return false;
}
}
public void taskActivated(AbstractTask task) {
// ignore
}
public void tasksActivated(List<AbstractTask> tasks) {
// ignore
}
public void taskDeactivated(AbstractTask task) {
saveTaskList(true, true);
}
public void localInfoChanged(AbstractTask task) {
saveTaskList(false, true);
}
public void repositoryInfoChanged(AbstractTask task) {
// ignore
}
/** For testing only * */
public BackgroundSaveTimer getSaveTimer() {
return saveTimer;
}
public void containersChanged(Set<TaskContainerDelta> containers) {
saveTaskList(false, true);
}
public void synchronizationCompleted() {
// ignore
}
private class TaskListSaverJob extends Job {
private final Queue<AbstractTask> taskQueue = new LinkedList<AbstractTask>();
private volatile boolean saveRequested = false;
private volatile boolean saveCompleted = true;
TaskListSaverJob() {
super("Task List Saver");
setPriority(Job.LONG);
setSystem(true);
}
@Override
protected IStatus run(IProgressMonitor monitor) {
while (true) {
if (saveRequested) {
saveRequested = false;
saveCompleted = false;
IInteractionContextManager contextManager = ContextCore.getContextManager();
while (!taskQueue.isEmpty()) {
AbstractTask task = taskQueue.poll();
if (task != null) {
contextManager.saveContext(task.getHandleIdentifier());
}
}
internalSaveTaskList();
}
if (!saveRequested) {
synchronized (this) {
saveCompleted = true;
notifyAll();
try {
wait();
} catch (InterruptedException ex) {
// ignore
}
}
}
}
}
void addTaskContext(AbstractTask task) {
taskQueue.add(task);
}
void requestSave() {
saveRequested = true;
}
void runRequested() {
synchronized (this) {
notifyAll();
}
}
void waitSaveCompleted() {
while (!saveCompleted) {
synchronized (this) {
try {
wait();
} catch (InterruptedException ex) {
// ignore
}
}
}
}
}
public void taskListRead() {
}
}