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<AbstractTask> getChangedSinceLastSync(TaskRepository repository,
153
	public Set<AbstractTask> getChangedSinceLastSync(TaskRepository repository,
154
			Set<AbstractTask> tasks, IProgressMonitor monitor) throws CoreException {
154
			Set<AbstractTask> 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<AbstractTask> result = new HashSet<AbstractTask>();
177
			Set<AbstractTask> result = new HashSet<AbstractTask>();
176
			if (!ids.isEmpty()) {
178
			for (AbstractTask task : tasks) {
177
				for (AbstractTask 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 (-24 / +14 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;
29
import org.eclipse.mylyn.tasks.core.getAllCategories;
25
import org.eclipse.mylyn.tasks.core.AbstractTask;
30
import org.eclipse.mylyn.tasks.core.TaskRepository;
26
import org.eclipse.mylyn.tasks.core.TaskRepository;
27
import org.eclipse.mylyn.tasks.core.getAllCategories;
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<AbstractTask> 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 (-25 / +32 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 27-35 Link Here
27
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
28
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
28
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
29
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
29
import org.eclipse.mylyn.tasks.core.AbstractTask;
30
import org.eclipse.mylyn.tasks.core.AbstractTask;
30
import org.eclipse.mylyn.tasks.core.AbstractTask;
31
import org.eclipse.mylyn.tasks.core.TaskCategory;
31
import org.eclipse.mylyn.tasks.core.TaskCategory;
32
import org.eclipse.mylyn.tasks.core.TaskRepository;
32
import org.eclipse.mylyn.tasks.core.TaskRepository;
33
import org.eclipse.mylyn.tasks.ui.RepositorySynchronizationManager;
33
import org.eclipse.mylyn.tasks.ui.TasksUiPlugin;
34
import org.eclipse.mylyn.tasks.ui.TasksUiPlugin;
34
import org.eclipse.ui.IActionBars;
35
import org.eclipse.ui.IActionBars;
35
import org.eclipse.ui.IViewActionDelegate;
36
import org.eclipse.ui.IViewActionDelegate;
Lines 69-79 Link Here
69
				} else if (obj instanceof TaskCategory) {
70
				} else if (obj instanceof TaskCategory) {
70
					TaskCategory cat = (TaskCategory) obj;
71
					TaskCategory cat = (TaskCategory) obj;
71
					for (AbstractTask task : cat.getChildren()) {
72
					for (AbstractTask task : cat.getChildren()) {
72
						if (task instanceof AbstractTask) {
73
						AbstractRepositoryConnector client = TasksUiPlugin.getRepositoryManager()
73
							AbstractRepositoryConnector client = TasksUiPlugin.getRepositoryManager()
74
								.getRepositoryConnector(((AbstractTask) task).getRepositoryKind());
74
									.getRepositoryConnector(((AbstractTask) task).getRepositoryKind());
75
						addTaskToSync(client, (AbstractTask) task);
75
							addTaskToSync(client, (AbstractTask) task);
76
						}
77
					}
76
					}
78
				} else if (obj instanceof AbstractTask) {
77
				} else if (obj instanceof AbstractTask) {
79
					AbstractTask repositoryTask = (AbstractTask) obj;
78
					AbstractTask repositoryTask = (AbstractTask) obj;
Lines 83-123 Link Here
83
				}
82
				}
84
			}
83
			}
85
84
85
			RepositorySynchronizationManager syncManager = TasksUiPlugin.getSynchronizationManager();
86
			if (!queriesToSyncMap.isEmpty()) {
86
			if (!queriesToSyncMap.isEmpty()) {
87
				
87
				
88
				// determine which repositories to synch changed tasks for
88
				// determine which repositories to synch changed tasks for
89
				HashMap<String, Set<TaskRepository>> repositoriesToSync = new HashMap<String, Set<TaskRepository>>();
89
				HashMap<TaskRepository, Set<AbstractRepositoryQuery>> repositoriesToSync = new HashMap<TaskRepository, Set<AbstractRepositoryQuery>>();
90
				for (AbstractRepositoryConnector connector : queriesToSyncMap.keySet()) {
90
				for (AbstractRepositoryConnector connector : queriesToSyncMap.keySet()) {
91
					List<AbstractRepositoryQuery> queriesToSync = queriesToSyncMap.get(connector);
91
					List<AbstractRepositoryQuery> queriesToSync = queriesToSyncMap.get(connector);
92
					if(queriesToSync==null || queriesToSync.isEmpty()) {
93
						continue;
94
					}
95
					
92
					for (AbstractRepositoryQuery query : queriesToSync) {
96
					for (AbstractRepositoryQuery query : queriesToSync) {
93
						TaskRepository repos = TasksUiPlugin.getRepositoryManager().getRepository(query.getRepositoryKind(), query.getRepositoryUrl());
97
						TaskRepository repos = TasksUiPlugin.getRepositoryManager().getRepository(query.getRepositoryKind(), query.getRepositoryUrl());
94
						Set<TaskRepository> repositories = repositoriesToSync.get(connector.getRepositoryType());
98
						Set<AbstractRepositoryQuery> queries = repositoriesToSync.get(repos);
95
						if(repositories == null) {
99
						if(queries == null) {
96
							repositories = new HashSet<TaskRepository>();
100
							queries = new HashSet<AbstractRepositoryQuery>();
97
							repositoriesToSync.put(connector.getRepositoryType(), repositories);
101
							repositoriesToSync.put(repos, queries);
98
						}
102
						}
99
						repositories.add(repos);
103
						queries.add(query);
100
					}
104
					}
101
				}
105
				}
102
				
106
				
103
				// synch the queries followed by the repositories
107
				for (Map.Entry<TaskRepository, Set<AbstractRepositoryQuery>> e : repositoriesToSync.entrySet()) {
104
				for (AbstractRepositoryConnector connector : queriesToSyncMap.keySet()) {
108
					TaskRepository repository = e.getKey();
105
					List<AbstractRepositoryQuery> queriesToSync = queriesToSyncMap.get(connector);
109
106
					if (queriesToSync != null && queriesToSync.size() > 0) {
110
					AbstractRepositoryConnector connector = TasksUiPlugin.getRepositoryManager()
107
						TasksUiPlugin.getSynchronizationManager().synchronize(connector, new HashSet<AbstractRepositoryQuery>(queriesToSync), null, Job.LONG, 0,
111
							.getRepositoryConnector(repository.getKind());
108
								false, true);
112
109
					}
113
					Set<AbstractTask> changed = syncManager.synchronizeChanged(connector, repository,
110
					//XXX enable?
114
							new NullProgressMonitor());
111
//					for (TaskRepository taskRepository : repositoriesToSync.get(connector.getRepositoryType())) {
115
112
//						TasksUiPlugin.getSynchronizationManager().synchronizeChanged(connector, taskRepository);
116
					if (changed != null) {
113
//					}
117
						Set<AbstractRepositoryQuery> queries = e.getValue();
114
				}				
118
						syncManager.synchronize(connector, new HashSet<AbstractRepositoryQuery>(queries), null,
119
								Job.LONG, 0L, true, changed);
120
					}
121
				}
115
			}
122
			}
116
			if (!tasksToSyncMap.isEmpty()) {
123
			if (!tasksToSyncMap.isEmpty()) {
117
				for (AbstractRepositoryConnector connector : tasksToSyncMap.keySet()) {
124
				for (AbstractRepositoryConnector connector : tasksToSyncMap.keySet()) {
118
					List<AbstractTask> tasksToSync = tasksToSyncMap.get(connector);
125
					List<AbstractTask> tasksToSync = tasksToSyncMap.get(connector);
119
					if (tasksToSync != null && tasksToSync.size() > 0) {
126
					if (tasksToSync != null && tasksToSync.size() > 0) {
120
						TasksUiPlugin.getSynchronizationManager().synchronize(connector, new HashSet<AbstractTask>(tasksToSync), true, null);
127
						syncManager.synchronize(connector, new HashSet<AbstractTask>(tasksToSync), true, null);
121
					}
128
					}
122
				}
129
				}
123
			}
130
			}
(-)src/org/eclipse/mylyn/tasks/ui/SynchronizeQueryJob.java (-21 / +35 lines)
Lines 28-35 Link Here
28
import org.eclipse.mylyn.tasks.core.AbstractTask;
28
import org.eclipse.mylyn.tasks.core.AbstractTask;
29
import org.eclipse.mylyn.tasks.core.QueryHitCollector;
29
import org.eclipse.mylyn.tasks.core.QueryHitCollector;
30
import org.eclipse.mylyn.tasks.core.RepositoryStatus;
30
import org.eclipse.mylyn.tasks.core.RepositoryStatus;
31
import org.eclipse.mylyn.tasks.core.getAllCategories;
32
import org.eclipse.mylyn.tasks.core.TaskRepository;
31
import org.eclipse.mylyn.tasks.core.TaskRepository;
32
import org.eclipse.mylyn.tasks.core.getAllCategories;
33
import org.eclipse.ui.PlatformUI;
33
import org.eclipse.ui.PlatformUI;
34
import org.eclipse.ui.progress.IProgressConstants;
34
import org.eclipse.ui.progress.IProgressConstants;
35
35
Lines 39-74 Link Here
39
 */
39
 */
40
class SynchronizeQueryJob extends Job {
40
class SynchronizeQueryJob extends Job {
41
41
42
	private final AbstractRepositoryConnector connector;
43
44
	private static final String JOB_LABEL = "Synchronizing queries";
42
	private static final String JOB_LABEL = "Synchronizing queries";
43
	
44
	private final AbstractRepositoryConnector connector;
45
45
46
	private Set<AbstractRepositoryQuery> queries;
46
	private final Set<AbstractRepositoryQuery> queries;
47
48
	private Set<TaskRepository> repositories;
49
50
	private boolean synchChangedTasks;
51
47
52
	private getAllCategories taskList;
48
	private final getAllCategories taskList;
53
49
54
// private RepositorySynchronizationManager synchronizationManager;
50
	private final Set<AbstractTask> changedTasks;
55
51
52
//	private final Set<TaskRepository> repositories;
53
	
54
//	private boolean synchChangedTasks;
55
	
56
	private boolean forced = false;
56
	private boolean forced = false;
57
57
58
58
	public SynchronizeQueryJob(RepositorySynchronizationManager synchronizationManager,
59
	public SynchronizeQueryJob(RepositorySynchronizationManager synchronizationManager,
59
			AbstractRepositoryConnector connector, Set<AbstractRepositoryQuery> queries, getAllCategories taskList) {
60
			AbstractRepositoryConnector connector, Set<AbstractRepositoryQuery> queries, getAllCategories taskList, Set<AbstractTask> changedTasks) {
60
		super(JOB_LABEL + ": " + connector.getRepositoryType());
61
		super(JOB_LABEL + ": " + connector.getRepositoryType());
61
		this.connector = connector;
62
		this.connector = connector;
62
		this.queries = queries;
63
		this.queries = queries;
63
		this.taskList = taskList;
64
		this.taskList = taskList;
64
		this.repositories = new HashSet<TaskRepository>();
65
		this.changedTasks = changedTasks;
66
//		this.repositories = new HashSet<TaskRepository>();
65
		// TODO: remove once architecture established
67
		// TODO: remove once architecture established
66
		// this.synchronizationManager = synchronizationManager;
68
		// this.synchronizationManager = synchronizationManager;
67
	}
69
	}
68
70
69
	public void setSynchChangedTasks(boolean syncChangedTasks) {
71
//	public void setSynchChangedTasks(boolean syncChangedTasks) {
70
		this.synchChangedTasks = syncChangedTasks;
72
//		this.synchChangedTasks = syncChangedTasks;
71
	}
73
//	}
72
74
73
	/**
75
	/**
74
	 * Returns true, if synchronization was triggered manually and not by an
76
	 * Returns true, if synchronization was triggered manually and not by an
Lines 91-96 Link Here
91
	protected IStatus run(IProgressMonitor monitor) {
93
	protected IStatus run(IProgressMonitor monitor) {
92
		monitor.beginTask(JOB_LABEL, queries.size());
94
		monitor.beginTask(JOB_LABEL, queries.size());
93
95
96
		
97
		
94
		for (AbstractRepositoryQuery repositoryQuery : queries) {
98
		for (AbstractRepositoryQuery repositoryQuery : queries) {
95
			taskList.notifyContainerUpdated(repositoryQuery);
99
			taskList.notifyContainerUpdated(repositoryQuery);
96
			repositoryQuery.setStatus(null);
100
			repositoryQuery.setStatus(null);
Lines 107-112 Link Here
107
				QueryHitCollector collector = new QueryHitCollector(taskList, new TaskFactory(repository));
111
				QueryHitCollector collector = new QueryHitCollector(taskList, new TaskFactory(repository));
108
				SubProgressMonitor collectorMonitor = new SubProgressMonitor(monitor, 1);
112
				SubProgressMonitor collectorMonitor = new SubProgressMonitor(monitor, 1);
109
				collector.setProgressMonitor(collectorMonitor);
113
				collector.setProgressMonitor(collectorMonitor);
114
115
				// 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,
116
				final IStatus resultingStatus = connector.performQuery(repositoryQuery, repository, collectorMonitor,
111
						collector, forced);
117
						collector, forced);
112
118
Lines 120-132 Link Here
120
					}
126
					}
121
127
122
					repositoryQuery.clear();
128
					repositoryQuery.clear();
129
130
					HashSet<AbstractTask> hitsToBeSynchronized = new HashSet<AbstractTask>();
123
					for (AbstractTask hit : collector.getTaskHits()) {
131
					for (AbstractTask hit : collector.getTaskHits()) {
124
						taskList.addTask(hit, repositoryQuery);
132
						taskList.addTask(hit, repositoryQuery);
133
						if(changedTasks==null || !changedTasks.contains(hit)) {
134
							hitsToBeSynchronized.add(hit);
135
						}
125
					}
136
					}
126
137
127
					if (synchChangedTasks) {
138
					// XXX synchronize task data for hitsToBeSynchronized collection
128
						repositories.add(repository);
139
					
129
					}
140
					
141
//					if (synchChangedTasks) {
142
//						repositories.add(repository);
143
//					}
130
144
131
					repositoryQuery.setLastRefreshTimeStamp(DateUtil.getFormattedDate(new Date(), "MMM d, H:mm:ss"));
145
					repositoryQuery.setLastRefreshTimeStamp(DateUtil.getFormattedDate(new Date(), "MMM d, H:mm:ss"));
132
				} else {
146
				} else {
Lines 146-154 Link Here
146
			taskList.notifyContainerUpdated(repositoryQuery);
160
			taskList.notifyContainerUpdated(repositoryQuery);
147
		}
161
		}
148
162
149
		for (TaskRepository repository : repositories) {
163
//		for (TaskRepository repository : repositories) {
150
			TasksUiPlugin.getSynchronizationManager().synchronizeChanged(connector, repository);
164
//			TasksUiPlugin.getSynchronizationManager().synchronizeChanged(connector, repository);
151
		}
165
//		}
152
166
153
		// HACK: force entire Task List to refresh in case containers need to
167
		// HACK: force entire Task List to refresh in case containers need to
154
		// appear or disappear
168
		// 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.AbstractTask;
30
import org.eclipse.mylyn.tasks.core.AbstractTask;
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.getAllCategories;
34
import org.eclipse.mylyn.tasks.core.getAllCategories;
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<AbstractTask> changedTasks) {
114
		getAllCategories taskList = TasksUiPlugin.getTaskListManager().getTaskList();
113
		getAllCategories 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<AbstractTask> 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
			getAllCategories taskList = TasksUiPlugin.getTaskListManager().getTaskList();
167
			Set<AbstractTask> 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<AbstractTask> 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<AbstractTask> 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<AbstractTask> getChangedSinceLastSync(TaskRepository repository,
268
	public abstract Set<AbstractTask> getChangedSinceLastSync(TaskRepository repository,
265
			Set<AbstractTask> tasks, IProgressMonitor monitor) throws CoreException;
269
			Set<AbstractTask> 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<AbstractTask> getChangedSinceLastSync(TaskRepository repository,
65
	public Set<AbstractTask> getChangedSinceLastSync(TaskRepository repository,
67
			Set<AbstractTask> tasks, IProgressMonitor monitor) throws CoreException {
66
			Set<AbstractTask> 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<AbstractTask> getChangedSinceLastSync(TaskRepository repository,
227
	public Set<AbstractTask> getChangedSinceLastSync(TaskRepository repository,
228
			Set<AbstractTask> tasks, IProgressMonitor monitor) throws CoreException {
228
			Set<AbstractTask> tasks, IProgressMonitor monitor, QueryHitCollector collector) throws CoreException {
229
		try {
229
		try {
230
			Set<AbstractTask> changedTasks = new HashSet<AbstractTask>();
230
			Set<AbstractTask> changedTasks = new HashSet<AbstractTask>();
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<AbstractTask> itr = tasks.iterator();
251
			Iterator<AbstractTask> 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 (-32 / +29 lines)
Lines 46-52 Link Here
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.AbstractTask;
50
import org.eclipse.mylyn.tasks.core.ITaskDataHandler;
49
import org.eclipse.mylyn.tasks.core.ITaskDataHandler;
51
import org.eclipse.mylyn.tasks.core.QueryHitCollector;
50
import org.eclipse.mylyn.tasks.core.QueryHitCollector;
52
import org.eclipse.mylyn.tasks.core.RepositoryTaskAttribute;
51
import org.eclipse.mylyn.tasks.core.RepositoryTaskAttribute;
Lines 157-165 Link Here
157
		}
156
		}
158
	}
157
	}
159
158
159
	@Override
160
	public Set<AbstractTask> getChangedSinceLastSync(TaskRepository repository,
160
	public Set<AbstractTask> getChangedSinceLastSync(TaskRepository repository,
161
			Set<AbstractTask> tasks, IProgressMonitor monitor) throws CoreException {
161
			Set<AbstractTask> tasks, IProgressMonitor monitor, QueryHitCollector collector) throws CoreException {
162
163
		String dateString = repository.getSyncTimeStamp();
162
		String dateString = repository.getSyncTimeStamp();
164
		Date lastSyncDate = convertDate(dateString);
163
		Date lastSyncDate = convertDate(dateString);
165
		if (lastSyncDate == null) {
164
		if (lastSyncDate == null) {
Lines 187-229 Link Here
187
		FilterDefinition changedFilter = new FilterDefinition("Changed Tasks");
186
		FilterDefinition changedFilter = new FilterDefinition("Changed Tasks");
188
		changedFilter.setUpdatedDateFilter(new RelativeDateRangeFilter(RangeType.MINUTE, minutes));
187
		changedFilter.setUpdatedDateFilter(new RelativeDateRangeFilter(RangeType.MINUTE, minutes));
189
		changedFilter.setOrdering(new Order[] { new Order(Order.Field.UPDATED, false) });
188
		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
189
		// TODO: Need some way to further scope this query
197
190
191
		List<Issue> issues = new ArrayList<Issue>();
192
		JiraClient client = JiraClientFacade.getDefault().getJiraClient(repository);
193
		// unlimited maxHits can create crazy amounts of traffic
194
		JiraIssueCollector issueCollector = new JiraIssueCollector(new NullProgressMonitor(), issues, 500);
198
		try {
195
		try {
199
			// XXX: disabled work around
196
			client.search(changedFilter, issueCollector);
200
			// TODO: remove, added to re-open connection, bug 164543
197
			
201
			// jiraServer.getServerInfo();
198
			if(issues.isEmpty()) {
202
			// Will get ALL issues that have changed since lastSyncDate
199
				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<AbstractTask> changedTasks = new HashSet<AbstractTask>();
209
		for (Issue issue : issues) {
210
			// String handle =
211
			// AbstractTask.getHandle(repository.getUrl(),
212
			// issue.getId());
213
			AbstractTask task = TasksUiPlugin.getTaskListManager().getTaskList().getTask(repository.getUrl(), issue.getId());
214
			if (task instanceof AbstractTask) {
215
				changedTasks.add((AbstractTask) task);
216
			}
200
			}
217
201
218
			if (issue.getUpdated() != null && issue.getUpdated().after(lastSyncDate)) {
202
			for (Issue issue : issues) {
219
				lastSyncDate = issue.getUpdated();
203
				AbstractTask task = TasksUiPlugin.getTaskListManager().getTaskList().getTask(repository.getUrl(), issue.getId());
204
				if (!tasks.contains(task)) {
205
					continue;
206
				}
207
				
208
				RepositoryTaskData taskData = offlineHandler.createTaskData(repository, client, issue);
209
				collector.accept(taskData);
210
				
211
				if (issue.getUpdated() != null && issue.getUpdated().after(lastSyncDate)) {
212
					lastSyncDate = issue.getUpdated();
213
				}
220
			}
214
			}
221
		}
222
215
223
		repository.setSyncTimeStamp( // 
216
			repository.setSyncTimeStamp( // 
224
				new SimpleDateFormat(JiraAttributeFactory.JIRA_DATE_FORMAT, Locale.US).format(lastSyncDate));
217
					new SimpleDateFormat(JiraAttributeFactory.JIRA_DATE_FORMAT, Locale.US).format(lastSyncDate));
218
			
219
			return Collections.emptySet();  // no need to synchronize anything
225
220
226
		return changedTasks;
221
		} catch (JiraException e) {
222
			throw new CoreException(JiraCorePlugin.toStatus(repository, e));
223
		}
227
	}
224
	}
228
225
229
	private Date convertDate(String dateString) {
226
	private Date convertDate(String dateString) {

Return to bug 191575