NEW - bug 292466: background synchronization stops if active synchronization is canceled
https://bugs.eclipse.org/bugs/show_bug.cgi?id=292466
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SubmitTaskJob.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SubmitTaskJob.java
index 0be919c..2c9dd15 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SubmitTaskJob.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SubmitTaskJob.java
@@ -69,43 +69,50 @@
@Override
protected IStatus run(IProgressMonitor jobMonitor) {
- monitor.attach(jobMonitor);
try {
- monitor.beginTask(Messages.SubmitTaskJob_Submitting_task, 2 * (1 + getSubmitJobListeners().length) * 100);
+ monitor.setCanceled(false);
+ monitor.attach(jobMonitor);
+ try {
+ monitor.beginTask(Messages.SubmitTaskJob_Submitting_task,
+ 2 * (1 + getSubmitJobListeners().length) * 100);
- // post task data
- AbstractTaskDataHandler taskDataHandler = connector.getTaskDataHandler();
- monitor.subTask(Messages.SubmitTaskJob_Sending_data);
- response = taskDataHandler.postTaskData(taskRepository, taskData, oldAttributes, Policy.subMonitorFor(
- monitor, 100));
- if (response == null || response.getTaskId() == null) {
- throw new CoreException(new RepositoryStatus(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN,
- RepositoryStatus.ERROR_INTERNAL,
- "Task could not be created. No additional information was provided by the connector.")); //$NON-NLS-1$
+ // post task data
+ AbstractTaskDataHandler taskDataHandler = connector.getTaskDataHandler();
+ monitor.subTask(Messages.SubmitTaskJob_Sending_data);
+ response = taskDataHandler.postTaskData(taskRepository, taskData, oldAttributes, Policy.subMonitorFor(
+ monitor, 100));
+ if (response == null || response.getTaskId() == null) {
+ throw new CoreException(new RepositoryStatus(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN,
+ RepositoryStatus.ERROR_INTERNAL,
+ "Task could not be created. No additional information was provided by the connector.")); //$NON-NLS-1$
+ }
+ fireTaskSubmitted(monitor);
+
+ // update task in task list
+ String taskId = response.getTaskId();
+ monitor.subTask(Messages.SubmitTaskJob_Receiving_data);
+ TaskData updatedTaskData = connector.getTaskData(taskRepository, taskId, Policy.subMonitorFor(monitor,
+ 100));
+ task = createTask(monitor, updatedTaskData);
+ taskDataManager.putSubmittedTaskData(task, updatedTaskData);
+ fireTaskSynchronized(monitor);
+ } catch (CoreException e) {
+ errorStatus = e.getStatus();
+ } catch (OperationCanceledException e) {
+ errorStatus = Status.CANCEL_STATUS;
+ } catch (Exception e) {
+ StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN,
+ "Unexpected error during task submission", e)); //$NON-NLS-1$
+ errorStatus = new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, "Unexpected error: " //$NON-NLS-1$
+ + e.getMessage(), e);
+ } finally {
+ monitor.done();
}
- fireTaskSubmitted(monitor);
-
- // update task in task list
- String taskId = response.getTaskId();
- monitor.subTask(Messages.SubmitTaskJob_Receiving_data);
- TaskData updatedTaskData = connector.getTaskData(taskRepository, taskId, Policy.subMonitorFor(monitor, 100));
- task = createTask(monitor, updatedTaskData);
- taskDataManager.putSubmittedTaskData(task, updatedTaskData);
- fireTaskSynchronized(monitor);
- } catch (CoreException e) {
- errorStatus = e.getStatus();
- } catch (OperationCanceledException e) {
- errorStatus = Status.CANCEL_STATUS;
- } catch (Exception e) {
- StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN,
- "Unexpected error during task submission", e)); //$NON-NLS-1$
- errorStatus = new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, "Unexpected error: " //$NON-NLS-1$
- + e.getMessage(), e);
+ fireDone();
+ return (errorStatus == Status.CANCEL_STATUS) ? Status.CANCEL_STATUS : Status.OK_STATUS;
} finally {
- monitor.done();
+ monitor.detach(jobMonitor);
}
- fireDone();
- return (errorStatus == Status.CANCEL_STATUS) ? Status.CANCEL_STATUS : Status.OK_STATUS;
}
private ITask createTask(IProgressMonitor monitor, TaskData updatedTaskData) throws CoreException {
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 7827423..8e15390 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
@@ -148,109 +148,114 @@
@Override
public IStatus run(IProgressMonitor jobMonitor) {
- monitor.attach(jobMonitor);
try {
- monitor.beginTask(Messages.SynchronizeQueriesJob_Processing, 20 + queries.size() * 20 + 40 + 10);
-
- Set<ITask> allTasks;
- if (!isFullSynchronization()) {
- allTasks = new HashSet<ITask>();
- for (RepositoryQuery query : queries) {
- allTasks.addAll(query.getChildren());
- }
- } else {
- allTasks = taskList.getTasks(repository.getRepositoryUrl());
- }
-
- ObjectSchedulingRule rule = new ObjectSchedulingRule(repository);
+ monitor.setCanceled(false);
+ monitor.attach(jobMonitor);
try {
- Job.getJobManager().beginRule(rule, monitor);
+ monitor.beginTask(Messages.SynchronizeQueriesJob_Processing, 20 + queries.size() * 20 + 40 + 10);
- final Map<String, TaskRelation[]> relationsByTaskId = new HashMap<String, TaskRelation[]>();
- SynchronizationSession session = new SynchronizationSession(taskDataManager) {
- @Override
- public void putTaskData(ITask task, TaskData taskData) throws CoreException {
- boolean changed = connector.hasTaskChanged(repository, task, taskData);
- taskDataManager.putUpdatedTaskData(task, taskData, isUser(), this);
- if (taskData.isPartial()) {
- if (changed && connector.canSynchronizeTask(repository, task)) {
- markStale(task);
- }
- } else {
- Collection<TaskRelation> relations = connector.getTaskRelations(taskData);
- if (relations != null) {
- relationsByTaskId.put(task.getTaskId(), relations.toArray(new TaskRelation[0]));
+ Set<ITask> allTasks;
+ if (!isFullSynchronization()) {
+ allTasks = new HashSet<ITask>();
+ for (RepositoryQuery query : queries) {
+ allTasks.addAll(query.getChildren());
+ }
+ } else {
+ allTasks = taskList.getTasks(repository.getRepositoryUrl());
+ }
+
+ ObjectSchedulingRule rule = new ObjectSchedulingRule(repository);
+ try {
+ Job.getJobManager().beginRule(rule, monitor);
+
+ final Map<String, TaskRelation[]> relationsByTaskId = new HashMap<String, TaskRelation[]>();
+ SynchronizationSession session = new SynchronizationSession(taskDataManager) {
+ @Override
+ public void putTaskData(ITask task, TaskData taskData) throws CoreException {
+ boolean changed = connector.hasTaskChanged(repository, task, taskData);
+ taskDataManager.putUpdatedTaskData(task, taskData, isUser(), this);
+ if (taskData.isPartial()) {
+ if (changed && connector.canSynchronizeTask(repository, task)) {
+ markStale(task);
+ }
+ } else {
+ Collection<TaskRelation> relations = connector.getTaskRelations(taskData);
+ if (relations != null) {
+ relationsByTaskId.put(task.getTaskId(), relations.toArray(new TaskRelation[0]));
+ }
}
}
- }
- };
- session.setTaskRepository(repository);
- session.setFullSynchronization(isFullSynchronization());
- session.setTasks(Collections.unmodifiableSet(allTasks));
- session.setNeedsPerformQueries(true);
- session.setUser(isUser());
+ };
+ session.setTaskRepository(repository);
+ session.setFullSynchronization(isFullSynchronization());
+ session.setTasks(Collections.unmodifiableSet(allTasks));
+ session.setNeedsPerformQueries(true);
+ session.setUser(isUser());
- updateQueryStatus(null);
- try {
- boolean success = preSynchronization(session, new SubProgressMonitor(monitor, 20));
+ updateQueryStatus(null);
+ try {
+ boolean success = preSynchronization(session, new SubProgressMonitor(monitor, 20));
- if ((success && session.needsPerformQueries()) || isUser()) {
- // synchronize queries, tasks changed within query are added to set of tasks to be synchronized
- synchronizeQueries(monitor, session);
- } else {
- monitor.worked(queries.size() * 20);
+ if ((success && session.needsPerformQueries()) || isUser()) {
+ // synchronize queries, tasks changed within query are added to set of tasks to be synchronized
+ synchronizeQueries(monitor, session);
+ } else {
+ monitor.worked(queries.size() * 20);
+ }
+ } finally {
+ for (RepositoryQuery repositoryQuery : queries) {
+ repositoryQuery.setSynchronizing(false);
+ }
+ taskList.notifySynchronizationStateChanged(queries);
}
+
+ Set<ITask> tasksToBeSynchronized = new HashSet<ITask>();
+ for (ITask task : session.getStaleTasks()) {
+ tasksToBeSynchronized.add(task);
+ ((AbstractTask) task).setSynchronizing(true);
+ }
+
+ // synchronize tasks that were marked by the connector
+ SynchronizeTasksJob job = new SynchronizeTasksJob(taskList, taskDataManager, tasksModel, connector,
+ repository, tasksToBeSynchronized);
+ job.setUser(isUser());
+ job.setSession(session);
+ if (!tasksToBeSynchronized.isEmpty()) {
+ Policy.checkCanceled(monitor);
+ IStatus result = job.run(new SubProgressMonitor(monitor, 30));
+ if (result == Status.CANCEL_STATUS) {
+ throw new OperationCanceledException();
+ }
+ statuses.addAll(job.getStatuses());
+ }
+ monitor.subTask(Messages.SynchronizeQueriesJob_Receiving_related_tasks);
+ job.synchronizedTaskRelations(monitor, relationsByTaskId);
+ monitor.worked(10);
+
+ session.setChangedTasks(tasksToBeSynchronized);
+ if (statuses.size() > 0) {
+ Status status = new MultiStatus(ITasksCoreConstants.ID_PLUGIN, 0,
+ statuses.toArray(new IStatus[0]), "Query synchronization failed", null); //$NON-NLS-1$
+ session.setStatus(status);
+ }
+
+ // hook into the connector for synchronization time stamp management
+ postSynchronization(session, new SubProgressMonitor(monitor, 10));
} finally {
- for (RepositoryQuery repositoryQuery : queries) {
- repositoryQuery.setSynchronizing(false);
- }
- taskList.notifySynchronizationStateChanged(queries);
+ Job.getJobManager().endRule(rule);
}
-
- Set<ITask> tasksToBeSynchronized = new HashSet<ITask>();
- for (ITask task : session.getStaleTasks()) {
- tasksToBeSynchronized.add(task);
- ((AbstractTask) task).setSynchronizing(true);
- }
-
- // synchronize tasks that were marked by the connector
- SynchronizeTasksJob job = new SynchronizeTasksJob(taskList, taskDataManager, tasksModel, connector,
- repository, tasksToBeSynchronized);
- job.setUser(isUser());
- job.setSession(session);
- if (!tasksToBeSynchronized.isEmpty()) {
- Policy.checkCanceled(monitor);
- IStatus result = job.run(new SubProgressMonitor(monitor, 30));
- if (result == Status.CANCEL_STATUS) {
- throw new OperationCanceledException();
- }
- statuses.addAll(job.getStatuses());
- }
- monitor.subTask(Messages.SynchronizeQueriesJob_Receiving_related_tasks);
- job.synchronizedTaskRelations(monitor, relationsByTaskId);
- monitor.worked(10);
-
- session.setChangedTasks(tasksToBeSynchronized);
- if (statuses.size() > 0) {
- Status status = new MultiStatus(ITasksCoreConstants.ID_PLUGIN, 0, statuses.toArray(new IStatus[0]),
- "Query synchronization failed", null); //$NON-NLS-1$
- session.setStatus(status);
- }
-
- // hook into the connector for synchronization time stamp management
- postSynchronization(session, new SubProgressMonitor(monitor, 10));
+ } catch (OperationCanceledException e) {
+ return Status.CANCEL_STATUS;
+ } catch (Exception e) {
+ StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, "Synchronization failed", e)); //$NON-NLS-1$
+ } catch (LinkageError e) {
+ StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, NLS.bind(
+ "Synchronization for connector ''{0}'' failed", connector.getConnectorKind()), e)); //$NON-NLS-1$
} finally {
- Job.getJobManager().endRule(rule);
+ monitor.done();
}
- } catch (OperationCanceledException e) {
- return Status.CANCEL_STATUS;
- } catch (Exception e) {
- StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, "Synchronization failed", e)); //$NON-NLS-1$
- } catch (LinkageError e) {
- StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, NLS.bind(
- "Synchronization for connector ''{0}'' failed", connector.getConnectorKind()), e)); //$NON-NLS-1$
} finally {
- monitor.done();
+ monitor.detach(jobMonitor);
}
return Status.OK_STATUS;
}
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 03444db..163b17f 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
@@ -81,69 +81,75 @@
@Override
public IStatus run(IProgressMonitor jobMonitor) {
- monitor.attach(jobMonitor);
- // get the current list of repositories
- Set<TaskRepository> repositories = this.repositories;
- if (repositories == null) {
- repositories = new HashSet<TaskRepository>(repositoryManager.getAllRepositories());
- }
try {
- monitor.beginTask(Messages.SynchronizeRepositoriesJob_Processing, repositories.size() * 100);
+ monitor.setCanceled(false);
+ monitor.attach(jobMonitor);
- if (TRACE_ENABLED) {
- trace("Starting repository synchronization"); //$NON-NLS-1$
+ // get the current list of repositories
+ Set<TaskRepository> repositories = this.repositories;
+ if (repositories == null) {
+ repositories = new HashSet<TaskRepository>(repositoryManager.getAllRepositories());
}
- for (TaskRepository repository : repositories) {
- if (monitor.isCanceled()) {
- return Status.CANCEL_STATUS;
- }
-
- if (repository.isOffline()) {
- if (TRACE_ENABLED) {
- trace("Skipping synchronization for " + repository.getRepositoryLabel()); //$NON-NLS-1$
- }
- monitor.worked(100);
- continue;
- }
-
- monitor.setTaskName(MessageFormat.format(Messages.SynchronizeRepositoriesJob_Processing_,
- repository.getRepositoryLabel()));
-
- final AbstractRepositoryConnector connector = repositoryManager.getRepositoryConnector(repository.getConnectorKind());
- Set<RepositoryQuery> queries = new HashSet<RepositoryQuery>(
- taskList.getRepositoryQueries(repository.getRepositoryUrl()));
- // remove queries that are not configured for auto update
- if (!isUser()) {
- for (Iterator<RepositoryQuery> it = queries.iterator(); it.hasNext();) {
- if (!it.next().getAutoUpdate()) {
- it.remove();
- }
- }
- }
-
- if (isUser() || queries.isEmpty()) {
- monitor.worked(20);
- } else {
- // occasionally request update of repository configuration attributes as part of background synchronizations
- updateRepositoryConfiguration(repository, connector, new SubProgressMonitor(monitor, 20));
- }
+ try {
+ monitor.beginTask(Messages.SynchronizeRepositoriesJob_Processing, repositories.size() * 100);
if (TRACE_ENABLED) {
- trace("Synchronizing queries for " + repository.getRepositoryLabel()); //$NON-NLS-1$
+ trace("Starting repository synchronization"); //$NON-NLS-1$
}
- updateQueries(repository, connector, queries, monitor);
- }
- if (TRACE_ENABLED) {
- trace("Completed repository synchronization"); //$NON-NLS-1$
- }
- // it's better to remove the job from the progress view instead of having it blocked until all child jobs finish
+ for (TaskRepository repository : repositories) {
+ if (monitor.isCanceled()) {
+ return Status.CANCEL_STATUS;
+ }
+
+ if (repository.isOffline()) {
+ if (TRACE_ENABLED) {
+ trace("Skipping synchronization for " + repository.getRepositoryLabel()); //$NON-NLS-1$
+ }
+ monitor.worked(100);
+ continue;
+ }
+
+ monitor.setTaskName(MessageFormat.format(Messages.SynchronizeRepositoriesJob_Processing_,
+ repository.getRepositoryLabel()));
+
+ final AbstractRepositoryConnector connector = repositoryManager.getRepositoryConnector(repository.getConnectorKind());
+ Set<RepositoryQuery> queries = new HashSet<RepositoryQuery>(
+ taskList.getRepositoryQueries(repository.getRepositoryUrl()));
+ // remove queries that are not configured for auto update
+ if (!isUser()) {
+ for (Iterator<RepositoryQuery> it = queries.iterator(); it.hasNext();) {
+ if (!it.next().getAutoUpdate()) {
+ it.remove();
+ }
+ }
+ }
+
+ if (isUser() || queries.isEmpty()) {
+ monitor.worked(20);
+ } else {
+ // occasionally request update of repository configuration attributes as part of background synchronizations
+ updateRepositoryConfiguration(repository, connector, new SubProgressMonitor(monitor, 20));
+ }
+
+ if (TRACE_ENABLED) {
+ trace("Synchronizing queries for " + repository.getRepositoryLabel()); //$NON-NLS-1$
+ }
+ updateQueries(repository, connector, queries, monitor);
+ }
+ if (TRACE_ENABLED) {
+ trace("Completed repository synchronization"); //$NON-NLS-1$
+ }
+ // it's better to remove the job from the progress view instead of having it blocked until all child jobs finish
// if (isUser()) {
// Job.getJobManager().join(family, monitor);
// }
- } catch (OperationCanceledException e) {
- return Status.CANCEL_STATUS;
+ } catch (OperationCanceledException e) {
+ return Status.CANCEL_STATUS;
+ } finally {
+ monitor.done();
+ }
} finally {
- monitor.done();
+ monitor.detach(jobMonitor);
}
return Status.OK_STATUS;
}
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 c6482d5..1bdf43b 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
@@ -100,43 +100,48 @@
@Override
public IStatus run(IProgressMonitor jobMonitor) {
- monitor.attach(jobMonitor);
try {
- if (taskRepository == null) {
- try {
- monitor.beginTask(Messages.SynchronizeTasksJob_Processing, allTasks.size() * 100);
- // group tasks by repository
- Map<TaskRepository, Set<ITask>> tasksByRepository = new HashMap<TaskRepository, Set<ITask>>();
- for (ITask task : allTasks) {
- TaskRepository repository = repositoryManager.getRepository(task.getConnectorKind(),
- task.getRepositoryUrl());
- Set<ITask> tasks = tasksByRepository.get(repository);
- if (tasks == null) {
- tasks = new HashSet<ITask>();
- tasksByRepository.put(repository, tasks);
+ monitor.setCanceled(false);
+ monitor.attach(jobMonitor);
+ try {
+ if (taskRepository == null) {
+ try {
+ monitor.beginTask(Messages.SynchronizeTasksJob_Processing, allTasks.size() * 100);
+ // group tasks by repository
+ Map<TaskRepository, Set<ITask>> tasksByRepository = new HashMap<TaskRepository, Set<ITask>>();
+ for (ITask task : allTasks) {
+ TaskRepository repository = repositoryManager.getRepository(task.getConnectorKind(),
+ task.getRepositoryUrl());
+ Set<ITask> tasks = tasksByRepository.get(repository);
+ if (tasks == null) {
+ tasks = new HashSet<ITask>();
+ tasksByRepository.put(repository, tasks);
+ }
+ tasks.add(task);
}
- tasks.add(task);
+ // synchronize tasks for each repositories
+ for (TaskRepository taskRepository : tasksByRepository.keySet()) {
+ setName(MessageFormat.format(Messages.SynchronizeTasksJob_Synchronizing_Tasks__X_,
+ taskRepository.getRepositoryLabel()));
+ this.taskRepository = taskRepository;
+ Set<ITask> repositoryTasks = tasksByRepository.get(taskRepository);
+ run(repositoryTasks, new SubProgressMonitor(monitor, repositoryTasks.size() * 100));
+ }
+ } finally {
+ monitor.done();
}
- // synchronize tasks for each repositories
- for (TaskRepository taskRepository : tasksByRepository.keySet()) {
- setName(MessageFormat.format(Messages.SynchronizeTasksJob_Synchronizing_Tasks__X_,
- taskRepository.getRepositoryLabel()));
- this.taskRepository = taskRepository;
- Set<ITask> repositoryTasks = tasksByRepository.get(taskRepository);
- run(repositoryTasks, new SubProgressMonitor(monitor, repositoryTasks.size() * 100));
- }
- } finally {
- monitor.done();
+ } else {
+ run(allTasks, monitor);
}
- } else {
- run(allTasks, monitor);
+ } catch (OperationCanceledException e) {
+ for (ITask task : allTasks) {
+ ((AbstractTask) task).setSynchronizing(false);
+ taskList.notifyElementChanged(task);
+ }
+ return Status.CANCEL_STATUS;
}
- } catch (OperationCanceledException e) {
- for (ITask task : allTasks) {
- ((AbstractTask) task).setSynchronizing(false);
- taskList.notifyElementChanged(task);
- }
- return Status.CANCEL_STATUS;
+ } finally {
+ monitor.detach(jobMonitor);
}
return Status.OK_STATUS;
}
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 d825736..8bbaffe 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
@@ -22,6 +22,7 @@
import org.eclipse.mylyn.tasks.tests.ui.RetrieveTitleFromUrlTest;
import org.eclipse.mylyn.tasks.tests.ui.TaskAttachmentPropertyTesterTest;
import org.eclipse.mylyn.tasks.tests.ui.TaskHyperlinkDetectorTest;
+import org.eclipse.mylyn.tasks.tests.ui.TaskListSynchronizationSchedulerTest;
import org.eclipse.mylyn.tasks.tests.ui.TaskRelationHyperlinkDetectorTest;
import org.eclipse.mylyn.tasks.tests.ui.editor.EditorUtilTest;
import org.eclipse.mylyn.tasks.tests.ui.editor.TaskEditorPartDescriptorTest;
@@ -92,6 +93,7 @@
suite.addTestSuite(RetrieveTitleFromUrlTest.class);
suite.addTestSuite(EditorUtilTest.class);
suite.addTestSuite(FileTaskAttachmentSourceTest.class);
+ suite.addTestSuite(TaskListSynchronizationSchedulerTest.class);
// XXX long running tests, put back?
//suite.addTestSuite(TaskDataImportTest.class);
diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/ui/TaskListSynchronizationSchedulerTest.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/ui/TaskListSynchronizationSchedulerTest.java
new file mode 100644
index 0000000..5bce51c
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/ui/TaskListSynchronizationSchedulerTest.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.mylyn.internal.tasks.ui.ITasksUiPreferenceConstants;
+import org.eclipse.mylyn.internal.tasks.ui.TaskListSynchronizationScheduler;
+import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
+import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.core.sync.ISynchronizationSession;
+import org.eclipse.mylyn.tasks.tests.TaskTestUtil;
+import org.eclipse.mylyn.tasks.tests.connector.MockRepositoryConnector;
+
+/**
+ * @author Steffen Pingel
+ */
+public class TaskListSynchronizationSchedulerTest extends TestCase {
+
+ private class TestConnector extends MockRepositoryConnector {
+
+ CountDownLatch latch = new CountDownLatch(1);
+
+ Throwable e;
+
+ @Override
+ public void preSynchronization(ISynchronizationSession event, IProgressMonitor monitor) throws CoreException {
+ latch.countDown();
+ try {
+ if (!mainLatch.await(10, TimeUnit.SECONDS)) {
+ this.e = new AssertionFailedError("Timed out waiting for main latch");
+ }
+ } catch (InterruptedException e) {
+ this.e = e;
+ }
+ }
+
+ public void reset() {
+ latch = new CountDownLatch(1);
+ }
+
+ }
+
+ private TaskRepository repository;
+
+ private TestConnector connector;
+
+ private AbstractRepositoryConnector oldConnector;
+
+ private final CountDownLatch mainLatch = new CountDownLatch(1);
+
+ @Override
+ protected void setUp() throws Exception {
+ TasksUiPlugin.getDefault().getPreferenceStore().setValue(
+ ITasksUiPreferenceConstants.REPOSITORY_SYNCH_SCHEDULE_ENABLED, false);
+
+ TaskTestUtil.resetTaskListAndRepositories();
+ repository = TaskTestUtil.createMockRepository();
+ TasksUiPlugin.getRepositoryManager().addRepository(repository);
+
+ oldConnector = TasksUiPlugin.getRepositoryManager().removeRepositoryConnector(repository.getConnectorKind());
+ connector = new TestConnector();
+ TasksUiPlugin.getRepositoryManager().addRepositoryConnector(connector);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ release();
+ TasksUiPlugin.getRepositoryManager().removeRepositoryConnector(repository.getConnectorKind());
+ TasksUiPlugin.getRepositoryManager().addRepositoryConnector(oldConnector);
+ }
+
+ public void testSynchronization() throws Exception {
+ TaskListSynchronizationScheduler scheduler = new TaskListSynchronizationScheduler(
+ TasksUiPlugin.getTaskJobFactory());
+ scheduler.setInterval(1);
+ assertTrue(connector.latch.await(10, TimeUnit.SECONDS));
+
+ // cancel and reschedule
+ scheduler.userAttentionLost();
+ scheduler.userAttentionGained();
+ release();
+
+ assertTrue("Expected synchronization to run again", connector.latch.await(5, TimeUnit.SECONDS));
+ }
+
+ private void release() throws Exception {
+ if (connector.e instanceof Error) {
+ throw (Error) connector.e;
+ }
+ if (connector.e instanceof Exception) {
+ throw (Exception) connector.e;
+ }
+ connector.reset();
+ mainLatch.countDown();
+ }
+
+}