summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorilya.ivanov2011-01-26 08:36:43 (EST)
committer Chris Aniszczyk2011-01-31 12:13:58 (EST)
commit010fa4291b0478ee27189f42ff0cc995ce539135 (patch)
treeac506a065681d1a53ed465d87c429293faaa4d2b
parent5024c9193da8b3987d7651f6d97d961fea87458b (diff)
downloadegit-010fa4291b0478ee27189f42ff0cc995ce539135.zip
egit-010fa4291b0478ee27189f42ff0cc995ce539135.tar.gz
egit-010fa4291b0478ee27189f42ff0cc995ce539135.tar.bz2
Support 'Open corresponding task'refs/changes/19/2319/7
Implemented repository url resolving. Task repository url is taken from 'bugtracker.url' config entry. If the config entry doesn't exist, assume the Mylyn task repository and remote git repository (origin) are on the same host. Change-Id: I18af5f3dcfa080cfb46d9e38ea91a9e55a634071 Signed-off-by: Ilya Ivanov <ilya.ivanov@intland.com> Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
-rw-r--r--org.eclipse.egit.mylyn.ui/META-INF/MANIFEST.MF11
-rw-r--r--org.eclipse.egit.mylyn.ui/src/org/eclipse/egit/internal/mylyn/ui/commit/TaskReferenceFactory.java169
2 files changed, 166 insertions, 14 deletions
diff --git a/org.eclipse.egit.mylyn.ui/META-INF/MANIFEST.MF b/org.eclipse.egit.mylyn.ui/META-INF/MANIFEST.MF
index 913fb6e..f97c74d 100644
--- a/org.eclipse.egit.mylyn.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.mylyn.ui/META-INF/MANIFEST.MF
@@ -9,19 +9,22 @@ Require-Bundle: org.eclipse.team.core,
org.eclipse.jface,
org.eclipse.core.resources,
org.eclipse.core.runtime,
+ org.eclipse.ui.navigator.resources,
+ org.eclipse.ui.workbench,
org.eclipse.mylyn.monitor.core;bundle-version="[3.0.0,4.0.0)",
org.eclipse.mylyn.tasks.core;bundle-version="[3.0.0,4.0.0)",
org.eclipse.mylyn.tasks.ui;bundle-version="[3.0.0,4.0.0)",
org.eclipse.mylyn.team.ui;bundle-version="[3.0.0,4.0.0)",
org.eclipse.mylyn.resources.ui;bundle-version="[3.0.0,4.0.0)",
- org.eclipse.mylyn.context.core;bundle-version="[3.0.0,4.0.0)",
- org.eclipse.ui.navigator.resources,
- org.eclipse.ui.workbench
+ org.eclipse.mylyn.context.core;bundle-version="[3.0.0,4.0.0)"
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Bundle-ActivationPolicy: lazy
Bundle-Localization: plugin
Export-Package: org.eclipse.egit.internal.mylyn.ui;version="0.11.0";x-internal:=true,
org.eclipse.egit.internal.mylyn.ui.commit;version="0.11.0";x-internal:=true
Import-Package: org.eclipse.egit.ui;version="[0.11.0,0.12.0)",
+ org.eclipse.egit.core;version="[0.11.0,0.12.0)",
org.eclipse.egit.ui.internal.synchronize.model;version="[0.11.0,0.12.0)",
- org.eclipse.jgit.revwalk;version="[0.11.0,0.12.0)"
+ org.eclipse.jgit.revwalk;version="[0.11.0,0.12.0)",
+ org.eclipse.jgit.lib;version="[0.11.0,0.12.0)",
+ org.eclipse.ui.plugin
diff --git a/org.eclipse.egit.mylyn.ui/src/org/eclipse/egit/internal/mylyn/ui/commit/TaskReferenceFactory.java b/org.eclipse.egit.mylyn.ui/src/org/eclipse/egit/internal/mylyn/ui/commit/TaskReferenceFactory.java
index 517b419..82b7359 100644
--- a/org.eclipse.egit.mylyn.ui/src/org/eclipse/egit/internal/mylyn/ui/commit/TaskReferenceFactory.java
+++ b/org.eclipse.egit.mylyn.ui/src/org/eclipse/egit/internal/mylyn/ui/commit/TaskReferenceFactory.java
@@ -6,22 +6,42 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Benjamin Muskalla <benjamin.muskalla@tasktop.com> - initial API and implementation
+ * Benjamin Muskalla <bmuskalla@tasktop.com> - initial API and implementation
+ * Ilya Ivanov <ilya.ivanov@intland.com> - task repository url resolving
*******************************************************************************/
package org.eclipse.egit.internal.mylyn.ui.commit;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.util.List;
+
import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.internal.mylyn.ui.EGitMylynUI;
import org.eclipse.egit.ui.internal.synchronize.model.GitModelCommit;
+import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.internal.team.ui.LinkedTaskInfo;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.team.ui.AbstractTaskReference;
/**
* Adapter factory to bridge between Mylyn and EGit domain models.
*/
+@SuppressWarnings("restriction")
public class TaskReferenceFactory implements IAdapterFactory {
private static final Class<?>[] ADAPTER_TYPES = new Class[] { AbstractTaskReference.class };
+ private static final String BUGTRACK_SECTION = "bugtracker"; //$NON-NLS-1$
+ private static final String BUGTRACK_URL = "url"; //$NON-NLS-1$
+
@SuppressWarnings({ "rawtypes" })
public Class[] getAdapterList() {
return ADAPTER_TYPES;
@@ -32,17 +52,56 @@ public class TaskReferenceFactory implements IAdapterFactory {
if (!AbstractTaskReference.class.equals(adapterType))
return null;
- return adaptFromComment(adaptableObject);
+ return adaptFromObject(adaptableObject);
}
- private AbstractTaskReference adaptFromComment(Object element) {
- String comment;
+ private AbstractTaskReference adaptFromObject(Object element) {
RevCommit commit = getCommitForElement(element);
- if(commit != null)
- comment = commit.getFullMessage();
- else
- return null;
- return new LinkedTaskInfo(null, null, null, comment);
+ if (commit != null)
+ return adaptFromRevCommit(commit);
+
+ return null;
+ }
+
+ /**
+ * Finds {@link TaskRepository} for provided {@link RevCommit} object and returns new {@link LinkedTaskInfo} object
+ * or <code>null</code> if nothing found.
+ * @param commit a {@link RevCommit} object to look for
+ * @return {@link LinkedTaskInfo} object, or <code>null</code> if repository not found
+ */
+ private AbstractTaskReference adaptFromRevCommit(RevCommit commit) {
+ Repository[] repositories = Activator.getDefault().getRepositoryCache().getAllRepositories();
+ for (Repository r : repositories) {
+ RevWalk revWalk = new RevWalk(r);
+
+ String repoUrl = null;
+ String message = null;
+
+ // try to get repository url and commit message
+ try {
+ RevCommit revCommit = revWalk.parseCommit(commit);
+ if (revCommit != null) {
+ repoUrl = getRepoUrl(r);
+ message = revCommit.getFullMessage();
+ }
+ } catch (Exception e) {
+ continue;
+ }
+
+ if (message == null || message.trim().length() == 0)
+ continue;
+
+ String taskRepositoryUrl = null;
+ if (repoUrl != null) {
+ TaskRepository repository = getTaskRepositoryByGitRepoURL(repoUrl);
+ if (repository != null)
+ taskRepositoryUrl = repository.getRepositoryUrl();
+ }
+
+ return new LinkedTaskInfo(taskRepositoryUrl, null, null, message);
+ }
+
+ return null;
}
private static RevCommit getCommitForElement(Object element) {
@@ -51,8 +110,98 @@ public class TaskReferenceFactory implements IAdapterFactory {
commit = (RevCommit) element;
else if (element instanceof GitModelCommit) {
GitModelCommit modelCommit = (GitModelCommit) element;
- commit= modelCommit.getBaseCommit();
+ commit = modelCommit.getBaseCommit();
}
return commit;
}
+
+ /**
+ * Finds {@link TaskRepository} by provided Git repository Url
+ * @param repoUrl Git repository url
+ * @return {@link TaskRepository} associated with this Git repo or <code>null</code> if nothing found
+ */
+ private TaskRepository getTaskRepositoryByGitRepoURL(final String repoUrl) {
+ try {
+ // replacing protocol name to avoid MalformedURIException
+ URI uri = repoUrl == null ? null : new URI(repoUrl.replaceFirst("\\w+://", "http://")); //$NON-NLS-1$ //$NON-NLS-2$
+ if (uri != null) {
+ String gitHost = uri.toURL().getHost();
+ return getTaskRepositoryByHost(gitHost);
+ }
+ } catch (Exception ex) {
+ EGitMylynUI.getDefault().getLog().log(
+ new Status(IStatus.ERROR, EGitMylynUI.PLUGIN_ID, "failed to get repo url", ex)); //$NON-NLS-1$
+ }
+ return null;
+ }
+
+ private static String getRepoUrl(Repository repo) {
+ String configuredUrl = repo.getConfig().getString(BUGTRACK_SECTION, null, BUGTRACK_URL);
+ String originUrl = repo.getConfig().getString("remote", "origin", "url"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ return configuredUrl != null ? configuredUrl : originUrl;
+ }
+
+ private TaskRepository getTaskRepositoryByHost(String host) {
+ List<TaskRepository> repositories = TasksUiPlugin.getRepositoryManager().getAllRepositories();
+ if (repositories == null || repositories.isEmpty())
+ return null;
+
+ if (repositories.size() == 1)
+ return repositories.iterator().next();
+
+ for (TaskRepository repository : repositories) {
+ if (!repository.isOffline()) {
+ try {
+ URL url = new URL(repository.getRepositoryUrl());
+
+ if (isSameHosts(host, url.getHost()))
+ return repository;
+ } catch (MalformedURLException e) {
+ // We cannot do anything.
+ }
+ }
+ }
+ return null;
+ }
+
+ private boolean isSameHosts(final String name1, final String name2) {
+ String hostname1 = name1 == null ? "" : name1.trim(); //$NON-NLS-1$
+ String hostname2 = name2 == null ? "" : name2.trim(); //$NON-NLS-1$
+
+ if (hostname1.equals(hostname2))
+ return true;
+
+ String localHost = "localhost"; //$NON-NLS-1$
+ String resolvedHostName;
+ try {
+ resolvedHostName = InetAddress.getLocalHost().getHostName();
+ } catch (UnknownHostException ex) {
+ resolvedHostName = localHost;
+ }
+
+ if (hostname1.length() == 0)
+ hostname1 = resolvedHostName;
+
+ if (hostname2.length() == 0)
+ hostname2 = resolvedHostName;
+
+ if (hostname1.equals(hostname2))
+ return true;
+
+ if ((hostname1.equals(localHost) && hostname2.equals(resolvedHostName))
+ || (hostname1.equals(resolvedHostName) && hostname2.equals(localHost)))
+ return true;
+
+ try {
+ String ipAddress1 = InetAddress.getByName(hostname1).getHostAddress();
+ String ipAddress2 = InetAddress.getByName(hostname2).getHostAddress();
+
+ return ipAddress1.equals(ipAddress2);
+ } catch (UnknownHostException ex) {
+ // Ignore it.
+ }
+
+ return false;
+ }
+
}