Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrandon Dong2016-05-19 16:11:51 -0400
committerGerrit Code Review @ Eclipse.org2016-06-08 14:38:38 -0400
commitee58f27b5dd6f493a23240024655e8d37293356d (patch)
treef28c5eb41307f594f80a785c02688d1aee04df9a /org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal
parentc7b61a4748ba0ca0687fef5563165c01cfde0dc3 (diff)
downloadorg.eclipse.mylyn.tasks-ee58f27b5dd6f493a23240024655e8d37293356d.tar.gz
org.eclipse.mylyn.tasks-ee58f27b5dd6f493a23240024655e8d37293356d.tar.xz
org.eclipse.mylyn.tasks-ee58f27b5dd6f493a23240024655e8d37293356d.zip
494568: support refactoring task ids
Change-Id: I32f749d32f072bb05045e4749717309df8f4cb86 Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=495066 Signed-off-by: Brandon Dong <brandon.dong@tasktop.com>
Diffstat (limited to 'org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal')
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskActivityManager.java41
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskList.java49
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataManager.java21
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataState.java12
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/operations/Messages.java31
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/operations/RefactorTaskIdsOperation.java93
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/operations/TaskListOperation.java74
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/operations/messages.properties3
8 files changed, 306 insertions, 18 deletions
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskActivityManager.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskActivityManager.java
index 99c302836..038209bec 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskActivityManager.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskActivityManager.java
@@ -62,12 +62,15 @@ public class TaskActivityManager implements ITaskActivityManager2 {
private final Set<ITask> allDueTasks = new HashSet<ITask>();
- private final SortedMap<DateRange, Set<ITask>> scheduledTasks = Collections.synchronizedSortedMap(new TreeMap<DateRange, Set<ITask>>());
+ private final SortedMap<DateRange, Set<ITask>> scheduledTasks = Collections
+ .synchronizedSortedMap(new TreeMap<DateRange, Set<ITask>>());
- private final SortedMap<Calendar, Set<ITask>> dueTasks = Collections.synchronizedSortedMap(new TreeMap<Calendar, Set<ITask>>());
+ private final SortedMap<Calendar, Set<ITask>> dueTasks = Collections
+ .synchronizedSortedMap(new TreeMap<Calendar, Set<ITask>>());
// Map of Calendar (hour) to Tasks active during that hour
- private final SortedMap<Calendar, Set<AbstractTask>> activeTasks = Collections.synchronizedSortedMap(new TreeMap<Calendar, Set<AbstractTask>>());
+ private final SortedMap<Calendar, Set<AbstractTask>> activeTasks = Collections
+ .synchronizedSortedMap(new TreeMap<Calendar, Set<AbstractTask>>());
// For a given task maps Calendar Hour to duration of time spent (milliseconds) with task active
private final Map<AbstractTask, SortedMap<Calendar, Long>> taskElapsedTimeMap = new ConcurrentHashMap<AbstractTask, SortedMap<Calendar, Long>>();
@@ -118,7 +121,8 @@ public class TaskActivityManager implements ITaskActivityManager2 {
listenersInitialized = true;
IExtensionRegistry registry = Platform.getExtensionRegistry();
- IExtensionPoint listenerExtensionPoint = registry.getExtensionPoint(TaskActivityManager.ID_EXTENSION_TASK_ACTIVATION_LISTENERS);
+ IExtensionPoint listenerExtensionPoint = registry
+ .getExtensionPoint(TaskActivityManager.ID_EXTENSION_TASK_ACTIVATION_LISTENERS);
IExtension[] listenerExtensions = listenerExtensionPoint.getExtensions();
for (IExtension extension : listenerExtensions) {
IConfigurationElement[] elements = extension.getConfigurationElements();
@@ -129,18 +133,15 @@ public class TaskActivityManager implements ITaskActivityManager2 {
if (object instanceof ITaskActivationListener) {
addActivationListener((ITaskActivationListener) object);
} else {
- StatusHandler.log(new Status(
- IStatus.ERROR,
- ITasksCoreConstants.ID_PLUGIN,
- NLS.bind(
- "Unexpected error registering listener contributed by {0}: ''{1}'' does not extend expected class", //$NON-NLS-1$
- element.getContributor().getName(), object.getClass()
- .getCanonicalName())));
+ StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, NLS.bind(
+ "Unexpected error registering listener contributed by {0}: ''{1}'' does not extend expected class", //$NON-NLS-1$
+ element.getContributor().getName(), object.getClass().getCanonicalName())));
}
} catch (Throwable e) {
- StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, NLS.bind(
- "Unexpected error registering listener contributed by {0}", //$NON-NLS-1$
- element.getContributor().getName()), e));
+ StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN,
+ NLS.bind("Unexpected error registering listener contributed by {0}", //$NON-NLS-1$
+ element.getContributor().getName()),
+ e));
}
}
}
@@ -689,6 +690,18 @@ public class TaskActivityManager implements ITaskActivityManager2 {
taskList.notifyElementChanged(task);
}
+ public void moveActivity(ITask oldTask, AbstractTask newTask) {
+ setDueDate(newTask, oldTask.getDueDate());
+ if (oldTask instanceof AbstractTask) {
+ setScheduledFor(newTask, ((AbstractTask) oldTask).getScheduledForDate());
+ }
+ if (oldTask.isActive()) {
+ activateTask(newTask);
+ }
+ removeDueTask(oldTask);
+ removeScheduledTask(oldTask);
+ }
+
/**
* @return if a repository task, will only return true if the user is a
*/
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskList.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskList.java
index 28ba83a1a..72190ee2e 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskList.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskList.java
@@ -568,6 +568,55 @@ public class TaskList implements ITaskList, ITransferList {
}
}
+ public AbstractTask refactorTaskId(ITask oldTask, String newTaskId) {
+ TaskTask newTask = new TaskTask(oldTask.getConnectorKind(), oldTask.getRepositoryUrl(), newTaskId);
+
+ newTask.setSummary(oldTask.getSummary());
+ newTask.setPriority(oldTask.getPriority());
+ newTask.setSynchronizationState(oldTask.getSynchronizationState());
+ newTask.setCompletionDate(oldTask.getCompletionDate());
+ newTask.setCreationDate(oldTask.getCreationDate());
+ newTask.setModificationDate(oldTask.getModificationDate());
+ newTask.setTaskKind(oldTask.getTaskKind());
+ newTask.setOwnerId(oldTask.getOwnerId());
+ newTask.setOwner(oldTask.getOwner());
+ newTask.setTaskKey(oldTask.getTaskKey());
+ if (oldTask instanceof AbstractTask) {
+ AbstractTask task = (AbstractTask) oldTask;
+ newTask.setSynchronizing(task.isSynchronizing());
+ newTask.setMarkReadPending(task.isMarkReadPending());
+ newTask.setNotified(task.isNotified());
+ newTask.setChanged(task.isChanged());
+ newTask.setReminded(task.isReminded());
+ newTask.setStatus(task.getStatus());
+ newTask.setNotes(task.getNotes());
+ newTask.setEstimatedTimeHours(task.getEstimatedTimeHours());
+ addTaskContainers(task, newTask);
+ }
+ Map<String, String> attributeMap = oldTask.getAttributes();
+ for (String key : attributeMap.keySet()) {
+ newTask.setAttribute(key, attributeMap.get(key));
+ }
+
+ deleteTask(oldTask);
+ return newTask;
+ }
+
+ private void addTaskContainers(AbstractTask oldTask, AbstractTask newTask) {
+ Set<AbstractTaskContainer> containers = oldTask.getParentContainers();
+ if (containers.isEmpty()
+ || (containers.size() == 1 && containers.iterator().next() instanceof UnmatchedTaskContainer)) {
+ addTask(newTask);
+ } else {
+ for (AbstractTaskContainer container : containers) {
+ addTask(newTask, container);
+ }
+ }
+ for (ITask subtask : oldTask.getChildren()) {
+ addTask(subtask, newTask);
+ }
+ }
+
public void removeChangeListener(ITaskListChangeListener listener) {
changeListeners.remove(listener);
}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataManager.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataManager.java
index 39a46aca0..710239789 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataManager.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataManager.java
@@ -618,4 +618,25 @@ public class TaskDataManager implements ITaskDataManager {
}
});
}
+
+ public void refactorTaskId(final AbstractTask task, final ITask newTask) throws CoreException {
+ final String kind = task.getConnectorKind();
+ taskList.run(new ITaskListRunnable() {
+ public void execute(IProgressMonitor monitor) throws CoreException {
+ File file = getMigratedFile(task, kind);
+ if (file.exists()) {
+ TaskDataState oldState = taskDataStore.getTaskDataState(file);
+ if (oldState != null) {
+ File newFile = getFile(task.getRepositoryUrl(), newTask, kind);
+ TaskDataState newState = new TaskDataState(oldState.getConnectorKind(), task.getRepositoryUrl(),
+ newTask.getTaskId());
+ newState.merge(oldState);
+ taskDataStore.putTaskData(ensurePathExists(newFile), newState);
+ taskDataStore.deleteTaskData(file);
+ }
+ }
+ }
+
+ });
+ }
}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataState.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataState.java
index 576776405..9cca8ae93 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataState.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataState.java
@@ -197,9 +197,9 @@ public class TaskDataState implements ITaskDataWorkingCopy {
}
public void merge(TaskDataState oldState) {
- setEditsData(createCopy(oldState.getEditsData()));
- setLocalTaskData(createCopy(oldState.getLocalData()));
- setRepositoryData(createCopy(oldState.getRepositoryData()));
+ setEditsData(createCopy(oldState.getEditsData(), getTaskId()));
+ setLocalTaskData(createCopy(oldState.getLocalData(), getTaskId()));
+ setRepositoryData(createCopy(oldState.getRepositoryData(), getTaskId()));
}
public void changeAttributeValues(ListMultimap<TaskAttribute, String> newValues) {
@@ -221,11 +221,15 @@ public class TaskDataState implements ITaskDataWorkingCopy {
}
public static TaskData createCopy(TaskData oldData) {
+ return createCopy(oldData, oldData.getTaskId());
+ }
+
+ private static TaskData createCopy(TaskData oldData, String newTaskId) {
if (oldData == null) {
return null;
}
TaskData newData = new TaskData(oldData.getAttributeMapper(), oldData.getConnectorKind(),
- oldData.getRepositoryUrl(), oldData.getTaskId());
+ oldData.getRepositoryUrl(), newTaskId);
newData.setVersion(oldData.getVersion());
for (TaskAttribute child : oldData.getRoot().getAttributes().values()) {
newData.getRoot().deepAddCopy(child);
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/operations/Messages.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/operations/Messages.java
new file mode 100644
index 000000000..3061d939b
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/operations/Messages.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Tasktop Technologies 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
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.core.operations;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.mylyn.internal.tasks.core.operations.messages"; //$NON-NLS-1$
+
+ public static String RefactorTaskIdsOperation_FailedTaskCount;
+
+ public static String RefactorTaskIdsOperation_TaskDataRefactorError;
+
+ public static String RefactorTaskIdsOperation_UpdateTaskId;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/operations/RefactorTaskIdsOperation.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/operations/RefactorTaskIdsOperation.java
new file mode 100644
index 000000000..2e997e657
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/operations/RefactorTaskIdsOperation.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Tasktop Technologies 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
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.core.operations;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
+import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
+import org.eclipse.mylyn.internal.tasks.core.TaskActivityManager;
+import org.eclipse.mylyn.internal.tasks.core.TaskList;
+import org.eclipse.mylyn.internal.tasks.core.data.TaskDataManager;
+import org.eclipse.mylyn.tasks.core.ITask;
+import org.eclipse.mylyn.tasks.core.context.AbstractTaskContextStore;
+import org.eclipse.osgi.util.NLS;
+
+public class RefactorTaskIdsOperation extends TaskListOperation {
+
+ private final Map<ITask, String> newTaskIdMap;
+
+ private final TaskActivityManager activityManager;
+
+ private final AbstractTaskContextStore contextStore;
+
+ private final TaskDataManager taskDataManager;
+
+ public RefactorTaskIdsOperation(Map<ITask, String> newTaskIdMap, TaskList taskList,
+ TaskActivityManager activityManager, AbstractTaskContextStore contextStore,
+ TaskDataManager taskDataManager) {
+ super(ITasksCoreConstants.ROOT_SCHEDULING_RULE, taskList);
+ this.newTaskIdMap = newTaskIdMap;
+ this.activityManager = activityManager;
+ this.contextStore = contextStore;
+ this.taskDataManager = taskDataManager;
+ }
+
+ @Override
+ protected void operations(IProgressMonitor monitor)
+ throws CoreException, InvocationTargetException, InterruptedException {
+ try {
+ monitor.beginTask(Messages.RefactorTaskIdsOperation_UpdateTaskId, newTaskIdMap.size() * 2);
+ Map<ITask, ITask> map = new HashMap<>();
+ MultiStatus status = new MultiStatus(ITasksCoreConstants.ID_PLUGIN, IStatus.OK, null, null);
+
+ for (ITask task : newTaskIdMap.keySet()) {
+ AbstractTask newTask = getTaskList().refactorTaskId(task, newTaskIdMap.get(task));
+ map.put(task, newTask);
+
+ activityManager.moveActivity(task, newTask);
+ if (task instanceof AbstractTask) {
+ try {
+ taskDataManager.refactorTaskId((AbstractTask) task, newTask);
+ } catch (CoreException e) {
+ status.add(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN,
+ NLS.bind(Messages.RefactorTaskIdsOperation_TaskDataRefactorError, task), e));
+ }
+ }
+ monitor.worked(1);
+ }
+
+ contextStore.moveContext(map);
+ monitor.worked(newTaskIdMap.size());
+ handleFailedMigrations(status);
+ } finally {
+ monitor.done();
+ }
+ }
+
+ private void handleFailedMigrations(MultiStatus status) throws CoreException {
+ if (!status.isOK()) {
+ MultiStatus errorStatus = new MultiStatus(ITasksCoreConstants.ID_PLUGIN, IStatus.ERROR,
+ NLS.bind(Messages.RefactorTaskIdsOperation_FailedTaskCount, status.getChildren().length), null);
+ errorStatus.merge(status);
+ throw new CoreException(errorStatus);
+ }
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/operations/TaskListOperation.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/operations/TaskListOperation.java
new file mode 100644
index 000000000..42a73f20b
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/operations/TaskListOperation.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Tasktop Technologies 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
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.core.operations;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.mylyn.internal.tasks.core.ITaskListRunnable;
+import org.eclipse.mylyn.internal.tasks.core.TaskList;
+
+public abstract class TaskListOperation {
+
+ private final ISchedulingRule rule;
+
+ private final TaskList taskList;
+
+ public TaskListOperation(TaskList taskList) {
+ this(null, taskList);
+ }
+
+ public TaskListOperation(ISchedulingRule rule, TaskList taskList) {
+ this.rule = rule;
+ this.taskList = taskList;
+ }
+
+ protected abstract void operations(IProgressMonitor monitor)
+ throws CoreException, InvocationTargetException, InterruptedException;
+
+ final public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ final InvocationTargetException[] ite = new InvocationTargetException[1];
+ try {
+ ITaskListRunnable runnable = new ITaskListRunnable() {
+
+ public void execute(IProgressMonitor monitor) throws CoreException {
+ try {
+ Job.getJobManager().beginRule(rule, new SubProgressMonitor(monitor, IProgressMonitor.UNKNOWN));
+ operations(monitor);
+ } catch (InvocationTargetException e) {
+ ite[0] = e;
+ } catch (InterruptedException e) {
+ throw new OperationCanceledException(e.getMessage());
+ } finally {
+ Job.getJobManager().endRule(rule);
+ }
+ }
+ };
+ getTaskList().run(runnable, monitor);
+ } catch (CoreException e) {
+ throw new InvocationTargetException(e);
+ }
+
+ if (ite[0] != null) {
+ throw ite[0];
+ }
+ }
+
+ protected TaskList getTaskList() {
+ return taskList;
+ }
+}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/operations/messages.properties b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/operations/messages.properties
new file mode 100644
index 000000000..6b30524b1
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/operations/messages.properties
@@ -0,0 +1,3 @@
+RefactorTaskIdsOperation_FailedTaskCount={0} tasks failed to migrate
+RefactorTaskIdsOperation_TaskDataRefactorError=Error while migrating task data for {0}
+RefactorTaskIdsOperation_UpdateTaskId=Task ID Update

Back to the top