diff options
10 files changed, 207 insertions, 30 deletions
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/ITaskJobFactory.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/ITaskJobFactory.java index 1966cf663..d9d714f7b 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/ITaskJobFactory.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/ITaskJobFactory.java @@ -51,4 +51,14 @@ public interface ITaskJobFactory { TaskRepository taskRepository, ITask task, AbstractTaskAttachmentSource source, String comment, TaskAttribute attachmentAttribute); + /** + * Specify whether subtasks should be fetched as part of task synchronization. Defaults to true. + */ + public void setFetchSubtasks(boolean fetchSubtasks); + + /** + * @return whether subtasks should be fetched as part of task synchronization + */ + public boolean getFetchSubtasks(); + } diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskJobFactory.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskJobFactory.java index c99315d0c..3fbab5c51 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskJobFactory.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskJobFactory.java @@ -66,6 +66,8 @@ public class TaskJobFactory implements ITaskJobFactory { private final IRepositoryModel tasksModel; + private boolean fetchSubtasks = true; + protected static synchronized List<TaskJobListener> getTaskJobListeners(AbstractRepositoryConnector connector) { if (taskJobListeners == null) { taskJobListeners = new HashMap<String, List<TaskJobListener>>(); @@ -101,6 +103,7 @@ public class TaskJobFactory implements ITaskJobFactory { public SynchronizationJob createSynchronizeTasksJob(AbstractRepositoryConnector connector, Set<ITask> tasks) { SynchronizeTasksJob job = new SynchronizeTasksJob(taskList, taskDataManager, tasksModel, connector, repositoryManager, tasks); + job.setFetchSubtasks(fetchSubtasks); job.setPriority(Job.LONG); return job; } @@ -109,6 +112,7 @@ public class TaskJobFactory implements ITaskJobFactory { TaskRepository taskRepository, Set<ITask> tasks) { SynchronizeTasksJob job = new SynchronizeTasksJob(taskList, taskDataManager, tasksModel, connector, taskRepository, tasks); + job.setFetchSubtasks(fetchSubtasks); job.setPriority(Job.LONG); return job; } @@ -117,6 +121,7 @@ public class TaskJobFactory implements ITaskJobFactory { TaskRepository repository, Set<RepositoryQuery> queries) { SynchronizationJob job = new SynchronizeQueriesJob(taskList, taskDataManager, tasksModel, connector, repository, queries); + job.setFetchSubtasks(fetchSubtasks); job.setPriority(Job.DECORATE); return job; } @@ -124,6 +129,7 @@ public class TaskJobFactory implements ITaskJobFactory { public SynchronizationJob createSynchronizeRepositoriesJob(Set<TaskRepository> repositories) { SynchronizeRepositoriesJob job = new SynchronizeRepositoriesJob(taskList, taskDataManager, tasksModel, repositoryManager); + job.setFetchSubtasks(fetchSubtasks); job.setRepositories(repositories); job.setPriority(Job.DECORATE); job.addJobChangeListener(new JobChangeAdapter() { @@ -191,4 +197,12 @@ public class TaskJobFactory implements ITaskJobFactory { job.setUser(true); return job; } + + public void setFetchSubtasks(boolean fetchSubtasks) { + this.fetchSubtasks = fetchSubtasks; + } + + public boolean getFetchSubtasks() { + return fetchSubtasks; + } } diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SynchronizeQueriesJob.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SynchronizeQueriesJob.java index c5ff6d12e..6902f098b 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SynchronizeQueriesJob.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SynchronizeQueriesJob.java @@ -218,6 +218,7 @@ public class SynchronizeQueriesJob extends SynchronizationJob { // synchronize tasks that were marked by the connector SynchronizeTasksJob job = new SynchronizeTasksJob(taskList, taskDataManager, tasksModel, connector, repository, tasksToBeSynchronized); + job.setFetchSubtasks(getFetchSubtasks()); job.setUser(isUser()); job.setSession(session); if (!tasksToBeSynchronized.isEmpty()) { diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SynchronizeRepositoriesJob.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SynchronizeRepositoriesJob.java index 42108e16c..03c445a03 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SynchronizeRepositoriesJob.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SynchronizeRepositoriesJob.java @@ -175,6 +175,7 @@ public class SynchronizeRepositoriesJob extends SynchronizationJob { return ITasksCoreConstants.JOB_FAMILY_SYNCHRONIZATION == family; } }; + job.setFetchSubtasks(getFetchSubtasks()); job.setUser(isUser()); job.setFullSynchronization(true); job.setPriority(Job.DECORATE); diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SynchronizeTasksJob.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SynchronizeTasksJob.java index bee3c788f..5ced40cee 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SynchronizeTasksJob.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SynchronizeTasksJob.java @@ -46,8 +46,6 @@ import org.eclipse.mylyn.tasks.core.data.AbstractTaskDataHandler; import org.eclipse.mylyn.tasks.core.data.TaskData; import org.eclipse.mylyn.tasks.core.data.TaskDataCollector; import org.eclipse.mylyn.tasks.core.data.TaskRelation; -import org.eclipse.mylyn.tasks.core.data.TaskRelation.Direction; -import org.eclipse.mylyn.tasks.core.data.TaskRelation.Kind; import org.eclipse.mylyn.tasks.core.sync.SynchronizationJob; import org.eclipse.osgi.util.NLS; @@ -163,18 +161,20 @@ public class SynchronizeTasksJob extends SynchronizationJob { TaskRelation[] relations = relationsByTaskId.get(taskId); for (TaskRelation relation : relations) { - if (relation.getDirection() == Direction.OUTWARD && relation.getKind() == Kind.CONTAINMENT) { + if (relation.isChildRelation()) { ITask task = taskList.getTask(taskRepository.getRepositoryUrl(), relation.getTaskId()); if (task == null) { - try { - task = synchronizeTask(monitor, relation.getTaskId()); - } catch (CoreException e) { - String taskKey = (task != null && task.getTaskKey() != null) - ? task.getTaskKey() - : relation.getTaskId(); - StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, NLS.bind( - Messages.SynchronizeTasksJob_Synchronization_of_task_ID_REPOSITORY_failed, - taskKey, taskRepository.getRepositoryLabel()), e)); + if (getFetchSubtasks()) { + try { + task = synchronizeTask(monitor, relation.getTaskId()); + } catch (CoreException e) { + StatusHandler.log(new Status( + IStatus.ERROR, + ITasksCoreConstants.ID_PLUGIN, + NLS.bind( + Messages.SynchronizeTasksJob_Synchronization_of_task_ID_REPOSITORY_failed, + relation.getTaskId(), taskRepository.getRepositoryLabel()), e)); + } } } else { removedChildTasks.remove(task); diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskRelation.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskRelation.java index 14fb166f5..0cfc3b6d0 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskRelation.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskRelation.java @@ -91,6 +91,20 @@ public class TaskRelation { return new TaskRelation(Kind.DEPENDENCY, direction, taskId); } + /** + * @since 3.12 + */ + public boolean isParentRelation() { + return kind == Kind.CONTAINMENT && direction == Direction.INWARD; + } + + /** + * @since 3.12 + */ + public boolean isChildRelation() { + return kind == Kind.CONTAINMENT && direction == Direction.OUTWARD; + } + @Override public int hashCode() { final int prime = 31; @@ -118,9 +132,9 @@ public class TaskRelation { @Override public String toString() { - if (kind == Kind.CONTAINMENT && direction == Direction.INWARD) { + if (isParentRelation()) { return Messages.TaskRelation_Parent; - } else if (kind == Kind.CONTAINMENT && direction == Direction.OUTWARD) { + } else if (isChildRelation()) { return Messages.TaskRelation_Subtask; } else { return Messages.TaskRelation_Dependency; diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/sync/SynchronizationJob.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/sync/SynchronizationJob.java index 4cc00d282..2d1677f04 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/sync/SynchronizationJob.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/sync/SynchronizationJob.java @@ -31,6 +31,8 @@ public abstract class SynchronizationJob extends Job { */ protected final IDelegatingProgressMonitor monitor; + private boolean fetchSubtasks = true; + /** * @since 3.0 */ @@ -68,4 +70,21 @@ public abstract class SynchronizationJob extends Job { public IDelegatingProgressMonitor getMonitor() { return monitor; } + + /** + * Specify whether subtasks should be fetched as part of task synchronization. Defaults to true. + * + * @since 3.12 + */ + public void setFetchSubtasks(boolean fetchSubtasks) { + this.fetchSubtasks = fetchSubtasks; + } + + /** + * @return whether subtasks should be fetched as part of task synchronization + * @since 3.12 + */ + public boolean getFetchSubtasks() { + return fetchSubtasks; + } } diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/AllTasksTests.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/AllTasksTests.java index 2729cb6a5..2fcfe655c 100644 --- a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/AllTasksTests.java +++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/AllTasksTests.java @@ -26,6 +26,7 @@ import org.eclipse.mylyn.tasks.tests.core.RepositoryConnectorContributorTest; import org.eclipse.mylyn.tasks.tests.core.SynchronizeTasksJobTest; import org.eclipse.mylyn.tasks.tests.core.TaskAttributeMetaDataTest; import org.eclipse.mylyn.tasks.tests.core.TaskInitializationDataTest; +import org.eclipse.mylyn.tasks.tests.core.TaskJobFactoryTest; import org.eclipse.mylyn.tasks.tests.core.TaskListUnmatchedContainerTest; import org.eclipse.mylyn.tasks.tests.core.TaskRepositoryLocationTest; import org.eclipse.mylyn.tasks.tests.core.TaskRepositoryTest; @@ -166,6 +167,7 @@ public class AllTasksTests { suite.addTestSuite(TaskDataDiffTest.class); suite.addTestSuite(TaskEditorExtensionsTest.class); suite.addTestSuite(AbstractRepositoryConnectorTest.class); + suite.addTestSuite(TaskJobFactoryTest.class); } } diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/SynchronizeTasksJobTest.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/SynchronizeTasksJobTest.java index 001d68d58..72262af36 100644 --- a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/SynchronizeTasksJobTest.java +++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/SynchronizeTasksJobTest.java @@ -523,6 +523,14 @@ public class SynchronizeTasksJobTest extends TestCase { } public void testGetSingleTaskDataWithRelationsAndRemoveRelation() throws Exception { + getSingleTaskDataWithRelationsAndRemoveRelation(true); + } + + public void testGetSingleTaskDataWithRelationsDisabled() throws Exception { + getSingleTaskDataWithRelationsAndRemoveRelation(false); + } + + private void getSingleTaskDataWithRelationsAndRemoveRelation(boolean fetchSubtasks) { final List<String> requestedTaskIds = new ArrayList<String>(); AbstractRepositoryConnector connector = new MockRepositoryConnectorWithTaskDataHandler() { @Override @@ -540,32 +548,49 @@ public class SynchronizeTasksJobTest extends TestCase { ArrayList<TaskRelation> relations = new ArrayList<TaskRelation>(); relations.add(TaskRelation.subtask("1.sub")); relations.add(TaskRelation.subtask("1.sub5")); + relations.add(TaskRelation.subtask("taskToBecomeSubtask")); return relations; } }; - final ITask task = new MockTask("1"); - final ITask subtaskToBeGone = new MockTask("1.sub2"); - final ITask subtaskToStay = new MockTask("1.sub5"); + ITask task = new MockTask("1"); + ITask subtaskToBeGone = new MockTask("1.sub2"); + ITask subtaskToStay = new MockTask("1.sub5"); + ITask taskToBecomeSubtask = new MockTask("taskToBecomeSubtask"); + taskList.addTask(task); taskList.addTask(subtaskToBeGone, ((AbstractTaskContainer) task)); taskList.addTask(subtaskToStay, ((AbstractTaskContainer) task)); + taskList.addTask(taskToBecomeSubtask); + Collection<ITask> children = ((AbstractTaskContainer) task).getChildren(); + assertEquals(2, children.size()); + assertTrue(children.contains(subtaskToBeGone)); + assertTrue(children.contains(subtaskToStay)); + SynchronizeTasksJob job = createSyncJob(connector, Collections.singleton(task)); + job.setFetchSubtasks(fetchSubtasks); job.run(new NullProgressMonitor()); - assertEquals(2, requestedTaskIds.size()); + assertEquals(fetchSubtasks ? 2 : 1, requestedTaskIds.size()); assertTrue(requestedTaskIds.contains("1")); - assertTrue(requestedTaskIds.contains("1.sub")); - - ITask sub1 = taskList.getTask(MockRepositoryConnector.REPOSITORY_URL, "1.sub"); - ITask sub2 = taskList.getTask(MockRepositoryConnector.REPOSITORY_URL, "1.sub2"); - ITask sub5 = taskList.getTask(MockRepositoryConnector.REPOSITORY_URL, "1.sub5"); - assertNotNull(sub1); - assertNotNull(sub2); - assertNotNull(sub5); + if (fetchSubtasks) { + assertTrue(requestedTaskIds.contains("1.sub")); + } - Collection<ITask> children = ((AbstractTaskContainer) task).getChildren(); - assertEquals(2, children.size()); - assertTrue(children.contains(sub1)); - assertTrue(children.contains(sub5)); + ITask newSubtask = taskList.getTask(MockRepositoryConnector.REPOSITORY_URL, "1.sub"); + subtaskToBeGone = taskList.getTask(MockRepositoryConnector.REPOSITORY_URL, "1.sub2"); + subtaskToStay = taskList.getTask(MockRepositoryConnector.REPOSITORY_URL, "1.sub5"); + taskToBecomeSubtask = taskList.getTask(MockRepositoryConnector.REPOSITORY_URL, "taskToBecomeSubtask"); + assertEquals(fetchSubtasks, newSubtask != null); + assertNotNull(subtaskToBeGone); + assertNotNull(subtaskToStay); + assertNotNull(taskToBecomeSubtask); + + children = ((AbstractTaskContainer) task).getChildren(); + assertEquals(fetchSubtasks ? 3 : 2, children.size()); + if (fetchSubtasks) { + assertTrue(children.contains(newSubtask)); + } + assertTrue(children.contains(subtaskToStay)); + assertTrue(children.contains(taskToBecomeSubtask)); } public void testErrorOnRelationRetrieval() throws Exception { diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/TaskJobFactoryTest.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/TaskJobFactoryTest.java new file mode 100644 index 000000000..d591cc19f --- /dev/null +++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/TaskJobFactoryTest.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2014 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.tasks.tests.core; + +import java.util.Collections; + +import junit.framework.TestCase; + +import org.eclipse.mylyn.internal.tasks.core.RepositoryQuery; +import org.eclipse.mylyn.internal.tasks.ui.TaskJobFactory; +import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin; +import org.eclipse.mylyn.tasks.core.ITask; +import org.eclipse.mylyn.tasks.core.TaskRepository; +import org.eclipse.mylyn.tasks.core.sync.SynchronizationJob; + +public class TaskJobFactoryTest extends TestCase { + private static abstract class JobCreator { + public abstract SynchronizationJob createJob(); + } + + private TaskJobFactory jobFactory; + + private boolean oldFetchSubtasks; + + @Override + protected void setUp() throws Exception { + jobFactory = TasksUiPlugin.getTaskJobFactory(); + oldFetchSubtasks = jobFactory.getFetchSubtasks(); + } + + @Override + protected void tearDown() throws Exception { + jobFactory.setFetchSubtasks(oldFetchSubtasks); + } + + public void testFetchSubtasksDefaultValue() throws Exception { + assertTrue(TasksUiPlugin.getTaskJobFactory().getFetchSubtasks()); + } + + private void assertFetchSubtasks(JobCreator jobCreator) { + jobFactory.setFetchSubtasks(true); + assertTrue(jobCreator.createJob().getFetchSubtasks()); + + jobFactory.setFetchSubtasks(false); + assertFalse(jobCreator.createJob().getFetchSubtasks()); + } + + public void testCreateSynchronizeTasksJob() { + assertFetchSubtasks(new JobCreator() { + @Override + public SynchronizationJob createJob() { + return jobFactory.createSynchronizeTasksJob(null, Collections.<ITask> emptySet()); + } + }); + assertFetchSubtasks(new JobCreator() { + @Override + public SynchronizationJob createJob() { + return jobFactory.createSynchronizeTasksJob(null, null, Collections.<ITask> emptySet()); + } + }); + } + + public void testCreateSynchronizeQueriesJob() { + assertFetchSubtasks(new JobCreator() { + @Override + public SynchronizationJob createJob() { + return jobFactory.createSynchronizeQueriesJob(null, new TaskRepository("mock", "http://mock"), + Collections.<RepositoryQuery> emptySet()); + } + }); + } + + public void testCreateSynchronizeRepositoriesJob() { + assertFetchSubtasks(new JobCreator() { + @Override + public SynchronizationJob createJob() { + return jobFactory.createSynchronizeRepositoriesJob(null); + } + }); + } + +} |