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 207498 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/mylyn/tasks/tests/TaskRepositoryTest.java (+16 lines)
Lines 9-14 Link Here
9
package org.eclipse.mylyn.tasks.tests;
9
package org.eclipse.mylyn.tasks.tests;
10
10
11
import java.net.URL;
11
import java.net.URL;
12
import java.util.Date;
12
import java.util.Map;
13
import java.util.Map;
13
14
14
import junit.framework.TestCase;
15
import junit.framework.TestCase;
Lines 117-120 Link Here
117
		assertEquals("pwd2", credentials.getPassword());
118
		assertEquals("pwd2", credentials.getPassword());
118
	}
119
	}
119
120
121
	public void testConfigUpdateStoring() throws Exception {
122
		URL url = new URL("http://url");
123
		TaskRepository taskRepository = new TaskRepository("kind", url.toString());
124
125
		Date stamp = taskRepository.getConfigurationDate();
126
		assertTrue("unset stap returns long ago", stamp.before(new Date()));
127
128
		stamp = taskRepository.updateConfigurationDate();
129
		assertEquals("Time stamp touched", stamp.getTime(),  taskRepository.getConfigurationDate().getTime());
130
131
		stamp.setTime(stamp.getTime() - 1000000L);
132
		taskRepository.setConfigurationDate(stamp);
133
		assertEquals("Time stamp set", stamp.getTime(), taskRepository.getConfigurationDate().getTime());
134
	}
135
120
}
136
}
(-)src/org/eclipse/mylyn/internal/tasks/ui/ScheduledTaskListSynchJob.java (-34 / +50 lines)
Lines 8-23 Link Here
8
8
9
package org.eclipse.mylyn.internal.tasks.ui;
9
package org.eclipse.mylyn.internal.tasks.ui;
10
10
11
import java.util.Calendar;
12
import java.util.List;
11
import java.util.List;
13
import java.util.Set;
12
import java.util.Set;
14
13
14
import org.eclipse.core.runtime.CoreException;
15
import org.eclipse.core.runtime.IProgressMonitor;
15
import org.eclipse.core.runtime.IProgressMonitor;
16
import org.eclipse.core.runtime.IStatus;
16
import org.eclipse.core.runtime.IStatus;
17
import org.eclipse.core.runtime.OperationCanceledException;
17
import org.eclipse.core.runtime.OperationCanceledException;
18
import org.eclipse.core.runtime.Platform;
18
import org.eclipse.core.runtime.Status;
19
import org.eclipse.core.runtime.Status;
19
import org.eclipse.core.runtime.SubProgressMonitor;
20
import org.eclipse.core.runtime.SubProgressMonitor;
20
import org.eclipse.core.runtime.jobs.Job;
21
import org.eclipse.core.runtime.jobs.Job;
22
import org.eclipse.mylyn.monitor.core.StatusHandler;
21
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
23
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
22
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
24
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
23
import org.eclipse.mylyn.tasks.core.TaskList;
25
import org.eclipse.mylyn.tasks.core.TaskList;
Lines 28-37 Link Here
28
30
29
/**
31
/**
30
 * @author Rob Elves
32
 * @author Rob Elves
31
 * 
33
 *
32
 * API-3.0 rename to TaskRepositorySynchronizationJob (?)
34
 * API-3.0 rename to TaskRepositorySynchronizationJob (?)
33
 */
35
 */
