Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrelves2007-06-14 21:20:27 +0000
committerrelves2007-06-14 21:20:27 +0000
commit024a0c4e4a82ce7ad5ee39a2a6e40e38667cb696 (patch)
tree44e169f73f3797995129213c411a96e02cbf2f94
parentfe5d2f52d079fdd2e099f8956b3bbad7fab1191b (diff)
downloadorg.eclipse.mylyn.tasks-024a0c4e4a82ce7ad5ee39a2a6e40e38667cb696.tar.gz
org.eclipse.mylyn.tasks-024a0c4e4a82ce7ad5ee39a2a6e40e38667cb696.tar.xz
org.eclipse.mylyn.tasks-024a0c4e4a82ce7ad5ee39a2a6e40e38667cb696.zip
NEW - bug 191575: [api] optimize query synchronization
https://bugs.eclipse.org/bugs/show_bug.cgi?id=191575
-rw-r--r--org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaClient.java101
-rw-r--r--org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaRepositoryConnector.java105
-rw-r--r--org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/RepositoryQueryResultsFactory.java28
-rw-r--r--org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/SaxBugzillaQueryContentHandler.java98
-rw-r--r--org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/BugzillaRepositoryConnectorTest.java17
-rw-r--r--org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/BugzillaSearchEngineTest.java2
-rw-r--r--org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/headless/BugzillaQueryTest.java2
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/LocalRepositoryConnector.java12
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/AbstractRepositoryConnector.java24
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/AbstractTask.java11
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/DelegatingTaskExternalizer.java12
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/ITaskCollector.java22
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/ITaskFactory.java2
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/QueryHitCollector.java107
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/TaskRepository.java26
-rw-r--r--org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/connector/MockRepositoryConnector.java11
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/ScheduledTaskListSynchJob.java32
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/actions/SynchronizeSelectedAction.java47
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/RepositorySynchronizationManager.java96
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/SynchronizeChangedTasksJob.java89
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/SynchronizeQueryJob.java199
-rw-r--r--org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/TracRepositoryConnector.java64
-rw-r--r--org.eclipse.mylyn.trac.tests/src/org/eclipse/mylyn/trac/tests/RepositorySearchQueryTest.java2
-rw-r--r--org.eclipse.mylyn.trac.tests/src/org/eclipse/mylyn/trac/tests/TracRepositoryConnectorTest.java2
-rw-r--r--org.eclipse.mylyn.trac.tests/src/org/eclipse/mylyn/trac/tests/TracTaskDataHandlerTest.java56
-rw-r--r--org.eclipse.mylyn.trac.ui/src/org/eclipse/mylyn/internal/trac/ui/editor/NewTracTaskEditor.java2
26 files changed, 631 insertions, 538 deletions
diff --git a/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaClient.java b/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaClient.java
index 53905ec76..b4aab562e 100644
--- a/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaClient.java
+++ b/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaClient.java
@@ -53,6 +53,7 @@ import org.eclipse.mylyn.core.MylarStatusHandler;
import org.eclipse.mylyn.internal.bugzilla.core.history.BugzillaTaskHistoryParser;
import org.eclipse.mylyn.internal.bugzilla.core.history.TaskHistory;
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
+import org.eclipse.mylyn.tasks.core.ITaskCollector;
import org.eclipse.mylyn.tasks.core.ITaskAttachment;
import org.eclipse.mylyn.tasks.core.QueryHitCollector;
import org.eclipse.mylyn.tasks.core.RepositoryOperation;
@@ -436,53 +437,9 @@ public class BugzillaClient {
// }
// }
-// public void getSearchHits(AbstractRepositoryQuery query, QueryHitCollector
-// collector, TaskList taskList)
-// throws IOException, CoreException {
-// GetMethod method = null;
-// try {
-// String queryUrl = query.getUrl();
-// // Test that we don't specify content type twice.
-// // Should only be specified here (not in passed in url if possible)
-// if (!queryUrl.contains("ctype=rdf")) {
-// queryUrl = queryUrl.concat(IBugzillaConstants.CONTENT_TYPE_RDF);
-// }
-//
-// method = getConnect(queryUrl);
-// if (method.getResponseHeader("Content-Type") != null) {
-// Header responseTypeHeader = method.getResponseHeader("Content-Type");
-// for (String type : VALID_CONFIG_CONTENT_TYPES) {
-// if (responseTypeHeader.getValue().toLowerCase(Locale.ENGLISH).contains(type))
-// {
-// RepositoryQueryResultsFactory queryFactory = new
-// RepositoryQueryResultsFactory(method
-// .getResponseBodyAsStream(), characterEncoding);
-// queryFactory.performQuery(taskList, repositoryUrl.toString(), collector,
-// QueryHitCollector.MAX_HITS);
-//
-//
-//
-//
-// //getTaskData(queryFactory.get)
-// // pass t
-//
-// return;
-// }
-// }
-// }
-// parseHtmlError(new BufferedReader(
-// new InputStreamReader(method.getResponseBodyAsStream(), characterEncoding)));
-// } finally {
-// if (method != null) {
-// method.releaseConnection();
-// }
-// }
-// }
-
- /**
- * Returns ids of bugs that match given query
- */
- public Set<String> getSearchHits(AbstractRepositoryQuery query) throws IOException, CoreException {
+ public boolean getSearchHits(AbstractRepositoryQuery query, ITaskCollector
+ collector)
+ throws IOException, CoreException {
GetMethod method = null;
try {
String queryUrl = query.getUrl();
@@ -496,12 +453,14 @@ public class BugzillaClient {
if (method.getResponseHeader("Content-Type") != null) {
Header responseTypeHeader = method.getResponseHeader("Content-Type");
for (String type : VALID_CONFIG_CONTENT_TYPES) {
- if (responseTypeHeader.getValue().toLowerCase(Locale.ENGLISH).contains(type)) {
- RepositoryQueryResultsFactory queryFactory = new RepositoryQueryResultsFactory(method
+ if (responseTypeHeader.getValue().toLowerCase(Locale.ENGLISH).contains(type))
+ {
+ RepositoryQueryResultsFactory queryFactory = new
+ RepositoryQueryResultsFactory(method
.getResponseBodyAsStream(), characterEncoding);
- queryFactory.performQuery(repositoryUrl.toString(), QueryHitCollector.MAX_HITS);
-
- return queryFactory.getHits();
+ queryFactory.performQuery(repositoryUrl.toString(), collector,
+ QueryHitCollector.MAX_HITS);
+ return !queryFactory.getHits().isEmpty();
}
}
}
@@ -512,9 +471,45 @@ public class BugzillaClient {
method.releaseConnection();
}
}
- return new HashSet<String>();
+ return false;
}
+// /**
+// * Returns ids of bugs that match given query
+// */
+// public Set<String> getSearchHits(AbstractRepositoryQuery query) throws IOException, CoreException {
+// GetMethod method = null;
+// try {
+// String queryUrl = query.getUrl();
+// // Test that we don't specify content type twice.
+// // Should only be specified here (not in passed in url if possible)
+// if (!queryUrl.contains("ctype=rdf")) {
+// queryUrl = queryUrl.concat(IBugzillaConstants.CONTENT_TYPE_RDF);
+// }
+//
+// method = getConnect(queryUrl);
+// if (method.getResponseHeader("Content-Type") != null) {
+// Header responseTypeHeader = method.getResponseHeader("Content-Type");
+// for (String type : VALID_CONFIG_CONTENT_TYPES) {
+// if (responseTypeHeader.getValue().toLowerCase(Locale.ENGLISH).contains(type)) {
+// RepositoryQueryResultsFactory queryFactory = new RepositoryQueryResultsFactory(method
+// .getResponseBodyAsStream(), characterEncoding);
+// queryFactory.performQuery(repositoryUrl.toString(), QueryHitCollector.MAX_HITS);
+//
+// return queryFactory.getHits();
+// }
+// }
+// }
+// parseHtmlError(new BufferedReader(
+// new InputStreamReader(method.getResponseBodyAsStream(), characterEncoding)));
+// } finally {
+// if (method != null) {
+// method.releaseConnection();
+// }
+// }
+// return new HashSet<String>();
+// }
+
public static void setupExistingBugAttributes(String serverUrl, RepositoryTaskData existingReport) {
// ordered list of elements as they appear in UI
// and additional elements that may not appear in the incoming xml
diff --git a/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaRepositoryConnector.java b/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaRepositoryConnector.java
index 353b7ab73..f3be5249b 100644
--- a/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaRepositoryConnector.java
+++ b/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaRepositoryConnector.java
@@ -21,7 +21,6 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
-import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
@@ -34,6 +33,7 @@ import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
import org.eclipse.mylyn.tasks.core.AbstractTask;
import org.eclipse.mylyn.tasks.core.IAttachmentHandler;
+import org.eclipse.mylyn.tasks.core.ITaskCollector;
import org.eclipse.mylyn.tasks.core.ITaskDataHandler;
import org.eclipse.mylyn.tasks.core.ITaskFactory;
import org.eclipse.mylyn.tasks.core.QueryHitCollector;
@@ -221,61 +221,79 @@ public class BugzillaRepositoryConnector extends AbstractRepositoryConnector {
}
}
-
@Override
- public Set<AbstractTask> getChangedSinceLastSync(TaskRepository repository,
- Set<AbstractTask> tasks, IProgressMonitor monitor) throws CoreException {
+ public boolean markStaleTasks(TaskRepository repository, Set<AbstractTask> tasks, IProgressMonitor monitor)
+ throws CoreException {
try {
- Set<AbstractTask> changedTasks = new HashSet<AbstractTask>();
+ monitor.beginTask("Checking for changed tasks", IProgressMonitor.UNKNOWN);
if (repository.getSyncTimeStamp() == null) {
- return tasks;
+ for (AbstractTask task : tasks) {
+ task.setStale(true);
+ }
+ return true;
}
String dateString = repository.getSyncTimeStamp();
if (dateString == null) {
dateString = "";
}
- String urlQueryBase;
- String urlQueryString;
- urlQueryBase = repository.getUrl() + CHANGED_BUGS_CGI_QUERY
+ String urlQueryBase = repository.getUrl() + CHANGED_BUGS_CGI_QUERY
+ URLEncoder.encode(dateString, repository.getCharacterEncoding()) + CHANGED_BUGS_CGI_ENDDATE;
- urlQueryString = urlQueryBase + BUG_ID;
+ String urlQueryString = urlQueryBase + BUG_ID;
+
+ // Need to replace this with query that would return list of tasks since last sync
+ // the trouble is that bugzilla only have 1 hour granularity for "changed since" query
+ // so, we can't say that no tasks has changed in repository
+ Set<AbstractTask> changedTasks = new HashSet<AbstractTask>();
int queryCounter = -1;
Iterator<AbstractTask> itr = tasks.iterator();
while (itr.hasNext()) {
queryCounter++;
AbstractTask task = itr.next();
String newurlQueryString = URLEncoder.encode(task.getTaskId() + ",", repository.getCharacterEncoding());
- if ((urlQueryString.length() + newurlQueryString.length() + IBugzillaConstants.CONTENT_TYPE_RDF
- .length()) > IBugzillaConstants.MAX_URL_LENGTH) {
+ if ((urlQueryString.length() + newurlQueryString.length() + IBugzillaConstants.CONTENT_TYPE_RDF.length()) > IBugzillaConstants.MAX_URL_LENGTH) {
queryForChanged(repository, changedTasks, urlQueryString);
queryCounter = 0;
urlQueryString = urlQueryBase + BUG_ID;
- urlQueryString += newurlQueryString;
- } else if (!itr.hasNext()) {
- urlQueryString += newurlQueryString;
+ }
+ urlQueryString += newurlQueryString;
+ if (!itr.hasNext()) {
queryForChanged(repository, changedTasks, urlQueryString);
- } else {
- urlQueryString += newurlQueryString;
}
}
- return changedTasks;
+
+ for (AbstractTask task : tasks) {
+ if (changedTasks.contains(task)) {
+ task.setStale(true);
+ }
+ }
+
+// for (AbstractTask task : changedTasks) {
+// task.setStale(true);
+// }
+
+ // FIXME check if new tasks were added
+ //return changedTasks.isEmpty();
+ return true;
} catch (UnsupportedEncodingException e) {
+ // XXX throw CoreException instead?
MylarStatusHandler.fail(e, "Repository configured with unsupported encoding: "
+ repository.getCharacterEncoding() + "\n\n Unable to determine changed tasks.", true);
- return tasks;
+ return false;
+ } finally {
+ monitor.done();
}
}
- private void queryForChanged(final TaskRepository repository, Set<AbstractTask> changedTasks,
- String urlQueryString) throws UnsupportedEncodingException, CoreException {
+ private void queryForChanged(final TaskRepository repository, Set<AbstractTask> changedTasks, String urlQueryString)
+ throws UnsupportedEncodingException, CoreException {
QueryHitCollector collector = new QueryHitCollector(taskList, new ITaskFactory() {
- public AbstractTask createTask(RepositoryTaskData taskData, boolean synchData, boolean forced, IProgressMonitor monitor) {
+ public AbstractTask createTask(RepositoryTaskData taskData, IProgressMonitor monitor) {
// do not construct actual task objects here as query shouldn't result in new tasks
return taskList.getTask(taskData.getRepositoryUrl(), taskData.getId());
}
@@ -283,7 +301,7 @@ public class BugzillaRepositoryConnector extends AbstractRepositoryConnector {
BugzillaRepositoryQuery query = new BugzillaRepositoryQuery(repository.getUrl(), urlQueryString, "");
- performQuery(query, repository, new NullProgressMonitor(), collector, false);
+ performQuery(query, repository, new NullProgressMonitor(), collector);
for (AbstractTask taskHit : collector.getTaskHits()) {
// String handle =
@@ -332,49 +350,30 @@ public class BugzillaRepositoryConnector extends AbstractRepositoryConnector {
@Override
public IStatus performQuery(final AbstractRepositoryQuery query, TaskRepository repository,
- IProgressMonitor monitor, QueryHitCollector resultCollector, boolean forced) {
- IStatus queryStatus = Status.OK_STATUS;
+ IProgressMonitor monitor, ITaskCollector resultCollector) {
try {
+ monitor.beginTask("Running query", IProgressMonitor.UNKNOWN);
BugzillaClient client = getClientManager().getClient(repository);
- resultCollector.clear();
- Set<String> ids = client.getSearchHits(query);
- if (ids.size() == 0) {
+ boolean hitsReceived = client.getSearchHits(query, resultCollector);
+ if (!hitsReceived) {
// XXX: HACK in case of ip change bugzilla can return 0 hits
// due to invalid authorization token, forcing relogin fixes
client.logout();
- ids = client.getSearchHits(query);
- }
-
- if (!forced) {
- // Only retrieve data for hits we don't already have
- for (AbstractTask existingTask : query.getChildren()) {
- AbstractTask repositoryTask = (AbstractTask) existingTask;
- if (ids.contains(repositoryTask.getTaskId())) {
- resultCollector.accept(repositoryTask);
- ids.remove(repositoryTask.getTaskId());
- }
- }
- }
-
- Map<String, RepositoryTaskData> hits = client.getTaskData(ids);
- for (RepositoryTaskData data : hits.values()) {
- if (data != null) {
- taskDataHandler.configureTaskData(repository, data);
- resultCollector.accept(data);
- }
+ client.getSearchHits(query, resultCollector);
}
+ return Status.OK_STATUS;
} catch (UnrecognizedReponseException e) {
- queryStatus = new Status(IStatus.ERROR, BugzillaCorePlugin.PLUGIN_ID, Status.INFO,
+ return new Status(IStatus.ERROR, BugzillaCorePlugin.PLUGIN_ID, Status.INFO,
"Unrecognized response from server", e);
} catch (IOException e) {
- queryStatus = new Status(IStatus.ERROR, BugzillaCorePlugin.PLUGIN_ID, Status.ERROR,
+ return new Status(IStatus.ERROR, BugzillaCorePlugin.PLUGIN_ID, Status.ERROR,
"Check repository configuration: " + e.getMessage(), e);
} catch (CoreException e) {
- queryStatus = e.getStatus();
+ return e.getStatus();
+ } finally {
+ monitor.done();
}
- return queryStatus;
-
}
@Override
diff --git a/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/RepositoryQueryResultsFactory.java b/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/RepositoryQueryResultsFactory.java
index d8faa0fc1..e6099baa0 100644
--- a/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/RepositoryQueryResultsFactory.java
+++ b/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/RepositoryQueryResultsFactory.java
@@ -17,6 +17,9 @@ import java.security.GeneralSecurityException;
import java.util.HashSet;
import java.util.Set;
+import org.eclipse.mylyn.tasks.core.ITaskCollector;
+import org.eclipse.mylyn.tasks.core.QueryHitCollector;
+
/**
* @author Rob Elves
*/
@@ -28,14 +31,23 @@ public class RepositoryQueryResultsFactory extends AbstractReportFactory {
super(inStream, encoding);
}
- /**
- * expects rdf returned from repository (ctype=rdf in url)
- *
- * @throws GeneralSecurityException
- */
- public void performQuery(String repositoryUrl, int maxHits) throws IOException {
-
- SaxBugzillaQueryContentHandler contentHandler = new SaxBugzillaQueryContentHandler(repositoryUrl, hits, maxHits);
+// /**
+// * expects rdf returned from repository (ctype=rdf in url)
+// *
+// * @throws GeneralSecurityException
+// */
+// public void performQuery(String repositoryUrl, int maxHits) throws IOException {
+//
+// SaxBugzillaQueryContentHandler contentHandler = new SaxBugzillaQueryContentHandler(repositoryUrl, hits, maxHits);
+// collectResults(contentHandler, false);
+// }
+
+ /** expects rdf returned from repository (ctype=rdf in url)
+ * @throws GeneralSecurityException */
+ public void performQuery(String repositoryUrl, ITaskCollector collector, int maxHits) throws IOException {
+
+ SaxBugzillaQueryContentHandler contentHandler = new SaxBugzillaQueryContentHandler(repositoryUrl,
+ collector, hits, maxHits);
collectResults(contentHandler, false);
}
diff --git a/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/SaxBugzillaQueryContentHandler.java b/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/SaxBugzillaQueryContentHandler.java
index f36a640e0..0c7b1fbd0 100644
--- a/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/SaxBugzillaQueryContentHandler.java
+++ b/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/SaxBugzillaQueryContentHandler.java
@@ -14,6 +14,9 @@ package org.eclipse.mylyn.internal.bugzilla.core;
import java.util.Locale;
import java.util.Set;
+import org.eclipse.mylyn.tasks.core.AbstractTask;
+import org.eclipse.mylyn.tasks.core.ITaskCollector;
+import org.eclipse.mylyn.tasks.core.QueryHitCollector;
import org.eclipse.mylyn.web.core.HtmlStreamTokenizer;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
@@ -29,18 +32,20 @@ public class SaxBugzillaQueryContentHandler extends DefaultHandler {
/** The bug id */
private String id;
-// /** The summary of the bug */
-// private String description = "";
-//
-// /** The priority of the bug */
-// private String priority = Task.PriorityLevel.getDefault().toString();
-//
-// /** The state of the bug */
-// private String state = "";
+ /** The summary of the bug */
+ private String description = "";
+
+ /** The priority of the bug */
+ private String priority = AbstractTask.PriorityLevel.getDefault().toString();
+
+ /** The state of the bug */
+ private String state = "";
private StringBuffer characters;
-// private String repositoryUrl;
+ private ITaskCollector collector;
+
+ private String repositoryUrl;
private Set<String> bugIds;
@@ -48,9 +53,10 @@ public class SaxBugzillaQueryContentHandler extends DefaultHandler {
private int numCollected = 0;
- public SaxBugzillaQueryContentHandler(String repositoryUrl, Set<String> hits, int maxHits) {
- //this.repositoryUrl = repositoryUrl;
+ public SaxBugzillaQueryContentHandler(String repositoryUrl, ITaskCollector collector, Set<String> hits, int maxHits) {
+ this.repositoryUrl = repositoryUrl;
this.maxHits = maxHits;
+ this.collector = collector;
this.bugIds = hits;
}
@@ -96,42 +102,42 @@ public class SaxBugzillaQueryContentHandler extends DefaultHandler {
//System.err.println(">>> "+id);
bugIds.add(id);
numCollected++;
- }
+ }
break;
-// // case BUG_SEVERITY:
-// // severity = parsedText;
-// // break;
-// case PRIORITY:
-// priority = parsedText;
-// break;
-// // case REP_PLATFORM:
-// // platform = parsedText;
-// // break;
-// case ASSIGNED_TO:
-// //hit.setOwner(parsedText);
-// break;
-// case BUG_STATUS:
-// state = parsedText;
-// break;
-// // case RESOLUTION:
-// // resolution = parsedText;
-// // break;
-// case SHORT_DESC:
-// description = parsedText;
-// break;
-// case SHORT_SHORT_DESC:
-// description = parsedText;
-// break;
-// case LI:
-// if (numCollected < maxHits || maxHits == IBugzillaConstants.RETURN_ALL_HITS)
-// {
-// hit = new BugzillaQueryHit(taskList, description, priority, repositoryUrl,
-// id, null, state);
-// collector.accept(hit);
-// numCollected++;
-// } else {
-// break;
-// }
+ // case BUG_SEVERITY:
+ // severity = parsedText;
+ // break;
+ case PRIORITY:
+ priority = parsedText;
+ break;
+ // case REP_PLATFORM:
+ // platform = parsedText;
+ // break;
+ case ASSIGNED_TO:
+ //hit.setOwner(parsedText);
+ break;
+ case BUG_STATUS:
+ state = parsedText;
+ break;
+ // case RESOLUTION:
+ // resolution = parsedText;
+ // break;
+ case SHORT_DESC:
+ description = parsedText;
+ break;
+ case SHORT_SHORT_DESC:
+ description = parsedText;
+ break;
+ case LI:
+ if (numCollected < maxHits || maxHits == IBugzillaConstants.RETURN_ALL_HITS) {
+ BugzillaTask task = new BugzillaTask(repositoryUrl, id, description);
+ task.setPriority(priority);
+ // TODO set state
+ collector.accept(task);
+ numCollected++;
+ } else {
+ break;
+ }
}
} catch (RuntimeException e) {
if (e instanceof IllegalArgumentException) {
diff --git a/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/BugzillaRepositoryConnectorTest.java b/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/BugzillaRepositoryConnectorTest.java
index 2c4f2a587..9f1270b28 100644
--- a/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/BugzillaRepositoryConnectorTest.java
+++ b/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/BugzillaRepositoryConnectorTest.java
@@ -386,9 +386,11 @@ public class BugzillaRepositoryConnectorTest extends AbstractBugzillaTest {
TasksUiPlugin.getRepositoryManager().setSyncTime(repository, task5.getLastSyncDateStamp(),
TasksUiPlugin.getDefault().getRepositoriesFilePath());
- Set<AbstractTask> changedTasks = connector.getChangedSinceLastSync(repository, tasks, new NullProgressMonitor());
+ boolean changed = connector.markStaleTasks(repository, tasks, new NullProgressMonitor());
+ assertTrue(changed);
// Always last known changed returned
- assertEquals(1, changedTasks.size());
+ assertFalse(task4.isStale());
+ assertTrue(task5.isStale());
String priority4 = null;
if (task4.getPriority().equals("P1")) {
@@ -414,14 +416,15 @@ public class BugzillaRepositoryConnectorTest extends AbstractBugzillaTest {
submit(task4, taskData4);
submit(task5, taskData5);
- changedTasks = connector.getChangedSinceLastSync(repository, tasks, new NullProgressMonitor());
+ changed = connector.markStaleTasks(repository, tasks, new NullProgressMonitor());
- assertEquals("Changed reports expected ", 2, changedTasks.size());
- assertTrue(tasks.containsAll(changedTasks));
+ assertTrue(task4.isStale());
+ assertTrue(task5.isStale());
- TasksUiPlugin.getSynchronizationManager().synchronize(connector, changedTasks, true, null);
+ TasksUiPlugin.getSynchronizationManager().synchronize(connector, tasks, true, null);
- for (AbstractTask task : changedTasks) {
+
+ for (AbstractTask task : tasks) {
if (task.getTaskId() == "4") {
assertEquals(priority4, task4.getPriority());
}
diff --git a/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/BugzillaSearchEngineTest.java b/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/BugzillaSearchEngineTest.java
index 493557319..9cc663dab 100644
--- a/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/BugzillaSearchEngineTest.java
+++ b/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/BugzillaSearchEngineTest.java
@@ -118,7 +118,7 @@ public class BugzillaSearchEngineTest extends TestCase {
TaskList taskList = TasksUiPlugin.getTaskListManager().getTaskList();
QueryHitCollector collector = new QueryHitCollector(taskList, new TaskFactory(repository));
- connector.performQuery(repositoryQuery, repository, new NullProgressMonitor(), collector, false);
+ connector.performQuery(repositoryQuery, repository, new NullProgressMonitor(), collector);
// results.addAll(connector.performQuery(repositoryQuery, new
// NullProgressMonitor(), new MultiStatus(TasksUiPlugin.PLUGIN_ID,
diff --git a/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/headless/BugzillaQueryTest.java b/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/headless/BugzillaQueryTest.java
index 1c136ce4c..f20bd5c05 100644
--- a/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/headless/BugzillaQueryTest.java
+++ b/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/headless/BugzillaQueryTest.java
@@ -136,7 +136,7 @@ public class BugzillaQueryTest extends TestCase {
BugzillaRepositoryConnector connector = new BugzillaRepositoryConnector();
connector.init(taskList);
BugzillaRepositoryQuery query = new BugzillaRepositoryQuery(repository.getUrl(), queryUrlString, "summary");
- connector.performQuery(query, repository, new NullProgressMonitor(), collector, false);
+ connector.performQuery(query, repository, new NullProgressMonitor(), collector);
assertEquals(2, collector.getTaskHits().size());
for (AbstractTask hit : collector.getTaskHits()) {
assertTrue(hit.getSummary().contains("search-match-test"));
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/LocalRepositoryConnector.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/LocalRepositoryConnector.java
index 331555779..1790c6a89 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/LocalRepositoryConnector.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/LocalRepositoryConnector.java
@@ -11,7 +11,7 @@
package org.eclipse.mylyn.internal.tasks.core;
-import java.util.Collections;
+
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
@@ -21,8 +21,8 @@ import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
import org.eclipse.mylyn.tasks.core.AbstractTask;
import org.eclipse.mylyn.tasks.core.IAttachmentHandler;
+import org.eclipse.mylyn.tasks.core.ITaskCollector;
import org.eclipse.mylyn.tasks.core.ITaskDataHandler;
-import org.eclipse.mylyn.tasks.core.QueryHitCollector;
import org.eclipse.mylyn.tasks.core.RepositoryTaskData;
import org.eclipse.mylyn.tasks.core.TaskRepository;
@@ -63,9 +63,9 @@ public class LocalRepositoryConnector extends AbstractRepositoryConnector {
}
@Override
- public Set<AbstractTask> getChangedSinceLastSync(TaskRepository repository,
- Set<AbstractTask> tasks, IProgressMonitor monitor) throws CoreException {
- return Collections.emptySet();
+ public boolean markStaleTasks(TaskRepository repository,
+ Set<AbstractTask> tasks, IProgressMonitor monitor) {
+ return false;
}
@Override
@@ -104,7 +104,7 @@ public class LocalRepositoryConnector extends AbstractRepositoryConnector {
@Override
public IStatus performQuery(AbstractRepositoryQuery query, TaskRepository repository, IProgressMonitor monitor,
- QueryHitCollector resultCollector, boolean forced) {
+ ITaskCollector resultCollector) {
// ignore
return null;
}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/AbstractRepositoryConnector.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/AbstractRepositoryConnector.java
index 8eca91e4a..fad1df265 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/AbstractRepositoryConnector.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/AbstractRepositoryConnector.java
@@ -171,7 +171,7 @@ public abstract class AbstractRepositoryConnector {
* IQueryHitCollector that collects the hits found
*/
public abstract IStatus performQuery(AbstractRepositoryQuery query, TaskRepository repository,
- IProgressMonitor monitor, QueryHitCollector resultCollector, boolean forced);
+ IProgressMonitor monitor, ITaskCollector resultCollector);
/**
* The connector's summary i.e. "JIRA (supports 3.3.1 and later)"
@@ -250,18 +250,23 @@ public abstract class AbstractRepositoryConnector {
}
/**
- * Of <code>tasks</code> provided, return all that have changed since last
- * synchronization of <code>repository</code>
+ * Of <code>tasks</code> provided, return all that have changed since last synchronization of
+ * <code>repository</code>.
*
- * All errors should be thrown as <code>CoreException</code> for the
- * framework to handle, since background synchronizations fail silently when
- * disconnected.
+ * Tasks that need to be synchronized (i.e. task data updated) should be passed to
+ * <code>collector.accept(Task)</code> method, or if repository connector can update task data, it can use
+ * <code>collector.accept(RepositoryTaskData)</code> call.
*
- * TODO: Add progress monitor as parameter
+ * All errors should be thrown as <code>CoreException</code> for the framework to handle, since background
+ * synchronizations fail silently when disconnected.
+ * @param tasks TODO
+ *
+ * @return null if there was no tasks changed in the repository, otherwise collection of updated tasks (within
+ * <code>tasks</code> collection), so empty collection means that there are some other tasks changed
*
* @throws CoreException
*/
- public abstract Set<AbstractTask> getChangedSinceLastSync(TaskRepository repository,
+ public abstract boolean markStaleTasks(TaskRepository repository,
Set<AbstractTask> tasks, IProgressMonitor monitor) throws CoreException;
/**
@@ -392,7 +397,7 @@ public abstract class AbstractRepositoryConnector {
* synchronization timestamp. Override to return actual timestamp from
* repository.
*/
- public String getLastSyncTimestamp(TaskRepository repository, Set<AbstractTask> changedTasks) {
+ public String getSynchronizationTimestamp(TaskRepository repository, Set<AbstractTask> changedTasks) {
Date mostRecent = new Date(0);
String mostRecentTimeStamp = repository.getSyncTimeStamp();
for (AbstractTask task : changedTasks) {
@@ -432,4 +437,5 @@ public abstract class AbstractRepositoryConnector {
this.taskDataManager = taskDataManager;
}
+
}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/AbstractTask.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/AbstractTask.java
index e1dfb29a7..ab8a3b448 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/AbstractTask.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/AbstractTask.java
@@ -66,6 +66,8 @@ public abstract class AbstractTask extends AbstractTaskContainer {
// transient
private IStatus errorStatus = null;
+
+ private boolean stale = false;
public enum RepositoryTaskSyncState {
OUTGOING, SYNCHRONIZED, INCOMING, CONFLICT
@@ -446,4 +448,13 @@ public abstract class AbstractTask extends AbstractTaskContainer {
public void setDueDate(Date date) {
this.dueDate = date;
}
+
+ public boolean isStale() {
+ return stale;
+ }
+
+ public void setStale(boolean stale) {
+ this.stale = stale;
+ }
+
}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/DelegatingTaskExternalizer.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/DelegatingTaskExternalizer.java
index 8f38aed49..a2995d956 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/DelegatingTaskExternalizer.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/DelegatingTaskExternalizer.java
@@ -126,6 +126,8 @@ public class DelegatingTaskExternalizer implements ITaskListExternalizer {
public static final String KEY_SYNC_STATE = "offlineSyncState";
public static final String KEY_OWNER = "Owner";
+
+ public static final String KEY_STALE = "Stale";
private List<ITaskListExternalizer> delegateExternalizers = new ArrayList<ITaskListExternalizer>();
@@ -204,6 +206,11 @@ public class DelegatingTaskExternalizer implements ITaskListExternalizer {
} else {
node.setAttribute(KEY_REMINDED, VAL_FALSE);
}
+ if (task.isStale()) {
+ node.setAttribute(KEY_STALE, VAL_TRUE);
+ } else {
+ node.setAttribute(KEY_STALE, VAL_FALSE);
+ }
if (task instanceof AbstractTask) {
AbstractTask abstractTask = (AbstractTask) task;
@@ -483,6 +490,11 @@ public class DelegatingTaskExternalizer implements ITaskListExternalizer {
} else {
task.setReminded(false);
}
+ if (element.hasAttribute(KEY_STALE) && element.getAttribute(KEY_STALE).compareTo(VAL_TRUE) == 0) {
+ task.setStale(true);
+ } else {
+ task.setStale(false);
+ }
if (task instanceof AbstractTask) {
AbstractTask abstractTask = (AbstractTask) task;
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/ITaskCollector.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/ITaskCollector.java
new file mode 100644
index 000000000..2aad2db65
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/ITaskCollector.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2006 University Of British Columbia 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:
+ * University Of British Columbia - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.tasks.core;
+
+import org.eclipse.core.runtime.CoreException;
+
+public interface ITaskCollector {
+
+ void accept(AbstractTask task);
+
+ void accept(RepositoryTaskData taskData) throws CoreException;
+
+}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/ITaskFactory.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/ITaskFactory.java
index 834e0947e..68583a7ad 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/ITaskFactory.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/ITaskFactory.java
@@ -23,6 +23,6 @@ public interface ITaskFactory {
* @param forced -
* user requested synchronization
*/
- public abstract AbstractTask createTask(RepositoryTaskData taskData, boolean synchData, boolean forced, IProgressMonitor monitor) throws CoreException;
+ public abstract AbstractTask createTask(RepositoryTaskData taskData, IProgressMonitor monitor) throws CoreException;
} \ No newline at end of file
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/QueryHitCollector.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/QueryHitCollector.java
index b68a980b8..310e337c3 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/QueryHitCollector.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/QueryHitCollector.java
@@ -10,131 +10,64 @@
*******************************************************************************/
package org.eclipse.mylyn.tasks.core;
-import java.text.MessageFormat;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.SubProgressMonitor;
/**
* Collects QueryHits resulting from repository search
*
* @author Shawn Minto
* @author Rob Elves (generalized from bugzilla)
+ * @author Steffen Pingel
*/
-public class QueryHitCollector {
+public class QueryHitCollector implements ITaskCollector {
public static final int MAX_HITS = 5000;
public static final String MAX_HITS_REACHED = "Max allowed number of hits returned exceeded. Some hits may not be displayed. Please narrow query scope.";
- protected Set<AbstractTask> taskResults = new HashSet<AbstractTask>();
+ private final Set<AbstractTask> taskResults = new HashSet<AbstractTask>();
- /** The progress monitor for the search operation */
- private IProgressMonitor monitor = new NullProgressMonitor();
+ private final TaskList taskList;
- /** The number of matches found */
- private int matchCount;
-
- /** The string to display to the user while querying */
- private static final String STARTING = "querying the server";
-
- /** The string to display to the user when we have 1 match */
- private static final String MATCH = "1 match";
-
- /** The string to display to the user when we have multiple or no matches */
- private static final String MATCHES = "{0} matches";
-
- /** The string to display to the user when the query is done */
- private static final String DONE = "done";
-
- protected TaskList taskList;
-
- protected ITaskFactory taskFactory;
+ private final ITaskFactory taskFactory;
public QueryHitCollector(TaskList tasklist, ITaskFactory taskFactory) {
this.taskList = tasklist;
this.taskFactory = taskFactory;
}
- public void aboutToStart(int startMatchCount) throws CoreException {
- taskResults.clear();
- matchCount = startMatchCount;
- monitor.setTaskName(STARTING);
- }
-
public void accept(AbstractTask task) {
-
- if (!getProgressMonitor().isCanceled()) {
- getProgressMonitor().subTask(getFormattedMatchesString(matchCount));
- getProgressMonitor().worked(1);
+ if (task == null) {
+ throw new IllegalArgumentException();
}
-
- if (task == null)
- return;
-
- AbstractTask hitTask = taskList.getTask(task.getHandleIdentifier());
- if (hitTask == null) {
- hitTask = task;
- // task is new, add to tasklist
- taskList.addTask(hitTask);
+
+ AbstractTask existingTask = taskList.getTask(task.getHandleIdentifier());
+ if (existingTask == null) {
+ task.setStale(true);
+ } else {
+ // preserve meta attributes of existing task
+ task.setLastSyncDateStamp(existingTask.getLastSyncDateStamp());
+ task.setStale(existingTask.isStale());
}
- taskResults.add((AbstractTask) hitTask);
- matchCount++;
+
+ taskResults.add((AbstractTask) task);
}
public void accept(RepositoryTaskData taskData) throws CoreException {
- if (taskData == null)
- return;
-
- if (!getProgressMonitor().isCanceled()) {
- getProgressMonitor().subTask(getFormattedMatchesString(matchCount));
- getProgressMonitor().worked(1);
+ if (taskData == null) {
+ throw new IllegalArgumentException();
}
- AbstractTask task = taskFactory.createTask(taskData, true, false, new SubProgressMonitor(monitor, 1));
+ AbstractTask task = taskFactory.createTask(taskData, new NullProgressMonitor());
taskResults.add(task);
- matchCount++;
- }
-
- public void done() {
- if (monitor != null && !monitor.isCanceled()) {
- // if the operation is cancelled, finish with the data that we
- // already have
- String matchesString = getFormattedMatchesString(matchCount);
- monitor.setTaskName(MessageFormat.format(DONE, new Object[] { matchesString }));
- monitor.done();
- }
-
- // Cut no longer used references because the collector might be re-used
- monitor = null;
- }
-
- protected String getFormattedMatchesString(int count) {
- if (count == 1) {
- return MATCH;
- }
- Object[] messageFormatArgs = { new Integer(count) };
- return MessageFormat.format(MATCHES, messageFormatArgs);
- }
-
- public IProgressMonitor getProgressMonitor() {
- return monitor;
- }
-
- public void setProgressMonitor(IProgressMonitor monitor) {
- this.monitor = monitor;
}
public Set<AbstractTask> getTaskHits() {
return taskResults;
}
- public void clear() {
- taskResults.clear();
- }
-
}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/TaskRepository.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/TaskRepository.java
index 70c727789..7d81e8de3 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/TaskRepository.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/TaskRepository.java
@@ -294,8 +294,23 @@ public class TaskRepository {
@Override
public boolean equals(Object object) {
- if (object instanceof TaskRepository && getUrl() != null) {
- return getUrl().equals(((TaskRepository) object).getUrl());
+ if (object instanceof TaskRepository) {
+ TaskRepository repository = (TaskRepository) object;
+ if (getUrl() == null) {
+ if (repository.getUrl() != null) {
+ return false;
+ }
+ } else {
+ if(!getUrl().equals(repository.getUrl())) {
+ return false;
+ }
+ }
+ if (getKind() == null) {
+ return repository.getKind() == null;
+ } else {
+ return getKind().equals(repository.getKind());
+ }
+
} else {
return super.equals(object);
}
@@ -303,11 +318,8 @@ public class TaskRepository {
@Override
public int hashCode() {
- if (getUrl() != null) {
- return getUrl().hashCode();
- } else {
- return super.hashCode();
- }
+ int res = getUrl()==null ? 1 : getUrl().hashCode();
+ return res * 31 + (getKind()==null ? 1 : getKind().hashCode());
}
@Override
diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/connector/MockRepositoryConnector.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/connector/MockRepositoryConnector.java
index f2c2e8e8a..184920bfe 100644
--- a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/connector/MockRepositoryConnector.java
+++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/connector/MockRepositoryConnector.java
@@ -22,8 +22,8 @@ import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
import org.eclipse.mylyn.tasks.core.AbstractTask;
import org.eclipse.mylyn.tasks.core.IAttachmentHandler;
+import org.eclipse.mylyn.tasks.core.ITaskCollector;
import org.eclipse.mylyn.tasks.core.ITaskDataHandler;
-import org.eclipse.mylyn.tasks.core.QueryHitCollector;
import org.eclipse.mylyn.tasks.core.RepositoryTaskData;
import org.eclipse.mylyn.tasks.core.TaskRepository;
@@ -133,9 +133,10 @@ public class MockRepositoryConnector extends AbstractRepositoryConnector {
}
@Override
- public Set<AbstractTask> getChangedSinceLastSync(TaskRepository repository,
- Set<AbstractTask> tasks, IProgressMonitor monitor) throws CoreException {
- return Collections.emptySet();
+ public boolean markStaleTasks(TaskRepository repository,
+ Set<AbstractTask> tasks, IProgressMonitor monitor) {
+ // ignore
+ return false;
}
@Override
@@ -153,7 +154,7 @@ public class MockRepositoryConnector extends AbstractRepositoryConnector {
@Override
public IStatus performQuery(AbstractRepositoryQuery query, TaskRepository repository, IProgressMonitor monitor,
- QueryHitCollector resultCollector, boolean forced) {
+ ITaskCollector resultCollector) {
// ignore
return null;
}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/ScheduledTaskListSynchJob.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/ScheduledTaskListSynchJob.java
index 1cae5a004..fa1a7a6fc 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/ScheduledTaskListSynchJob.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/ScheduledTaskListSynchJob.java
@@ -11,23 +11,20 @@
package org.eclipse.mylyn.internal.tasks.ui;
-import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
import org.eclipse.mylyn.tasks.core.TaskList;
import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.ui.RepositorySynchronizationManager;
import org.eclipse.mylyn.tasks.ui.TaskListManager;
import org.eclipse.mylyn.tasks.ui.TasksUiPlugin;
@@ -68,12 +65,8 @@ public class ScheduledTaskListSynchJob extends Job {
}
@Override
- public IStatus run(IProgressMonitor monitor) {
+ public IStatus run(final IProgressMonitor monitor) {
try {
- if (monitor == null) {
- monitor = new NullProgressMonitor();
- }
-
taskList = taskListManager.getTaskList();
if (repositories == null) {
repositories = TasksUiPlugin.getRepositoryManager().getAllRepositories();
@@ -113,22 +106,11 @@ public class ScheduledTaskListSynchJob extends Job {
updateJob.schedule();
}
- Set<AbstractRepositoryQuery> queries = Collections.unmodifiableSet(taskList
- .getRepositoryQueries(repository.getUrl()));
- if (queries.size() > 0) {
- if (connector != null) {
- JobChangeAdapter jobAdapter = new JobChangeAdapter() {
- @Override
- public void done(IJobChangeEvent event) {
- TasksUiPlugin.getSynchronizationManager().synchronizeChanged(connector, repository);
- }
- };
- TasksUiPlugin.getSynchronizationManager().synchronize(connector, queries, jobAdapter,
- Job.DECORATE, 0, false, false);
- }
- } else {
- TasksUiPlugin.getSynchronizationManager().synchronizeChanged(connector, repository);
- }
+ RepositorySynchronizationManager synchronizationManager = TasksUiPlugin.getSynchronizationManager();
+ Set<AbstractRepositoryQuery> queries = taskList.getRepositoryQueries(repository.getUrl());
+ synchronizationManager.synchronize(connector, repository, queries, null,
+ Job.DECORATE, 0, false);
+
monitor.worked(1);
}
} finally {
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/actions/SynchronizeSelectedAction.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/actions/SynchronizeSelectedAction.java
index 13c0c9d38..dd8fdbaa3 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/actions/SynchronizeSelectedAction.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/actions/SynchronizeSelectedAction.java
@@ -29,6 +29,7 @@ import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
import org.eclipse.mylyn.tasks.core.AbstractTask;
import org.eclipse.mylyn.tasks.core.TaskCategory;
import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.ui.RepositorySynchronizationManager;
import org.eclipse.mylyn.tasks.ui.TasksUiPlugin;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IViewActionDelegate;
@@ -68,11 +69,9 @@ public class SynchronizeSelectedAction extends ActionDelegate implements IViewAc
} else if (obj instanceof TaskCategory) {
TaskCategory cat = (TaskCategory) obj;
for (AbstractTask task : cat.getChildren()) {
- if (task instanceof AbstractTask) {
- AbstractRepositoryConnector client = TasksUiPlugin.getRepositoryManager()
- .getRepositoryConnector(((AbstractTask) task).getRepositoryKind());
- addTaskToSync(client, (AbstractTask) task);
- }
+ AbstractRepositoryConnector client = TasksUiPlugin.getRepositoryManager()
+ .getRepositoryConnector(((AbstractTask) task).getRepositoryKind());
+ addTaskToSync(client, (AbstractTask) task);
}
} else if (obj instanceof AbstractTask) {
AbstractTask repositoryTask = (AbstractTask) obj;
@@ -82,41 +81,41 @@ public class SynchronizeSelectedAction extends ActionDelegate implements IViewAc
}
}
+ RepositorySynchronizationManager syncManager = TasksUiPlugin.getSynchronizationManager();
if (!queriesToSyncMap.isEmpty()) {
// determine which repositories to synch changed tasks for
- HashMap<String, Set<TaskRepository>> repositoriesToSync = new HashMap<String, Set<TaskRepository>>();
+ HashMap<TaskRepository, Set<AbstractRepositoryQuery>> repositoriesToSync = new HashMap<TaskRepository, Set<AbstractRepositoryQuery>>();
for (AbstractRepositoryConnector connector : queriesToSyncMap.keySet()) {
List<AbstractRepositoryQuery> queriesToSync = queriesToSyncMap.get(connector);
+ if(queriesToSync==null || queriesToSync.isEmpty()) {
+ continue;
+ }
+
for (AbstractRepositoryQuery query : queriesToSync) {
TaskRepository repos = TasksUiPlugin.getRepositoryManager().getRepository(query.getRepositoryKind(), query.getRepositoryUrl());
- Set<TaskRepository> repositories = repositoriesToSync.get(connector.getRepositoryType());
- if(repositories == null) {
- repositories = new HashSet<TaskRepository>();
- repositoriesToSync.put(connector.getRepositoryType(), repositories);
+ Set<AbstractRepositoryQuery> queries = repositoriesToSync.get(repos);
+ if(queries == null) {
+ queries = new HashSet<AbstractRepositoryQuery>();
+ repositoriesToSync.put(repos, queries);
}
- repositories.add(repos);
+ queries.add(query);
}
}
- // synch the queries followed by the repositories
- for (AbstractRepositoryConnector connector : queriesToSyncMap.keySet()) {
- List<AbstractRepositoryQuery> queriesToSync = queriesToSyncMap.get(connector);
- if (queriesToSync != null && queriesToSync.size() > 0) {
- TasksUiPlugin.getSynchronizationManager().synchronize(connector, new HashSet<AbstractRepositoryQuery>(queriesToSync), null, Job.LONG, 0,
- false, true);
- }
- //XXX enable?
-// for (TaskRepository taskRepository : repositoriesToSync.get(connector.getRepositoryType())) {
-// TasksUiPlugin.getSynchronizationManager().synchronizeChanged(connector, taskRepository);
-// }
- }
+ for (Map.Entry<TaskRepository, Set<AbstractRepositoryQuery>> entry : repositoriesToSync.entrySet()) {
+ TaskRepository repository = entry.getKey();
+ AbstractRepositoryConnector connector = TasksUiPlugin.getRepositoryManager()
+ .getRepositoryConnector(repository.getKind());
+ Set<AbstractRepositoryQuery> queries = entry.getValue();
+ syncManager.synchronize(connector, repository, queries, null, Job.LONG, 0L, true);
+ }
}
if (!tasksToSyncMap.isEmpty()) {
for (AbstractRepositoryConnector connector : tasksToSyncMap.keySet()) {
List<AbstractTask> tasksToSync = tasksToSyncMap.get(connector);
if (tasksToSync != null && tasksToSync.size() > 0) {
- TasksUiPlugin.getSynchronizationManager().synchronize(connector, new HashSet<AbstractTask>(tasksToSync), true, null);
+ syncManager.synchronize(connector, new HashSet<AbstractTask>(tasksToSync), true, null);
}
}
}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/RepositorySynchronizationManager.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/RepositorySynchronizationManager.java
index abf321820..4632e8a23 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/RepositorySynchronizationManager.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/RepositorySynchronizationManager.java
@@ -12,17 +12,10 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.IJobChangeListener;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.mylyn.core.MylarStatusHandler;
import org.eclipse.mylyn.internal.tasks.core.TaskDataManager;
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
@@ -103,22 +96,23 @@ public class RepositorySynchronizationManager {
*/
public final Job synchronize(AbstractRepositoryConnector connector, final AbstractRepositoryQuery repositoryQuery,
IJobChangeListener listener, boolean forceSync) {
- HashSet<AbstractRepositoryQuery> items = new HashSet<AbstractRepositoryQuery>();
- items.add(repositoryQuery);
- return synchronize(connector, items, listener, Job.LONG, 0, true, forceSync);
+ TaskRepository repository = TasksUiPlugin.getRepositoryManager().getRepository(
+ repositoryQuery.getRepositoryKind(), repositoryQuery.getRepositoryUrl());
+ return synchronize(connector, repository, Collections.singleton(repositoryQuery), listener, Job.LONG, 0, forceSync);
}
- public final Job synchronize(AbstractRepositoryConnector connector,
+ public final Job synchronize(AbstractRepositoryConnector connector, TaskRepository repository,
final Set<AbstractRepositoryQuery> repositoryQueries, final IJobChangeListener listener, int priority,
- long delay, boolean syncChangedTasks, boolean userForcedSync) {
+ long delay, boolean userForcedSync) {
TaskList taskList = TasksUiPlugin.getTaskListManager().getTaskList();
- final SynchronizeQueryJob job = new SynchronizeQueryJob(this, connector, repositoryQueries, taskList);
- job.setSynchChangedTasks(syncChangedTasks);
- job.setForced(userForcedSync);
for (AbstractRepositoryQuery repositoryQuery : repositoryQueries) {
repositoryQuery.setCurrentlySynchronizing(true);
// TasksUiPlugin.getTaskListManager().getTaskList().notifyContainerUpdated(repositoryQuery);
}
+
+ final SynchronizeQueryJob job = new SynchronizeQueryJob(connector, repository, repositoryQueries, taskList);
+ job.setSynchronizeChangedTasks(true);
+ job.setForced(userForcedSync);
if (listener != null) {
job.addJobChangeListener(listener);
}
@@ -145,70 +139,20 @@ public class RepositorySynchronizationManager {
* TaskRepository.syncTime.
*/
public final void synchronizeChanged(final AbstractRepositoryConnector connector, final TaskRepository repository) {
- if (connector.getTaskDataHandler() != null) {
- final SynchronizeChangedTasksJob getChangedTasksJob = new SynchronizeChangedTasksJob(connector, repository);
- getChangedTasksJob.setSystem(true);
- getChangedTasksJob.setRule(new RepositoryMutexRule(repository));
- if (!forceSyncExecForTesting) {
- getChangedTasksJob.schedule();
- } else {
- PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
- public void run() {
- getChangedTasksJob.run(new NullProgressMonitor());
- }
- });
- }
+ final SynchronizeChangedTasksJob synchronizeChangedTasksJob = new SynchronizeChangedTasksJob(connector, repository);
+ synchronizeChangedTasksJob.setSystem(true);
+ synchronizeChangedTasksJob.setRule(new RepositoryMutexRule(repository));
+ if (!forceSyncExecForTesting) {
+ synchronizeChangedTasksJob.schedule();
+ } else {
+ PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
+ public void run() {
+ synchronizeChangedTasksJob.run(new NullProgressMonitor());
+ }
+ });
}
}
- private class SynchronizeChangedTasksJob extends Job {
-
- private AbstractRepositoryConnector connector;
-
- private TaskRepository repository;
-
- private Set<AbstractTask> changedTasks;
-
- public SynchronizeChangedTasksJob(AbstractRepositoryConnector connector, TaskRepository repository) {
- super("Get Changed Tasks");
- this.connector = connector;
- this.repository = repository;
- }
-
- @Override
- public IStatus run(IProgressMonitor monitor) {
- TaskList taskList = TasksUiPlugin.getTaskListManager().getTaskList();
- Set<AbstractTask> repositoryTasks = Collections.unmodifiableSet(taskList
- .getRepositoryTasks(repository.getUrl()));
-
- try {
- changedTasks = connector.getChangedSinceLastSync(repository, repositoryTasks, monitor);
-
- if (changedTasks == null || changedTasks.size() == 0) {
- return Status.OK_STATUS;
- }
-
- synchronize(connector, changedTasks, false, new JobChangeAdapter() {
-
- @Override
- public void done(IJobChangeEvent event) {
- if (!Platform.isRunning() || TasksUiPlugin.getRepositoryManager() == null) {
- return;
- }
- TasksUiPlugin.getRepositoryManager().setSyncTime(repository,
- connector.getLastSyncTimestamp(repository, changedTasks),
- TasksUiPlugin.getDefault().getRepositoriesFilePath());
- }
- });
-
- } catch (final CoreException e) {
- // ignore, indicates working offline
- // error reported in ui (tooltip and warning icon)
- }
- return Status.OK_STATUS;
- };
- };
-
/**
* @param repositoryTask
* task that changed
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/SynchronizeChangedTasksJob.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/SynchronizeChangedTasksJob.java
new file mode 100644
index 000000000..2faa09b21
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/SynchronizeChangedTasksJob.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2006 Mylar 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.tasks.ui;
+
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.mylyn.core.MylarStatusHandler;
+import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
+import org.eclipse.mylyn.tasks.core.AbstractTask;
+import org.eclipse.mylyn.tasks.core.TaskList;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
+
+public class SynchronizeChangedTasksJob extends Job {
+
+ private final AbstractRepositoryConnector connector;
+
+ private final TaskRepository repository;
+
+ private boolean forced;
+
+ public SynchronizeChangedTasksJob(AbstractRepositoryConnector connector, TaskRepository repository) {
+ super("Get Changed Tasks");
+
+ this.connector = connector;
+ this.repository = repository;
+ }
+
+ /**
+ * Returns true, if synchronization was triggered manually and not by an automatic background job.
+ */
+ public boolean isForced() {
+ return forced;
+ }
+
+ /**
+ * Indicates a manual synchronization (User initiated). If set to true, a dialog will be displayed in case of
+ * errors. Any tasks with missing data will be retrieved.
+ */
+ public void setForced(boolean forced) {
+ this.forced = forced;
+ }
+
+ @Override
+ public IStatus run(IProgressMonitor monitor) {
+ try {
+ monitor.beginTask("Synchronizing changed tasks", IProgressMonitor.UNKNOWN);
+
+ TaskList taskList = TasksUiPlugin.getTaskListManager().getTaskList();
+ Set<AbstractTask> tasks = taskList.getRepositoryTasks(repository.getUrl());
+
+ boolean changed = connector.markStaleTasks(repository, tasks, new SubProgressMonitor(monitor, 1));
+ if (!changed) {
+ return Status.OK_STATUS;
+ }
+
+ for (Iterator<AbstractTask> it = tasks.iterator(); it.hasNext();) {
+ if (!it.next().isStale()) {
+ it.remove();
+ }
+ }
+
+ if (!tasks.isEmpty()) {
+ return Status.OK_STATUS;
+ }
+
+ TasksUiPlugin.getSynchronizationManager().synchronize(connector, tasks, forced, null);
+ } catch (final CoreException e) {
+ MylarStatusHandler.log(e.getStatus());
+ } finally {
+ monitor.done();
+ }
+
+ return Status.OK_STATUS;
+ };
+
+}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/SynchronizeQueryJob.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/SynchronizeQueryJob.java
index 4783e7ba3..9bd21352a 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/SynchronizeQueryJob.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/SynchronizeQueryJob.java
@@ -11,24 +11,26 @@
package org.eclipse.mylyn.tasks.ui;
+import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
+import org.eclipse.core.runtime.CoreException;
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.SubProgressMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.mylyn.core.MylarStatusHandler;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiImages;
+import org.eclipse.mylyn.internal.tasks.ui.views.TaskListView;
import org.eclipse.mylyn.monitor.core.DateUtil;
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
import org.eclipse.mylyn.tasks.core.AbstractTask;
import org.eclipse.mylyn.tasks.core.QueryHitCollector;
-import org.eclipse.mylyn.tasks.core.RepositoryStatus;
-import org.eclipse.mylyn.tasks.core.TaskContainerDelta;
import org.eclipse.mylyn.tasks.core.TaskList;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.ui.PlatformUI;
@@ -37,52 +39,48 @@ import org.eclipse.ui.progress.IProgressConstants;
/**
* @author Mik Kersten
* @author Rob Elves
+ * @author Steffen Pingel
*/
class SynchronizeQueryJob extends Job {
private final AbstractRepositoryConnector connector;
- private static final String JOB_LABEL = "Synchronizing queries";
+ private final TaskRepository repository;
- private Set<AbstractRepositoryQuery> queries;
+ private final Set<AbstractRepositoryQuery> queries;
- private Set<TaskRepository> repositories;
+ private final TaskList taskList;
- private boolean synchChangedTasks;
+ private boolean synchronizeChangedTasks;
- private TaskList taskList;
+ private boolean forced = false;
-// private RepositorySynchronizationManager synchronizationManager;
+ private HashSet<AbstractTask> tasksToBeSynchronized = new HashSet<AbstractTask>();
- private boolean forced = false;
+ public SynchronizeQueryJob(AbstractRepositoryConnector connector, TaskRepository repository,
+ Set<AbstractRepositoryQuery> queries, TaskList taskList) {
+ super("Synchronizying queries for " + repository.getRepositoryLabel());
- public SynchronizeQueryJob(RepositorySynchronizationManager synchronizationManager,
- AbstractRepositoryConnector connector, Set<AbstractRepositoryQuery> queries, TaskList taskList) {
- super(JOB_LABEL + ": " + connector.getRepositoryType());
this.connector = connector;
+ this.repository = repository;
this.queries = queries;
this.taskList = taskList;
- this.repositories = new HashSet<TaskRepository>();
- // TODO: remove once architecture established
- // this.synchronizationManager = synchronizationManager;
}
- public void setSynchChangedTasks(boolean syncChangedTasks) {
- this.synchChangedTasks = syncChangedTasks;
+ public void setSynchronizeChangedTasks(boolean synchronizeChangedTasks) {
+ this.synchronizeChangedTasks = synchronizeChangedTasks;
}
/**
- * Returns true, if synchronization was triggered manually and not by an
- * automatic background job.
+ * Returns true, if synchronization was triggered manually and not by an automatic background job.
*/
public boolean isForced() {
return forced;
}
/**
- * Indicates a manual synchronization (User initiated). If set to true, a
- * dialog will be displayed in case of errors. Any tasks with missing data
- * will be retrieved.
+ * Indicates a manual synchronization (User initiated). If set to true, a dialog will be displayed in case of
+ * errors. Any tasks with missing data will be retrieved.
*/
public void setForced(boolean forced) {
this.forced = forced;
@@ -90,72 +88,121 @@ class SynchronizeQueryJob extends Job {
@Override
protected IStatus run(IProgressMonitor monitor) {
- monitor.beginTask(JOB_LABEL, queries.size());
-
- taskList.notifyContainersUpdated(queries);
- for (AbstractRepositoryQuery repositoryQuery : queries) {
-// taskList.notifyContainerUpdated(repositoryQuery);
- repositoryQuery.setStatus(null);
-
- monitor.setTaskName("Synchronizing: " + repositoryQuery.getSummary());
- setProperty(IProgressConstants.ICON_PROPERTY, TasksUiImages.REPOSITORY_SYNCHRONIZE);
- TaskRepository repository = TasksUiPlugin.getRepositoryManager().getRepository(
- repositoryQuery.getRepositoryKind(), repositoryQuery.getRepositoryUrl());
- if (repository == null) {
- repositoryQuery.setStatus(RepositoryStatus.createNotFoundError(repositoryQuery.getRepositoryUrl(),
- TasksUiPlugin.PLUGIN_ID));
- } else {
-
- QueryHitCollector collector = new QueryHitCollector(taskList, new TaskFactory(repository));
- SubProgressMonitor collectorMonitor = new SubProgressMonitor(monitor, 1);
- collector.setProgressMonitor(collectorMonitor);
- final IStatus resultingStatus = connector.performQuery(repositoryQuery, repository, collectorMonitor,
- collector, forced);
-
- if (resultingStatus.getSeverity() == IStatus.CANCEL) {
- // do nothing
- } else if (resultingStatus.isOK()) {
-
- if (collector.getTaskHits().size() >= QueryHitCollector.MAX_HITS) {
- MylarStatusHandler.log(
- QueryHitCollector.MAX_HITS_REACHED + "\n" + repositoryQuery.getSummary(), this);
+ try {
+ monitor.beginTask("Synchronizing " + queries.size() + " queries", 20 + queries.size() * 10 + 40);
+
+ Set<AbstractTask> allTasks = Collections.unmodifiableSet(taskList.getRepositoryTasks(repository.getUrl()));
+
+ // check if the repository has changed at all and have the connector mark tasks that need synchronization
+ try {
+ monitor.subTask("Checking for changed tasks");
+ boolean hasChangedOrNew = connector.markStaleTasks(repository, allTasks,
+ new SubProgressMonitor(monitor, 20));
+ if (!hasChangedOrNew && !forced) {
+ for (AbstractRepositoryQuery repositoryQuery : queries) {
+ repositoryQuery.setStatus(null);
+ repositoryQuery.setCurrentlySynchronizing(false);
+ taskList.notifyContainersUpdated(queries);
}
+ return Status.OK_STATUS;
+ }
+ } catch (CoreException e) {
+ // there is no good way of informing the user at this point, just log the error
+ MylarStatusHandler.log(e.getStatus());
+ }
- repositoryQuery.clear();
- for (AbstractTask hit : collector.getTaskHits()) {
- taskList.addTask(hit, repositoryQuery);
- }
+ // synchronize queries
+ int n = 0;
+ for (AbstractRepositoryQuery repositoryQuery : queries) {
+ repositoryQuery.setStatus(null);
+ taskList.notifyContainersUpdated(Collections.singleton(repositoryQuery));
- if (synchChangedTasks) {
- repositories.add(repository);
- }
+ monitor.setTaskName("Synchronizing " + ++n + "/" + queries.size() + ": " + repositoryQuery.getSummary());
+ synchronizeQuery(repositoryQuery, new SubProgressMonitor(monitor, 10));
- repositoryQuery.setLastRefreshTimeStamp(DateUtil.getFormattedDate(new Date(), "MMM d, H:mm:ss"));
- } else {
- repositoryQuery.setStatus(resultingStatus);
- if (isForced()) {
- PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
- public void run() {
- MylarStatusHandler.displayStatus("Query Synchronization Failed", resultingStatus);
- }
- });
+ repositoryQuery.setCurrentlySynchronizing(false);
+ taskList.notifyContainersUpdated(Collections.singleton(repositoryQuery));
+ }
+
+ // for background synchronizations all changed tasks are synchronized including the ones that are not part of a query
+ if (forced) {
+ for (AbstractTask task : allTasks) {
+ if (task.isStale()) {
+ tasksToBeSynchronized.add(task);
+ task.setCurrentlySynchronizing(true);
}
}
}
- repositoryQuery.setCurrentlySynchronizing(false);
- taskList.notifyContainersUpdated(queries);
-// taskList.notifyContainerUpdated(repositoryQuery);
- }
+ // synchronize tasks that were marked by the connector
+ if (!tasksToBeSynchronized.isEmpty()) {
+ monitor.setTaskName("Synchronizing " + tasksToBeSynchronized.size() + " changed tasks");
+ SynchronizeTaskJob job = new SynchronizeTaskJob(connector, tasksToBeSynchronized);
+ job.setForced(forced);
+ job.run(new SubProgressMonitor(monitor, 40));
+
+ if (Platform.isRunning() && !(TasksUiPlugin.getRepositoryManager() == null)) {
+ TasksUiPlugin.getRepositoryManager().setSyncTime(repository,
+ connector.getSynchronizationTimestamp(repository, tasksToBeSynchronized),
+ TasksUiPlugin.getDefault().getRepositoriesFilePath());
+ }
+ }
+
+
+ taskList.notifyContainersUpdated(null);
- for (TaskRepository repository : repositories) {
- TasksUiPlugin.getSynchronizationManager().synchronizeChanged(connector, repository);
+// // HACK: force entire Task List to refresh in case containers need to
+// // appear or disappear
+// PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
+// public void run() {
+// TaskListView view = TaskListView.getFromActivePerspective();
+// if (view != null) {
+// // TODO: remove explicit refresh
+// view.getViewer().refresh();
+// }
+// }
+// });
+
+ return Status.OK_STATUS;
+ } finally {
+ monitor.done();
}
- taskList.notifyContainersUpdated(null);
+ }
+
+ private void synchronizeQuery(AbstractRepositoryQuery repositoryQuery, IProgressMonitor monitor) {
+ setProperty(IProgressConstants.ICON_PROPERTY, TasksUiImages.REPOSITORY_SYNCHRONIZE);
+
+ QueryHitCollector collector = new QueryHitCollector(taskList, new TaskFactory(repository));
+
+ final IStatus resultingStatus = connector.performQuery(repositoryQuery, repository, monitor, collector);
+ if (resultingStatus.getSeverity() == IStatus.CANCEL) {
+ // do nothing
+ } else if (resultingStatus.isOK()) {
+ if (collector.getTaskHits().size() >= QueryHitCollector.MAX_HITS) {
+ MylarStatusHandler.log(QueryHitCollector.MAX_HITS_REACHED + "\n" + repositoryQuery.getSummary(), this);
+ }
- monitor.done();
+ repositoryQuery.clear();
- return Status.OK_STATUS;
+ for (AbstractTask hit : collector.getTaskHits()) {
+ taskList.addTask(hit, repositoryQuery);
+ if (synchronizeChangedTasks && hit.isStale()) {
+ tasksToBeSynchronized.add(hit);
+ hit.setCurrentlySynchronizing(true);
+ }
+ }
+
+ repositoryQuery.setLastRefreshTimeStamp(DateUtil.getFormattedDate(new Date(), "MMM d, H:mm:ss"));
+ } else {
+ repositoryQuery.setStatus(resultingStatus);
+ if (isForced()) {
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ MylarStatusHandler.displayStatus("Query Synchronization Failed", resultingStatus);
+ }
+ });
+ }
+ }
}
} \ No newline at end of file
diff --git a/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/TracRepositoryConnector.java b/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/TracRepositoryConnector.java
index 199ed9deb..96eeb70a8 100644
--- a/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/TracRepositoryConnector.java
+++ b/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/TracRepositoryConnector.java
@@ -13,9 +13,7 @@ package org.eclipse.mylyn.internal.trac.core;
import java.io.File;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Date;
-import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -33,8 +31,8 @@ import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
import org.eclipse.mylyn.tasks.core.AbstractTask;
import org.eclipse.mylyn.tasks.core.IAttachmentHandler;
+import org.eclipse.mylyn.tasks.core.ITaskCollector;
import org.eclipse.mylyn.tasks.core.ITaskDataHandler;
-import org.eclipse.mylyn.tasks.core.QueryHitCollector;
import org.eclipse.mylyn.tasks.core.RepositoryOperation;
import org.eclipse.mylyn.tasks.core.RepositoryStatus;
import org.eclipse.mylyn.tasks.core.RepositoryTaskAttribute;
@@ -126,7 +124,7 @@ public class TracRepositoryConnector extends AbstractRepositoryConnector {
@Override
public IStatus performQuery(AbstractRepositoryQuery query, TaskRepository repository, IProgressMonitor monitor,
- QueryHitCollector resultCollector, boolean force) {
+ ITaskCollector resultCollector) {
final List<TracTicket> tickets = new ArrayList<TracTicket>();
@@ -150,41 +148,51 @@ public class TracRepositoryConnector extends AbstractRepositoryConnector {
}
@Override
- public Set<AbstractTask> getChangedSinceLastSync(TaskRepository repository,
+ public boolean markStaleTasks(TaskRepository repository,
Set<AbstractTask> tasks, IProgressMonitor monitor) throws CoreException {
- if (repository.getSyncTimeStamp() == null) {
- return tasks;
- }
+ try {
+ monitor.beginTask("Getting changed tasks", IProgressMonitor.UNKNOWN);
+
+ if (!TracRepositoryConnector.hasChangedSince(repository)) {
+ // always run the queries for web mode
+ return true;
+ }
- if (!TracRepositoryConnector.hasChangedSince(repository)) {
- // return an empty list to avoid causing all tasks to synchronized
- return Collections.emptySet();
- }
+ if (repository.getSyncTimeStamp() == null) {
+ for (AbstractTask task : tasks) {
+ task.setStale(true);
+ }
+ return true;
+ }
- Date since = new Date(0);
- try {
- since = TracUtils.parseDate(Integer.parseInt(repository.getSyncTimeStamp()));
- } catch (NumberFormatException e) {
- }
+ Date since = new Date(0);
+ try {
+ since = TracUtils.parseDate(Integer.parseInt(repository.getSyncTimeStamp()));
+ } catch (NumberFormatException e) {
+ }
- ITracClient client;
- try {
- client = getClientManager().getRepository(repository);
- Set<Integer> ids = client.getChangedTickets(since);
+ try {
+ ITracClient client = getClientManager().getRepository(repository);
+ Set<Integer> ids = client.getChangedTickets(since);
+ if (ids.isEmpty()) {
+ // repository is unchanged
+ return false;
+ }
- Set<AbstractTask> result = new HashSet<AbstractTask>();
- if (!ids.isEmpty()) {
for (AbstractTask task : tasks) {
Integer id = getTicketId(task.getTaskId());
if (ids.contains(id)) {
- result.add(task);
+ task.setStale(true);
}
}
+
+ return true;
+ } catch (Exception e) {
+ throw new CoreException(new Status(IStatus.ERROR, TracCorePlugin.PLUGIN_ID, IStatus.OK,
+ "Could not determine changed tasks", e));
}
- return result;
- } catch (Exception e) {
- throw new CoreException(new Status(IStatus.ERROR, TracCorePlugin.PLUGIN_ID, IStatus.OK,
- "could not determine changed tasks", e));
+ } finally {
+ monitor.done();
}
}
diff --git a/org.eclipse.mylyn.trac.tests/src/org/eclipse/mylyn/trac/tests/RepositorySearchQueryTest.java b/org.eclipse.mylyn.trac.tests/src/org/eclipse/mylyn/trac/tests/RepositorySearchQueryTest.java
index af318c588..7ccd00c14 100644
--- a/org.eclipse.mylyn.trac.tests/src/org/eclipse/mylyn/trac/tests/RepositorySearchQueryTest.java
+++ b/org.eclipse.mylyn.trac.tests/src/org/eclipse/mylyn/trac/tests/RepositorySearchQueryTest.java
@@ -78,7 +78,7 @@ public class RepositorySearchQueryTest extends TestCase {
String queryUrl = repository.getUrl() + ITracClient.QUERY_URL + search.toUrl();
TracRepositoryQuery query = new TracRepositoryQuery(repository.getUrl(), queryUrl, "description");
SearchHitCollector collector = new SearchHitCollector(TasksUiPlugin.getTaskListManager()
- .getTaskList(), repository, query, new TaskFactory(repository));
+ .getTaskList(), repository, query, new TaskFactory(repository, false, false));
collector.run(new NullProgressMonitor());
for (AbstractTask task : collector.getTaskHits()) {
diff --git a/org.eclipse.mylyn.trac.tests/src/org/eclipse/mylyn/trac/tests/TracRepositoryConnectorTest.java b/org.eclipse.mylyn.trac.tests/src/org/eclipse/mylyn/trac/tests/TracRepositoryConnectorTest.java
index 00cf18b9e..b11bf9c0d 100644
--- a/org.eclipse.mylyn.trac.tests/src/org/eclipse/mylyn/trac/tests/TracRepositoryConnectorTest.java
+++ b/org.eclipse.mylyn.trac.tests/src/org/eclipse/mylyn/trac/tests/TracRepositoryConnectorTest.java
@@ -217,7 +217,7 @@ public class TracRepositoryConnectorTest extends TestCase {
public void accept(AbstractTask hit) {
result.add(hit);
}};
- IStatus queryStatus = connector.performQuery(query, repository, new NullProgressMonitor(), hitCollector, false);
+ IStatus queryStatus = connector.performQuery(query, repository, new NullProgressMonitor(), hitCollector);
assertTrue(queryStatus.isOK());
assertEquals(3, result.size());
diff --git a/org.eclipse.mylyn.trac.tests/src/org/eclipse/mylyn/trac/tests/TracTaskDataHandlerTest.java b/org.eclipse.mylyn.trac.tests/src/org/eclipse/mylyn/trac/tests/TracTaskDataHandlerTest.java
index 5d238227e..bc8c00c19 100644
--- a/org.eclipse.mylyn.trac.tests/src/org/eclipse/mylyn/trac/tests/TracTaskDataHandlerTest.java
+++ b/org.eclipse.mylyn.trac.tests/src/org/eclipse/mylyn/trac/tests/TracTaskDataHandlerTest.java
@@ -79,19 +79,23 @@ public class TracTaskDataHandlerTest extends TestCase {
public void testGetChangedSinceLastSyncWeb096() throws Exception {
init(TracTestConstants.TEST_TRAC_096_URL, Version.TRAC_0_9);
- TracTask task = (TracTask) connector.createTaskFromExistingId(repository, data.offlineHandlerTicketId + "", new NullProgressMonitor());
+ TracTask task = (TracTask) connector.createTaskFromExistingId(repository, data.offlineHandlerTicketId + "",
+ new NullProgressMonitor());
Set<AbstractTask> tasks = new HashSet<AbstractTask>();
tasks.add(task);
-
+
assertEquals(null, repository.getSyncTimeStamp());
- Set<AbstractTask> result = connector.getChangedSinceLastSync(repository, tasks, new NullProgressMonitor());
- assertEquals(tasks, result);
+ boolean changed = connector.markStaleTasks(repository, tasks, new NullProgressMonitor());
+ assertEquals(true, changed);
assertEquals(null, repository.getSyncTimeStamp());
-
- int time = (int)(System.currentTimeMillis() / 1000) + 1;
+ assertFalse(task.isStale());
+
+ int time = (int) (System.currentTimeMillis() / 1000) + 1;
repository.setSyncTimeStamp(time + "");
- assertEquals(tasks, result);
+ changed = connector.markStaleTasks(repository, tasks, new NullProgressMonitor());
+ assertEquals(true, changed);
+ assertFalse(task.isStale());
}
public void testGetChangedSinceLastSyncXmlRpc010() throws Exception {
@@ -105,28 +109,35 @@ public class TracTaskDataHandlerTest extends TestCase {
}
private void getChangedSinceLastSync() throws Exception {
- TracTask task = (TracTask) connector.createTaskFromExistingId(repository, data.offlineHandlerTicketId + "", new NullProgressMonitor());
+ TracTask task = (TracTask) connector.createTaskFromExistingId(repository, data.offlineHandlerTicketId + "",
+ new NullProgressMonitor());
TasksUiPlugin.getSynchronizationManager().synchronize(connector, task, true, null);
- RepositoryTaskData taskData = TasksUiPlugin.getDefault().getTaskDataManager().getNewTaskData(task.getHandleIdentifier());
-
+ RepositoryTaskData taskData = TasksUiPlugin.getDefault().getTaskDataManager().getNewTaskData(
+ task.getHandleIdentifier());
+
int lastModified = Integer.parseInt(taskData.getLastModified());
-
+
Set<AbstractTask> tasks = new HashSet<AbstractTask>();
tasks.add(task);
assertEquals(null, repository.getSyncTimeStamp());
- Set<AbstractTask> result = connector.getChangedSinceLastSync(repository, tasks, new NullProgressMonitor());
- assertEquals(tasks, result);
+ boolean changed = connector.markStaleTasks(repository, tasks, new NullProgressMonitor());
+ assertTrue(changed);
+ assertTrue(task.isStale());
// always returns the ticket because time comparison mode is >=
+ task.setStale(false);
repository.setSyncTimeStamp(lastModified + "");
- result = connector.getChangedSinceLastSync(repository, tasks, new NullProgressMonitor());
- assertEquals(tasks, result);
+ changed = connector.markStaleTasks(repository, tasks, new NullProgressMonitor());
+ assertTrue(changed);
+ assertTrue(task.isStale());
+ task.setStale(false);
repository.setSyncTimeStamp((lastModified + 1) + "");
- result = connector.getChangedSinceLastSync(repository, tasks, new NullProgressMonitor());
- assertTrue(result.isEmpty());
-
+ changed = connector.markStaleTasks(repository, tasks, new NullProgressMonitor());
+ assertTrue(changed);
+ assertFalse(task.isStale());
+
// change ticket making sure it gets a new change time
Thread.sleep(1000);
ITracClient client = connector.getClientManager().getRepository(repository);
@@ -138,11 +149,13 @@ public class TracTaskDataHandlerTest extends TestCase {
}
client.updateTicket(ticket, "comment");
+ task.setStale(false);
repository.setSyncTimeStamp((lastModified + 1) + "");
- result = connector.getChangedSinceLastSync(repository, tasks, new NullProgressMonitor());
- assertEquals(tasks, result);
+ changed = connector.markStaleTasks(repository, tasks, new NullProgressMonitor());
+ assertTrue(changed);
+ assertTrue(task.isStale());
}
-
+
public void testNonNumericTaskId() {
try {
connector.getTaskDataHandler().getTaskData(repository, "abc", new NullProgressMonitor());
@@ -150,6 +163,5 @@ public class TracTaskDataHandlerTest extends TestCase {
} catch (CoreException e) {
}
}
-
}
diff --git a/org.eclipse.mylyn.trac.ui/src/org/eclipse/mylyn/internal/trac/ui/editor/NewTracTaskEditor.java b/org.eclipse.mylyn.trac.ui/src/org/eclipse/mylyn/internal/trac/ui/editor/NewTracTaskEditor.java
index 7d81e0c33..6d3a7bacb 100644
--- a/org.eclipse.mylyn.trac.ui/src/org/eclipse/mylyn/internal/trac/ui/editor/NewTracTaskEditor.java
+++ b/org.eclipse.mylyn.trac.ui/src/org/eclipse/mylyn/internal/trac/ui/editor/NewTracTaskEditor.java
@@ -49,7 +49,7 @@ public class NewTracTaskEditor extends AbstractNewRepositoryTaskEditor {
TracRepositoryQuery query = new TracRepositoryQuery(repository.getUrl(), sb.toString(), "<Duplicate Search>");
SearchHitCollector collector = new SearchHitCollector(TasksUiPlugin.getTaskListManager().getTaskList(),
- repository, query, new TaskFactory(repository));
+ repository, query, new TaskFactory(repository, false, false));
return collector;
}

Back to the top