|
Lines 15-21
Link Here
|
| 15 |
import java.text.SimpleDateFormat; |
15 |
import java.text.SimpleDateFormat; |
| 16 |
import java.util.ArrayList; |
16 |
import java.util.ArrayList; |
| 17 |
import java.util.Calendar; |
17 |
import java.util.Calendar; |
| 18 |
import java.util.Collections; |
|
|
| 19 |
import java.util.Date; |
18 |
import java.util.Date; |
| 20 |
import java.util.HashSet; |
19 |
import java.util.HashSet; |
| 21 |
import java.util.List; |
20 |
import java.util.List; |
|
Lines 41-57
Link Here
|
| 41 |
import org.eclipse.mylyn.internal.jira.core.model.filter.RelativeDateRangeFilter.RangeType; |
40 |
import org.eclipse.mylyn.internal.jira.core.model.filter.RelativeDateRangeFilter.RangeType; |
| 42 |
import org.eclipse.mylyn.internal.jira.core.service.JiraClient; |
41 |
import org.eclipse.mylyn.internal.jira.core.service.JiraClient; |
| 43 |
import org.eclipse.mylyn.internal.jira.core.service.JiraException; |
42 |
import org.eclipse.mylyn.internal.jira.core.service.JiraException; |
|
|
43 |
import org.eclipse.mylyn.internal.tasks.core.RepositoryTaskHandleUtil; |
| 44 |
import org.eclipse.mylyn.tasks.core.AbstractAttributeFactory; |
44 |
import org.eclipse.mylyn.tasks.core.AbstractAttributeFactory; |
| 45 |
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector; |
45 |
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector; |
| 46 |
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery; |
46 |
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery; |
| 47 |
import org.eclipse.mylyn.tasks.core.AbstractTask; |
47 |
import org.eclipse.mylyn.tasks.core.AbstractTask; |
| 48 |
import org.eclipse.mylyn.tasks.core.IAttachmentHandler; |
48 |
import org.eclipse.mylyn.tasks.core.IAttachmentHandler; |
|
|
49 |
import org.eclipse.mylyn.tasks.core.ITaskCollector; |
| 49 |
import org.eclipse.mylyn.tasks.core.ITaskDataHandler; |
50 |
import org.eclipse.mylyn.tasks.core.ITaskDataHandler; |
| 50 |
import org.eclipse.mylyn.tasks.core.QueryHitCollector; |
51 |
import org.eclipse.mylyn.tasks.core.QueryHitCollector; |
| 51 |
import org.eclipse.mylyn.tasks.core.RepositoryTaskAttribute; |
52 |
import org.eclipse.mylyn.tasks.core.RepositoryTaskAttribute; |
| 52 |
import org.eclipse.mylyn.tasks.core.RepositoryTaskData; |
53 |
import org.eclipse.mylyn.tasks.core.RepositoryTaskData; |
| 53 |
import org.eclipse.mylyn.tasks.core.TaskRepository; |
54 |
import org.eclipse.mylyn.tasks.core.TaskRepository; |
| 54 |
import org.eclipse.mylyn.tasks.core.AbstractTask.PriorityLevel; |
55 |
import org.eclipse.mylyn.tasks.core.AbstractTask.PriorityLevel; |
|
|
56 |
import org.eclipse.mylyn.tasks.ui.TaskFactory; |
| 55 |
import org.eclipse.mylyn.tasks.ui.TasksUiPlugin; |
57 |
import org.eclipse.mylyn.tasks.ui.TasksUiPlugin; |
| 56 |
|
58 |
|
| 57 |
/** |
59 |
/** |
|
Lines 109-164
Link Here
|
| 109 |
|
111 |
|
| 110 |
@Override |
112 |
@Override |
| 111 |
public IStatus performQuery(AbstractRepositoryQuery repositoryQuery, TaskRepository repository, |
113 |
public IStatus performQuery(AbstractRepositoryQuery repositoryQuery, TaskRepository repository, |
| 112 |
IProgressMonitor monitor, QueryHitCollector resultCollector, boolean forced) { |
114 |
IProgressMonitor monitor, ITaskCollector resultCollector) { |
| 113 |
JiraClient client = JiraClientFacade.getDefault().getJiraClient(repository); |
115 |
try { |
|
|
116 |
monitor.beginTask("Running query", IProgressMonitor.UNKNOWN); |
| 117 |
|
| 118 |
JiraClient client = JiraClientFacade.getDefault().getJiraClient(repository); |
| 114 |
|
119 |
|
| 115 |
Query filter; |
120 |
Query filter; |
| 116 |
if (repositoryQuery instanceof JiraRepositoryQuery) { |
121 |
if (repositoryQuery instanceof JiraRepositoryQuery) { |
| 117 |
filter = ((JiraRepositoryQuery) repositoryQuery).getNamedFilter(); |
122 |
filter = ((JiraRepositoryQuery) repositoryQuery).getNamedFilter(); |
| 118 |
} else if (repositoryQuery instanceof JiraCustomQuery) { |
123 |
} else if (repositoryQuery instanceof JiraCustomQuery) { |
| 119 |
try { |
124 |
try { |
| 120 |
if (!client.hasDetails()) { |
125 |
if (!client.hasDetails()) { |
| 121 |
client.refreshDetails(monitor); |
126 |
client.refreshDetails(monitor); |
|
|
127 |
} |
| 128 |
filter = ((JiraCustomQuery) repositoryQuery).getFilterDefinition(client, true); |
| 129 |
} catch (JiraException e) { |
| 130 |
return JiraCorePlugin.toStatus(repository, e); |
| 131 |
} catch (InvalidJiraQueryException e) { |
| 132 |
return new Status(IStatus.ERROR, TasksUiPlugin.PLUGIN_ID, 0, |
| 133 |
"The query parameters do not match the repository configuration, please check the query properties; " |
| 134 |
+ e.getMessage(), null); |
| 122 |
} |
135 |
} |
| 123 |
filter = ((JiraCustomQuery) repositoryQuery).getFilterDefinition(client, true); |
136 |
} else { |
|
|
137 |
return new Status(IStatus.ERROR, TasksUiPlugin.PLUGIN_ID, 0, // |
| 138 |
"Invalid query type: " + repositoryQuery.getClass(), null); |
| 139 |
} |
| 140 |
|
| 141 |
List<Issue> issues = new ArrayList<Issue>(); |
| 142 |
try { |
| 143 |
client.search(filter, new JiraIssueCollector(monitor, issues, QueryHitCollector.MAX_HITS)); |
| 124 |
} catch (JiraException e) { |
144 |
} catch (JiraException e) { |
| 125 |
return JiraCorePlugin.toStatus(repository, e); |
145 |
return JiraCorePlugin.toStatus(repository, e); |
| 126 |
} catch (InvalidJiraQueryException e) { |
|
|
| 127 |
return new Status(IStatus.ERROR, TasksUiPlugin.PLUGIN_ID, 0, |
| 128 |
"The query parameters do not match the repository configuration, please check the query properties; " |
| 129 |
+ e.getMessage(), null); |
| 130 |
} |
146 |
} |
| 131 |
} else { |
|
|
| 132 |
return new Status(IStatus.ERROR, TasksUiPlugin.PLUGIN_ID, 0, // |
| 133 |
"Invalid query type: " + repositoryQuery.getClass(), null); |
| 134 |
} |
| 135 |
|
| 136 |
List<Issue> issues = new ArrayList<Issue>(); |
| 137 |
try { |
| 138 |
client.search(filter, new JiraIssueCollector(monitor, issues, QueryHitCollector.MAX_HITS)); |
| 139 |
} catch (JiraException e) { |
| 140 |
return JiraCorePlugin.toStatus(repository, e); |
| 141 |
} |
| 142 |
|
| 143 |
try { |
| 144 |
int n = 0; |
| 145 |
for (Issue issue : issues) { |
| 146 |
if(monitor.isCanceled()) return Status.CANCEL_STATUS; |
| 147 |
|
147 |
|
| 148 |
monitor.subTask(n++ + "/" + issues.size() +" " + issue.getKey() + " " + issue.getSummary()); |
148 |
try { |
| 149 |
resultCollector.accept(offlineHandler.createTaskData(repository, client, issue)); |
149 |
int n = 0; |
|
|
150 |
for (Issue issue : issues) { |
| 151 |
if (monitor.isCanceled()) |
| 152 |
return Status.CANCEL_STATUS; |
| 153 |
|
| 154 |
monitor.subTask(++n + "/" + issues.size() + " " + issue.getKey() + " " + issue.getSummary()); |
| 155 |
String handle = RepositoryTaskHandleUtil.getHandle(repository.getUrl(), issue.getId()); |
| 156 |
RepositoryTaskData oldTaskData = TasksUiPlugin.getDefault().getTaskDataManager().getNewTaskData(handle); |
| 157 |
resultCollector.accept(offlineHandler.createTaskData(repository, client, issue, oldTaskData)); |
| 158 |
} |
| 159 |
return Status.OK_STATUS; |
| 160 |
} catch (JiraException e) { |
| 161 |
return JiraCorePlugin.toStatus(repository, e); |
| 162 |
} catch (CoreException e) { |
| 163 |
return e.getStatus(); |
| 150 |
} |
164 |
} |
| 151 |
return Status.OK_STATUS; |
165 |
} finally { |
| 152 |
} catch (JiraException e) { |
166 |
monitor.done(); |
| 153 |
return JiraCorePlugin.toStatus(repository, e); |
|
|
| 154 |
} catch (CoreException e) { |
| 155 |
return e.getStatus(); |
| 156 |
} |
167 |
} |
| 157 |
} |
168 |
} |
| 158 |
|
169 |
|
| 159 |
public Set<AbstractTask> getChangedSinceLastSync(TaskRepository repository, |
170 |
@Override |
| 160 |
Set<AbstractTask> tasks, IProgressMonitor monitor) throws CoreException { |
171 |
public boolean markStaleTasks(TaskRepository repository, Set<AbstractTask> tasks, |
| 161 |
|
172 |
IProgressMonitor monitor) throws CoreException { |
| 162 |
String dateString = repository.getSyncTimeStamp(); |
173 |
String dateString = repository.getSyncTimeStamp(); |
| 163 |
Date lastSyncDate = convertDate(dateString); |
174 |
Date lastSyncDate = convertDate(dateString); |
| 164 |
if (lastSyncDate == null) { |
175 |
if (lastSyncDate == null) { |
|
Lines 170-228
Link Here
|
| 170 |
} |
181 |
} |
| 171 |
} |
182 |
} |
| 172 |
if (lastSyncDate == null) { |
183 |
if (lastSyncDate == null) { |
| 173 |
return tasks; |
184 |
for (AbstractTask task : tasks) { |
|
|
185 |
task.setStale(true); |
| 186 |
} |
| 187 |
return true; |
| 174 |
} |
188 |
} |
| 175 |
|
189 |
|
| 176 |
long mil = lastSyncDate.getTime(); |
190 |
long mil = lastSyncDate.getTime(); |
| 177 |
long now = Calendar.getInstance().getTimeInMillis(); |
191 |
long now = Calendar.getInstance().getTimeInMillis(); |
| 178 |
if (now - mil <= 0) { |
192 |
if (now - mil <= 0) { |
| 179 |
return Collections.emptySet(); |
193 |
return false; |
| 180 |
} |
194 |
} |
| 181 |
long minutes = -1 * ((now - mil) / (1000 * 60)); |
195 |
long minutes = -1 * ((now - mil) / (1000 * 60)); |
| 182 |
if (minutes == 0) { |
196 |
if (minutes == 0) { |
| 183 |
return Collections.emptySet(); |
197 |
return false; |
| 184 |
} |
198 |
} |
| 185 |
|
199 |
|
| 186 |
FilterDefinition changedFilter = new FilterDefinition("Changed Tasks"); |
200 |
FilterDefinition changedFilter = new FilterDefinition("Changed Tasks"); |
| 187 |
changedFilter.setUpdatedDateFilter(new RelativeDateRangeFilter(RangeType.MINUTE, minutes)); |
201 |
changedFilter.setUpdatedDateFilter(new RelativeDateRangeFilter(RangeType.MINUTE, minutes)); |
| 188 |
changedFilter.setOrdering(new Order[] { new Order(Order.Field.UPDATED, false) }); |
202 |
changedFilter.setOrdering(new Order[] { new Order(Order.Field.UPDATED, false) }); |
| 189 |
|
|
|
| 190 |
final List<Issue> issues = new ArrayList<Issue>(); |
| 191 |
// unlimited maxHits can create crazy amounts of traffic |
| 192 |
JiraIssueCollector collector = new JiraIssueCollector(new NullProgressMonitor(), issues, 500); |
| 193 |
JiraClient client = JiraClientFacade.getDefault().getJiraClient(repository); |
| 194 |
|
| 195 |
// TODO: Need some way to further scope this query |
203 |
// TODO: Need some way to further scope this query |
| 196 |
|
204 |
|
|
|
205 |
List<Issue> issues = new ArrayList<Issue>(); |
| 206 |
JiraClient client = JiraClientFacade.getDefault().getJiraClient(repository); |
| 207 |
// unlimited maxHits can create crazy amounts of traffic |
| 208 |
JiraIssueCollector issueCollector = new JiraIssueCollector(new NullProgressMonitor(), issues, 500); |
| 197 |
try { |
209 |
try { |
| 198 |
// XXX: disabled work around |
210 |
client.search(changedFilter, issueCollector); |
| 199 |
// TODO: remove, added to re-open connection, bug 164543 |
|
|
| 200 |
// jiraServer.getServerInfo(); |
| 201 |
// Will get ALL issues that have changed since lastSyncDate |
| 202 |
client.search(changedFilter, collector); |
| 203 |
} catch (JiraException e) { |
| 204 |
throw new CoreException(JiraCorePlugin.toStatus(repository, e)); |
| 205 |
} |
| 206 |
|
211 |
|
| 207 |
Set<AbstractTask> changedTasks = new HashSet<AbstractTask>(); |
212 |
if (issues.isEmpty()) { |
| 208 |
for (Issue issue : issues) { |
213 |
return false; // no hits |
| 209 |
// String handle = |
|
|
| 210 |
// AbstractTask.getHandle(repository.getUrl(), |
| 211 |
// issue.getId()); |
| 212 |
AbstractTask task = TasksUiPlugin.getTaskListManager().getTaskList().getTask(repository.getUrl(), issue.getId()); |
| 213 |
if (task instanceof AbstractTask) { |
| 214 |
changedTasks.add((AbstractTask) task); |
| 215 |
} |
214 |
} |
| 216 |
|
215 |
|
| 217 |
if (issue.getUpdated() != null && issue.getUpdated().after(lastSyncDate)) { |
216 |
int n = 0; |
| 218 |
lastSyncDate = issue.getUpdated(); |
217 |
TaskFactory factory = new TaskFactory(repository); |
|
|
218 |
for (Issue issue : issues) { |
| 219 |
AbstractTask task = TasksUiPlugin.getTaskListManager().getTaskList().getTask(repository.getUrl(), |
| 220 |
issue.getId()); |
| 221 |
if (!tasks.contains(task)) { |
| 222 |
continue; |
| 223 |
} |
| 224 |
|
| 225 |
monitor.subTask(++n + "/" + issues.size() + " " + issue.getKey() + " " + issue.getSummary()); |
| 226 |
String handle = RepositoryTaskHandleUtil.getHandle(repository.getUrl(), issue.getId()); |
| 227 |
RepositoryTaskData oldTaskData = TasksUiPlugin.getDefault().getTaskDataManager().getNewTaskData(handle); |
| 228 |
RepositoryTaskData taskData = offlineHandler.createTaskData(repository, client, issue, oldTaskData); |
| 229 |
factory.createTask(taskData, new NullProgressMonitor()); |
| 230 |
|
| 231 |
if (issue.getUpdated() != null && issue.getUpdated().after(lastSyncDate)) { |
| 232 |
lastSyncDate = issue.getUpdated(); |
| 233 |
} |
| 219 |
} |
234 |
} |
| 220 |
} |
|
|
| 221 |
|
235 |
|
| 222 |
repository.setSyncTimeStamp( // |
236 |
repository.setSyncTimeStamp( // |
| 223 |
new SimpleDateFormat(JiraAttributeFactory.JIRA_DATE_FORMAT, Locale.US).format(lastSyncDate)); |
237 |
new SimpleDateFormat(JiraAttributeFactory.JIRA_DATE_FORMAT, Locale.US).format(lastSyncDate)); |
| 224 |
|
238 |
|
| 225 |
return changedTasks; |
239 |
return true; |
|
|
240 |
} catch (JiraException e) { |
| 241 |
throw new CoreException(JiraCorePlugin.toStatus(repository, e)); |
| 242 |
} |
| 226 |
} |
243 |
} |
| 227 |
|
244 |
|
| 228 |
private Date convertDate(String dateString) { |
245 |
private Date convertDate(String dateString) { |
|
Lines 238-245
Link Here
|
| 238 |
} |
255 |
} |
| 239 |
|
256 |
|
| 240 |
@Override |
257 |
@Override |
| 241 |
public String getLastSyncTimestamp(TaskRepository repository, Set<AbstractTask> changedTasks) { |
258 |
public String getSynchronizationTimestamp(TaskRepository repository, Set<AbstractTask> changedTasks) { |
| 242 |
// XXX to late for JIRA to calcualate the timestamp: bug 176934 |
259 |
// the timestamp is updated in markStaleTasks() |
| 243 |
return repository.getSyncTimeStamp(); |
260 |
return repository.getSyncTimeStamp(); |
| 244 |
} |
261 |
} |
| 245 |
|
262 |
|
|
Lines 372-379
Link Here
|
| 372 |
jiraTask.setTaskUrl(getTaskUrl(repository.getUrl(), repositoryTask.getTaskKey())); |
389 |
jiraTask.setTaskUrl(getTaskUrl(repository.getUrl(), repositoryTask.getTaskKey())); |
| 373 |
|
390 |
|
| 374 |
JiraClient client = JiraClientFacade.getDefault().getJiraClient(repository); |
391 |
JiraClient client = JiraClientFacade.getDefault().getJiraClient(repository); |
| 375 |
jiraTask.setPriority(getMylarPriority(client, taskData.getAttributeValue(RepositoryTaskAttribute.PRIORITY)) |
392 |
jiraTask.setPriority(getMylarPriority(client, taskData.getAttributeValue(RepositoryTaskAttribute.PRIORITY)).toString()); |
| 376 |
.toString()); |
|
|
| 377 |
for (org.eclipse.mylyn.internal.jira.core.model.Status status : client.getStatuses()) { |
393 |
for (org.eclipse.mylyn.internal.jira.core.model.Status status : client.getStatuses()) { |
| 378 |
if (status.getName().equals(taskData.getAttributeValue(RepositoryTaskAttribute.STATUS))) { |
394 |
if (status.getName().equals(taskData.getAttributeValue(RepositoryTaskAttribute.STATUS))) { |
| 379 |
if (isCompleted(status)) { |
395 |
if (isCompleted(status)) { |