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

Collapse All | Expand All

(-)src/org/eclipse/mylar/internal/jira/core/JiraRepositoryConnector.java (-4 / +15 lines)
Lines 197-206 Link Here
197
			return null;
197
			return null;
198
		}
198
		}
199
		int index = url.indexOf(DELIM_URL);
199
		int index = url.indexOf(DELIM_URL);
200
		if (index != -1) {
200
		return index == -1 ? null : url.substring(0, index);
201
			return url.substring(0, index);
201
	}
202
203
	@Override
204
	public String getTaskIdFromTaskUrl(String url) {
205
		if (url == null) {
206
			return null;
202
		}
207
		}
203
		return null;
208
		int index = url.indexOf(DELIM_URL);
209
		return index == -1 ? null : url.substring(index + DELIM_URL.length());
210
	}
211
	
212
	@Override
213
	public String getTaskWebUrl(String repositoryUrl, String taskId) {
214
		return repositoryUrl + DELIM_URL + taskId;
204
	}
215
	}
205
216
206
	public static void updateTaskDetails(String repositoryUrl, JiraTask task, Issue issue, boolean notifyOfChange) {
217
	public static void updateTaskDetails(String repositoryUrl, JiraTask task, Issue issue, boolean notifyOfChange) {
Lines 226-232 Link Here
226
			PriorityLevel priorityLevel = JiraTask.PriorityLevel.fromPriority(issue.getPriority());
237
			PriorityLevel priorityLevel = JiraTask.PriorityLevel.fromPriority(issue.getPriority());
227
			if (priorityLevel != null) {
238
			if (priorityLevel != null) {
228
				task.setPriority(priorityLevel.toString());
239
				task.setPriority(priorityLevel.toString());
229
			} 
240
			}
230
//			else {
241
//			else {
231
//				MylarStatusHandler.log("unrecognized priority: " + issue.getPriority().getDescription(), null);
242
//				MylarStatusHandler.log("unrecognized priority: " + issue.getPriority().getDescription(), null);
232
//			}
243
//			}
(-)src/org/eclipse/mylar/tasks/core/AbstractRepositoryConnector.java (-8 / +16 lines)
Lines 26-32 Link Here
26
26
27
/**
27
/**
28
 * Operations on a task repository
28
 * Operations on a task repository
29
 * 
29
 *
30
 * @author Mik Kersten
30
 * @author Mik Kersten
31
 * @author Rob Elves
31
 * @author Rob Elves
32
 */
32
 */
Lines 45-51 Link Here
45
	protected TaskList taskList;
45
	protected TaskList taskList;
46
46
47
	public void init(TaskList taskList) {
47
	public void init(TaskList taskList) {
48
		this.taskList = taskList;		
48
		this.taskList = taskList;
49
	}
49
	}
50
50
51
	/**
51
	/**
Lines 58-65 Link Here
58
	 */
58
	 */
59
	public abstract IOfflineTaskHandler getOfflineTaskHandler();
59
	public abstract IOfflineTaskHandler getOfflineTaskHandler();
60
60
61
	public abstract String getRepositoryUrlFromTaskUrl(String url);
61
	public abstract String getRepositoryUrlFromTaskUrl(String taskFullUrl);
62
62
63
	public abstract String getTaskIdFromTaskUrl(String taskFullUrl);
64
65
	public abstract String getTaskWebUrl(String repositoryUrl, String taskId);
66
	
63
	public abstract boolean canCreateTaskFromKey(TaskRepository repository);
67
	public abstract boolean canCreateTaskFromKey(TaskRepository repository);
64
68
65
	public abstract boolean canCreateNewTask(TaskRepository repository);
69
	public abstract boolean canCreateNewTask(TaskRepository repository);
Lines 78-84 Link Here
78
82
79
	/**
83
	/**
80
	 * Implementors must execute query synchronously.
84
	 * Implementors must execute query synchronously.
81
	 * 
85
	 *
82
	 * @param query
86
	 * @param query
83
	 * @param repository
87
	 * @param repository
84
	 *            TODO
88
	 *            TODO
Lines 128-134 Link Here
128
	 * Implementors of this repositoryOperations must perform it locally without
132
	 * Implementors of this repositoryOperations must perform it locally without
129
	 * going to the server since it is used for frequent repositoryOperations
133
	 * going to the server since it is used for frequent repositoryOperations
130
	 * such as decoration.
134
	 * such as decoration.
131
	 * 
135
	 *
132
	 * @return an empty set if no contexts
136
	 * @return an empty set if no contexts
133
	 */
137
	 */
134
	public final Set<RepositoryAttachment> getContextAttachments(TaskRepository repository, AbstractRepositoryTask task) {
138
	public final Set<RepositoryAttachment> getContextAttachments(TaskRepository repository, AbstractRepositoryTask task) {
Lines 155-161 Link Here
155
159
156
	/**
160
	/**
157
	 * Attaches the associated context to <code>task</code>.
161
	 * Attaches the associated context to <code>task</code>.
158
	 * 
162
	 *
159
	 * @return false, if operation is not supported by repository
163
	 * @return false, if operation is not supported by repository
160
	 */
164
	 */
161
	public final boolean attachContext(TaskRepository repository, AbstractRepositoryTask task, String longComment) throws CoreException {
165
	public final boolean attachContext(TaskRepository repository, AbstractRepositoryTask task, String longComment) throws CoreException {
Lines 185-191 Link Here
185
	/**
189
	/**
186
	 * Retrieves a context stored in <code>attachment</code> from
190
	 * Retrieves a context stored in <code>attachment</code> from
187
	 * <code>task</code>.
191
	 * <code>task</code>.
188
	 * 
192
	 *
189
	 * @return false, if operation is not supported by repository
193
	 * @return false, if operation is not supported by repository
190
	 */
194
	 */
191
	public final boolean retrieveContext(TaskRepository repository, AbstractRepositoryTask task,
195
	public final boolean retrieveContext(TaskRepository repository, AbstractRepositoryTask task,
Lines 216-221 Link Here
216
		return templates;
220
		return templates;
217
	}
221
	}
218
222
223
	public void removeTemplate(RepositoryTemplate template) {
224
		this.templates.remove(template);
225
	}
226
219
	/** returns null if template not found */
227
	/** returns null if template not found */
220
	public RepositoryTemplate getTemplate(String label) {
228
	public RepositoryTemplate getTemplate(String label) {
221
		for (RepositoryTemplate template : getTemplates()) {
229
		for (RepositoryTemplate template : getTemplates()) {
Lines 233-239 Link Here
233
	/**
241
	/**
234
	 * Reset and update the repository attributes from the server (e.g.
242
	 * Reset and update the repository attributes from the server (e.g.
235
	 * products, components)
243
	 * products, components)
236
	 * 
244
	 *
237
	 * TODO: remove?
245
	 * TODO: remove?
238
	 */
246
	 */
239
	public abstract void updateAttributes(TaskRepository repository, IProgressMonitor monitor) throws CoreException;
247
	public abstract void updateAttributes(TaskRepository repository, IProgressMonitor monitor) throws CoreException;
(-)src/org/eclipse/mylar/internal/bugzilla/core/BugzillaRepositoryConnector.java (-7 / +16 lines)
Lines 193-206 Link Here
193
	public String getRepositoryUrlFromTaskUrl(String url) {
193
	public String getRepositoryUrlFromTaskUrl(String url) {
194
		if (url == null) {
194
		if (url == null) {
195
			return null;
195
			return null;
196
		} else {
197
			int index = url.indexOf(IBugzillaConstants.URL_GET_SHOW_BUG);
198
			if (index != -1) {
199
				return url.substring(0, index);
200
			} else {
201
				return null;
202
			}
203
		}
196
		}
197
		int index = url.indexOf(IBugzillaConstants.URL_GET_SHOW_BUG);
198
		return index == -1 ? null : url.substring(0, index);
199
	}
200
201
	@Override
202
	public String getTaskIdFromTaskUrl(String url) {
203
		if (url == null) {
204
			return null;
205
		}
206
		int index = url.indexOf(IBugzillaConstants.URL_GET_SHOW_BUG);
207
		return index == -1 ? null : url.substring(index + IBugzillaConstants.URL_GET_SHOW_BUG.length());
208
	}
209
	
210
	@Override
211
	public String getTaskWebUrl(String repositoryUrl, String taskId) {
212
		return repositoryUrl + IBugzillaConstants.URL_GET_SHOW_BUG + taskId;
204
	}
213
	}
205
214
206
	// @Override
215
	// @Override
(-)src/org/eclipse/mylar/tasks/tests/connector/MockRepositoryConnector.java (+11 lines)
Lines 81-88 Link Here
81
		// ignore
81
		// ignore
82
		return null;
82
		return null;
83
	}
83
	}
84
	
85
	@Override
86
	public String getTaskIdFromTaskUrl(String url) {
87
		// ignore
88
		return null;
89
	}
84
90
85
	@Override
91
	@Override
92
	public String getTaskWebUrl(String repositoryUrl, String taskId) {
93
		return null;
94
	}
95
	
96
	@Override
86
	public List<String> getSupportedVersions() {
97
	public List<String> getSupportedVersions() {
87
		// ignore
98
		// ignore
88
		return null;
99
		return null;
(-)src/org/eclipse/mylar/internal/tasks/web/WebRepositoryConnector.java (-55 / +82 lines)
Lines 52-58 Link Here
52
52
53
/**
53
/**
54
 * Generic connector for web based issue tracking systems
54
 * Generic connector for web based issue tracking systems
55
 * 
55
 *
56
 * @author Eugene Kuleshov
56
 * @author Eugene Kuleshov
57
 */
57
 */
58
public class WebRepositoryConnector extends AbstractRepositoryConnector {
58
public class WebRepositoryConnector extends AbstractRepositoryConnector {
Lines 89-94 Link Here
89
89
90
	public static final String REQUEST_GET = "GET";
90
	public static final String REQUEST_GET = "GET";
91
91
92
93
92
	@Override
94
	@Override
93
	public String getRepositoryType() {
95
	public String getRepositoryType() {
94
		return WebTask.REPOSITORY_TYPE;
96
		return WebTask.REPOSITORY_TYPE;
Lines 146-159 Link Here
146
148
147
	@Override
149
	@Override
148
	public String getRepositoryUrlFromTaskUrl(String url) {
150
	public String getRepositoryUrlFromTaskUrl(String url) {
151
		if (url == null) {
152
			return null;
153
		}
154
149
		// lookup repository using task prefix url
155
		// lookup repository using task prefix url
150
		TaskRepositoryManager repositoryManager = TasksUiPlugin.getRepositoryManager();
156
		TaskRepositoryManager repositoryManager = TasksUiPlugin.getRepositoryManager();
151
		for (TaskRepository repository : repositoryManager.getAllRepositories()) {
157
		for (TaskRepository repository : repositoryManager.getRepositories(getRepositoryType())) {
152
			if (getRepositoryType().equals(repository.getKind())) {
158
			String start = evaluateParams(repository.getProperty(PROPERTY_TASK_URL), repository);
153
				String start = evaluateParams(repository.getProperty(PROPERTY_TASK_URL), repository);
159
			if (start != null && url.startsWith(start)) {
154
				if (start != null && url.startsWith(start)) {
160
				return repository.getUrl();
155
					return repository.getUrl();
156
				}
157
			}
161
			}
158
		}
162
		}
159
163
Lines 170-176 Link Here
170
				}
174
				}
171
			}
175
			}
172
		}
176
		}
177
		return null;
178
	}
179
180
	@Override
181
	public String getTaskIdFromTaskUrl(String url) {
182
		if (url == null) {
183
			return null;
184
		}
173
185
186
		TaskRepositoryManager repositoryManager = TasksUiPlugin.getRepositoryManager();
187
		for (TaskRepository repository : repositoryManager.getRepositories(getRepositoryType())) {
188
			String start = evaluateParams(repository.getProperty(PROPERTY_TASK_URL), repository);
189
			if (start != null && url.startsWith(start)) {
190
				return url.substring(start.length());
191
			}
192
		}
193
		return null;
194
	}
195
	
196
	@Override
197
	public String getTaskWebUrl(String repositoryUrl, String taskId) {
198
		TaskRepositoryManager repositoryManager = TasksUiPlugin.getRepositoryManager();
199
		TaskRepository repository = repositoryManager.getRepository(getRepositoryType(), repositoryUrl);
200
		if (repository != null) {
201
			String prefix = evaluateParams(repository.getProperty(PROPERTY_TASK_URL), repository);
202
			return prefix + taskId;
203
		}
174
		return null;
204
		return null;
175
	}
205
	}
176
206
Lines 229-234 Link Here
229
	public void updateTask(TaskRepository repository, AbstractRepositoryTask repositoryTask) throws CoreException {
259
	public void updateTask(TaskRepository repository, AbstractRepositoryTask repositoryTask) throws CoreException {
230
	}
260
	}
231
261
262
232
	// utility methods
263
	// utility methods
233
264
234
	public static IStatus performQuery(String resource, String regexp, String taskPrefix, IProgressMonitor monitor,
265
	public static IStatus performQuery(String resource, String regexp, String taskPrefix, IProgressMonitor monitor,
Lines 279-330 Link Here
279
		return text.trim();
310
		return text.trim();
280
	}
311
	}
281
312
282
	// public static IStatus performRssQuery(String queryUrl, String taskPrefix,
313
283
	// String repositoryUrl,
314
//	 public static IStatus performRssQuery(String queryUrl, String taskPrefix, String repositoryUrl,
284
	// String repositoryUser, String repositoryPassword, IProgressMonitor
315
//			String repositoryUser, String repositoryPassword, IProgressMonitor monitor, QueryHitCollector collector) {
285
	// monitor, QueryHitCollector collector) {
316
//		SyndFeedInput input = new SyndFeedInput();
286
	// SyndFeedInput input = new SyndFeedInput();
317
//		try {
287
	// try {
318
//			SyndFeed feed = input.build(new XmlReader(new URL(queryUrl)));
288
	// SyndFeed feed = input.build(new XmlReader(new URL(queryUrl)));
319
//
289
	//
320
//			SimpleDateFormat df = new SimpleDateFormat("MMM dd, HH:mm");
290
	// SimpleDateFormat df = new SimpleDateFormat("MMM dd, HH:mm");
321
//
291
	//
322
//			for (Iterator it = feed.getEntries().iterator(); it.hasNext();) {
292
	// for (Iterator it = feed.getEntries().iterator(); it.hasNext();) {
323
//				SyndEntry entry = (SyndEntry) it.next();
293
	// SyndEntry entry = (SyndEntry) it.next();
324
//
294
	//
325
//				Date date = entry.getUpdatedDate();
295
	// Date date = entry.getUpdatedDate();
326
//				if (date == null) {
296
	// if (date == null) {
327
//					date = entry.getPublishedDate();
297
	// date = entry.getPublishedDate();
328
//				}
298
	// }
329
//				if (date == null) {
299
	// if (date == null) {
330
//					DCModule module = (DCModule) entry.getModule("http://purl.org/dc/elements/1.1/");
300
	// DCModule module = (DCModule)
331
//					date = module.getDate();
301
	// entry.getModule("http://purl.org/dc/elements/1.1/");
332
//				}
302
	// date = module.getDate();
333
//				if (date == null) {
303
	// }
334
//					// TODO
304
	// if (date == null) {
335
//				}
305
	// // TODO
336
//
306
	// }
337
//				String entryUri = entry.getUri();
307
	//
338
//				if (entryUri.startsWith(taskPrefix)) {
308
	// String entryUri = entry.getUri();
339
//					String id = df.format(date); // entryUri.substring(taskPrefix.length());
309
	// if (entryUri.startsWith(taskPrefix)) {
340
//
310
	// String id = df.format(date); // entryUri.substring(taskPrefix.length());
341
//					try {
311
	//
342
//						collector.accept(new WebQueryHit(id, id + ": " + entry.getTitle(), taskPrefix, repositoryUrl));
312
	// try {
343
//					} catch (CoreException e) {
313
	// collector.accept(new WebQueryHit(id, id + ": " + entry.getTitle(),
344
//						return new Status(IStatus.ERROR, TasksUiPlugin.PLUGIN_ID, IStatus.ERROR,
314
	// taskPrefix, repositoryUrl));
345
//								"Unable collect results.", e);
315
	// } catch (CoreException e) {
346
//					}
316
	// return new Status(IStatus.ERROR, TasksUiPlugin.PLUGIN_ID, IStatus.ERROR,
347
//				}
317
	// "Unable collect results.", e);
348
//			}
318
	// }
349
//			return Status.OK_STATUS;
319
	// }
350
//		} catch (Exception ex) {
320
	// }
351
//			return new Status(IStatus.OK, TasksUiPlugin.PLUGIN_ID, IStatus.OK, "Could not fetch resource: " + queryUrl,
321
	// return Status.OK_STATUS;
352
//					ex);
322
	// } catch (Exception ex) {
353
//		}
323
	// return new Status(IStatus.OK, TasksUiPlugin.PLUGIN_ID, IStatus.OK, "Could
354
//	}
324
	// not fetch resource: " + queryUrl,
325
	// ex);
326
	// }
327
	// }
328
355
329
	public static String fetchResource(String url, Map<String, String> params, TaskRepository repository)
356
	public static String fetchResource(String url, Map<String, String> params, TaskRepository repository)
330
			throws IOException {
357
			throws IOException {
Lines 394-407 Link Here
394
			int statusCode = client.executeMethod(method);
421
			int statusCode = client.executeMethod(method);
395
			if (statusCode == 300 || statusCode == 301 || statusCode == 302 || statusCode == 303 || statusCode == 307) {
422
			if (statusCode == 300 || statusCode == 301 || statusCode == 302 || statusCode == 303 || statusCode == 307) {
396
				Header location = method.getResponseHeader("Location");
423
				Header location = method.getResponseHeader("Location");
397
				if (location != null) {
424
				if (location!=null) {
398
					refreshUrl = location.getValue();
425
					refreshUrl = location.getValue();
399
					if (!refreshUrl.startsWith("/")) {
426
					if (!refreshUrl.startsWith("/")) {
400
						refreshUrl = "/" + refreshUrl;
427
						refreshUrl = "/" + refreshUrl;
401
					}
428
					}
402
				}
429
				}
403
			}
430
			}
404
			if (refreshUrl == null) {
431
			if(refreshUrl == null) {
405
				refreshUrl = getRefreshUrl(url, method);
432
				refreshUrl = getRefreshUrl(url, method);
406
			}
433
			}
407
			if (refreshUrl == null) {
434
			if (refreshUrl == null) {
(-)src/org/eclipse/mylar/internal/trac/core/TracRepositoryConnector.java (-2 / +16 lines)
Lines 81-90 Link Here
81
		if (url == null) {
81
		if (url == null) {
82
			return null;
82
			return null;
83
		}
83
		}
84
		int i = url.lastIndexOf(ITracClient.TICKET_URL);
84
		int index = url.lastIndexOf(ITracClient.TICKET_URL);
85
		return (i != -1) ? url.substring(0, i) : null;
85
		return index == -1 ? null : url.substring(0, index);
86
	}
86
	}
87
87
88
	public String getTaskIdFromTaskUrl(String url) {
89
		if (url == null) {
90
			return null;
91
		}
92
		int index = url.lastIndexOf(ITracClient.TICKET_URL);
93
		return index == -1 ? null : url.substring(index + ITracClient.TICKET_URL.length());
94
	}
95
96
	@Override
97
	public String getTaskWebUrl(String repositoryUrl, String taskId) {
98
		return repositoryUrl + ITracClient.TICKET_URL + taskId;
99
	}
100
101
	
88
	@Override
102
	@Override
89
	public List<String> getSupportedVersions() {
103
	public List<String> getSupportedVersions() {
90
		if (supportedVersions == null) {
104
		if (supportedVersions == null) {
(-)src/org/eclipse/mylar/ide/tests/OpenCorrespondingTaskActionTest.java (-3 / +3 lines)
Lines 13-19 Link Here
13
13
14
import junit.framework.TestCase;
14
import junit.framework.TestCase;
15
15
16
import org.eclipse.mylar.internal.team.ui.actions.OpenCorrespondingTaskAction;
16
import org.eclipse.mylar.internal.team.LinkedTaskInfoAdapterFactory;
17
17
18
/**
18
/**
19
 * @author Mik Kersten
19
 * @author Mik Kersten
Lines 34-46 Link Here
34
34
35
	public void test07LegacyMatching() {
35
	public void test07LegacyMatching() {
36
		String label = "Progress on: 123: foo \nhttps://bugs.eclipse.org";
36
		String label = "Progress on: 123: foo \nhttps://bugs.eclipse.org";
37
		String id = OpenCorrespondingTaskAction.getTaskIdFromLegacy07Label(label);
37
		String id = LinkedTaskInfoAdapterFactory.getTaskIdFromLegacy07Label(label);
38
		assertEquals("123", id);
38
		assertEquals("123", id);
39
	}
39
	}
40
	
40
	
41
	public void testUrlMatching() {
41
	public void testUrlMatching() {
42
		String label = "bla bla\nhttp://foo.bar-123 bla bla";
42
		String label = "bla bla\nhttp://foo.bar-123 bla bla";
43
		String id = OpenCorrespondingTaskAction.getUrlFromComment(label);
43
		String id = LinkedTaskInfoAdapterFactory.getUrlFromComment(label);
44
		assertEquals("http://foo.bar-123", id);
44
		assertEquals("http://foo.bar-123", id);
45
	}
45
	}
46
	
46
	
(-)src/org/eclipse/mylar/tasks/ui/AbstractRepositoryConnectorUi.java (-5 / +13 lines)
Lines 14-23 Link Here
14
import org.eclipse.jface.wizard.WizardDialog;
14
import org.eclipse.jface.wizard.WizardDialog;
15
import org.eclipse.jface.wizard.WizardPage;
15
import org.eclipse.jface.wizard.WizardPage;
16
import org.eclipse.mylar.context.core.MylarStatusHandler;
16
import org.eclipse.mylar.context.core.MylarStatusHandler;
17
import org.eclipse.mylar.internal.tasks.ui.TasksUiUtil;
17
import org.eclipse.mylar.internal.tasks.ui.wizards.AbstractRepositorySettingsPage;
18
import org.eclipse.mylar.internal.tasks.ui.wizards.AbstractRepositorySettingsPage;
18
import org.eclipse.mylar.internal.tasks.ui.wizards.CommonAddExistingTaskWizard;
19
import org.eclipse.mylar.internal.tasks.ui.wizards.CommonAddExistingTaskWizard;
20
import org.eclipse.mylar.tasks.core.AbstractRepositoryConnector;
19
import org.eclipse.mylar.tasks.core.AbstractRepositoryQuery;
21
import org.eclipse.mylar.tasks.core.AbstractRepositoryQuery;
20
import org.eclipse.mylar.tasks.core.TaskRepository;
22
import org.eclipse.mylar.tasks.core.TaskRepository;
23
import org.eclipse.mylar.tasks.core.TaskRepositoryManager;
21
import org.eclipse.swt.widgets.Shell;
24
import org.eclipse.swt.widgets.Shell;
22
import org.eclipse.ui.PlatformUI;
25
import org.eclipse.ui.PlatformUI;
23
26
Lines 82-94 Link Here
82
85
83
	/**
86
	/**
84
	 * Only override if task should be opened by a custom editor, default
87
	 * Only override if task should be opened by a custom editor, default
85
	 * beahvior is to open with browser.
88
	 * behavior is to open with browser.
86
	 * 
89
	 * 
87
	 * @return	true if the task was successfully opened
90
	 * @return true if the task was successfully opened
88
	 */
91
	 */
89
	public boolean openRemoteTask(String repositoryUrl, String idString) {
92
	public boolean openRemoteTask(String repositoryUrl, String idString) {
90
		return false;
93
		TaskRepositoryManager repositoryManager = TasksUiPlugin.getRepositoryManager();
91
//		MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
94
		AbstractRepositoryConnector connector = repositoryManager.getRepositoryConnector(getRepositoryType());
92
//				TasksUiPlugin.TITLE_DIALOG, "Not supported by connector: " + this.getClass().getSimpleName());
95
		TasksUiUtil.openUrl(connector.getTaskWebUrl(repositoryUrl, idString));
96
97
		return true;
98
		// MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
99
		// TasksUiPlugin.TITLE_DIALOG, "Not supported by connector: " +
100
		// this.getClass().getSimpleName());
93
	}
101
	}
94
}
102
}
(-)src/org/eclipse/mylar/team/MylarTeamPlugin.java (+5 lines)
Lines 13-18 Link Here
13
13
14
import org.eclipse.mylar.context.core.MylarStatusHandler;
14
import org.eclipse.mylar.context.core.MylarStatusHandler;
15
import org.eclipse.mylar.internal.team.ContextChangeSetManager;
15
import org.eclipse.mylar.internal.team.ContextChangeSetManager;
16
import org.eclipse.mylar.internal.team.LinkedTaskInfoAdapterFactory;
16
import org.eclipse.mylar.internal.team.template.CommitTemplateManager;
17
import org.eclipse.mylar.internal.team.template.CommitTemplateManager;
17
import org.eclipse.ui.IStartup;
18
import org.eclipse.ui.IStartup;
18
import org.eclipse.ui.PlatformUI;
19
import org.eclipse.ui.PlatformUI;
Lines 48-53 Link Here
48
		initPreferenceDefaults();
49
		initPreferenceDefaults();
49
		commitTemplateManager = new CommitTemplateManager();
50
		commitTemplateManager = new CommitTemplateManager();
50
		
51
		
52
		LinkedTaskInfoAdapterFactory.registerAdapters();
53
51
		PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
54
		PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
52
			public void run() {
55
			public void run() {
53
				try {
56
				try {
Lines 71-76 Link Here
71
		INSTANCE = null;
74
		INSTANCE = null;
72
		super.stop(context);
75
		super.stop(context);
73
		changeSetManager.disable();
76
		changeSetManager.disable();
77
78
		LinkedTaskInfoAdapterFactory.unregisterAdapters();
74
	}
79
	}
75
80
76
	private void initPreferenceDefaults() {
81
	private void initPreferenceDefaults() {
(-)plugin.xml (+16 lines)
Lines 68-73 Link Here
68
	           tooltip="Open Corresponding Task"> 
68
	           tooltip="Open Corresponding Task"> 
69
	  		</action> 
69
	  		</action> 
70
	    </objectContribution>
70
	    </objectContribution>
71
		
72
		<!-- Subclipse History view -->
73
		<objectContribution
74
            objectClass="org.tigris.subversion.subclipse.core.history.LogEntry"
75
            id="org.eclipse.mylar.ui.team.synchronize.open.report">
76
         <action
77
	           class="org.eclipse.mylar.internal.team.ui.actions.OpenCorrespondingTaskAction"
78
	           enablesFor="1" 
79
	           icon="icons/elcl16/task-repository.gif"
80
	           id="org.eclipse.mylar.ui.team.synchronize.contribution.open.report"
81
	           label="Open Corresponding Task"
82
	           menubarPath="mylar"
83
	           tooltip="Open Corresponding Task">
84
	  		</action> 
85
	    </objectContribution>
86
	    
71
	    <!--
87
	    <!--
72
		<objectContribution
88
		<objectContribution
73
            objectClass="org.eclipse.team.internal.ui.synchronize.ChangeSetDiffNode"
89
            objectClass="org.eclipse.team.internal.ui.synchronize.ChangeSetDiffNode"
(-)src/org/eclipse/mylar/internal/team/ILinkedTaskInfo.java (+33 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004 - 2006 University Of British Columbia and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Eugene Kuleshov - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylar.internal.team;
13
14
import org.eclipse.mylar.tasks.core.ITask;
15
16
/**
17
 * Task information linked to artifacts from version control integration 
18
 * 
19
 * TODO move to mylar core?
20
 * 
21
 * @author Eugene Kuleshov
22
 */
23
public interface ILinkedTaskInfo {
24
25
	String getTaskId();
26
27
	String getTaskFullUrl();
28
29
	String getRepositoryUrl();
30
	
31
	ITask getTask();
32
	
33
}
(-)src/org/eclipse/mylar/internal/team/LinkedTaskInfo.java (+120 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004 - 2006 University Of British Columbia and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Eugene Kuleshov - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylar.internal.team;
13
14
import org.eclipse.mylar.tasks.core.AbstractRepositoryConnector;
15
import org.eclipse.mylar.tasks.core.AbstractRepositoryTask;
16
import org.eclipse.mylar.tasks.core.ITask;
17
import org.eclipse.mylar.tasks.core.TaskRepository;
18
import org.eclipse.mylar.tasks.core.TaskRepositoryManager;
19
import org.eclipse.mylar.tasks.ui.TasksUiPlugin;
20
21
/**
22
 * Default implementation of {@link ILinkedTaskInfo}
23
 * 
24
 * @author Eugene Kuleshov
25
 */
26
public class LinkedTaskInfo implements ILinkedTaskInfo {
27
28
	private String taskId;
29
30
	private String taskFullUrl;
31
32
	private String repositoryUrl;
33
34
	private ITask task;
35
36
	public LinkedTaskInfo(ITask task) {
37
		init(task, //
38
				AbstractRepositoryTask.getRepositoryUrl(task.getHandleIdentifier()), //
39
				AbstractRepositoryTask.getTaskId(task.getHandleIdentifier()), //
40
				task.getUrl());
41
	}
42
43
	public LinkedTaskInfo(String taskFullUrl) {
44
		init(null, null, null, taskFullUrl);
45
	}
46
47
	public LinkedTaskInfo(String repositoryUrl, String taskId, String taskFullUrl) {
48
		init(null, repositoryUrl, taskId, taskFullUrl);
49
	}
50
51
	private void init(ITask task, String repositoryUrl, String taskId, String taskFullUrl) {
52
		// TODO should this even be here?
53
54
		TaskRepositoryManager repositoryManager = TasksUiPlugin.getRepositoryManager();
55
		AbstractRepositoryConnector connector = repositoryManager.getConnectorForRepositoryTaskUrl(taskFullUrl);
56
		if (connector == null && repositoryUrl != null) {
57
			TaskRepository repository = repositoryManager.getRepository(repositoryUrl);
58
			if (repository != null) {
59
				connector = repositoryManager.getRepositoryConnector(repository.getKind());
60
			}
61
		}
62
63
		if (repositoryUrl == null && connector != null) {
64
			repositoryUrl = connector.getRepositoryUrlFromTaskUrl(taskFullUrl);
65
		}
66
67
		if (taskId == null && connector != null) {
68
			taskId = connector.getTaskIdFromTaskUrl(taskFullUrl);
69
		}
70
71
		if (taskFullUrl == null && repositoryUrl != null && taskId != null && connector != null) {
72
			taskFullUrl = connector.getTaskWebUrl(repositoryUrl, taskId);
73
		}
74
		
75
		if (task == null) {
76
			if (taskId != null && repositoryUrl != null) {
77
				String handle = AbstractRepositoryTask.getHandle(repositoryUrl, taskId);
78
				task = TasksUiPlugin.getTaskListManager().getTaskList().getTask(handle);
79
			}
80
			if (task == null && taskFullUrl != null) {
81
				// search by fullUrl
82
				for (ITask currTask : TasksUiPlugin.getTaskListManager().getTaskList().getAllTasks()) {
83
					if (currTask instanceof AbstractRepositoryTask) {
84
						String currUrl = ((AbstractRepositoryTask) currTask).getUrl();
85
						if (taskFullUrl.equals(currUrl)) {
86
							task = currTask;
87
							break;
88
						}
89
					}
90
				}
91
			}
92
		}
93
94
		if (taskFullUrl == null && task != null) {
95
			taskFullUrl = task.getUrl();
96
		}
97
98
		this.task = task;
99
		this.repositoryUrl = repositoryUrl;
100
		this.taskId = taskId;
101
		this.taskFullUrl = taskFullUrl;
102
	}
103
104
	public String getRepositoryUrl() {
105
		return repositoryUrl;
106
	}
107
108
	public ITask getTask() {
109
		return task;
110
	}
111
112
	public String getTaskFullUrl() {
113
		return taskFullUrl;
114
	}
115
116
	public String getTaskId() {
117
		return taskId;
118
	}
119
120
}
(-)src/org/eclipse/mylar/internal/team/LinkedTaskInfoAdapterFactory.java (+363 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004 - 2006 University Of British Columbia and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Eugene Kuleshov - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylar.internal.team;
13
14
import org.eclipse.compare.structuremergeviewer.DiffNode;
15
import org.eclipse.compare.structuremergeviewer.IDiffElement;
16
import org.eclipse.core.resources.IProject;
17
import org.eclipse.core.resources.IResource;
18
import org.eclipse.core.resources.ResourcesPlugin;
19
import org.eclipse.core.runtime.IAdaptable;
20
import org.eclipse.core.runtime.IAdapterFactory;
21
import org.eclipse.core.runtime.IAdapterManager;
22
import org.eclipse.core.runtime.Platform;
23
import org.eclipse.mylar.internal.team.template.CommitTemplateManager;
24
import org.eclipse.mylar.tasks.core.TaskRepository;
25
import org.eclipse.mylar.tasks.ui.TasksUiPlugin;
26
import org.eclipse.mylar.team.MylarTeamPlugin;
27
import org.eclipse.team.core.TeamException;
28
import org.eclipse.team.core.history.IFileRevision;
29
import org.eclipse.team.core.variants.IResourceVariant;
30
import org.eclipse.team.internal.ccvs.core.CVSException;
31
import org.eclipse.team.internal.ccvs.core.ICVSResource;
32
import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
33
import org.eclipse.team.internal.ccvs.core.resources.RemoteResource;
34
import org.eclipse.team.internal.core.subscribers.ChangeSet;
35
import org.eclipse.team.internal.core.subscribers.DiffChangeSet;
36
import org.eclipse.team.internal.ui.synchronize.ChangeSetDiffNode;
37
import org.eclipse.team.internal.ui.synchronize.SyncInfoModelElement;
38
import org.eclipse.team.internal.ui.synchronize.SynchronizeModelElement;
39
40
import org.tigris.subversion.subclipse.core.ISVNRemoteResource;
41
import org.tigris.subversion.subclipse.core.sync.SVNStatusSyncInfo;
42
import org.tigris.subversion.subclipse.ui.settings.ProjectProperties;
43
import org.tigris.subversion.svnclientadapter.ISVNLogMessage;
44
import org.tigris.subversion.svnclientadapter.SVNRevision;
45
46
47
/**
48
 * Adapter factory used to create adapters for <code>LinkedTaskInfo</code> 
49
 * 
50
 * @author Eugene Kuleshov
51
 */
52
public class LinkedTaskInfoAdapterFactory implements IAdapterFactory {
53
54
	private static final Class[] ADAPTER_TYPES = new Class[] { ILinkedTaskInfo.class };
55
56
	private static IAdapterFactory FACTORY = new LinkedTaskInfoAdapterFactory();
57
58
	private static final String PREFIX_HTTP = "http://";
59
60
    private static final String PREFIX_HTTPS = "https://";
61
62
    private static boolean haveSubclipse;
63
64
    
65
	public static void registerAdapters() {
66
		IAdapterManager adapterManager = Platform.getAdapterManager();
67
68
		// Mylar
69
		adapterManager.registerAdapters(FACTORY, ContextChangeSet.class);
70
71
		// Team public
72
		adapterManager.registerAdapters(FACTORY, IFileRevision.class);
73
		adapterManager.registerAdapters(FACTORY, DiffNode.class);
74
75
		// Team internal
76
		adapterManager.registerAdapters(FACTORY, DiffChangeSet.class); // CVSCheckedInChangeSet ???
77
		adapterManager.registerAdapters(FACTORY, ChangeSetDiffNode.class);
78
		adapterManager.registerAdapters(FACTORY, SynchronizeModelElement.class);
79
		
80
		// Team CVS internal; is it used? Maybe CVS History view in Eclipse 3.1?
81
		adapterManager.registerAdapters(FACTORY, org.eclipse.team.internal.ccvs.core.client.listeners.LogEntry.class);
82
		
83
		// Subclipse		
84
		try {
85
			SubclipseWrapper.init(adapterManager, FACTORY);
86
			haveSubclipse = true;
87
		} catch (Throwable ex) {
88
			// ignore
89
		}  
90
	}
91
	
92
	public static void unregisterAdapters() {
93
		Platform.getAdapterManager().unregisterAdapters(FACTORY); 
94
	}
95
    
96
	
97
	private LinkedTaskInfoAdapterFactory() {
98
	}
99
	
100
	public Object getAdapter(Object object, Class adapterType) {
101
		if(!ILinkedTaskInfo.class.equals(adapterType)) {
102
			return null;
103
		}
104
			
105
		if(object instanceof ChangeSetDiffNode) {
106
			return adaptChangeSetDiffNode(object);
107
		}
108
		
109
		if(object instanceof DiffNode) {
110
			return getAdapter(((DiffNode) object).getParent(), adapterType);
111
		}
112
		
113
		if(haveSubclipse &&
114
				"org.tigris.subversion.subclipse.core.history.LogEntry".equals(object.getClass().getName())) {
115
			ILinkedTaskInfo info = SubclipseWrapper.adaptSubclipseLogEntry(object);
116
			if(info!=null) {
117
				return info;
118
			}
119
		}
120
		
121
		// TODO add other adapted types
122
123
		return adaptFromComment(object);
124
	}
125
126
	public Class[] getAdapterList() {
127
		return ADAPTER_TYPES;
128
	}
129
130
	private ILinkedTaskInfo adaptChangeSetDiffNode(Object object) {
131
        ChangeSetDiffNode diffNode = (ChangeSetDiffNode) object;
132
        ChangeSet set = diffNode.getSet();
133
        if (set instanceof ContextChangeSet) {
134
            return new LinkedTaskInfo(((ContextChangeSet) set).getTask());
135
        } else if(haveSubclipse && set.getClass().getName().startsWith("org.tigris")) {
136
            ILinkedTaskInfo info = SubclipseWrapper.adaptSubclipseChangeset(diffNode, set);
137
			if(info!=null) {
138
				return info;
139
			}
140
        }
141
142
        return adaptFromComment(object);
143
	}
144
145
	private ILinkedTaskInfo adaptFromComment(Object object) {
146
		String comment = getCommentFromElement(object);
147
		
148
		CommitTemplateManager commitTemplateManager = MylarTeamPlugin.getDefault().getCommitTemplateManager();
149
		String taskId = commitTemplateManager.getTaskIdFromCommentOrLabel(comment);
150
		if (taskId == null) {
151
			taskId = getTaskIdFromLegacy07Label(comment);
152
		}
153
154
		IProject project = findCorrespondingProject(object);
155
		if (project != null) {
156
			TaskRepository repository = TasksUiPlugin.getDefault().getRepositoryForResource(project, false);
157
			if (repository != null && taskId!=null) {
158
				return new LinkedTaskInfo(repository.getUrl(), taskId, null);
159
			}
160
		}
161
		
162
		String fullTaskUrl = getUrlFromComment(comment);
163
        if(fullTaskUrl!=null) {
164
        	return new LinkedTaskInfo(fullTaskUrl);
165
        }
166
        
167
        return null;
168
	}
169
	
170
    private String getCommentFromElement(Object element) {
171
        if (element instanceof DiffChangeSet) {
172
            return ((DiffChangeSet) element).getComment();
173
        } else if (element instanceof ChangeSetDiffNode) {
174
            return ((ChangeSetDiffNode) element).getName();
175
        } else if (element instanceof IFileRevision) {
176
        	return ((IFileRevision) element).getComment();
177
        } else if (element instanceof org.eclipse.team.internal.ccvs.core.client.listeners.LogEntry) {
178
            return ((org.eclipse.team.internal.ccvs.core.client.listeners.LogEntry) element).getComment();
179
        } else if (element instanceof org.tigris.subversion.subclipse.core.history.LogEntry) {
180
            return ((org.tigris.subversion.subclipse.core.history.LogEntry) element).getComment();
181
        }
182
        return null;
183
    }
184
	
185
	
186
	//
187
188
    public static String getUrlFromComment(String comment) {
189
        int httpIndex = comment.indexOf(PREFIX_HTTP);
190
        int httpsIndex = comment.indexOf(PREFIX_HTTPS);
191
        int idStart = -1;
192
        if (httpIndex != -1) {
193
            idStart = httpIndex;
194
        } else if (httpsIndex != -1) {
195
            idStart = httpsIndex;
196
        }
197
        if (idStart != -1) {
198
            int idEnd = comment.indexOf(' ', idStart);
199
            if (idEnd == -1) {
200
                return comment.substring(idStart);
201
            } else if (idEnd != -1 && idStart < idEnd) {
202
                return comment.substring(idStart, idEnd);
203
            }
204
        }
205
        return null;
206
    }
207
208
    public static String getTaskIdFromLegacy07Label(String comment) {
209
        String PREFIX_DELIM = ":";
210
        String PREFIX_START_1 = "Progress on:";
211
        String PREFIX_START_2 = "Completed:";
212
        String usedPrefix = PREFIX_START_1;
213
        int firstDelimIndex = comment.indexOf(PREFIX_START_1);
214
        if (firstDelimIndex == -1) {
215
            firstDelimIndex = comment.indexOf(PREFIX_START_2);
216
            usedPrefix = PREFIX_START_2;
217
        }
218
        if (firstDelimIndex != -1) {
219
            int idStart = firstDelimIndex + usedPrefix.length();
220
            int idEnd = comment.indexOf(PREFIX_DELIM, firstDelimIndex + usedPrefix.length());// comment.indexOf(PREFIX_DELIM);
221
            if (idEnd != -1 && idStart < idEnd) {
222
                String id = comment.substring(idStart, idEnd);
223
                if (id != null) {
224
                    return id.trim();
225
                }
226
            } else {
227
                return comment.substring(0, firstDelimIndex);
228
            }
229
        }
230
        return null;
231
    }
232
	
233
    private static IProject findCorrespondingProject(Object element) {
234
        if (element instanceof DiffChangeSet) {
235
            IResource[] resources = ((DiffChangeSet) element).getResources();
236
            if (resources.length > 0) {
237
                // TODO: only checks first resource
238
                return resources[0].getProject();
239
            }
240
        } else if (element instanceof SynchronizeModelElement) {
241
            SynchronizeModelElement modelElement = (SynchronizeModelElement)element;
242
            IResource resource = modelElement.getResource();
243
            if (resource != null) {
244
                return resource.getProject();
245
            } else {
246
                IDiffElement[] elements = modelElement.getChildren();
247
                if (elements.length > 0) {
248
                    // TODO: only checks first diff
249
                    if (elements[0] instanceof SynchronizeModelElement) {
250
                        return ((SynchronizeModelElement)elements[0]).getResource().getProject();
251
                    }
252
                }
253
            }
254
        } else if (element instanceof IAdaptable) {
255
        	IAdaptable adaptable = (IAdaptable) element;
256
			IResourceVariant resourceVariant = (IResourceVariant) adaptable.getAdapter(IResourceVariant.class);
257
            if (resourceVariant != null && resourceVariant instanceof RemoteResource) {
258
            	RemoteResource remoteResource = (RemoteResource) resourceVariant;
259
            	// TODO is there a better way then iterating trough all projects?
260
                String path = remoteResource.getRepositoryRelativePath();
261
                for (IProject project : ResourcesPlugin.getWorkspace().getRoot().getProjects()) {
262
                	if(project.isAccessible()) {
263
                		ICVSResource cvsResource = CVSWorkspaceRoot.getCVSFolderFor(project);
264
                		try {
265
							if(cvsResource!=null && path.startsWith(cvsResource.getRepositoryRelativePath())) {
266
								return project;
267
							}
268
						} catch (CVSException ex) {
269
							// ignore
270
						}
271
                	}
272
                }
273
                
274
                return null;
275
            }
276
        } else {
277
        	// TODO
278
        	
279
        }
280
        return null;
281
    }
282
283
    
284
    /**
285
     * Wrapper class used to isolate Subclibse dependencies  
286
     */
287
	private static class SubclipseWrapper {
288
289
		public static void init(IAdapterManager adapterManager, IAdapterFactory factory) {
290
			Class logEntryClass = org.tigris.subversion.subclipse.core.history.LogEntry.class;
291
			adapterManager.registerAdapters(FACTORY, logEntryClass);
292
		}
293
294
		private static ILinkedTaskInfo adaptSubclipseChangeset(ChangeSetDiffNode diff, ChangeSet set) {
295
	        SynchronizeModelElement diffContainer = (SynchronizeModelElement) diff.getChildren()[0];
296
297
	        IResource res = diffContainer.getResource();
298
299
	        SyncInfoModelElement melement = (SyncInfoModelElement) diffContainer.getChildren()[0];
300
301
	        // Specific to Subclipse
302
	        SVNStatusSyncInfo info = (SVNStatusSyncInfo) melement.getSyncInfo();
303
304
	        ISVNRemoteResource remoteResource = (ISVNRemoteResource) info.getRemote();
305
	        SVNRevision rev = remoteResource.getLastChangedRevision();
306
307
			String comment;
308
			try {
309
				ISVNLogMessage[] messages = remoteResource.getLogMessages(rev, rev, SVNRevision.START, false, false, 1);
310
				comment = messages[0].getMessage();
311
			} catch (TeamException ex) {
312
				comment = diff.getSet().getComment();
313
			}
314
			return adaptFromComment(diff, res, comment);
315
		}
316
317
		private static ILinkedTaskInfo adaptSubclipseLogEntry(Object object) {
318
			org.tigris.subversion.subclipse.core.history.LogEntry logEntry = 
319
				(org.tigris.subversion.subclipse.core.history.LogEntry) object;
320
321
			String comment = logEntry.getComment();
322
			IResource res = logEntry.getResource().getResource();
323
			
324
			return adaptFromComment(object, res, comment);
325
		}
326
327
		private static ILinkedTaskInfo adaptFromComment(Object object, IResource res, String comment) {
328
			ProjectProperties props = null;
329
			try {
330
				props = ProjectProperties.getProjectProperties(res);
331
			} catch (TeamException ex) {
332
				// ignore?
333
			}
334
			
335
			String[] urls = null;
336
			String repositoryUrl = null;
337
			if(props!=null) {
338
				repositoryUrl = getRepositoryUrl(props.getUrl());
339
				urls = props.getLinkList(comment).getUrls();
340
			}
341
			if (urls == null || urls.length == 0) {
342
				// we can do better job then this method
343
				urls = ProjectProperties.getUrls(comment).getUrls();
344
			}
345
			if (urls != null && urls.length > 0) {
346
				return new LinkedTaskInfo(repositoryUrl, null, urls[0]);
347
			}
348
			return null;
349
		}
350
351
		private static String getRepositoryUrl(String url) {
352
			for (TaskRepository repository : TasksUiPlugin.getRepositoryManager().getAllRepositories()) {
353
				if(url.startsWith(repository.getUrl())) {
354
					return repository.getUrl();
355
				}
356
			}
357
			return null;
358
		}
359
		
360
	}
361
    
362
}
363

Return to bug 165581