|
Lines 11-25
Link Here
|
| 11 |
|
11 |
|
| 12 |
package org.eclipse.mylyn.tasks.ui; |
12 |
package org.eclipse.mylyn.tasks.ui; |
| 13 |
|
13 |
|
|
|
14 |
import java.util.Collections; |
| 14 |
import java.util.Date; |
15 |
import java.util.Date; |
| 15 |
import java.util.HashSet; |
16 |
import java.util.HashSet; |
| 16 |
import java.util.Set; |
17 |
import java.util.Set; |
| 17 |
|
18 |
|
|
|
19 |
import org.eclipse.core.runtime.CoreException; |
| 18 |
import org.eclipse.core.runtime.IProgressMonitor; |
20 |
import org.eclipse.core.runtime.IProgressMonitor; |
| 19 |
import org.eclipse.core.runtime.IStatus; |
21 |
import org.eclipse.core.runtime.IStatus; |
|
|
22 |
import org.eclipse.core.runtime.Platform; |
| 20 |
import org.eclipse.core.runtime.Status; |
23 |
import org.eclipse.core.runtime.Status; |
| 21 |
import org.eclipse.core.runtime.SubProgressMonitor; |
24 |
import org.eclipse.core.runtime.SubProgressMonitor; |
|
|
25 |
import org.eclipse.core.runtime.jobs.IJobChangeEvent; |
| 22 |
import org.eclipse.core.runtime.jobs.Job; |
26 |
import org.eclipse.core.runtime.jobs.Job; |
|
|
27 |
import org.eclipse.core.runtime.jobs.JobChangeAdapter; |
| 23 |
import org.eclipse.mylyn.core.MylarStatusHandler; |
28 |
import org.eclipse.mylyn.core.MylarStatusHandler; |
| 24 |
import org.eclipse.mylyn.internal.tasks.ui.TasksUiImages; |
29 |
import org.eclipse.mylyn.internal.tasks.ui.TasksUiImages; |
| 25 |
import org.eclipse.mylyn.monitor.core.DateUtil; |
30 |
import org.eclipse.mylyn.monitor.core.DateUtil; |
|
Lines 27-33
Link Here
|
| 27 |
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery; |
32 |
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery; |
| 28 |
import org.eclipse.mylyn.tasks.core.AbstractTask; |
33 |
import org.eclipse.mylyn.tasks.core.AbstractTask; |
| 29 |
import org.eclipse.mylyn.tasks.core.QueryHitCollector; |
34 |
import org.eclipse.mylyn.tasks.core.QueryHitCollector; |
| 30 |
import org.eclipse.mylyn.tasks.core.RepositoryStatus; |
|
|
| 31 |
import org.eclipse.mylyn.tasks.core.TaskList; |
35 |
import org.eclipse.mylyn.tasks.core.TaskList; |
| 32 |
import org.eclipse.mylyn.tasks.core.TaskRepository; |
36 |
import org.eclipse.mylyn.tasks.core.TaskRepository; |
| 33 |
import org.eclipse.ui.PlatformUI; |
37 |
import org.eclipse.ui.PlatformUI; |
|
Lines 36-87
Link Here
|
| 36 |
/** |
40 |
/** |
| 37 |
* @author Mik Kersten |
41 |
* @author Mik Kersten |
| 38 |
* @author Rob Elves |
42 |
* @author Rob Elves |
|
|
43 |
* @author Steffen Pingel |
| 39 |
*/ |
44 |
*/ |
| 40 |
class SynchronizeQueryJob extends Job { |
45 |
class SynchronizeQueryJob extends Job { |
| 41 |
|
46 |
|
| 42 |
private final AbstractRepositoryConnector connector; |
|
|
| 43 |
|
| 44 |
private static final String JOB_LABEL = "Synchronizing queries"; |
47 |
private static final String JOB_LABEL = "Synchronizing queries"; |
| 45 |
|
48 |
|
| 46 |
private Set<AbstractRepositoryQuery> queries; |
49 |
private final AbstractRepositoryConnector connector; |
| 47 |
|
50 |
|
| 48 |
private Set<TaskRepository> repositories; |
51 |
private final TaskRepository repository; |
| 49 |
|
52 |
|
| 50 |
private boolean synchChangedTasks; |
53 |
private final Set<AbstractRepositoryQuery> queries; |
| 51 |
|
54 |
|
| 52 |
private TaskList taskList; |
55 |
private final TaskList taskList; |
| 53 |
|
56 |
|
| 54 |
// private RepositorySynchronizationManager synchronizationManager; |
57 |
private boolean synchronizeChangedTasks; |
| 55 |
|
58 |
|
| 56 |
private boolean forced = false; |
59 |
private boolean forced = false; |
| 57 |
|
60 |
|
| 58 |
public SynchronizeQueryJob(RepositorySynchronizationManager synchronizationManager, |
61 |
private HashSet<AbstractTask> tasksToBeSynchronized = new HashSet<AbstractTask>(); |
| 59 |
AbstractRepositoryConnector connector, Set<AbstractRepositoryQuery> queries, TaskList taskList) { |
62 |
|
|
|
63 |
public SynchronizeQueryJob(AbstractRepositoryConnector connector, TaskRepository repository, |
| 64 |
Set<AbstractRepositoryQuery> queries, TaskList taskList) { |
| 60 |
super(JOB_LABEL + ": " + connector.getRepositoryType()); |
65 |
super(JOB_LABEL + ": " + connector.getRepositoryType()); |
|
|
66 |
|
| 61 |
this.connector = connector; |
67 |
this.connector = connector; |
|
|
68 |
this.repository = repository; |
| 62 |
this.queries = queries; |
69 |
this.queries = queries; |
| 63 |
this.taskList = taskList; |
70 |
this.taskList = taskList; |
| 64 |
this.repositories = new HashSet<TaskRepository>(); |
|
|
| 65 |
// TODO: remove once architecture established |
| 66 |
// this.synchronizationManager = synchronizationManager; |
| 67 |
} |
71 |
} |
| 68 |
|
72 |
|
| 69 |
public void setSynchChangedTasks(boolean syncChangedTasks) { |
73 |
public void setSynchronizeChangedTasks(boolean synchronizeChangedTasks) { |
| 70 |
this.synchChangedTasks = syncChangedTasks; |
74 |
this.synchronizeChangedTasks = synchronizeChangedTasks; |
| 71 |
} |
75 |
} |
| 72 |
|
76 |
|
| 73 |
/** |
77 |
/** |
| 74 |
* Returns true, if synchronization was triggered manually and not by an |
78 |
* Returns true, if synchronization was triggered manually and not by an automatic background job. |
| 75 |
* automatic background job. |
|
|
| 76 |
*/ |
79 |
*/ |
| 77 |
public boolean isForced() { |
80 |
public boolean isForced() { |
| 78 |
return forced; |
81 |
return forced; |
| 79 |
} |
82 |
} |
| 80 |
|
83 |
|
| 81 |
/** |
84 |
/** |
| 82 |
* Indicates a manual synchronization (User initiated). If set to true, a |
85 |
* Indicates a manual synchronization (User initiated). If set to true, a dialog will be displayed in case of |
| 83 |
* dialog will be displayed in case of errors. Any tasks with missing data |
86 |
* errors. Any tasks with missing data will be retrieved. |
| 84 |
* will be retrieved. |
|
|
| 85 |
*/ |
87 |
*/ |
| 86 |
public void setForced(boolean forced) { |
88 |
public void setForced(boolean forced) { |
| 87 |
this.forced = forced; |
89 |
this.forced = forced; |
|
Lines 89-163
Link Here
|
| 89 |
|
91 |
|
| 90 |
@Override |
92 |
@Override |
| 91 |
protected IStatus run(IProgressMonitor monitor) { |
93 |
protected IStatus run(IProgressMonitor monitor) { |
| 92 |
monitor.beginTask(JOB_LABEL, queries.size()); |
94 |
try { |
|
|
95 |
monitor.beginTask(JOB_LABEL, queries.size() + 1); |
| 93 |
|
96 |
|
| 94 |
taskList.notifyContainersUpdated(queries); |
97 |
Set<AbstractTask> allTasks = Collections.unmodifiableSet(taskList.getRepositoryTasks(repository.getUrl())); |
| 95 |
for (AbstractRepositoryQuery repositoryQuery : queries) { |
|
|
| 96 |
// taskList.notifyContainerUpdated(repositoryQuery); |
| 97 |
repositoryQuery.setStatus(null); |
| 98 |
|
| 99 |
monitor.setTaskName("Synchronizing: " + repositoryQuery.getSummary()); |
| 100 |
setProperty(IProgressConstants.ICON_PROPERTY, TasksUiImages.REPOSITORY_SYNCHRONIZE); |
| 101 |
TaskRepository repository = TasksUiPlugin.getRepositoryManager().getRepository( |
| 102 |
repositoryQuery.getRepositoryKind(), repositoryQuery.getRepositoryUrl()); |
| 103 |
if (repository == null) { |
| 104 |
repositoryQuery.setStatus(RepositoryStatus.createNotFoundError(repositoryQuery.getRepositoryUrl(), |
| 105 |
TasksUiPlugin.PLUGIN_ID)); |
| 106 |
} else { |
| 107 |
|
| 108 |
QueryHitCollector collector = new QueryHitCollector(taskList, new TaskFactory(repository)); |
| 109 |
SubProgressMonitor collectorMonitor = new SubProgressMonitor(monitor, 1); |
| 110 |
collector.setProgressMonitor(collectorMonitor); |
| 111 |
final IStatus resultingStatus = connector.performQuery(repositoryQuery, repository, collectorMonitor, |
| 112 |
collector, forced); |
| 113 |
|
| 114 |
if (resultingStatus.getSeverity() == IStatus.CANCEL) { |
| 115 |
// do nothing |
| 116 |
} else if (resultingStatus.isOK()) { |
| 117 |
|
| 118 |
if (collector.getTaskHits().size() >= QueryHitCollector.MAX_HITS) { |
| 119 |
MylarStatusHandler.log( |
| 120 |
QueryHitCollector.MAX_HITS_REACHED + "\n" + repositoryQuery.getSummary(), this); |
| 121 |
} |
| 122 |
|
98 |
|
| 123 |
repositoryQuery.clear(); |
99 |
// check if the repository has changed at all and have the connector mark tasks that need synchronization |
| 124 |
for (AbstractTask hit : collector.getTaskHits()) { |
100 |
try { |
| 125 |
taskList.addTask(hit, repositoryQuery); |
101 |
boolean hasChangedOrNew = connector.updateNeedsSynchronization(repository, allTasks, |
|
|
102 |
new SubProgressMonitor(monitor, 1)); |
| 103 |
if (!hasChangedOrNew && !forced) { |
| 104 |
for (AbstractRepositoryQuery repositoryQuery : queries) { |
| 105 |
repositoryQuery.setStatus(null); |
| 106 |
repositoryQuery.setCurrentlySynchronizing(false); |
| 107 |
taskList.notifyContainersUpdated(queries); |
| 126 |
} |
108 |
} |
|
|
109 |
return Status.OK_STATUS; |
| 110 |
} |
| 111 |
} catch (CoreException e) { |
| 112 |
// there is no good way of informing the user at this point, just log the error |
| 113 |
MylarStatusHandler.log(e.getStatus()); |
| 114 |
} |
| 115 |
|
| 116 |
// synchronize queries |
| 117 |
for (AbstractRepositoryQuery repositoryQuery : queries) { |
| 118 |
repositoryQuery.setStatus(null); |
| 119 |
taskList.notifyContainersUpdated(queries); |
| 120 |
|
| 121 |
synchronizeQuery(repositoryQuery, new SubProgressMonitor(monitor, 1)); |
| 122 |
|
| 123 |
repositoryQuery.setCurrentlySynchronizing(false); |
| 124 |
taskList.notifyContainersUpdated(queries); |
| 125 |
} |
| 127 |
|
126 |
|
| 128 |
if (synchChangedTasks) { |
127 |
// for background synchronizations all changed tasks are synchronized including the ones that are not part of a query |
| 129 |
repositories.add(repository); |
128 |
if (forced) { |
|
|
129 |
for (AbstractTask task : allTasks) { |
| 130 |
if (task.getNeedsSynchronization()) { |
| 131 |
tasksToBeSynchronized.add(task); |
| 130 |
} |
132 |
} |
|
|
133 |
} |
| 134 |
} |
| 131 |
|
135 |
|
| 132 |
repositoryQuery.setLastRefreshTimeStamp(DateUtil.getFormattedDate(new Date(), "MMM d, H:mm:ss")); |
136 |
// synchronize tasks that were marked by the connector |
| 133 |
} else { |
137 |
if (!tasksToBeSynchronized.isEmpty()) { |
| 134 |
repositoryQuery.setStatus(resultingStatus); |
138 |
TasksUiPlugin.getSynchronizationManager().synchronize(connector, tasksToBeSynchronized, forced, |
| 135 |
if (isForced()) { |
139 |
new JobChangeAdapter() { |
| 136 |
PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { |
140 |
@Override |
| 137 |
public void run() { |
141 |
public void done(IJobChangeEvent event) { |
| 138 |
MylarStatusHandler.displayStatus("Query Synchronization Failed", resultingStatus); |
142 |
if (!Platform.isRunning() || TasksUiPlugin.getRepositoryManager() == null) { |
|
|
143 |
return; |
| 144 |
} |
| 145 |
TasksUiPlugin.getRepositoryManager().setSyncTime(repository, |
| 146 |
connector.getSynchronizationTimestamp(repository, tasksToBeSynchronized), |
| 147 |
TasksUiPlugin.getDefault().getRepositoriesFilePath()); |
| 139 |
} |
148 |
} |
| 140 |
}); |
149 |
}); |
| 141 |
} |
|
|
| 142 |
} |
| 143 |
} |
150 |
} |
| 144 |
|
151 |
|
| 145 |
repositoryQuery.setCurrentlySynchronizing(false); |
152 |
// HACK: force entire Task List to refresh in case containers need to |
| 146 |
taskList.notifyContainersUpdated(queries); |
153 |
// appear or disappear |
| 147 |
// taskList.notifyContainerUpdated(repositoryQuery); |
154 |
// FIXME taskList.notifyContainersUpdated(null); |
|
|
155 |
|
| 156 |
return Status.OK_STATUS; |
| 157 |
} finally { |
| 158 |
monitor.done(); |
| 148 |
} |
159 |
} |
|
|
160 |
} |
| 149 |
|
161 |
|
| 150 |
for (TaskRepository repository : repositories) { |
162 |
private void synchronizeQuery(AbstractRepositoryQuery repositoryQuery, IProgressMonitor monitor) { |
| 151 |
TasksUiPlugin.getSynchronizationManager().synchronizeChanged(connector, repository); |
163 |
monitor.setTaskName("Synchronizing: " + repositoryQuery.getSummary()); |
| 152 |
} |
164 |
setProperty(IProgressConstants.ICON_PROPERTY, TasksUiImages.REPOSITORY_SYNCHRONIZE); |
|
|
165 |
|
| 166 |
QueryHitCollector collector = new QueryHitCollector(taskList, new TaskFactory(repository)); |
| 167 |
|
| 168 |
final IStatus resultingStatus = connector.performQuery(repositoryQuery, repository, monitor, collector); |
| 169 |
if (resultingStatus.getSeverity() == IStatus.CANCEL) { |
| 170 |
// do nothing |
| 171 |
} else if (resultingStatus.isOK()) { |
| 172 |
if (collector.getTaskHits().size() >= QueryHitCollector.MAX_HITS) { |
| 173 |
MylarStatusHandler.log(QueryHitCollector.MAX_HITS_REACHED + "\n" + repositoryQuery.getSummary(), this); |
| 174 |
} |
| 153 |
|
175 |
|
| 154 |
// HACK: force entire Task List to refresh in case containers need to |
176 |
repositoryQuery.clear(); |
| 155 |
// appear or disappear |
|
|
| 156 |
taskList.notifyContainersUpdated(null); |
| 157 |
|
177 |
|
| 158 |
monitor.done(); |
178 |
for (AbstractTask hit : collector.getTaskHits()) { |
|
|
179 |
taskList.addTask(hit, repositoryQuery); |
| 180 |
if (synchronizeChangedTasks && hit.getNeedsSynchronization()) { |
| 181 |
tasksToBeSynchronized.add(hit); |
| 182 |
} |
| 183 |
} |
| 159 |
|
184 |
|
| 160 |
return Status.OK_STATUS; |
185 |
repositoryQuery.setLastRefreshTimeStamp(DateUtil.getFormattedDate(new Date(), "MMM d, H:mm:ss")); |
|
|
186 |
} else { |
| 187 |
repositoryQuery.setStatus(resultingStatus); |
| 188 |
if (isForced()) { |
| 189 |
PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { |
| 190 |
public void run() { |
| 191 |
MylarStatusHandler.displayStatus("Query Synchronization Failed", resultingStatus); |
| 192 |
} |
| 193 |
}); |
| 194 |
} |
| 195 |
} |
| 161 |
} |
196 |
} |
| 162 |
|
197 |
|
| 163 |
} |
198 |
} |