34
public class ScheduledTaskListSynchJob extends Job {
36
public class ScheduledTaskListSynchJob extends Job {
37
	static private boolean DEBUGCONFIGUPDATE = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.mylyn.tasks.ui/debug/config-update"));
38
35
39
36
	private static final int UPDATE_ATTRIBUTES_FREQUENCY = 10;
40
	private static final int UPDATE_ATTRIBUTES_FREQUENCY = 10;
37
41
Lines 43-52 Link Here
43
47
44
	private TaskList taskList = null;
48
	private TaskList taskList = null;
45
49
50
	/**
51
	 * for testing ONLY!
52
	 */
46
	private static long count = 0;
53
	private static long count = 0;
47
54
48
	private static Calendar lastRepositoryRefresh;
49
50
	private TaskListManager taskListManager;
55
	private TaskListManager taskListManager;
51
56
52
	private List<TaskRepository> repositories = null;
57
	private List<TaskRepository> repositories = null;
Lines 112-142 Link Here
112
				Set<AbstractRepositoryQuery> queries = taskList.getRepositoryQueries(repository.getUrl());
117
				Set<AbstractRepositoryQuery> queries = taskList.getRepositoryQueries(repository.getUrl());
113
118
114
				// Occasionally request update of repository configuration attributes
119
				// Occasionally request update of repository configuration attributes
115
				if ((lastRepositoryRefresh == null || lastRepositoryRefresh.get(Calendar.DAY_OF_MONTH) != Calendar.getInstance()
120
				try {
116
						.get(Calendar.DAY_OF_MONTH))
121
					if (queries != null && queries.size() > 0 && connector.isRepositoryConfigurationStale(repository)) {
117
						&& queries != null && queries.size() > 0) {
122
						updateConfigurationWithJob(repository, connector);
118
					Job updateJob = new Job("Updating attributes for " + repository.getUrl()) {
123
						if(DEBUGCONFIGUPDATE) System.out.println("Performing Scheduled config update for: " + repository.toString());
119
124
					}
120
						@Override
125
				} catch (CoreException e) {
121
						protected IStatus run(IProgressMonitor monitor) {
126
					StatusHandler.fail(e, "Error retrieving configuration status for " + repository.getUrl(), false);
122
							try {
123
								if (connector.isRepositoryConfigurationStale(repository)) {
124
									connector.updateAttributes(repository, new SubProgressMonitor(monitor, 1));
125
									// HACK: A configuration update occurred. Save on behalf of connector which 
126
									// currently can't access the repository manager itself
127
									TasksUiPlugin.getRepositoryManager().saveRepositories(
128
											TasksUiPlugin.getDefault().getRepositoriesFilePath());
129
								}
130
							} catch (Exception e) {
131
								// ignore, since we might not be connected
132
							}
133
							return Status.OK_STATUS;
134
						}
135
					};
136
					//updateJob.setSystem(true);
137
					updateJob.setPriority(Job.LONG);
138
					updateJob.schedule();
139
					lastRepositoryRefresh = null;
140
				}
127
				}
141
128
142
				synchronizationManager.synchronize(connector, repository, queries, null, Job.DECORATE, 0, false,
129
				synchronizationManager.synchronize(connector, repository, queries, null, Job.DECORATE, 0, false,
Lines 146-154 Link Here
146
			}
133
			}
147
		} finally {
134
		} finally {
148
			count = count >= UPDATE_ATTRIBUTES_FREQUENCY ? 0 : count + 1;
135
			count = count >= UPDATE_ATTRIBUTES_FREQUENCY ? 0 : count + 1;
149
			if (lastRepositoryRefresh == null) {
150
				lastRepositoryRefresh = Calendar.getInstance();
151
			}
152
			if (monitor != null) {
136
			if (monitor != null) {
153
				monitor.done();
137
				monitor.done();
154
			}
138
			}
Lines 156-161 Link Here
156
		return Status.OK_STATUS;
140
		return Status.OK_STATUS;
157
	}
141
	}
158
142
143
	/**
144
	 * Update the configuration file for the repository.
145
	 *
146
	 * @param repository
147
	 * @param connector
148
	 */
149
	private void updateConfigurationWithJob(final TaskRepository repository, final AbstractRepositoryConnector connector) {
150
		Job updateJob = new Job("Updating attributes for " + repository.getUrl()) {
151
152
			@Override
153
			protected IStatus run(IProgressMonitor monitor) {
154
				try {
155
					connector.updateAttributes(repository, new SubProgressMonitor(monitor, 1));
156
					// HACK: A configuration update occurred. Save on behalf of connector which
157
					// currently can't access the repository manager itself
158
					repository.updateConfigurationDate();
159
					TasksUiPlugin.getRepositoryManager().saveRepositories(
160
							// ignore, since we might not be connected
161
							TasksUiPlugin.getDefault().getRepositoriesFilePath());
162
				} catch (Exception e) {
163
					// ignore, since we might not be connected
164
				}
165
				return Status.OK_STATUS;
166
			}
167
		};
168
		//updateJob.setSystem(true);
169
		updateJob.setPriority(Job.LONG);
170
		updateJob.schedule();
171
	}
172
159
	public void setSchedule(long schedule) {
173
	public void setSchedule(long schedule) {
160
		this.scheduleDelay = schedule;
174
		this.scheduleDelay = schedule;
161
	}
175
	}
