Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 191575 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/mylyn/internal/trac/core/TracRepositoryConnector.java (-9 / +11 lines)
Lines 151-157 Link Here
151
151
152
	@Override
152
	@Override
153
	public Set<AbstractRepositoryTask> getChangedSinceLastSync(TaskRepository repository,
153
	public Set<AbstractRepositoryTask> getChangedSinceLastSync(TaskRepository repository,
154
			Set<AbstractRepositoryTask> tasks, IProgressMonitor monitor) throws CoreException {
154
			Set<AbstractRepositoryTask> tasks, IProgressMonitor monitor, QueryHitCollector collector) throws CoreException {
155
		if (repository.getSyncTimeStamp() == null) {
155
		if (repository.getSyncTimeStamp() == null) {
156
			return tasks;
156
			return tasks;
157
		}
157
		}
Lines 167-186 Link Here
167
		} catch (NumberFormatException e) {
167
		} catch (NumberFormatException e) {
168
		}
168
		}
169
169
170
		ITracClient client;
171
		try {
170
		try {
172
			client = getClientManager().getRepository(repository);
171
			ITracClient client = getClientManager().getRepository(repository);
173
			Set<Integer> ids = client.getChangedTickets(since);
172
			Set<Integer> ids = client.getChangedTickets(since);
173
			if(ids.isEmpty()) {
174
				return null;  // no changes
175
			}
174
176
175
			Set<AbstractRepositoryTask> result = new HashSet<AbstractRepositoryTask>();
177
			Set<AbstractRepositoryTask> result = new HashSet<AbstractRepositoryTask>();
176
			if (!ids.isEmpty()) {
178
			for (AbstractRepositoryTask task : tasks) {
177
				for (AbstractRepositoryTask task : tasks) {
179
				Integer id = getTicketId(task.getTaskId());
178
					Integer id = getTicketId(task.getTaskId());
180
				if (ids.contains(id)) {
179
					if (ids.contains(id)) {
181
					result.add(task);
180
						result.add(task);
181
					}
182
				}
182
				}
183
			}
183
			}
184
			
185
			// these changed tasks will be synchronized outside
184
			return result;
186
			return result;
185
		} catch (Exception e) {
187
		} catch (Exception e) {
186
			throw new CoreException(new Status(IStatus.ERROR, TracCorePlugin.PLUGIN_ID, IStatus.OK,
188
			throw new CoreException(new Status(IStatus.ERROR, TracCorePlugin.PLUGIN_ID, IStatus.OK,
(-)src/org/eclipse/mylyn/internal/tasks/ui/ScheduledTaskListSynchJob.java (-23 / +13 lines)
Lines 11-33 Link Here
11
11
12
package org.eclipse.mylyn.internal.tasks.ui;
12
package org.eclipse.mylyn.internal.tasks.ui;
13
13
14
import java.util.Collections;
15
import java.util.List;
14
import java.util.List;
16
import java.util.Set;
15
import java.util.Set;
17
16
18
import org.eclipse.core.runtime.IProgressMonitor;
17
import org.eclipse.core.runtime.IProgressMonitor;
19
import org.eclipse.core.runtime.IStatus;
18
import org.eclipse.core.runtime.IStatus;
20
import org.eclipse.core.runtime.NullProgressMonitor;
21
import org.eclipse.core.runtime.OperationCanceledException;
19
import org.eclipse.core.runtime.OperationCanceledException;
22
import org.eclipse.core.runtime.Status;
20
import org.eclipse.core.runtime.Status;
23
import org.eclipse.core.runtime.SubProgressMonitor;
21
import org.eclipse.core.runtime.SubProgressMonitor;
24
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
25
import org.eclipse.core.runtime.jobs.Job;
22
import org.eclipse.core.runtime.jobs.Job;
26
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
27
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
23
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
28
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
24
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
25
import org.eclipse.mylyn.tasks.core.AbstractRepositoryTask;
29
import org.eclipse.mylyn.tasks.core.TaskList;
26
import org.eclipse.mylyn.tasks.core.TaskList;
30
import org.eclipse.mylyn.tasks.core.TaskRepository;
27
import org.eclipse.mylyn.tasks.core.TaskRepository;
28
import org.eclipse.mylyn.tasks.ui.RepositorySynchronizationManager;
31
import org.eclipse.mylyn.tasks.ui.TaskListManager;
29
import org.eclipse.mylyn.tasks.ui.TaskListManager;
32
import org.eclipse.mylyn.tasks.ui.TasksUiPlugin;
30
import org.eclipse.mylyn.tasks.ui.TasksUiPlugin;
33
31
Lines 68-79 Link Here
68
	}
66
	}
69
67
70
	@Override
68
	@Override
71
	public IStatus run(IProgressMonitor monitor) {
69
	public IStatus run(final IProgressMonitor monitor) {
72
		try {
70
		try {
73
			if (monitor == null) {
74
				monitor = new NullProgressMonitor();
75
			}
76
77
			taskList = taskListManager.getTaskList();
71
			taskList = taskListManager.getTaskList();
78
			if (repositories == null) {
72
			if (repositories == null) {
79
				repositories = TasksUiPlugin.getRepositoryManager().getAllRepositories();
73
				repositories = TasksUiPlugin.getRepositoryManager().getAllRepositories();
Lines 113-134 Link Here
113
					updateJob.schedule();
107
					updateJob.schedule();
114
				}
108
				}
115
109
116
				Set<AbstractRepositoryQuery> queries = Collections.unmodifiableSet(taskList
110
				RepositorySynchronizationManager synchronizationManager = TasksUiPlugin.getSynchronizationManager();
117
						.getRepositoryQueries(repository.getUrl()));
111
				Set<AbstractRepositoryTask> changedTasks = synchronizationManager.synchronizeChanged(connector, repository,
118
				if (queries.size() > 0) {
112
						new SubProgressMonitor(monitor, SubProgressMonitor.UNKNOWN));
119
					if (connector != null) {
113
				if(changedTasks!=null) {
120
						JobChangeAdapter jobAdapter = new JobChangeAdapter() {
114
					// only sync queries if there were any changes
121
							@Override
115
					Set<AbstractRepositoryQuery> queries = taskList.getRepositoryQueries(repository.getUrl());
122
							public void done(IJobChangeEvent event) {
116
					if (queries.size() > 0) {
123
								TasksUiPlugin.getSynchronizationManager().synchronizeChanged(connector, repository);
117
						synchronizationManager.synchronize(connector, queries, null,
124
							}
118
								Job.DECORATE, 0, false, changedTasks);
125
						};
126
						TasksUiPlugin.getSynchronizationManager().synchronize(connector, queries, jobAdapter,
127
								Job.DECORATE, 0, false, false);
128
					}
119
					}
129
				} else {
130
					TasksUiPlugin.getSynchronizationManager().synchronizeChanged(connector, repository);
131
				}
120
				}
121
				
132
				monitor.worked(1);
122
				monitor.worked(1);
133
			}
123
			}
134
		} finally {
124
		} finally {
(-)src/org/eclipse/mylyn/internal/tasks/ui/actions/SynchronizeSelectedAction.java (-19 / +29 lines)
Lines 19-24 Link Here
19
import java.util.Map;
19
import java.util.Map;
20
import java.util.Set;
20
import java.util.Set;
21
21
22
import org.eclipse.core.runtime.NullProgressMonitor;
22
import org.eclipse.core.runtime.jobs.Job;
23
import org.eclipse.core.runtime.jobs.Job;
23
import org.eclipse.jface.action.IAction;
24
import org.eclipse.jface.action.IAction;
24
import org.eclipse.jface.viewers.ISelection;
25
import org.eclipse.jface.viewers.ISelection;
Lines 30-35 Link Here
30
import org.eclipse.mylyn.tasks.core.ITask;
31
import org.eclipse.mylyn.tasks.core.ITask;
31
import org.eclipse.mylyn.tasks.core.TaskCategory;
32
import org.eclipse.mylyn.tasks.core.TaskCategory;
32
import org.eclipse.mylyn.tasks.core.TaskRepository;
33
import org.eclipse.mylyn.tasks.core.TaskRepository;
34
import org.eclipse.mylyn.tasks.ui.RepositorySynchronizationManager;
33
import org.eclipse.mylyn.tasks.ui.TasksUiPlugin;
35
import org.eclipse.mylyn.tasks.ui.TasksUiPlugin;
34
import org.eclipse.ui.IActionBars;
36
import org.eclipse.ui.IActionBars;
35
import org.eclipse.ui.IViewActionDelegate;
37
import org.eclipse.ui.IViewActionDelegate;
Lines 83-123 Link Here
83
				}
85
				}
84
			}
86
			}
85
87
88
			RepositorySynchronizationManager syncManager = TasksUiPlugin.getSynchronizationManager();
86
			if (!queriesToSyncMap.isEmpty()) {
89
			if (!queriesToSyncMap.isEmpty()) {
87
				
90
				
88
				// determine which repositories to synch changed tasks for
91
				// determine which repositories to synch changed tasks for
89
				HashMap<String, Set<TaskRepository>> repositoriesToSync = new HashMap<String, Set<TaskRepository>>();
92
				HashMap<TaskRepository, Set<AbstractRepositoryQuery>> repositoriesToSync = new HashMap<TaskRepository, Set<AbstractRepositoryQuery>>();
90
				for (AbstractRepositoryConnector connector : queriesToSyncMap.keySet()) {
93
				for (AbstractRepositoryConnector connector : queriesToSyncMap.keySet()) {
91
					List<AbstractRepositoryQuery> queriesToSync = queriesToSyncMap.get(connector);
94
					List<AbstractRepositoryQuery> queriesToSync = queriesToSyncMap.get(connector);
95
					if(queriesToSync==null || queriesToSync.isEmpty()) {
96
						continue;
97
					}
98
					
92
					for (AbstractRepositoryQuery query : queriesToSync) {
99
					for (AbstractRepositoryQuery query : queriesToSync) {
93
						TaskRepository repos = TasksUiPlugin.getRepositoryManager().getRepository(query.getRepositoryKind(), query.getRepositoryUrl());
100
						TaskRepository repos = TasksUiPlugin.getRepositoryManager().getRepository(query.getRepositoryKind(), query.getRepositoryUrl());
94
						Set<TaskRepository> repositories = repositoriesToSync.get(connector.getRepositoryType());
101
						Set<AbstractRepositoryQuery> queries = repositoriesToSync.get(repos);
95
						if(repositories == null) {
102
						if(queries == null) {
96
							repositories = new HashSet<TaskRepository>();
103
							queries = new HashSet<AbstractRepositoryQuery>();
97
							repositoriesToSync.put(connector.getRepositoryType(), repositories);
104
							repositoriesToSync.put(repos, queries);
98
						}
105
						}
99
						repositories.add(repos);
106
						queries.add(query);
100
					}
107
					}
101
				}
108
				}
102
				
109
				
103
				// synch the queries followed by the repositories
110
				for (Map.Entry<TaskRepository, Set<AbstractRepositoryQuery>> e : repositoriesToSync.entrySet()) {
104
				for (AbstractRepositoryConnector connector : queriesToSyncMap.keySet()) {
111
					TaskRepository repository = e.getKey();
105
					List<AbstractRepositoryQuery> queriesToSync = queriesToSyncMap.get(connector);
112
106
					if (queriesToSync != null && queriesToSync.size() > 0) {
113
					AbstractRepositoryConnector connector = TasksUiPlugin.getRepositoryManager()
107
						TasksUiPlugin.getSynchronizationManager().synchronize(connector, new HashSet<AbstractRepositoryQuery>(queriesToSync), null, Job.LONG, 0,
114
							.getRepositoryConnector(repository.getKind());
108
								false, true);
115
109
					}
116
					Set<AbstractRepositoryTask> changed = syncManager.synchronizeChanged(connector, repository,
110
					//XXX enable?
117
							new NullProgressMonitor());
111
//					for (TaskRepository taskRepository : repositoriesToSync.get(connector.getRepositoryType())) {
118
112
//						TasksUiPlugin.getSynchronizationManager().synchronizeChanged(connector, taskRepository);
119
					if (changed != null) {
113
//					}
120
						Set<AbstractRepositoryQuery> queries = e.getValue();
114
				}				
121
						syncManager.synchronize(connector, new HashSet<AbstractRepositoryQuery>(queries), null,
122
								Job.LONG, 0L, true, changed);
123
					}
124
				}
115
			}
125
			}
116
			if (!tasksToSyncMap.isEmpty()) {
126
			if (!tasksToSyncMap.isEmpty()) {
117
				for (AbstractRepositoryConnector connector : tasksToSyncMap.keySet()) {
127
				for (AbstractRepositoryConnector connector : tasksToSyncMap.keySet()) {
118
					List<AbstractRepositoryTask> tasksToSync = tasksToSyncMap.get(connector);
128
					List<AbstractRepositoryTask> tasksToSync = tasksToSyncMap.get(connector);
119
					if (tasksToSync != null && tasksToSync.size() > 0) {
129
					if (tasksToSync != null && tasksToSync.size() > 0) {
120
						TasksUiPlugin.getSynchronizationManager().synchronize(connector, new HashSet<AbstractRepositoryTask>(tasksToSync), true, null);
130
						syncManager.synchronize(connector, new HashSet<AbstractRepositoryTask>(tasksToSync), true, null);
121
					}
131
					}
122
				}
132
				}
123
			}
133
			}
(-)src/org/eclipse/mylyn/tasks/ui/SynchronizeQueryJob.java (-20 / +35 lines)
Lines 26-31 Link Here
26
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
26
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
27
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
27
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
28
import org.eclipse.mylyn.tasks.core.AbstractRepositoryTask;
28
import org.eclipse.mylyn.tasks.core.AbstractRepositoryTask;
29
import org.eclipse.mylyn.tasks.core.AbstractTaskContainer;
29
import org.eclipse.mylyn.tasks.core.QueryHitCollector;
30
import org.eclipse.mylyn.tasks.core.QueryHitCollector;
30
import org.eclipse.mylyn.tasks.core.RepositoryStatus;
31
import org.eclipse.mylyn.tasks.core.RepositoryStatus;
31
import org.eclipse.mylyn.tasks.core.TaskList;
32
import org.eclipse.mylyn.tasks.core.TaskList;
Lines 39-74 Link Here
39
 */
40
 */
40
class SynchronizeQueryJob extends Job {
41
class SynchronizeQueryJob extends Job {
41
42
42
	private final AbstractRepositoryConnector connector;
43
44
	private static final String JOB_LABEL = "Synchronizing queries";
43
	private static final String JOB_LABEL = "Synchronizing queries";
44
	
45
	private final AbstractRepositoryConnector connector;
45
46
46
	private Set<AbstractRepositoryQuery> queries;
47
	private final Set<AbstractRepositoryQuery> queries;
47
48
	private Set<TaskRepository> repositories;
49
50
	private boolean synchChangedTasks;
51
48
52
	private TaskList taskList;
49
	private final TaskList taskList;
53
50
54
// private RepositorySynchronizationManager synchronizationManager;
51
	private final Set<AbstractRepositoryTask> changedTasks;
55
52
53
//	private final Set<TaskRepository> repositories;
54
	
55
//	private boolean synchChangedTasks;
56
	
56
	private boolean forced = false;
57
	private boolean forced = false;
57
58
59
58
	public SynchronizeQueryJob(RepositorySynchronizationManager synchronizationManager,
60
	public SynchronizeQueryJob(RepositorySynchronizationManager synchronizationManager,
59
			AbstractRepositoryConnector connector, Set<AbstractRepositoryQuery> queries, TaskList taskList) {
61
			AbstractRepositoryConnector connector, Set<AbstractRepositoryQuery> queries, TaskList taskList, Set<AbstractRepositoryTask> changedTasks) {
60
		super(JOB_LABEL + ": " + connector.getRepositoryType());
62
		super(JOB_LABEL + ": " + connector.getRepositoryType());
61
		this.connector = connector;
63
		this.connector = connector;
62
		this.queries = queries;
64
		this.queries = queries;
63
		this.taskList = taskList;
65
		this.taskList = taskList;
64
		this.repositories = new HashSet<TaskRepository>();
66
		this.changedTasks = changedTasks;
67
//		this.repositories = new HashSet<TaskRepository>();
65
		// TODO: remove once architecture established
68
		// TODO: remove once architecture established
66
		// this.synchronizationManager = synchronizationManager;
69
		// this.synchronizationManager = synchronizationManager;
67
	}
70
	}
68
71
69
	public void setSynchChangedTasks(boolean syncChangedTasks) {
72
//	public void setSynchChangedTasks(boolean syncChangedTasks) {
70
		this.synchChangedTasks = syncChangedTasks;
73
//		this.synchChangedTasks = syncChangedTasks;
71
	}
74
//	}
72
75
73
	/**
76
	/**
74
	 * Returns true, if synchronization was triggered manually and not by an
77
	 * Returns true, if synchronization was triggered manually and not by an
Lines 91-96 Link Here
91
	protected IStatus run(IProgressMonitor monitor) {
94
	protected IStatus run(IProgressMonitor monitor) {
92
		monitor.beginTask(JOB_LABEL, queries.size());
95
		monitor.beginTask(JOB_LABEL, queries.size());
93
96
97
		
98
		
94
		for (AbstractRepositoryQuery repositoryQuery : queries) {
99
		for (AbstractRepositoryQuery repositoryQuery : queries) {
95
			taskList.notifyContainerUpdated(repositoryQuery);
100
			taskList.notifyContainerUpdated(repositoryQuery);
96
			repositoryQuery.setStatus(null);
101
			repositoryQuery.setStatus(null);
Lines 107-112 Link Here
107
				QueryHitCollector collector = new QueryHitCollector(taskList, new TaskFactory(repository));
112
				QueryHitCollector collector = new QueryHitCollector(taskList, new TaskFactory(repository));
108
				SubProgressMonitor collectorMonitor = new SubProgressMonitor(monitor, 1);
113
				SubProgressMonitor collectorMonitor = new SubProgressMonitor(monitor, 1);
109
				collector.setProgressMonitor(collectorMonitor);
114
				collector.setProgressMonitor(collectorMonitor);
115
116
				// XXX may need to pass changedTasks to this call so it can skip synchronizing them again  
110
				final IStatus resultingStatus = connector.performQuery(repositoryQuery, repository, collectorMonitor,
117
				final IStatus resultingStatus = connector.performQuery(repositoryQuery, repository, collectorMonitor,
111
						collector, forced);
118
						collector, forced);
112
119
Lines 120-132 Link Here
120
					}
127
					}
121
128
122
					repositoryQuery.clear();
129
					repositoryQuery.clear();
130
131
					HashSet<AbstractRepositoryTask> hitsToBeSynchronized = new HashSet<AbstractRepositoryTask>();
123
					for (AbstractRepositoryTask hit : collector.getTaskHits()) {
132
					for (AbstractRepositoryTask hit : collector.getTaskHits()) {
124
						taskList.addTask(hit, repositoryQuery);
133
						taskList.addTask(hit, repositoryQuery);
134
						if(changedTasks==null || !changedTasks.contains(hit)) {
135
							hitsToBeSynchronized.add(hit);
136
						}
125
					}
137
					}
126
138
127
					if (synchChangedTasks) {
139
					// XXX synchronize task data for hitsToBeSynchronized collection
128
						repositories.add(repository);
140
					
129
					}
141
					
142
//					if (synchChangedTasks) {
143
//						repositories.add(repository);
144
//					}
130
145
131
					repositoryQuery.setLastRefreshTimeStamp(DateUtil.getFormattedDate(new Date(), "MMM d, H:mm:ss"));
146
					repositoryQuery.setLastRefreshTimeStamp(DateUtil.getFormattedDate(new Date(), "MMM d, H:mm:ss"));
132
				} else {
147
				} else {
Lines 146-154 Link Here
146
			taskList.notifyContainerUpdated(repositoryQuery);
161
			taskList.notifyContainerUpdated(repositoryQuery);
147
		}
162
		}
148
163
149
		for (TaskRepository repository : repositories) {
164
//		for (TaskRepository repository : repositories) {
150
			TasksUiPlugin.getSynchronizationManager().synchronizeChanged(connector, repository);
165
//			TasksUiPlugin.getSynchronizationManager().synchronizeChanged(connector, repository);
151
		}
166
//		}
152
167
153
		// HACK: force entire Task List to refresh in case containers need to
168
		// HACK: force entire Task List to refresh in case containers need to
154
		// appear or disappear
169
		// appear or disappear
(-)src/org/eclipse/mylyn/tasks/ui/RepositorySynchronizationManager.java (-19 / +63 lines)
Lines 28-33 Link Here
28
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
28
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
29
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
29
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
30
import org.eclipse.mylyn.tasks.core.AbstractRepositoryTask;
30
import org.eclipse.mylyn.tasks.core.AbstractRepositoryTask;
31
import org.eclipse.mylyn.tasks.core.QueryHitCollector;
31
import org.eclipse.mylyn.tasks.core.RepositoryTaskAttribute;
32
import org.eclipse.mylyn.tasks.core.RepositoryTaskAttribute;
32
import org.eclipse.mylyn.tasks.core.RepositoryTaskData;
33
import org.eclipse.mylyn.tasks.core.RepositoryTaskData;
33
import org.eclipse.mylyn.tasks.core.TaskList;
34
import org.eclipse.mylyn.tasks.core.TaskList;
Lines 103-119 Link Here
103
	 */
104
	 */
104
	public final Job synchronize(AbstractRepositoryConnector connector, final AbstractRepositoryQuery repositoryQuery,
105
	public final Job synchronize(AbstractRepositoryConnector connector, final AbstractRepositoryQuery repositoryQuery,
105
			IJobChangeListener listener, boolean forceSync) {
106
			IJobChangeListener listener, boolean forceSync) {
106
		HashSet<AbstractRepositoryQuery> items = new HashSet<AbstractRepositoryQuery>();
107
		return synchronize(connector, Collections.singleton(repositoryQuery), listener, Job.LONG, 0, forceSync, null);
107
		items.add(repositoryQuery);
108
		return synchronize(connector, items, listener, Job.LONG, 0, true, forceSync);
109
	}
108
	}
110
109
111
	public final Job synchronize(AbstractRepositoryConnector connector,
110
	public final Job synchronize(AbstractRepositoryConnector connector,
112
			final Set<AbstractRepositoryQuery> repositoryQueries, final IJobChangeListener listener, int priority,
111
			final Set<AbstractRepositoryQuery> repositoryQueries, final IJobChangeListener listener, int priority,
113
			long delay, boolean syncChangedTasks, boolean userForcedSync) {
112
			long delay, boolean userForcedSync, Set<AbstractRepositoryTask> changedTasks) {
114
		TaskList taskList = TasksUiPlugin.getTaskListManager().getTaskList();
113
		TaskList taskList = TasksUiPlugin.getTaskListManager().getTaskList();
115
		final SynchronizeQueryJob job = new SynchronizeQueryJob(this, connector, repositoryQueries, taskList);
114
		final SynchronizeQueryJob job = new SynchronizeQueryJob(this, connector, repositoryQueries, taskList, changedTasks);
116
		job.setSynchChangedTasks(syncChangedTasks);
115
//		job.setSynchChangedTasks(syncChangedTasks);
117
		job.setForced(userForcedSync);
116
		job.setForced(userForcedSync);
118
		for (AbstractRepositoryQuery repositoryQuery : repositoryQueries) {
117
		for (AbstractRepositoryQuery repositoryQuery : repositoryQueries) {
119
			repositoryQuery.setCurrentlySynchronizing(true);
118
			repositoryQuery.setCurrentlySynchronizing(true);
Lines 143-164 Link Here
143
	 * Synchronizes only those tasks that have changed since the last time the
142
	 * Synchronizes only those tasks that have changed since the last time the
144
	 * given repository was synchronized. Calls to this method update
143
	 * given repository was synchronized. Calls to this method update
145
	 * TaskRepository.syncTime.
144
	 * TaskRepository.syncTime.
145
	 * 
146
	 * @return tasks updated, or <code>null</code>, if there is no updated tasks found.
146
	 */
147
	 */
147
	public final void synchronizeChanged(final AbstractRepositoryConnector connector, final TaskRepository repository) {
148
	public final Set<AbstractRepositoryTask> synchronizeChanged(final AbstractRepositoryConnector connector,
149
			final TaskRepository repository, IProgressMonitor monitor) {
148
		if (connector.getTaskDataHandler() != null) {
150
		if (connector.getTaskDataHandler() != null) {
149
			final SynchronizeChangedTasksJob getChangedTasksJob = new SynchronizeChangedTasksJob(connector, repository);
151
150
			getChangedTasksJob.setSystem(true);
152
// THIS IS ONLY CALLED FROM OTHER JOBS, SO PROBABLY NO NEED TO CREATE ANOTHER NESTED JOB			
151
			getChangedTasksJob.setRule(new RepositoryMutexRule(repository));
153
//			final SynchronizeChangedTasksJob getChangedTasksJob = new SynchronizeChangedTasksJob(connector, repository);
152
			if (!forceSyncExecForTesting) {
154
//			getChangedTasksJob.setSystem(true);
153
				getChangedTasksJob.schedule();
155
//			getChangedTasksJob.setRule(new RepositoryMutexRule(repository));
154
			} else {
156
//			if (!forceSyncExecForTesting) {
155
				PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
157
//				getChangedTasksJob.schedule();
156
					public void run() {
158
//			} else {
157
						getChangedTasksJob.run(new NullProgressMonitor());
159
//				PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
160
//					public void run() {
161
//						getChangedTasksJob.run(new NullProgressMonitor());
162
//					}
163
//				});
164
//			}
165
			
166
			TaskList taskList = TasksUiPlugin.getTaskListManager().getTaskList();
167
			Set<AbstractRepositoryTask> repositoryTasks = Collections.unmodifiableSet(taskList
168
					.getRepositoryTasks(repository.getUrl()));
169
170
			try {
171
			  // XXX not sure if it is using right TaskFactory
172
				QueryHitCollector collector = new QueryHitCollector(taskList, new TaskFactory(repository));
173
				
174
				final Set<AbstractRepositoryTask> changedTasks = connector.getChangedSinceLastSync(repository, repositoryTasks, monitor, collector);
175
				if (changedTasks == null) {
176
					return changedTasks;
177
				}
178
				
179
				synchronize(connector, changedTasks, false, new JobChangeAdapter() {
180
					@Override
181
					public void done(IJobChangeEvent event) {
182
						if (!Platform.isRunning() || TasksUiPlugin.getRepositoryManager() == null) {
183
							return;
184
						}
185
						TasksUiPlugin.getRepositoryManager().setSyncTime(repository,
186
								connector.getLastSyncTimestamp(repository, changedTasks),
187
								TasksUiPlugin.getDefault().getRepositoriesFilePath());
158
					}
188
					}
159
				});
189
				});
190
191
				return changedTasks;
192
193
			} catch (final CoreException e) {
194
				// ignore, indicates working offline
195
				// error reported in ui (tooltip and warning icon)
160
			}
196
			}
161
		}
197
		}
198
		return null;
162
	}
199
	}
163
200
164
	private class SynchronizeChangedTasksJob extends Job {
201
	private class SynchronizeChangedTasksJob extends Job {
Lines 182-194 Link Here
182
					.getRepositoryTasks(repository.getUrl()));
219
					.getRepositoryTasks(repository.getUrl()));
183
220
184
			try {
221
			try {
185
				changedTasks = connector.getChangedSinceLastSync(repository, repositoryTasks, monitor);
222
				QueryHitCollector collector = new QueryHitCollector(taskList, new TaskFactory(repository));
223
				
224
				changedTasks = connector.getChangedSinceLastSync(repository, repositoryTasks, monitor, collector);
186
225
187
				if (changedTasks == null || changedTasks.size() == 0) {
226
				if (changedTasks == null || changedTasks.size() == 0) {
188
					return Status.OK_STATUS;
227
					return Status.OK_STATUS;
189
				}
228
				}
229
				
230
				final Set<AbstractRepositoryTask> taskHits = collector.getTaskHits();
231
				if(taskHits.isEmpty()) {
232
					return Status.OK_STATUS;
233
				}
190
234
191
				synchronize(connector, changedTasks, false, new JobChangeAdapter() {
235
				synchronize(connector, taskHits, false, new JobChangeAdapter() {
192
236
193
					@Override
237
					@Override
194
					public void done(IJobChangeEvent event) {
238
					public void done(IJobChangeEvent event) {
Lines 196-202 Link Here
196
							return;
240
							return;
197
						}
241
						}
198
						TasksUiPlugin.getRepositoryManager().setSyncTime(repository,
242
						TasksUiPlugin.getRepositoryManager().setSyncTime(repository,
199
								connector.getLastSyncTimestamp(repository, changedTasks),
243
								connector.getLastSyncTimestamp(repository, taskHits),
200
								TasksUiPlugin.getDefault().getRepositoriesFilePath());
244
								TasksUiPlugin.getDefault().getRepositoriesFilePath());
201
					}
245
					}
202
				});
246
				});
(-)src/org/eclipse/mylyn/tasks/core/AbstractRepositoryConnector.java (-7 / +11 lines)
Lines 250-268 Link Here
250
	}
250
	}
251
251
252
	/**
252
	/**
253
	 * Of <code>tasks</code> provided, return all that have changed since last
253
	 * Of <code>tasks</code> provided, return all that have changed since last synchronization of
254
	 * synchronization of <code>repository</code>
254
	 * <code>repository</code>.
255
	 * 
255
	 * 
256
	 * All errors should be thrown as <code>CoreException</code> for the
256
	 * Tasks that need to be synchronized (i.e. task data updated) should be passed to
257
	 * framework to handle, since background synchronizations fail silently when
257
	 * <code>collector.accept(Task)</code> method, or if repository connector can update task data, it can use
258
	 * disconnected.
258
	 * <code>collector.accept(RepositoryTaskData)</code> call.
259
	 * 
259
	 * 
260
	 * TODO: Add progress monitor as parameter
260
	 * All errors should be thrown as <code>CoreException</code> for the framework to handle, since background
261
	 * synchronizations fail silently when disconnected.
262
	 * 
263
	 * @return null if there was no tasks changed in the repository, otherwise collection of updated tasks (within
264
	 *         <code>tasks</code> collection), so empty collection means that there are some other tasks changed
261
	 * 
265
	 * 
262
	 * @throws CoreException
266
	 * @throws CoreException
263
	 */
267
	 */
264
	public abstract Set<AbstractRepositoryTask> getChangedSinceLastSync(TaskRepository repository,
268
	public abstract Set<AbstractRepositoryTask> getChangedSinceLastSync(TaskRepository repository,
265
			Set<AbstractRepositoryTask> tasks, IProgressMonitor monitor) throws CoreException;
269
			Set<AbstractRepositoryTask> tasks, IProgressMonitor monitor, QueryHitCollector collector) throws CoreException;
266
270
267
	/**
271
	/**
268
	 * Attaches the associated context to <code>task</code>.
272
	 * Attaches the associated context to <code>task</code>.
(-)src/org/eclipse/mylyn/tasks/core/TaskRepository.java (-7 / +19 lines)
Lines 290-297 Link Here
290
290
291
	@Override
291
	@Override
292
	public boolean equals(Object object) {
292
	public boolean equals(Object object) {
293
		if (object instanceof TaskRepository && getUrl() != null) {
293
		if (object instanceof TaskRepository) {
294
			return getUrl().equals(((TaskRepository) object).getUrl());
294
			TaskRepository repository = (TaskRepository) object;
295
			if (getUrl() == null) {
296
				if (repository.getUrl() != null) {
297
					return false;
298
				}
299
			} else {
300
				if(!getUrl().equals(repository.getUrl())) {
301
					return false;
302
				}
303
			}
304
			if (getKind() == null) {
305
				return repository.getKind() == null;
306
			} else {
307
				return getKind().equals(repository.getKind());
308
			}
309
295
		} else {
310
		} else {
296
			return super.equals(object);
311
			return super.equals(object);
297
		}
312
		}
Lines 299-309 Link Here
299
314
300
	@Override
315
	@Override
301
	public int hashCode() {
316
	public int hashCode() {
302
		if (getUrl() != null) {
317
		int res = getUrl()==null ? 1 : getUrl().hashCode();
303
			return getUrl().hashCode();
318
		return res * 31 + (getKind()==null ? 1 : getKind().hashCode());
304
		} else {
305
			return super.hashCode();
306
		}
307
	}
319
	}
308
320
309
	@Override
321
	@Override
(-)src/org/eclipse/mylyn/internal/tasks/core/LocalRepositoryConnector.java (-3 / +2 lines)
Lines 11-17 Link Here
11
11
12
package org.eclipse.mylyn.internal.tasks.core;
12
package org.eclipse.mylyn.internal.tasks.core;
13
13
14
import java.util.Collections;
15
import java.util.Set;
14
import java.util.Set;
16
15
17
import org.eclipse.core.runtime.CoreException;
16
import org.eclipse.core.runtime.CoreException;
Lines 64-71 Link Here
64
63
65
	@Override
64
	@Override
66
	public Set<AbstractRepositoryTask> getChangedSinceLastSync(TaskRepository repository,
65
	public Set<AbstractRepositoryTask> getChangedSinceLastSync(TaskRepository repository,
67
			Set<AbstractRepositoryTask> tasks, IProgressMonitor monitor) throws CoreException {
66
			Set<AbstractRepositoryTask> tasks, IProgressMonitor monitor, QueryHitCollector collector) {
68
		return Collections.emptySet();
67
		return null;
69
	}
68
	}
70
69
71
	@Override
70
	@Override
(-)src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaRepositoryConnector.java (-12 / +12 lines)
Lines 225-231 Link Here
225
225
226
	@Override
226
	@Override
227
	public Set<AbstractRepositoryTask> getChangedSinceLastSync(TaskRepository repository,
227
	public Set<AbstractRepositoryTask> getChangedSinceLastSync(TaskRepository repository,
228
			Set<AbstractRepositoryTask> tasks, IProgressMonitor monitor) throws CoreException {
228
			Set<AbstractRepositoryTask> tasks, IProgressMonitor monitor, QueryHitCollector collector) throws CoreException {
229
		try {
229
		try {
230
			Set<AbstractRepositoryTask> changedTasks = new HashSet<AbstractRepositoryTask>();
230
			Set<AbstractRepositoryTask> changedTasks = new HashSet<AbstractRepositoryTask>();
231
231
Lines 237-250 Link Here
237
			if (dateString == null) {
237
			if (dateString == null) {
238
				dateString = "";
238
				dateString = "";
239
			}
239
			}
240
			String urlQueryBase;
241
			String urlQueryString;
242
240
243
			urlQueryBase = repository.getUrl() + CHANGED_BUGS_CGI_QUERY
241
			String urlQueryBase = repository.getUrl() + CHANGED_BUGS_CGI_QUERY
244
					+ URLEncoder.encode(dateString, repository.getCharacterEncoding()) + CHANGED_BUGS_CGI_ENDDATE;
242
					+ URLEncoder.encode(dateString, repository.getCharacterEncoding()) + CHANGED_BUGS_CGI_ENDDATE;
245
243
			
246
			urlQueryString = urlQueryBase + BUG_ID;
244
			String urlQueryString = urlQueryBase + BUG_ID;
247
245
			
246
			// Need to replace this with query that would return list of tasks since last sync
247
			// the trouble is that bugzilla only have 1 hour granularity for "changed since" query
248
			// so, we can't say that no tasks has changed in repository
249
			
248
			int queryCounter = -1;
250
			int queryCounter = -1;
249
			Iterator<AbstractRepositoryTask> itr = tasks.iterator();
251
			Iterator<AbstractRepositoryTask> itr = tasks.iterator();
250
			while (itr.hasNext()) {
252
			while (itr.hasNext()) {
Lines 256-267 Link Here
256
					queryForChanged(repository, changedTasks, urlQueryString);
258
					queryForChanged(repository, changedTasks, urlQueryString);
257
					queryCounter = 0;
259
					queryCounter = 0;
258
					urlQueryString = urlQueryBase + BUG_ID;
260
					urlQueryString = urlQueryBase + BUG_ID;
259
					urlQueryString += newurlQueryString;
261
				}
260
				} else if (!itr.hasNext()) {
262
				urlQueryString += newurlQueryString;
261
					urlQueryString += newurlQueryString;
263
				if (!itr.hasNext()) {
262
					queryForChanged(repository, changedTasks, urlQueryString);
264
					queryForChanged(repository, changedTasks, urlQueryString);
263
				} else {
264
					urlQueryString += newurlQueryString;
265
				}
265
				}
266
			}
266
			}
267
			return changedTasks;
267
			return changedTasks;
(-)src/org/eclipse/mylyn/internal/jira/ui/JiraRepositoryConnector.java (-31 / +29 lines)
Lines 157-165 Link Here
157
		}
157
		}
158
	}
158
	}
159
159
160
	@Override
160
	public Set<AbstractRepositoryTask> getChangedSinceLastSync(TaskRepository repository,
161
	public Set<AbstractRepositoryTask> getChangedSinceLastSync(TaskRepository repository,
161
			Set<AbstractRepositoryTask> tasks, IProgressMonitor monitor) throws CoreException {
162
			Set<AbstractRepositoryTask> tasks, IProgressMonitor monitor, QueryHitCollector collector) throws CoreException {
162
163
		String dateString = repository.getSyncTimeStamp();
163
		String dateString = repository.getSyncTimeStamp();
164
		Date lastSyncDate = convertDate(dateString);
164
		Date lastSyncDate = convertDate(dateString);
165
		if (lastSyncDate == null) {
165
		if (lastSyncDate == null) {
Lines 187-229 Link Here
187
		FilterDefinition changedFilter = new FilterDefinition("Changed Tasks");
187
		FilterDefinition changedFilter = new FilterDefinition("Changed Tasks");
188
		changedFilter.setUpdatedDateFilter(new RelativeDateRangeFilter(RangeType.MINUTE, minutes));
188
		changedFilter.setUpdatedDateFilter(new RelativeDateRangeFilter(RangeType.MINUTE, minutes));
189
		changedFilter.setOrdering(new Order[] { new Order(Order.Field.UPDATED, false) });
189
		changedFilter.setOrdering(new Order[] { new Order(Order.Field.UPDATED, false) });
190
191
		final List<Issue> issues = new ArrayList<Issue>();
192
		// unlimited maxHits can create crazy amounts of traffic
193
		JiraIssueCollector collector = new JiraIssueCollector(new NullProgressMonitor(), issues, 500);
194
		JiraClient client = JiraClientFacade.getDefault().getJiraClient(repository);
195
196
		// TODO: Need some way to further scope this query
190
		// TODO: Need some way to further scope this query
197
191
192
		List<Issue> issues = new ArrayList<Issue>();
193
		JiraClient client = JiraClientFacade.getDefault().getJiraClient(repository);
194
		// unlimited maxHits can create crazy amounts of traffic
195
		JiraIssueCollector issueCollector = new JiraIssueCollector(new NullProgressMonitor(), issues, 500);
198
		try {
196
		try {
199
			// XXX: disabled work around
197
			client.search(changedFilter, issueCollector);
200
			// TODO: remove, added to re-open connection, bug 164543
198
			
201
			// jiraServer.getServerInfo();
199
			if(issues.isEmpty()) {
202
			// Will get ALL issues that have changed since lastSyncDate
200
				return null;  // no hits
203
			client.search(changedFilter, collector);
204
		} catch (JiraException e) {
205
			throw new CoreException(JiraCorePlugin.toStatus(repository, e));
206
		}
207
208
		Set<AbstractRepositoryTask> changedTasks = new HashSet<AbstractRepositoryTask>();
209
		for (Issue issue : issues) {
210
			// String handle =
211
			// AbstractRepositoryTask.getHandle(repository.getUrl(),
212
			// issue.getId());
213
			ITask task = TasksUiPlugin.getTaskListManager().getTaskList().getTask(repository.getUrl(), issue.getId());
214
			if (task instanceof AbstractRepositoryTask) {
215
				changedTasks.add((AbstractRepositoryTask) task);
216
			}
201
			}
217
202
218
			if (issue.getUpdated() != null && issue.getUpdated().after(lastSyncDate)) {
203
			for (Issue issue : issues) {
219
				lastSyncDate = issue.getUpdated();
204
				ITask task = TasksUiPlugin.getTaskListManager().getTaskList().getTask(repository.getUrl(), issue.getId());
205
				if (!tasks.contains(task)) {
206
					continue;
207
				}
208
				
209
				RepositoryTaskData taskData = offlineHandler.createTaskData(repository, client, issue);
210
				collector.accept(taskData);
211
				
212
				if (issue.getUpdated() != null && issue.getUpdated().after(lastSyncDate)) {
213
					lastSyncDate = issue.getUpdated();
214
				}
220
			}
215
			}
221
		}
222
216
223
		repository.setSyncTimeStamp( // 
217
			repository.setSyncTimeStamp( // 
224
				new SimpleDateFormat(JiraAttributeFactory.JIRA_DATE_FORMAT, Locale.US).format(lastSyncDate));
218
					new SimpleDateFormat(JiraAttributeFactory.JIRA_DATE_FORMAT, Locale.US).format(lastSyncDate));
219
			
220
			return Collections.emptySet();  // no need to synchronize anything
225
221
226
		return changedTasks;
222
		} catch (JiraException e) {
223
			throw new CoreException(JiraCorePlugin.toStatus(repository, e));
224
		}
227
	}
225
	}
228
226
229
	private Date convertDate(String dateString) {
227
	private Date convertDate(String dateString) {

Return to bug 191575