| /******************************************************************************* |
| * Copyright (c) 2004, 2007 Mylyn project committers and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| *******************************************************************************/ |
| |
| package org.eclipse.mylyn.internal.team.ui.actions; |
| |
| import java.util.Collection; |
| import java.util.Collections; |
| |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.jface.action.Action; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.mylyn.internal.tasks.core.AbstractTask; |
| import org.eclipse.mylyn.internal.tasks.core.RepositoryTaskHandleUtil; |
| import org.eclipse.mylyn.internal.tasks.core.TaskRepositoryManager; |
| import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin; |
| import org.eclipse.mylyn.internal.tasks.ui.actions.OpenRepositoryTask; |
| import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal; |
| import org.eclipse.mylyn.internal.team.ui.FocusedTeamUiPlugin; |
| import org.eclipse.mylyn.internal.team.ui.LinkedTaskInfo; |
| import org.eclipse.mylyn.internal.team.ui.templates.CommitTemplateManager; |
| import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector; |
| import org.eclipse.mylyn.tasks.core.ITask; |
| import org.eclipse.mylyn.tasks.core.TaskRepository; |
| import org.eclipse.mylyn.tasks.ui.AbstractRepositoryConnectorUi; |
| import org.eclipse.mylyn.tasks.ui.TasksUi; |
| import org.eclipse.mylyn.tasks.ui.TasksUiImages; |
| import org.eclipse.mylyn.tasks.ui.TasksUiUtil; |
| import org.eclipse.mylyn.team.ui.AbstractTaskReference; |
| import org.eclipse.ui.IViewActionDelegate; |
| import org.eclipse.ui.IViewPart; |
| import org.eclipse.ui.IWorkbenchWindow; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.internal.ObjectPluginAction; |
| |
| /** |
| * Action used to open linked task. |
| * |
| * TODO: this class has evolved into a complete mess and has to be fixed. |
| * |
| * @author Mik Kersten |
| * @author Eugene Kuleshov |
| */ |
| public class OpenCorrespondingTaskAction extends Action implements IViewActionDelegate { |
| |
| private static final String LABEL = "Open Corresponding Task"; |
| |
| private static final String PREFIX_HTTP = "http://"; |
| |
| private static final String PREFIX_HTTPS = "https://"; |
| |
| private ISelection selection; |
| |
| public OpenCorrespondingTaskAction() { |
| setText(LABEL); |
| setToolTipText(LABEL); |
| setImageDescriptor(TasksUiImages.TASK_REPOSITORY); |
| } |
| |
| public void init(IViewPart view) { |
| // ignore |
| } |
| |
| @Override |
| public void run() { |
| if (selection instanceof StructuredSelection) { |
| run((StructuredSelection) selection); |
| } |
| } |
| |
| public void run(IAction action) { |
| if (action instanceof ObjectPluginAction) { |
| ObjectPluginAction objectAction = (ObjectPluginAction) action; |
| if (objectAction.getSelection() instanceof StructuredSelection) { |
| StructuredSelection selection = (StructuredSelection) objectAction.getSelection(); |
| run(selection); |
| } |
| } |
| } |
| |
| private void run(StructuredSelection selection) { |
| final Object element = selection.getFirstElement(); |
| |
| Job job = new OpenCorrespondingTaskJob("Opening Corresponding Task", element); |
| job.schedule(); |
| } |
| |
| public void selectionChanged(IAction action, ISelection selection) { |
| this.selection = selection; |
| } |
| |
| /** |
| * Reconcile <code>ILinkedTaskInfo</code> data. |
| * |
| * This is used in order to keep LinkedTaskInfo lightweight with minimal dependencies. |
| */ |
| private static AbstractTaskReference reconcile(AbstractTaskReference info) { |
| ITask task; |
| if (info instanceof LinkedTaskInfo) { |
| task = ((LinkedTaskInfo) info).getTask(); |
| } else { |
| task = null; |
| } |
| |
| if (task != null) { |
| return info; |
| } |
| |
| String repositoryUrl = info.getRepositoryUrl(); |
| String taskId = info.getTaskId(); |
| String taskFullUrl = info.getTaskUrl(); |
| String comment = info.getText(); |
| |
| TaskRepositoryManager repositoryManager = TasksUiPlugin.getRepositoryManager(); |
| |
| TaskRepository repository = null; |
| if (repositoryUrl != null) { |
| repository = repositoryManager.getRepository(repositoryUrl); |
| } |
| |
| if (taskFullUrl == null && comment != null) { |
| taskFullUrl = getUrlFromComment(comment); |
| } |
| |
| AbstractRepositoryConnector connector = null; |
| if (taskFullUrl != null) { |
| connector = repositoryManager.getConnectorForRepositoryTaskUrl(taskFullUrl); |
| } |
| if (connector == null && repository != null) { |
| connector = repositoryManager.getRepositoryConnector(repository.getConnectorKind()); |
| } |
| |
| if (repositoryUrl == null && connector != null) { |
| repositoryUrl = connector.getRepositoryUrlFromTaskUrl(taskFullUrl); |
| if (repository == null) { |
| repository = repositoryManager.getRepository(repositoryUrl); |
| } |
| } |
| |
| if (taskId == null && connector != null) { |
| taskId = connector.getTaskIdFromTaskUrl(taskFullUrl); |
| } |
| |
| // XXX: clean up and remove break to label |
| if (taskId == null && comment != null) { |
| Collection<AbstractRepositoryConnector> connectors = connector != null ? Collections.singletonList(connector) |
| : TasksUi.getRepositoryManager().getRepositoryConnectors(); |
| REPOSITORIES: for (AbstractRepositoryConnector c : connectors) { |
| Collection<TaskRepository> repositories = repository != null ? Collections.singletonList(repository) |
| : TasksUi.getRepositoryManager().getRepositories(c.getConnectorKind()); |
| for (TaskRepository r : repositories) { |
| String[] ids = c.getTaskIdsFromComment(r, comment); |
| if (ids != null && ids.length > 0) { |
| taskId = ids[0]; |
| connector = c; |
| repository = r; |
| repositoryUrl = r.getRepositoryUrl(); |
| break REPOSITORIES; |
| } |
| } |
| } |
| } |
| if (taskId == null && comment != null) { |
| CommitTemplateManager commitTemplateManager = FocusedTeamUiPlugin.getDefault().getCommitTemplateManager(); |
| taskId = commitTemplateManager.getTaskIdFromCommentOrLabel(comment); |
| if (taskId == null) { |
| taskId = getTaskIdFromLegacy07Label(comment); |
| } |
| } |
| |
| if (taskFullUrl == null && repositoryUrl != null && taskId != null && connector != null) { |
| taskFullUrl = connector.getTaskUrl(repositoryUrl, taskId); |
| } |
| |
| if (task == null) { |
| if (taskId != null && repositoryUrl != null) { |
| // XXX fix this hack (jira ids don't work here) |
| if (!taskId.contains(RepositoryTaskHandleUtil.HANDLE_DELIM)) { |
| // String handle = AbstractTask.getHandle(repositoryUrl, taskId); |
| task = TasksUiInternal.getTaskList().getTask(repositoryUrl, taskId); |
| } |
| } |
| if (task == null && taskFullUrl != null) { |
| // search by fullUrl |
| for (AbstractTask currTask : TasksUiPlugin.getTaskList().getAllTasks()) { |
| if (currTask != null) { |
| String currUrl = currTask.getUrl(); |
| if (taskFullUrl.equals(currUrl)) { |
| return new LinkedTaskInfo(currTask, null); |
| } |
| } |
| } |
| } |
| } |
| if (task != null) { |
| return new LinkedTaskInfo(task, null); |
| } |
| |
| return new LinkedTaskInfo(repositoryUrl, taskId, taskFullUrl, comment); |
| } |
| |
| public static String getUrlFromComment(String comment) { |
| int httpIndex = comment.indexOf(PREFIX_HTTP); |
| int httpsIndex = comment.indexOf(PREFIX_HTTPS); |
| int idStart = -1; |
| if (httpIndex != -1) { |
| idStart = httpIndex; |
| } else if (httpsIndex != -1) { |
| idStart = httpsIndex; |
| } |
| if (idStart != -1) { |
| int idEnd = comment.indexOf(' ', idStart); |
| if (idEnd == -1) { |
| return comment.substring(idStart); |
| } else if (idEnd != -1 && idStart < idEnd) { |
| return comment.substring(idStart, idEnd); |
| } |
| } |
| return null; |
| } |
| |
| public static String getTaskIdFromLegacy07Label(String comment) { |
| String PREFIX_DELIM = ":"; |
| String PREFIX_START_1 = "Progress on:"; |
| String PREFIX_START_2 = "Completed:"; |
| String usedPrefix = PREFIX_START_1; |
| int firstDelimIndex = comment.indexOf(PREFIX_START_1); |
| if (firstDelimIndex == -1) { |
| firstDelimIndex = comment.indexOf(PREFIX_START_2); |
| usedPrefix = PREFIX_START_2; |
| } |
| if (firstDelimIndex != -1) { |
| int idStart = firstDelimIndex + usedPrefix.length(); |
| int idEnd = comment.indexOf(PREFIX_DELIM, firstDelimIndex + usedPrefix.length());// comment.indexOf(PREFIX_DELIM); |
| if (idEnd != -1 && idStart < idEnd) { |
| String id = comment.substring(idStart, idEnd); |
| if (id != null) { |
| return id.trim(); |
| } |
| } else { |
| return comment.substring(0, firstDelimIndex); |
| } |
| } |
| return null; |
| } |
| |
| private static final class OpenCorrespondingTaskJob extends Job { |
| private final Object element; |
| |
| private OpenCorrespondingTaskJob(String name, Object element) { |
| super(name); |
| this.element = element; |
| } |
| |
| @Override |
| protected IStatus run(IProgressMonitor monitor) { |
| AbstractTaskReference info = null; |
| if (element instanceof AbstractTaskReference) { |
| info = (AbstractTaskReference) element; |
| } else if (element instanceof IAdaptable) { |
| info = (AbstractTaskReference) ((IAdaptable) element).getAdapter(AbstractTaskReference.class); |
| } |
| if (info == null) { |
| info = (AbstractTaskReference) Platform.getAdapterManager().getAdapter(element, |
| AbstractTaskReference.class); |
| } |
| |
| if (info != null) { |
| info = reconcile(info); |
| final ITask task; |
| if (info instanceof LinkedTaskInfo) { |
| task = ((LinkedTaskInfo) info).getTask(); |
| } else { |
| task = null; |
| } |
| if (task != null) { |
| PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { |
| public void run() { |
| TasksUiUtil.openTask(task); |
| } |
| }); |
| return Status.OK_STATUS; |
| } |
| if (info.getRepositoryUrl() != null && info.getTaskId() != null) { |
| TaskRepository repository = TasksUiPlugin.getRepositoryManager().getRepository( |
| info.getRepositoryUrl()); |
| String taskId = info.getTaskId(); |
| if (repository != null && taskId != null) { |
| AbstractRepositoryConnectorUi connectorUi = TasksUiPlugin.getConnectorUi(repository.getConnectorKind()); |
| if (connectorUi != null) { |
| TasksUiInternal.openRepositoryTask(connectorUi.getConnectorKind(), |
| repository.getRepositoryUrl(), taskId); |
| return Status.OK_STATUS; |
| } |
| } |
| } |
| final String taskFullUrl = info.getTaskUrl(); |
| if (taskFullUrl != null) { |
| PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { |
| public void run() { |
| TasksUiUtil.openUrl(taskFullUrl); |
| } |
| }); |
| |
| return Status.OK_STATUS; |
| } |
| } |
| |
| PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { |
| public void run() { |
| IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); |
| boolean openDialog = MessageDialog.openQuestion(window.getShell(), "Open Task", |
| "Unable to match task. Open Repository Task dialog?"); |
| if (openDialog) { |
| new OpenRepositoryTask().run(null); |
| } |
| } |
| }); |
| |
| return Status.OK_STATUS; |
| } |
| } |
| |
| } |