Lines 165-177 Link Here
165
	}
179
	}
166
180
167
	/**
181
	/**
168
	 * for testing purposes
182
	 * for testing purposes ONLY!
169
	 */
183
	 */
170
	public static long getCount() {
184
	public static long getCount() {
171
		return count;
185
		return count;
172
	}
186
	}
173
187
174
	/** for testing */
188
	/**
189
	 * for testing purposes ONLY!
190
	 */
175
	public static void resetCount() {
191
	public static void resetCount() {
176
		try {
192
		try {
177
			if (TasksUiPlugin.getSynchronizationScheduler().getRefreshJob() != null) {
193
			if (TasksUiPlugin.getSynchronizationScheduler().getRefreshJob() != null) {
(-).options (-1 / +4 lines)
Line 1 Link Here
1
org.eclipse.mylyn.tasks.ui/debug/httpclient=true
1
org.eclipse.mylyn.tasks.ui/debug/httpclient=true
2
org.eclipse.mylyn.tasks.ui/debug/gzip-get=true
3
org.eclipse.mylyn.tasks.ui/debug/gzip-post=true
4
org.eclipse.mylyn.tasks.ui/debug/config-update=true
(-)src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaRepositoryConnector.java (-16 / +25 lines)
Lines 464-488 Link Here
464
		}
464
		}
465
	}
465
	}
466
466
467
	/**
468
	 *	BugzillaReplositoryConnector also tests the configuration date on the server using a HEAD request and Last-Modified header.
469
	 * 	@param repository
470
	 * 	@throws CoreException
471
	 *  @return true when the configuration needs updating
472
	 */
473
	@Override
467
	public boolean isRepositoryConfigurationStale(TaskRepository repository) throws CoreException {
474
	public boolean isRepositoryConfigurationStale(TaskRepository repository) throws CoreException {
468
475
		if (super.isRepositoryConfigurationStale(repository)) {
469
		boolean result = true;
476
			boolean result = true;
470
		try {
477
			try {
471
			BugzillaClient client = getClientManager().getClient(repository);
478
				BugzillaClient client = getClientManager().getClient(repository);
472
			if (client != null) {
479
				if (client != null) {
473
				String timestamp = client.getConfigurationTimestamp();
480
					String timestamp = client.getConfigurationTimestamp();
474
				if (timestamp != null) {
481
					if (timestamp != null) {
475
					String oldTimestamp = repository.getProperty(IBugzillaConstants.PROPERTY_CONFIGTIMESTAMP);
482
						String oldTimestamp = repository.getProperty(IBugzillaConstants.PROPERTY_CONFIGTIMESTAMP);
476
					if (oldTimestamp != null) {
483
						if (oldTimestamp != null) {
477
						result = !timestamp.equals(oldTimestamp);
484
							result = !timestamp.equals(oldTimestamp);
485
						}
486
						repository.setProperty(IBugzillaConstants.PROPERTY_CONFIGTIMESTAMP, timestamp);
478
					}
487
					}
479
					repository.setProperty(IBugzillaConstants.PROPERTY_CONFIGTIMESTAMP, timestamp);
480
				}
488
				}
489
			} catch (MalformedURLException e) {
490
				StatusHandler.fail(e, "Error retrieving configuration timestamp for " + repository.getUrl(), false);
481
			}
491
			}
482
		} catch (MalformedURLException e) {
492
			return result;
483
			StatusHandler.fail(e, "Error retrieving configuration timestamp for " + repository.getUrl(), false);
484
		}
493
		}
485
		return result;
494
		return false;
486
	}
495
	}
487
496
488
	public void updateAttributeOptions(TaskRepository taskRepository, RepositoryTaskData existingReport)
497
	public void updateAttributeOptions(TaskRepository taskRepository, RepositoryTaskData existingReport)
Lines 522-533 Link Here
522
531
523
	/**
532
	/**
524
	 * Adds bug attributes to new bug model and sets defaults
533
	 * Adds bug attributes to new bug model and sets defaults
525
	 * 
534
	 *
526
	 * @param proxySettings
535
	 * @param proxySettings
527
	 *            TODO
536
	 *            TODO
528
	 * @param characterEncoding
537
	 * @param characterEncoding
529
	 *            TODO
538
	 *            TODO
530
	 * 
539
	 *
531
	 */
540
	 */
532
	public static void setupNewBugAttributes(TaskRepository taskRepository, RepositoryTaskData newTaskData)
541
	public static void setupNewBugAttributes(TaskRepository taskRepository, RepositoryTaskData newTaskData)
533
			throws CoreException {
542
			throws CoreException {
(-)src/org/eclipse/mylyn/tasks/core/TaskRepository.java (-17 / +72 lines)
Lines 11-16 Link Here
11
import java.net.MalformedURLException;
11
import java.net.MalformedURLException;
12
import java.net.Proxy;
12
import java.net.Proxy;
13
import java.net.URL;
13
import java.net.URL;
14
import java.util.Date;
14
import java.util.HashMap;
15
import java.util.HashMap;
15
import java.util.LinkedHashMap;
16
import java.util.LinkedHashMap;
16
import java.util.Map;
17
import java.util.Map;
Lines 20-25 Link Here
20
import org.eclipse.core.runtime.Platform;
21
import org.eclipse.core.runtime.Platform;
21
import org.eclipse.core.runtime.PlatformObject;
22
import org.eclipse.core.runtime.PlatformObject;
22
import org.eclipse.mylyn.internal.tasks.core.IRepositoryConstants;
23
import org.eclipse.mylyn.internal.tasks.core.IRepositoryConstants;
24
import org.eclipse.mylyn.internal.tasks.core.TaskActivityUtil;
23
import org.eclipse.mylyn.monitor.core.StatusHandler;
25
import org.eclipse.mylyn.monitor.core.StatusHandler;
24
import org.eclipse.mylyn.web.core.WebClientUtil;
26
import org.eclipse.mylyn.web.core.WebClientUtil;
25
import org.eclipse.mylyn.web.core.WebCredentials;
27
import org.eclipse.mylyn.web.core.WebCredentials;
Lines 36-42 Link Here
36
 * <li>The solution we have come up with thus far is not to interpret the date as a DATE object but rather simply use
38
 * <li>The solution we have come up with thus far is not to interpret the date as a DATE object but rather simply use
37
 * the date string given to us by the repository itself.</li>
39
 * the date string given to us by the repository itself.</li>
38
 * </ul>
40
 * </ul>
39
 * 
41
 *
40
 * @author Mik Kersten
42
 * @author Mik Kersten
41
 * @author Rob Elves
43
 * @author Rob Elves
42
 * @author Eugene Kuleshov
44
 * @author Eugene Kuleshov
Lines 139-148 Link Here
139
	private Map<String, String> transientProperties = new HashMap<String, String>();
141
	private Map<String, String> transientProperties = new HashMap<String, String>();
140
142
141
	/*
143
	/*
142
	 * TODO: should be externalized and added to extension point, see bug 183606 
144
	 * TODO: should be externalized and added to extension point, see bug 183606
143
	 */
145
	 */
144
	private boolean isBugRepository = false;
146
	private boolean isBugRepository = false;
145
147
148
	public static final String LAST_CONFIG_REFRESH = "config.lastupdate";
149
150
	private static final long LONG_AGO = 1000L * 3600L * 48L; // 48 hrs ago
151
146
	/**
152
	/**
147
	 * for testing purposes
153
	 * for testing purposes
148
	 */
154
	 */
Lines 194-200 Link Here
194
200
195
	/**
201
	/**
196
	 * <b>Note: </b> This method will be deprecated in 2.3.
202
	 * <b>Note: </b> This method will be deprecated in 2.3.
197
	 * 
203
	 *
198
	 * @see #getCredentials(Type)
204
	 * @see #getCredentials(Type)
199
	 */
205
	 */
200
	public boolean hasCredentials() {
206
	public boolean hasCredentials() {
Lines 221-227 Link Here
221
227
222
	/**
228
	/**
223
	 * <b>Note: </b> This method will be deprecated in 2.3.
229
	 * <b>Note: </b> This method will be deprecated in 2.3.
224
	 * 
230
	 *
225
	 * @see #getCredentials(Type)
231
	 * @see #getCredentials(Type)
226
	 */
232
	 */
227
	public String getProxyUsername() {
233
	public String getProxyUsername() {
Lines 230-236 Link Here
230
236
231
	/**
237
	/**
232
	 * <b>Note: </b> This method will be deprecated in 2.3.
238
	 * <b>Note: </b> This method will be deprecated in 2.3.
233
	 * 
239
	 *
234
	 * @see #getCredentials(Type)
240
	 * @see #getCredentials(Type)
235
	 */
241
	 */
236
	public String getProxyPassword() {
242
	public String getProxyPassword() {
Lines 239-245 Link Here
239
245
240
	/**
246
	/**
241
	 * <b>Note: </b> This method will be deprecated in 2.3.
247
	 * <b>Note: </b> This method will be deprecated in 2.3.
242
	 * 
248
	 *
243
	 * @see #getCredentials(Type)
249
	 * @see #getCredentials(Type)
244
	 */
250
	 */
245
	public String getHttpUser() {
251
	public String getHttpUser() {
Lines 248-254 Link Here
248
254
249
	/**
255
	/**
250
	 * <b>Note: </b> This method will be deprecated in 2.3.
256
	 * <b>Note: </b> This method will be deprecated in 2.3.
251
	 * 
257
	 *
252
	 * @see #getCredentials(Type)
258
	 * @see #getCredentials(Type)
253
	 */
259
	 */
254
	public String getHttpPassword() {
260
	public String getHttpPassword() {
Lines 257-263 Link Here
257
263
258
	/**
264
	/**
259
	 * <b>Note: </b> This method will be deprecated in 2.3.
265
	 * <b>Note: </b> This method will be deprecated in 2.3.
260
	 * 
266
	 *
261
	 * @see #setCredentials(Type, WebCredentials, boolean)
267
	 * @see #setCredentials(Type, WebCredentials, boolean)
262
	 */
268
	 */
263
	public void setAuthenticationCredentials(String username, String password) {
269
	public void setAuthenticationCredentials(String username, String password) {
Lines 266-272 Link Here
266
272
267
	/**
273
	/**
268
	 * <b>Note: </b> This method will be deprecated in 2.3.
274
	 * <b>Note: </b> This method will be deprecated in 2.3.
269
	 * 
275
	 *
270
	 * @see #setCredentials(Type, WebCredentials, boolean)
276
	 * @see #setCredentials(Type, WebCredentials, boolean)
271
	 */
277
	 */
272
	public void setProxyAuthenticationCredentials(String username, String password) {
278
	public void setProxyAuthenticationCredentials(String username, String password) {
Lines 275-281 Link Here
275
281
276
	/**
282
	/**
277
	 * <b>Note: </b> This method will be deprecated in 2.3.
283
	 * <b>Note: </b> This method will be deprecated in 2.3.
278
	 * 
284
	 *
279
	 * @see #setCredentials(Type, WebCredentials, boolean)
285
	 * @see #setCredentials(Type, WebCredentials, boolean)
280
	 */
286
	 */
281
	public void setHttpAuthenticationCredentials(String username, String password) {
287
	public void setHttpAuthenticationCredentials(String username, String password) {
Lines 300-306 Link Here
300
	public void flushAuthenticationCredentials() {
306
	public void flushAuthenticationCredentials() {
301
		synchronized (LOCK) {
307
		synchronized (LOCK) {
302
			isCachedUserName = false;
308
			isCachedUserName = false;
303
		
309
304
			transientProperties.clear();
310
			transientProperties.clear();
305
311
306
			// API30: legacy support for versions prior to 2.2 that did not set the enable flag, remove for 3.0
312
			// API30: legacy support for versions prior to 2.2 that did not set the enable flag, remove for 3.0
Lines 533-539 Link Here
533
539
534
	/**
540
	/**
535
	 * <b>Note: </b> This method will be deprecated in 2.3.
541
	 * <b>Note: </b> This method will be deprecated in 2.3.
536
	 * 
542
	 *
537
	 * @see #setCredentials(Type, WebCredentials, boolean)
543
	 * @see #setCredentials(Type, WebCredentials, boolean)
538
	 */
544
	 */
539
	public void setAnonymous(boolean b) {
545
	public void setAnonymous(boolean b) {
Lines 542-548 Link Here
542
548
543
	/**
549
	/**
544
	 * <b>Note: </b> This method will be deprecated in 2.3.
550
	 * <b>Note: </b> This method will be deprecated in 2.3.
545
	 * 
551
	 *
546
	 * @see #getCredentials(Type)
552
	 * @see #getCredentials(Type)
547
	 */
553
	 */
548
	public boolean isAnonymous() {
554
	public boolean isAnonymous() {
Lines 571-577 Link Here
571
	public boolean getSavePassword(Type authType) {
577
	public boolean getSavePassword(Type authType) {
572
		String value = getProperty(getKeyPrefix(authType) + SAVE_PASSWORD);
578
		String value = getProperty(getKeyPrefix(authType) + SAVE_PASSWORD);
573
		return value != null && "true".equals(value);
579
		return value != null && "true".equals(value);
574
	}
580
		}
575
581
576
	private static String getKeyPrefix(Type type) {
582
	private static String getKeyPrefix(Type type) {
577
		switch (type) {
583
		switch (type) {
Lines 587-593 Link Here
587
593
588
	/**
594
	/**
589
	 * Returns the credentials for an authentication type.
595
	 * Returns the credentials for an authentication type.
590
	 * 
596
	 *
591
	 * @param authType
597
	 * @param authType
592
	 *            the type of authentication
598
	 *            the type of authentication
593
	 * @return null, if no credentials are set for <code>authType</code>
599
	 * @return null, if no credentials are set for <code>authType</code>
Lines 628-634 Link Here
628
634
629
	/**
635
	/**
630
	 * Sets the credentials for <code>authType</code>.
636
	 * Sets the credentials for <code>authType</code>.
631
	 * 
637
	 *
632
	 * @param authType
638
	 * @param authType
633
	 *            the type of authentication
639
	 *            the type of authentication
634
	 * @param credentials
640
	 * @param credentials
Lines 688-694 Link Here
688
	private String getUserName(WebCredentials.Type authType) {
694
	private String getUserName(WebCredentials.Type authType) {
689
		WebCredentials credentials = getCredentials(authType);
695
		WebCredentials credentials = getCredentials(authType);
690
		return (credentials != null) ? credentials.getUserName() : null;
696
		return (credentials != null) ? credentials.getUserName() : null;
691
	}
697
		}
698
692
699
693
	/**
700
	/**
694
	 * Legacy support for < 2.2. Remove in 2.3.
701
	 * Legacy support for < 2.2. Remove in 2.3.
Lines 698-701 Link Here
698
		return (credentials != null) ? credentials.getPassword() : null;
705
		return (credentials != null) ? credentials.getPassword() : null;
699
	}
706
	}
700
707
708
709
	/**
710
	 *	Get the last <em>successful</em> refresh date as initialized {@link Date} object.<br />
711
	 *  Internal representation is {@link String} determined by {@link TaskActivityUtil}.<br />
712
	 *	See <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=207660">bug
713
	 *  207660: do not update repository configuration on every startup</a>
714
	 * @return {@link Date} set to last config update OR LONG_AGO if not found
715
	 *
716
	 * @since 2.2
717
	 */
718
	final public Date getConfigurationDate() {
719
		String value = this.getProperty(LAST_CONFIG_REFRESH);
720
		Date stamp = null;
721
		if(null != value) {
722
			stamp = TaskActivityUtil.stringToDate(value);
723
		} else {
724
			stamp = new Date((new Date()).getTime() - LONG_AGO);
725
		}
726
		return stamp;
727
	}
728
729
	/**
730
	 * Utility method, set the Configuration Timestamp to now AND return it. Use to set
731
	 * date when <em>successful</em> update occurred.
732
	 *
733
	 * @since 2.2
734
	 */
735
	final public Date updateConfigurationDate() {
736
		Date now = new Date();
737
		this.setConfigurationDate(now);
738
		return now;
739
	}
740
741
	/**
742
	 * set the Configuration Timestamp to the {@link Date} indicated after a succesful update.
743
	 *
744
	 * 	The last <em>successful</em> configuration update day is persisted as {@link String} determined in {@link TaskActivityUtil}.<br />
745
	 *	See <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=207660">bug
746
	 *	207660: do not update repository configuration on every startup</a>
747
	 * @param {@link Date} setting the day
748
	 *
749
	 * @since 2.2
750
	 */
751
	final public void setConfigurationDate(final Date timeStamp) {
752
		this.setProperty(LAST_CONFIG_REFRESH, TaskActivityUtil.dateToString(timeStamp));
753
		//  should persist here, but that can only be done by the TaskRepositoryManager
754
		// However this is also included when persisting ordinary sync time
755
	}
701
}
756
}
(-)src/org/eclipse/mylyn/tasks/core/AbstractRepositoryConnector.java (-15 / +37 lines)
Lines 24-30 Link Here
24
/**
24
/**
25
 * Encapsulates common operations that can be performed on a task repository. Extend to connect with a Java API or WS
25
 * Encapsulates common operations that can be performed on a task repository. Extend to connect with a Java API or WS
26
 * API for accessing the repository.
26
 * API for accessing the repository.
27
 * 
27
 *
28
 * @author Mik Kersten
28
 * @author Mik Kersten
29
 * @author Rob Elves
29
 * @author Rob Elves
30
 * @since 2.0
30
 * @since 2.0
Lines 33-38 Link Here
33
33
34
	protected Set<RepositoryTemplate> templates = new LinkedHashSet<RepositoryTemplate>();
34
	protected Set<RepositoryTemplate> templates = new LinkedHashSet<RepositoryTemplate>();
35
35
36
	private static final long HOUR = 1000L * 3600L;
37
38
	private static final long DAY = HOUR * 24L;
39
36
	protected TaskList taskList;
40
	protected TaskList taskList;
37
41
38
	private boolean userManaged = true;
42
	private boolean userManaged = true;
Lines 148-161 Link Here
148
152
149
	/**
153
	/**
150
	 * Utility method for construction of connector specific task object TODO: Move to 'task' factory
154
	 * Utility method for construction of connector specific task object TODO: Move to 'task' factory
151
	 * 
155
	 *
152
	 * @return instance of AbstractTask
156
	 * @return instance of AbstractTask
153
	 */
157
	 */
154
	public abstract AbstractTask createTask(String repositoryUrl, String id, String summary);
158
	public abstract AbstractTask createTask(String repositoryUrl, String id, String summary);
155
159
156
	/**
160
	/**
157
	 * Implementors must execute query synchronously.
161
	 * Implementors must execute query synchronously.
158
	 * 
162
	 *
159
	 * @param query
163
	 * @param query
160
	 * @param repository
164
	 * @param repository
161
	 *            TODO
165
	 *            TODO
Lines 180-189 Link Here
180
	 * Updates the properties of <code>repositoryTask</code>. Invoked when on task synchronization if
184
	 * Updates the properties of <code>repositoryTask</code>. Invoked when on task synchronization if
181
	 * {@link #getTaskDataHandler()} returns <code>null</code> or
185
	 * {@link #getTaskDataHandler()} returns <code>null</code> or
182
	 * {@link AbstractTaskDataHandler#getTaskData(TaskRepository, String)} returns <code>null</code>.
186
	 * {@link AbstractTaskDataHandler#getTaskData(TaskRepository, String)} returns <code>null</code>.
183
	 * 
187
	 *
184
	 * <p>
188
	 * <p>
185
	 * Connectors that provide {@link RepositoryTaskData} objects for all tasks do not need to implement this method.
189
	 * Connectors that provide {@link RepositoryTaskData} objects for all tasks do not need to implement this method.
186
	 * 
190
	 *
187
	 * @param repository
191
	 * @param repository
188
	 *            the repository
192
	 *            the repository
189
	 * @param repositoryTask
193
	 * @param repositoryTask
Lines 197-203 Link Here
197
201
198
	/**
202
	/**
199
	 * Updates task with latest information from {@code taskData}
203
	 * Updates task with latest information from {@code taskData}
200
	 * 
204
	 *
201
	 * @since 2.0
205
	 * @since 2.0
202
	 */
206
	 */
203
	public abstract void updateTaskFromTaskData(TaskRepository repository, AbstractTask repositoryTask,
207
	public abstract void updateTaskFromTaskData(TaskRepository repository, AbstractTask repositoryTask,
Lines 205-211 Link Here
205
209
206
	/**
210
	/**
207
	 * Updates <code>existingTask</code> with latest information from <code>queryHit</code>.
211
	 * Updates <code>existingTask</code> with latest information from <code>queryHit</code>.
208
	 * 
212
	 *
209
	 * @return true, if properties of <code>existingTask</code> were changed
213
	 * @return true, if properties of <code>existingTask</code> were changed
210
	 * @since 2.0
214
	 * @since 2.0
211
	 */
215
	 */
Lines 255-274 Link Here
255
	/**
259
	/**
256
	 * Of <code>tasks</code> provided, return all that have changed since last synchronization of
260
	 * Of <code>tasks</code> provided, return all that have changed since last synchronization of
257
	 * <code>repository</code>.
261
	 * <code>repository</code>.
258
	 * 
262
	 *
259
	 * Tasks that need to be synchronized (i.e. task data updated) should be passed to
263
	 * Tasks that need to be synchronized (i.e. task data updated) should be passed to
260
	 * <code>collector.accept(Task)</code> method, or if repository connector can update task data, it can use
264
	 * <code>collector.accept(Task)</code> method, or if repository connector can update task data, it can use
261
	 * <code>collector.accept(RepositoryTaskData)</code> call.
265
	 * <code>collector.accept(RepositoryTaskData)</code> call.
262
	 * 
266
	 *
263
	 * All errors should be thrown as <code>CoreException</code> for the framework to handle, since background
267
	 * All errors should be thrown as <code>CoreException</code> for the framework to handle, since background
264
	 * synchronizations fail silently when disconnected.
268
	 * synchronizations fail silently when disconnected.
265
	 * 
269
	 *
266
	 * @param tasks
270
	 * @param tasks
267
	 *            TODO
271
	 *            TODO
268
	 * 
272
	 *
269
	 * @return null if there was no tasks changed in the repository, otherwise collection of updated tasks (within
273
	 * @return null if there was no tasks changed in the repository, otherwise collection of updated tasks (within
270
	 *         <code>tasks</code> collection), so empty collection means that there are some other tasks changed
274
	 *         <code>tasks</code> collection), so empty collection means that there are some other tasks changed
271
	 * 
275
	 *
272
	 * @throws CoreException
276
	 * @throws CoreException
273
	 */
277
	 */
274
	public abstract boolean markStaleTasks(TaskRepository repository, Set<AbstractTask> tasks, IProgressMonitor monitor)
278
	public abstract boolean markStaleTasks(TaskRepository repository, Set<AbstractTask> tasks, IProgressMonitor monitor)
Lines 298-304 Link Here
298
302
299
	/**
303
	/**
300
	 * Used for referring to the task in the UI.
304
	 * Used for referring to the task in the UI.
301
	 * 
305
	 *
302
	 * @return
306
	 * @return
303
	 */
307
	 */
304
	public String getTaskIdPrefix() {
308
	public String getTaskIdPrefix() {
Lines 307-323 Link Here
307
311
308
	/**
312
	/**
309
	 * Reset and update the repository attributes from the server (e.g. products, components)
313
	 * Reset and update the repository attributes from the server (e.g. products, components)
310
	 * 
314
	 *
311
	 * API-3.0: Rename to updateRepositoryConfiguration()
315
	 * API-3.0: Rename to updateRepositoryConfiguration()
312
	 */
316
	 */
313
	public abstract void updateAttributes(TaskRepository repository, IProgressMonitor monitor) throws CoreException;
317
	public abstract void updateAttributes(TaskRepository repository, IProgressMonitor monitor) throws CoreException;
314
318
315
	/**
319
	/**
320
	 * Default implementation returns true every 24hrs (since 2.2). Before 2.2 returned true always.
321
	 * Override this in implementations and check to see whether repository is online (return
322
	 * false if off-line), and add connector specific tests: query the repository using head requests, etc.<br />
323
	 * <em>Repository configurations are usually quite large, and Mylyn must try to be well-behaved.</em>
324
	 *
316
	 * @return true to indicate that the repository configuration is stale and requires update
325
	 * @return true to indicate that the repository configuration is stale and requires update
317
	 * @throws CoreException
326
	 * @throws CoreException
327
	 *
328
	 * @since 2.2
318
	 */
329
	 */
319
	public boolean isRepositoryConfigurationStale(TaskRepository repository) throws CoreException {
330
	public boolean isRepositoryConfigurationStale(TaskRepository repository) throws CoreException {
320
		return true;
331
		boolean isStale = true;
332
		Date configDate = repository.getConfigurationDate();
333
		if (configDate != null) {
334
			isStale = (new Date().getTime() - configDate.getTime()) > DAY;
335
		}
336
337
// do not set, as we don't know whether it was susccesfully update yet.
338
//		if (isStale) {
339
//			repository.setConfigurationDate(new Date());
340
//		}
341
342
		return isStale;
321
	}
343
	}
322
344
323
	public void setUserManaged(boolean userManaged) {
345
	public void setUserManaged(boolean userManaged) {

Return to bug 207498