/******************************************************************************* * Copyright (c) 2004, 2013 Tasktop Technologies 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 * * Contributors: * Tasktop Technologies - initial API and implementation * Eugene Kuleshov - improvements * Frank Becker - improvements *******************************************************************************/ package org.eclipse.mylyn.internal.bugzilla.ui.tasklist; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.text.Region; import org.eclipse.jface.text.hyperlink.IHyperlink; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.IWizard; import org.eclipse.jface.wizard.IWizardPage; import org.eclipse.mylyn.commons.ui.PlatformUiUtil; import org.eclipse.mylyn.internal.bugzilla.core.BugzillaAttribute; import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCorePlugin; import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants; import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaImages; import org.eclipse.mylyn.internal.bugzilla.ui.TaskAttachmentHyperlink; import org.eclipse.mylyn.internal.bugzilla.ui.TaskAttachmentTableEditorHyperlink; import org.eclipse.mylyn.internal.bugzilla.ui.search.BugzillaSearchPage; import org.eclipse.mylyn.internal.bugzilla.ui.wizard.NewBugzillaTaskWizard; import org.eclipse.mylyn.tasks.core.IRepositoryQuery; import org.eclipse.mylyn.tasks.core.ITask; import org.eclipse.mylyn.tasks.core.ITaskMapping; import org.eclipse.mylyn.tasks.core.TaskRepository; import org.eclipse.mylyn.tasks.core.data.TaskAttachmentModel; import org.eclipse.mylyn.tasks.core.data.TaskAttribute; import org.eclipse.mylyn.tasks.ui.AbstractRepositoryConnectorUi; import org.eclipse.mylyn.tasks.ui.LegendElement; import org.eclipse.mylyn.tasks.ui.TaskHyperlink; import org.eclipse.mylyn.tasks.ui.wizards.AbstractRepositoryQueryPage; import org.eclipse.mylyn.tasks.ui.wizards.ITaskRepositoryPage; import org.eclipse.mylyn.tasks.ui.wizards.RepositoryQueryWizard; /** * @author Mik Kersten * @author Robert Elves * @author Frank Becker */ public class BugzillaConnectorUi extends AbstractRepositoryConnectorUi { private static final String BUG = "(?:duplicate of|bug|task)[ \t]*(?:#|:)?[ \t]*(\\d+)"; //$NON-NLS-1$ private static final String COMMENT = "comment[ \t]*#?[ \t]*(\\d+)"; //$NON-NLS-1$ private static final String REGEXP_BUG = "(?:\\W||^)(" + BUG + "(?:[ \t]*" + COMMENT + ")?)|(" + COMMENT + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ private static final String REGEXP_ATTACHMENT = "(?:Created (?:an )?)?attachment[ \t]*#?[ \t]*(?:\\(id=)?(\\d+)\\)?"; //$NON-NLS-1$ private static final Pattern PATTERN_BUG = Pattern.compile(REGEXP_BUG, Pattern.CASE_INSENSITIVE); private static final Pattern PATTERN_ATTACHMENT = Pattern.compile(REGEXP_ATTACHMENT, Pattern.CASE_INSENSITIVE); private final boolean doAttachmentTableEditorHyperlink; public BugzillaConnectorUi() { doAttachmentTableEditorHyperlink = PlatformUiUtil.supportsMultipleHyperlinkPresenter(); } @Override public String getAccountCreationUrl(TaskRepository taskRepository) { return taskRepository.getRepositoryUrl() + "/createaccount.cgi"; //$NON-NLS-1$ } @Override public String getAccountManagementUrl(TaskRepository taskRepository) { return taskRepository.getRepositoryUrl() + "/userprefs.cgi"; //$NON-NLS-1$ } @Override public String getTaskHistoryUrl(TaskRepository taskRepository, ITask task) { return taskRepository.getRepositoryUrl() + IBugzillaConstants.URL_BUG_ACTIVITY + task.getTaskId(); } @Override public List<LegendElement> getLegendElements() { List<LegendElement> legendItems = new ArrayList<LegendElement>(); legendItems.add(LegendElement.createTask("blocker", BugzillaImages.OVERLAY_CRITICAL)); //$NON-NLS-1$ legendItems.add(LegendElement.createTask("critical", BugzillaImages.OVERLAY_CRITICAL)); //$NON-NLS-1$ legendItems.add(LegendElement.createTask("major", BugzillaImages.OVERLAY_CRITICAL)); //$NON-NLS-1$ legendItems.add(LegendElement.createTask("normal", null)); //$NON-NLS-1$ legendItems.add(LegendElement.createTask("minor", BugzillaImages.OVERLAY_MAJOR)); //$NON-NLS-1$ legendItems.add(LegendElement.createTask("enhancement", BugzillaImages.OVERLAY_ENHANCEMENT)); //$NON-NLS-1$ legendItems.add(LegendElement.createTask("trivial", BugzillaImages.OVERLAY_TRIVIAL)); //$NON-NLS-1$ return legendItems; } @Override public ImageDescriptor getTaskKindOverlay(ITask task) { String severity = task.getAttribute(BugzillaAttribute.BUG_SEVERITY.getKey()); if (severity != null) { // XXX: refactor to use configuration if ("blocker".equals(severity) || "critical".equals(severity) || "major".equals(severity)) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ return BugzillaImages.OVERLAY_CRITICAL; } else if ("minor".equals(severity)) { //$NON-NLS-1$ return BugzillaImages.OVERLAY_MAJOR; } else if ("enhancement".equals(severity)) { //$NON-NLS-1$ return BugzillaImages.OVERLAY_ENHANCEMENT; } else if ("trivial".equals(severity)) { //$NON-NLS-1$ return BugzillaImages.OVERLAY_TRIVIAL; } else { return null; } } return super.getTaskKindOverlay(task); } @Override public String getTaskKindLabel(ITask repositoryTask) { return IBugzillaConstants.BUGZILLA_TASK_KIND; } @Override public ITaskRepositoryPage getSettingsPage(TaskRepository taskRepository) { return new BugzillaRepositorySettingsPage(taskRepository); } @Override public AbstractRepositoryQueryPage getSearchPage(TaskRepository repository, IStructuredSelection selection) { return new BugzillaSearchPage(repository); } @Override public IWizard getNewTaskWizard(TaskRepository taskRepository, ITaskMapping selection) { return new NewBugzillaTaskWizard(taskRepository, selection); } @Override public IWizard getQueryWizard(TaskRepository repository, IRepositoryQuery query) { RepositoryQueryWizard wizard = new RepositoryQueryWizard(repository); if (query == null) { wizard.addPage(new BugzillaQueryTypeWizardPage(repository)); } else { if (isCustomQuery(query)) { wizard.addPage(new BugzillaCustomQueryWizardPage(repository, query)); } else { wizard.addPage(new BugzillaSearchPage(repository, query)); } } return wizard; } @Override public boolean hasSearchPage() { return true; } @Override public String getConnectorKind() { return BugzillaCorePlugin.CONNECTOR_KIND; } private boolean isCustomQuery(IRepositoryQuery query2) { String custom = query2.getAttribute(IBugzillaConstants.ATTRIBUTE_BUGZILLA_QUERY_CUSTOM); return custom != null && custom.equals(Boolean.TRUE.toString()); } @Override public IWizardPage getTaskAttachmentPage(TaskAttachmentModel model) { return new BugzillaTaskAttachmentPage(model); } @Deprecated @Override public IHyperlink[] findHyperlinks(TaskRepository repository, String text, int index, int textOffset) { return findHyperlinks(repository, null, text, index, textOffset); } @Override public IHyperlink[] findHyperlinks(TaskRepository repository, ITask task, String text, int index, int textOffset) { ArrayList<IHyperlink> hyperlinksFound = null; Matcher mb = PATTERN_BUG.matcher(text); while (mb.find()) { if (index == -1 || (index >= mb.start() && index <= mb.end())) { TaskHyperlink link = null; if (mb.group(1) != null) { // bug comment Region region = new Region(textOffset + mb.start(1), mb.end(1) - mb.start(1)); link = new TaskHyperlink(region, repository, mb.group(2)); if (mb.group(3) != null) { link.setSelection(TaskAttribute.PREFIX_COMMENT + mb.group(3)); } } else if (task != null && mb.group(4) != null) { // comment Region region = new Region(textOffset + mb.start(4), mb.end(4) - mb.start(4)); link = new TaskHyperlink(region, repository, task.getTaskId()); link.setSelection(TaskAttribute.PREFIX_COMMENT + mb.group(5)); } if (link != null) { if (hyperlinksFound == null) { hyperlinksFound = new ArrayList<IHyperlink>(); } hyperlinksFound.add(link); } } } Matcher ma = PATTERN_ATTACHMENT.matcher(text); while (ma.find()) { if (index == -1 || (index >= ma.start() && index <= ma.end())) { // attachment Region region = new Region(textOffset + ma.start(), ma.end() - ma.start()); TaskAttachmentHyperlink link0 = new TaskAttachmentHyperlink(region, repository, ma.group(1)); if (hyperlinksFound == null) { hyperlinksFound = new ArrayList<IHyperlink>(); } hyperlinksFound.add(link0); if (doAttachmentTableEditorHyperlink) { hyperlinksFound.add(new TaskAttachmentTableEditorHyperlink(region, repository, ma.group(1))); } } } return (hyperlinksFound != null) ? hyperlinksFound.toArray(new IHyperlink[0]) : null; } }