Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormkersten2007-06-07 14:46:12 -0400
committermkersten2007-06-07 14:46:12 -0400
commit498ef850601aac16bde56c5f896ac9d00f780a1a (patch)
tree5d484f39078bbc1db8928fd36e2ae9d8af68f8e0
parent497c8061cb819fd12dbdccfdd3be4942a13770a7 (diff)
downloadorg.eclipse.mylyn.tasks-498ef850601aac16bde56c5f896ac9d00f780a1a.tar.gz
org.eclipse.mylyn.tasks-498ef850601aac16bde56c5f896ac9d00f780a1a.tar.xz
org.eclipse.mylyn.tasks-498ef850601aac16bde56c5f896ac9d00f780a1a.zip
NEW - bug 187602: Provide extension point for specifying duplicate detectors
https://bugs.eclipse.org/bugs/show_bug.cgi?id=187602
-rw-r--r--org.eclipse.mylyn.bugzilla.ui/plugin.xml11
-rw-r--r--org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/DummySearchHitProvider.java36
-rw-r--r--org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/NewBugzillaTaskEditor.java35
-rw-r--r--org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/search/StackTraceDuplicateDetector.java59
-rw-r--r--org.eclipse.mylyn.tasks.ui/plugin.xml4
-rw-r--r--org.eclipse.mylyn.tasks.ui/schema/duplicateDetectors.exsd116
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TasksUiExtensionReader.java100
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/AbstractDuplicateDetector.java39
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/TasksUiPlugin.java38
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AbstractNewRepositoryTaskEditor.java164
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/search/SearchHitCollector.java10
-rw-r--r--org.eclipse.mylyn.trac.ui/src/org/eclipse/mylyn/internal/trac/ui/editor/NewTracTaskEditor.java5
12 files changed, 482 insertions, 135 deletions
diff --git a/org.eclipse.mylyn.bugzilla.ui/plugin.xml b/org.eclipse.mylyn.bugzilla.ui/plugin.xml
index d74f0deca..9d637ff52 100644
--- a/org.eclipse.mylyn.bugzilla.ui/plugin.xml
+++ b/org.eclipse.mylyn.bugzilla.ui/plugin.xml
@@ -38,4 +38,15 @@
<newWizardShortcut id="org.eclipse.mylar.bugzilla.bugWizard"/>
</perspectiveExtension>
</extension>
+
+
+
+ <extension
+ point="org.eclipse.mylar.tasks.ui.duplicateDetectors">
+ <detector class="org.eclipse.mylar.internal.bugzilla.ui.search.StackTraceDuplicateDetector"
+ name="Stack Trace">
+ </detector>
+
+ </extension>
+
</plugin>
diff --git a/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/DummySearchHitProvider.java b/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/DummySearchHitProvider.java
new file mode 100644
index 000000000..19c813c74
--- /dev/null
+++ b/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/DummySearchHitProvider.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2006 University Of British Columbia 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:
+ * University Of British Columbia - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylar.internal.bugzilla.ui.editor;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.mylar.tasks.core.AbstractRepositoryTask;
+import org.eclipse.mylar.tasks.core.ITaskFactory;
+import org.eclipse.mylar.tasks.core.QueryHitCollector;
+import org.eclipse.mylar.tasks.core.RepositoryTaskData;
+import org.eclipse.mylar.tasks.core.TaskList;
+
+public class DummySearchHitProvider extends QueryHitCollector {
+
+ public DummySearchHitProvider(TaskList tasklist) {
+ super(tasklist, new ITaskFactory() {
+
+ public AbstractRepositoryTask createTask(RepositoryTaskData taskData, boolean synchData,
+ boolean forced, IProgressMonitor monitor) throws CoreException {
+ return null;
+ }
+ });
+ // ignore
+ }
+
+
+}
diff --git a/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/NewBugzillaTaskEditor.java b/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/NewBugzillaTaskEditor.java
index 59ac5c2b8..2c9bd85b1 100644
--- a/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/NewBugzillaTaskEditor.java
+++ b/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/NewBugzillaTaskEditor.java
@@ -10,17 +10,14 @@
*******************************************************************************/
package org.eclipse.mylar.internal.bugzilla.ui.editor;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
+import java.util.List;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.mylar.core.MylarStatusHandler;
-import org.eclipse.mylar.internal.bugzilla.core.BugzillaRepositoryQuery;
import org.eclipse.mylar.tasks.core.RepositoryTaskAttribute;
-import org.eclipse.mylar.tasks.ui.TaskFactory;
+import org.eclipse.mylar.tasks.ui.AbstractDuplicateDetector;
import org.eclipse.mylar.tasks.ui.TasksUiPlugin;
import org.eclipse.mylar.tasks.ui.editors.AbstractNewRepositoryTaskEditor;
import org.eclipse.mylar.tasks.ui.search.SearchHitCollector;
@@ -102,23 +99,21 @@ public class NewBugzillaTaskEditor extends AbstractNewRepositoryTaskEditor {
}
@Override
- public SearchHitCollector getDuplicateSearchCollector(String searchString) {
- String queryUrl = "";
- try {
- queryUrl = repository.getUrl() + "/buglist.cgi?long_desc_type=allwordssubstr&long_desc="
- + URLEncoder.encode(searchString, repository.getCharacterEncoding());
- } catch (UnsupportedEncodingException e) {
- MylarStatusHandler.log(e, "Error during duplicate detection");
- return null;
- }
-
- queryUrl += "&product=" + taskData.getProduct();
+ public SearchHitCollector getDuplicateSearchCollector(String name) {
+ String duplicateDetectorName = name.equals("default") ? "Stack Trace" : name;
+ List<AbstractDuplicateDetector> allDetectors = getDuplicateSearchCollectorsList();
- BugzillaRepositoryQuery bugzillaQuery = new BugzillaRepositoryQuery(repository.getUrl(), queryUrl, "search");
+ for (AbstractDuplicateDetector detector : allDetectors) {
+ if (detector.getName().equals(duplicateDetectorName)) {
+ return detector.getSearchHitCollector(repository, taskData);
+ }
+ }
+ // didn't find it
+ return null;
+ }
- SearchHitCollector collector = new SearchHitCollector(TasksUiPlugin.getTaskListManager().getTaskList(),
- repository, bugzillaQuery, new TaskFactory(repository));
- return collector;
+ protected List<AbstractDuplicateDetector> getDuplicateSearchCollectorsList() {
+ return TasksUiPlugin.getDefault().getDuplicateSearchCollectorsList();
}
@Override
diff --git a/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/search/StackTraceDuplicateDetector.java b/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/search/StackTraceDuplicateDetector.java
new file mode 100644
index 000000000..aa180d418
--- /dev/null
+++ b/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/search/StackTraceDuplicateDetector.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2006 Mylar 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.mylar.internal.bugzilla.ui.search;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.mylar.core.MylarStatusHandler;
+import org.eclipse.mylar.internal.bugzilla.core.BugzillaRepositoryQuery;
+import org.eclipse.mylar.tasks.core.RepositoryTaskData;
+import org.eclipse.mylar.tasks.core.TaskRepository;
+import org.eclipse.mylar.tasks.ui.AbstractDuplicateDetector;
+import org.eclipse.mylar.tasks.ui.TaskFactory;
+import org.eclipse.mylar.tasks.ui.TasksUiPlugin;
+import org.eclipse.mylar.tasks.ui.editors.AbstractNewRepositoryTaskEditor;
+import org.eclipse.mylar.tasks.ui.search.SearchHitCollector;
+
+/**
+ * @author Meghan Allen
+ */
+public class StackTraceDuplicateDetector extends AbstractDuplicateDetector {
+
+ private static final String NO_STACK_MESSAGE = "Unable to locate a stack trace in the description text.";
+
+ @Override
+ public SearchHitCollector getSearchHitCollector(TaskRepository repository, RepositoryTaskData taskData) {
+ String queryUrl = "";
+ String searchString = AbstractNewRepositoryTaskEditor.getStackTraceFromDescription(taskData.getDescription());
+
+ if (searchString == null) {
+ MessageDialog.openWarning(null, "No Stack Trace Found", NO_STACK_MESSAGE);
+ return null;
+ }
+
+ try {
+ queryUrl = repository.getUrl() + "/buglist.cgi?long_desc_type=allwordssubstr&long_desc="
+ + URLEncoder.encode(searchString, repository.getCharacterEncoding());
+ } catch (UnsupportedEncodingException e) {
+ MylarStatusHandler.log(e, "Error during duplicate detection");
+ return null;
+ }
+
+ queryUrl += "&product=" + taskData.getProduct();
+
+ BugzillaRepositoryQuery bugzillaQuery = new BugzillaRepositoryQuery(repository.getUrl(), queryUrl, "search");
+
+ SearchHitCollector collector = new SearchHitCollector(TasksUiPlugin.getTaskListManager().getTaskList(),
+ repository, bugzillaQuery, new TaskFactory(repository));
+ return collector;
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.ui/plugin.xml b/org.eclipse.mylyn.tasks.ui/plugin.xml
index d995167b8..65fadaa9d 100644
--- a/org.eclipse.mylyn.tasks.ui/plugin.xml
+++ b/org.eclipse.mylyn.tasks.ui/plugin.xml
@@ -5,6 +5,7 @@
<extension-point id="repositories" name="Task Repositories" schema="schema/repositories.exsd"/>
<extension-point id="editors" name="Task Editors" schema="schema/editors.exsd"/>
<extension-point id="projectLinkProviders" name="Linking Provider from Project to the Task Repository" schema="schema/projectLinkProviders.exsd"/>
+ <extension-point id="duplicateDetectors" name="duplicateDetectors" schema="schema/duplicateDetectors.exsd"/>
<!--
<extension
@@ -840,8 +841,7 @@
class="org.eclipse.mylar.internal.tasks.ui.workingset.TaskElementFactory"
id="org.eclipse.mylar.tasks.ui.elementFactory">
</factory>
- </extension>
-
+</extension>
</plugin>
<!--
diff --git a/org.eclipse.mylyn.tasks.ui/schema/duplicateDetectors.exsd b/org.eclipse.mylyn.tasks.ui/schema/duplicateDetectors.exsd
new file mode 100644
index 000000000..3f933e582
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.ui/schema/duplicateDetectors.exsd
@@ -0,0 +1,116 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.mylar.tasks.ui">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.mylar.tasks.ui" id="duplicateDetectors" name="duplicateDetectors"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="detector"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="detector">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="kind" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TasksUiExtensionReader.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TasksUiExtensionReader.java
index 22b8e14ba..6aa040dd3 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TasksUiExtensionReader.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TasksUiExtensionReader.java
@@ -27,6 +27,7 @@ import org.eclipse.mylar.internal.tasks.ui.TasksUiImages;
import org.eclipse.mylar.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylar.tasks.core.ITaskListExternalizer;
import org.eclipse.mylar.tasks.core.RepositoryTemplate;
+import org.eclipse.mylar.tasks.ui.AbstractDuplicateDetector;
import org.eclipse.mylar.tasks.ui.AbstractRepositoryConnectorUi;
import org.eclipse.mylar.tasks.ui.AbstractTaskRepositoryLinkProvider;
import org.eclipse.mylar.tasks.ui.TasksUiPlugin;
@@ -53,7 +54,7 @@ public class TasksUiExtensionReader {
public static final String ELMNT_TMPL_URLREPOSITORY = "urlRepository";
public static final String ELMNT_TMPL_REPOSITORYKIND = "repositoryKind";
-
+
public static final String ELMNT_TMPL_CHARACTERENCODING = "characterEncoding";
public static final String ELMNT_TMPL_ANONYMOUS = "anonymous";
@@ -71,15 +72,15 @@ public class TasksUiExtensionReader {
public static final String ELMNT_TMPL_ADDAUTO = "addAutomatically";
public static final String ELMNT_REPOSITORY_CONNECTOR = "connectorCore";
-
+
public static final String ATTR_USER_MANAGED = "userManaged";
-
+
public static final String ATTR_CUSTOM_NOTIFICATIONS = "customNotifications";
public static final String ELMNT_REPOSITORY_LINK_PROVIDER = "linkProvider";
-
- public static final String ELMNT_REPOSITORY_UI= "connectorUi";
-
+
+ public static final String ELMNT_REPOSITORY_UI = "connectorUi";
+
public static final String ELMNT_EXTERNALIZER = "externalizer";
public static final String ATTR_BRANDING_ICON = "brandingIcon";
@@ -101,7 +102,7 @@ public class TasksUiExtensionReader {
public static final String ATTR_CLASS = "class";
public static final String ATTR_MENU_PATH = "menuPath";
-
+
public static final String EXTENSION_EDITORS = "org.eclipse.mylar.tasks.ui.editors";
public static final String ELMNT_EDITOR_FACTORY = "editorFactory";
@@ -110,6 +111,14 @@ public class TasksUiExtensionReader {
public static final String ELMNT_HYPERLINK_DETECTOR = "hyperlinkDetector";
+ public static final String EXTENSION_DUPLICATE_DETECTORS = "org.eclipse.mylar.tasks.ui.duplicateDetectors";
+
+ public static final String ELMNT_DUPLICATE_DETECTOR = "detector";
+
+ public static final String ATTR_NAME = "name";
+
+ public static final String ATTR_KIND = "kind";
+
private static boolean coreExtensionsRead = false;
public static void initStartupExtensions(TaskListWriter delegatingExternalizer) {
@@ -180,7 +189,7 @@ public class TasksUiExtensionReader {
for (int j = 0; j < elements.length; j++) {
if (elements[j].getName().equals(ELMNT_REPOSITORY_UI)) {
readRepositoryConnectorUi(elements[j]);
- }
+ }
}
}
@@ -191,20 +200,48 @@ public class TasksUiExtensionReader {
for (int j = 0; j < elements.length; j++) {
if (elements[j].getName().equals(ELMNT_REPOSITORY_LINK_PROVIDER)) {
readLinkProvider(elements[j]);
- }
+ }
+ }
+ }
+
+ IExtensionPoint duplicateDetectorsExtensionPoint = registry.getExtensionPoint(EXTENSION_DUPLICATE_DETECTORS);
+ IExtension[] dulicateDetectorsExtensions = duplicateDetectorsExtensionPoint.getExtensions();
+ for (int i = 0; i < dulicateDetectorsExtensions.length; i++) {
+ IConfigurationElement[] elements = dulicateDetectorsExtensions[i].getConfigurationElements();
+ for (int j = 0; j < elements.length; j++) {
+ if (elements[j].getName().equals(ELMNT_DUPLICATE_DETECTOR)) {
+ readDuplicateDetector(elements[j]);
+ }
}
}
-
+
+ }
+
+ private static void readDuplicateDetector(IConfigurationElement element) {
+ try {
+ Object obj = element.createExecutableExtension(ATTR_CLASS);
+ if (obj instanceof AbstractDuplicateDetector) {
+ AbstractDuplicateDetector duplicateDetector = (AbstractDuplicateDetector) obj;
+ duplicateDetector.setName(element.getAttribute(ATTR_NAME));
+ duplicateDetector.setKind(element.getAttribute(ATTR_KIND));
+ TasksUiPlugin.getDefault().addDuplicateDetector((AbstractDuplicateDetector) duplicateDetector);
+ } else {
+ MylarStatusHandler.log("Could not load duplicate detector: " + obj.getClass().getCanonicalName(), null);
+ }
+ } catch (CoreException e) {
+ MylarStatusHandler.log(e, "Could not load duplicate detector extension");
+ }
}
-
+
private static void readLinkProvider(IConfigurationElement element) {
try {
Object repositoryLinkProvider = element.createExecutableExtension(ATTR_CLASS);
if (repositoryLinkProvider instanceof AbstractTaskRepositoryLinkProvider) {
- TasksUiPlugin.getDefault().addRepositoryLinkProvider((AbstractTaskRepositoryLinkProvider) repositoryLinkProvider);
+ TasksUiPlugin.getDefault().addRepositoryLinkProvider(
+ (AbstractTaskRepositoryLinkProvider) repositoryLinkProvider);
} else {
- MylarStatusHandler.log("Could not load repository link provider: " + repositoryLinkProvider.getClass().getCanonicalName(),
- null);
+ MylarStatusHandler.log("Could not load repository link provider: "
+ + repositoryLinkProvider.getClass().getCanonicalName(), null);
}
} catch (CoreException e) {
MylarStatusHandler.log(e, "Could not load repository link provider extension");
@@ -246,12 +283,12 @@ public class TasksUiExtensionReader {
if (connectorCore instanceof AbstractRepositoryConnector && type != null) {
AbstractRepositoryConnector repositoryConnector = (AbstractRepositoryConnector) connectorCore;
TasksUiPlugin.getRepositoryManager().addRepositoryConnector(repositoryConnector);
-
+
String userManagedString = element.getAttribute(ATTR_USER_MANAGED);
- if(userManagedString != null){
+ if (userManagedString != null) {
boolean userManaged = Boolean.parseBoolean(userManagedString);
- repositoryConnector.setUserManaged(userManaged);
- }
+ repositoryConnector.setUserManaged(userManaged);
+ }
} else {
MylarStatusHandler.log("could not not load connector core: " + connectorCore, null);
}
@@ -265,21 +302,22 @@ public class TasksUiExtensionReader {
try {
Object connectorUiObject = element.createExecutableExtension(ATTR_CLASS);
if (connectorUiObject instanceof AbstractRepositoryConnectorUi) {
- AbstractRepositoryConnectorUi connectorUi = (AbstractRepositoryConnectorUi)connectorUiObject;
+ AbstractRepositoryConnectorUi connectorUi = (AbstractRepositoryConnectorUi) connectorUiObject;
TasksUiPlugin.addRepositoryConnectorUi((AbstractRepositoryConnectorUi) connectorUi);
String customNotificationsString = element.getAttribute(ATTR_CUSTOM_NOTIFICATIONS);
- if(customNotificationsString != null){
+ if (customNotificationsString != null) {
boolean customNotifications = Boolean.parseBoolean(customNotificationsString);
- connectorUi.setCustomNotificationHandling(customNotifications);
+ connectorUi.setCustomNotificationHandling(customNotifications);
}
-
+
String iconPath = element.getAttribute(ATTR_BRANDING_ICON);
if (iconPath != null) {
ImageDescriptor descriptor = AbstractUIPlugin.imageDescriptorFromPlugin(element.getContributor()
.getName(), iconPath);
if (descriptor != null) {
- TasksUiPlugin.getDefault().addBrandingIcon(((AbstractRepositoryConnectorUi)connectorUi).getRepositoryType(),
+ TasksUiPlugin.getDefault().addBrandingIcon(
+ ((AbstractRepositoryConnectorUi) connectorUi).getRepositoryType(),
TasksUiImages.getImage(descriptor));
}
}
@@ -288,8 +326,8 @@ public class TasksUiExtensionReader {
ImageDescriptor descriptor = AbstractUIPlugin.imageDescriptorFromPlugin(element.getContributor()
.getName(), overlayIconPath);
if (descriptor != null) {
- TasksUiPlugin.getDefault().addOverlayIcon(((AbstractRepositoryConnectorUi)connectorUi).getRepositoryType(),
- descriptor);
+ TasksUiPlugin.getDefault().addOverlayIcon(
+ ((AbstractRepositoryConnectorUi) connectorUi).getRepositoryType(), descriptor);
}
}
} else {
@@ -300,7 +338,7 @@ public class TasksUiExtensionReader {
MylarStatusHandler.log(e, "Could not load tasklist listener extension");
}
}
-
+
private static void readRepositoryTemplate(IConfigurationElement element) {
boolean anonymous = false;
@@ -322,18 +360,18 @@ public class TasksUiExtensionReader {
&& TasksUiPlugin.getRepositoryManager().getRepositoryConnector(repKind) != null) {
AbstractRepositoryConnector connector = TasksUiPlugin.getRepositoryManager()
.getRepositoryConnector(repKind);
- RepositoryTemplate template = new RepositoryTemplate(label, serverUrl, encoding, version, newTaskUrl, taskPrefix,
- taskQueryUrl, newAccountUrl, anonymous, addAuto);
+ RepositoryTemplate template = new RepositoryTemplate(label, serverUrl, encoding, version, newTaskUrl,
+ taskPrefix, taskQueryUrl, newAccountUrl, anonymous, addAuto);
connector.addTemplate(template);
-
+
for (IConfigurationElement configElement : element.getChildren()) {
String name = configElement.getAttribute("name");
String value = configElement.getAttribute("value");
- if(name != null && !name.equals("") && value != null) {
+ if (name != null && !name.equals("") && value != null) {
template.addAttribute(name, value);
}
}
-
+
} else {
MylarStatusHandler.log("Could not load repository template extension " + element.getName(),
TasksUiExtensionReader.class);
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/AbstractDuplicateDetector.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/AbstractDuplicateDetector.java
new file mode 100644
index 000000000..998110d75
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/AbstractDuplicateDetector.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2006 Mylar 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.mylar.tasks.ui;
+
+import org.eclipse.mylar.tasks.core.RepositoryTaskData;
+import org.eclipse.mylar.tasks.core.TaskRepository;
+import org.eclipse.mylar.tasks.ui.search.SearchHitCollector;
+
+public abstract class AbstractDuplicateDetector {
+
+ protected String name;
+
+ protected String kind;
+
+ public abstract SearchHitCollector getSearchHitCollector(TaskRepository repository, RepositoryTaskData taskData);
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setKind(String kind) {
+ this.kind = kind;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public String getKind() {
+ return this.kind;
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/TasksUiPlugin.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/TasksUiPlugin.java
index 2ff2e8ffd..fab25dc9c 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/TasksUiPlugin.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/TasksUiPlugin.java
@@ -144,6 +144,8 @@ public class TasksUiPlugin extends AbstractUIPlugin implements IStartup {
private Map<String, ImageDescriptor> overlayIcons = new HashMap<String, ImageDescriptor>();
+ private List<AbstractDuplicateDetector> duplicateDetectors = new ArrayList<AbstractDuplicateDetector>();
+
private boolean eclipse_3_3_workbench = false;
private ISaveParticipant saveParticipant;
@@ -282,7 +284,8 @@ public class TasksUiPlugin extends AbstractUIPlugin implements IStartup {
repository.getKind());
AbstractRepositoryConnectorUi connectorUi = getRepositoryUi(repository.getKind());
if (connectorUi != null && !connectorUi.hasCustomNotificationHandling()) {
- for (AbstractRepositoryTask repositoryTask : TasksUiPlugin.getTaskListManager().getTaskList()
+ for (AbstractRepositoryTask repositoryTask : TasksUiPlugin.getTaskListManager()
+ .getTaskList()
.getRepositoryTasks(repository.getUrl())) {
if ((repositoryTask.getLastSyncDateStamp() == null || repositoryTask.getSyncState() == RepositoryTaskSyncState.INCOMING)
&& repositoryTask.isNotified() == false) {
@@ -385,8 +388,8 @@ public class TasksUiPlugin extends AbstractUIPlugin implements IStartup {
for (RepositoryTemplate template : connector.getTemplates()) {
if (template.addAutomatically) {
try {
- TaskRepository taskRepository = taskRepositoryManager.getRepository(connector
- .getRepositoryType(), template.repositoryUrl);
+ TaskRepository taskRepository = taskRepositoryManager.getRepository(
+ connector.getRepositoryType(), template.repositoryUrl);
if (taskRepository == null) {
taskRepository = new TaskRepository(connector.getRepositoryType(),
template.repositoryUrl, template.version);
@@ -783,17 +786,6 @@ public class TasksUiPlugin extends AbstractUIPlugin implements IStartup {
// }
}
-// /**
-// * Returns the path to the file caching the offline bug reports. PUBLIC FOR
-// * TESTING
-// */
-// public IPath getOfflineReportsFilePath() {
-// IPath stateLocation =
-// Platform.getStateLocation(TasksUiPlugin.getDefault().getBundle());
-// IPath configFile = stateLocation.append("offlineReports");
-// return configFile;
-// }
-
public TaskDataManager getTaskDataManager() {
if (taskDataManager == null) {
MylarStatusHandler.fail(null, "Offline reports file not created, try restarting.", true);
@@ -819,6 +811,16 @@ public class TasksUiPlugin extends AbstractUIPlugin implements IStartup {
return synchronizationManager;
}
+ public void addDuplicateDetector(AbstractDuplicateDetector duplicateDetector) {
+ if (duplicateDetector != null) {
+ duplicateDetectors.add(duplicateDetector);
+ }
+ }
+
+ public List<AbstractDuplicateDetector> getDuplicateSearchCollectorsList() {
+ return duplicateDetectors;
+ }
+
public String getRepositoriesFilePath() {
return getDataDirectory() + File.separator + TaskRepositoryManager.DEFAULT_REPOSITORIES_FILE;
}
@@ -872,8 +874,7 @@ public class TasksUiPlugin extends AbstractUIPlugin implements IStartup {
}
/**
- * Retrieve the task repository that has been associated with the given
- * project (or resource belonging to a project)
+ * Retrieve the task repository that has been associated with the given project (or resource belonging to a project)
*/
public TaskRepository getRepositoryForResource(IResource resource, boolean silent) {
if (resource == null) {
@@ -888,9 +889,8 @@ public class TasksUiPlugin extends AbstractUIPlugin implements IStartup {
}
if (!silent) {
- MessageDialog
- .openInformation(null, "No Repository Found",
- "No repository was found. Associate a Task Repository with this project via the project's property page.");
+ MessageDialog.openInformation(null, "No Repository Found",
+ "No repository was found. Associate a Task Repository with this project via the project's property page.");
}
return null;
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AbstractNewRepositoryTaskEditor.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AbstractNewRepositoryTaskEditor.java
index 56a788782..651934671 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AbstractNewRepositoryTaskEditor.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AbstractNewRepositoryTaskEditor.java
@@ -35,6 +35,7 @@ import org.eclipse.mylar.tasks.core.RepositoryTaskAttribute;
import org.eclipse.mylar.tasks.core.TaskCategory;
import org.eclipse.mylar.tasks.core.TaskList;
import org.eclipse.mylar.tasks.core.UncategorizedCategory;
+import org.eclipse.mylar.tasks.ui.AbstractDuplicateDetector;
import org.eclipse.mylar.tasks.ui.DatePicker;
import org.eclipse.mylar.tasks.ui.TasksUiPlugin;
import org.eclipse.mylar.tasks.ui.search.SearchHitCollector;
@@ -78,12 +79,16 @@ public abstract class AbstractNewRepositoryTaskEditor extends AbstractRepository
private static final String LABEL_SEARCH_DUPS = "Search for Duplicates";
- private static final String ERROR_CREATING_BUG_REPORT = "Error creating bug report";
+ private static final String LABEL_SELECT_DETECTOR = "Select duplicate detector:";
- private static final String NO_STACK_MESSAGE = "Unable to locate a stack trace in the description text.\nDuplicate search currently only supports stack trace matching.";
+ private static final String ERROR_CREATING_BUG_REPORT = "Error creating bug report";
protected Button searchForDuplicates;
+ protected CCombo duplicateDetectorChooser;
+
+ protected Label duplicateDetectorLabel;
+
protected DatePicker scheduledForDate;
protected Spinner estimatedTime;
@@ -110,7 +115,7 @@ public abstract class AbstractNewRepositoryTaskEditor extends AbstractRepository
newSummary = taskData.getSummary();
repository = editorInput.getRepository();
connector = TasksUiPlugin.getRepositoryManager().getRepositoryConnector(repository.getKind());
- isDirty = false;
+ isDirty = false;
}
@Override
@@ -265,52 +270,6 @@ public abstract class AbstractNewRepositoryTaskEditor extends AbstractRepository
// ignore
}
- public String getStackTraceFromDescription() {
- String description = descriptionTextViewer.getTextWidget().getText().trim();
- String stackTrace = null;
-
- if (description == null) {
- return null;
- }
-
- String punct = "!\"#$%&'\\(\\)*+,-./:;\\<=\\>?@\\[\\]^_`\\{|\\}~\n";
- String lineRegex = " *at\\s+[\\w" + punct + "]+ ?\\(.*\\) *\n?";
- Pattern tracePattern = Pattern.compile(lineRegex);
- Matcher match = tracePattern.matcher(description);
-
- if (match.find()) {
- // record the index of the first stack trace line
- int start = match.start();
- int lastEnd = match.end();
-
- // find the last stack trace line
- while (match.find()) {
- lastEnd = match.end();
- }
-
- // make sure there's still room to find the exception
- if (start <= 0) {
- return null;
- }
-
- // count back to the line before the stack trace to find the
- // exception
- int stackStart = 0;
- int index = start - 1;
- while (index > 1 && description.charAt(index) == ' ') {
- index--;
- }
-
- // locate the exception line index
- stackStart = description.substring(0, index - 1).lastIndexOf("\n");
- stackStart = (stackStart == -1) ? 0 : stackStart + 1;
-
- stackTrace = description.substring(stackStart, lastEnd);
- }
-
- return stackTrace;
- }
-
@Override
protected void updateTask() {
taskData.setSummary(newSummary);
@@ -324,8 +283,8 @@ public abstract class AbstractNewRepositoryTaskEditor extends AbstractRepository
protected class DescriptionListener implements Listener {
public void handleEvent(Event event) {
fireSelectionChanged(new SelectionChangedEvent(selectionProvider, new StructuredSelection(
- new RepositoryTaskSelection(taskData.getId(), taskData.getRepositoryUrl(), taskData.getRepositoryKind(), "New Description",
- false, taskData.getSummary()))));
+ new RepositoryTaskSelection(taskData.getId(), taskData.getRepositoryUrl(), taskData
+ .getRepositoryKind(), "New Description", false, taskData.getSummary()))));
}
}
@@ -432,8 +391,34 @@ public abstract class AbstractNewRepositoryTaskEditor extends AbstractRepository
protected void addActionButtons(Composite buttonComposite) {
FormToolkit toolkit = new FormToolkit(buttonComposite.getDisplay());
- SearchHitCollector collector = getDuplicateSearchCollector("");
- if (collector != null) {
+ List<AbstractDuplicateDetector> allCollectors = getDuplicateSearchCollectorsList();
+ if (allCollectors != null) {
+ duplicateDetectorLabel = new Label(buttonComposite, SWT.LEFT);
+ duplicateDetectorLabel.setText(LABEL_SELECT_DETECTOR);
+
+ duplicateDetectorChooser = new CCombo(buttonComposite, SWT.FLAT | SWT.READ_ONLY | SWT.BORDER);
+
+ duplicateDetectorChooser.setLayoutData(GridDataFactory.swtDefaults().hint(150, SWT.DEFAULT).create());
+ duplicateDetectorChooser.setFont(TEXT_FONT);
+
+ Collections.sort(allCollectors, new Comparator<AbstractDuplicateDetector>() {
+
+ public int compare(AbstractDuplicateDetector c1, AbstractDuplicateDetector c2) {
+ return c1.getName().compareToIgnoreCase(c2.getName());
+ }
+
+ });
+
+ for (AbstractDuplicateDetector detector : allCollectors) {
+ duplicateDetectorChooser.add(detector.getName());
+ }
+
+ duplicateDetectorChooser.select(0);
+ duplicateDetectorChooser.setEnabled(true);
+ duplicateDetectorChooser.setData(allCollectors);
+ }
+
+ if (allCollectors != null && allCollectors.size() > 0) {
searchForDuplicates = toolkit.createButton(buttonComposite, LABEL_SEARCH_DUPS, SWT.NONE);
GridData searchDuplicatesButtonData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
@@ -444,7 +429,10 @@ public abstract class AbstractNewRepositoryTaskEditor extends AbstractRepository
}
});
}
-
+
+ Label spacer = new Label(buttonComposite, SWT.NULL);
+ spacer.setText("");
+
submitButton = toolkit.createButton(buttonComposite, LABEL_CREATE, SWT.NONE);
GridData submitButtonData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
submitButton.setLayoutData(submitButtonData);
@@ -491,12 +479,13 @@ public abstract class AbstractNewRepositoryTaskEditor extends AbstractRepository
public boolean searchForDuplicates() {
- String stackTrace = getStackTraceFromDescription();
- if (stackTrace == null) {
- MessageDialog.openWarning(null, "No Stack Trace Found", NO_STACK_MESSAGE);
- return false;
- }
- SearchHitCollector collector = getDuplicateSearchCollector(stackTrace);
+ String duplicateDetectorName = duplicateDetectorChooser.getItem(duplicateDetectorChooser.getSelectionIndex());
+
+ // updatetask() needs to be called so that the description text is save before we
+ // search for duplicates
+ this.updateTask();
+
+ SearchHitCollector collector = getDuplicateSearchCollector(duplicateDetectorName);
if (collector != null) {
NewSearchUI.runQueryInBackground(collector);
return true;
@@ -541,12 +530,63 @@ public abstract class AbstractNewRepositoryTaskEditor extends AbstractRepository
return newTask;
}
- protected abstract SearchHitCollector getDuplicateSearchCollector(String description);
+ protected abstract SearchHitCollector getDuplicateSearchCollector(String name);
+
+ protected List<AbstractDuplicateDetector> getDuplicateSearchCollectorsList() {
+ return TasksUiPlugin.getDefault().getDuplicateSearchCollectorsList();
+ }
@Override
public void doSave(IProgressMonitor monitor) {
- new MessageDialog(null, "Operation not supported", null, "Save of un-submitted new tasks is not currently supported.\nPlease submit all new tasks.", MessageDialog.INFORMATION, new String[] { IDialogConstants.OK_LABEL }, 0).open();
+ new MessageDialog(null, "Operation not supported", null,
+ "Save of un-submitted new tasks is not currently supported.\nPlease submit all new tasks.",
+ MessageDialog.INFORMATION, new String[] { IDialogConstants.OK_LABEL }, 0).open();
monitor.setCanceled(true);
return;
}
+
+ public static String getStackTraceFromDescription(String description) {
+ String stackTrace = null;
+
+ if (description == null) {
+ return null;
+ }
+
+ String punct = "!\"#$%&'\\(\\)*+,-./:;\\<=\\>?@\\[\\]^_`\\{|\\}~\n";
+ String lineRegex = " *at\\s+[\\w" + punct + "]+ ?\\(.*\\) *\n?";
+ Pattern tracePattern = Pattern.compile(lineRegex);
+ Matcher match = tracePattern.matcher(description);
+
+ if (match.find()) {
+ // record the index of the first stack trace line
+ int start = match.start();
+ int lastEnd = match.end();
+
+ // find the last stack trace line
+ while (match.find()) {
+ lastEnd = match.end();
+ }
+
+ // make sure there's still room to find the exception
+ if (start <= 0) {
+ return null;
+ }
+
+ // count back to the line before the stack trace to find the
+ // exception
+ int stackStart = 0;
+ int index = start - 1;
+ while (index > 1 && description.charAt(index) == ' ') {
+ index--;
+ }
+
+ // locate the exception line index
+ stackStart = description.substring(0, index - 1).lastIndexOf("\n");
+ stackStart = (stackStart == -1) ? 0 : stackStart + 1;
+
+ stackTrace = description.substring(stackStart, lastEnd);
+ }
+
+ return stackTrace;
+ }
}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/search/SearchHitCollector.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/search/SearchHitCollector.java
index e1b8ecc48..40582458f 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/search/SearchHitCollector.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/search/SearchHitCollector.java
@@ -43,6 +43,8 @@ import org.eclipse.ui.PlatformUI;
public class SearchHitCollector extends QueryHitCollector implements ISearchQuery {
private static final String QUERYING_REPOSITORY = "Querying Repository...";
+
+ private String type;
private TaskRepository repository;
@@ -118,7 +120,15 @@ public class SearchHitCollector extends QueryHitCollector implements ISearchQuer
public String getLabel() {
return QUERYING_REPOSITORY;
}
+
+ public String getTypeLabel() {
+ return type;
+ }
+ public void setTypeLabel(String type) {
+ this.type = type;
+ }
+
public boolean canRerun() {
return true;
}
diff --git a/org.eclipse.mylyn.trac.ui/src/org/eclipse/mylyn/internal/trac/ui/editor/NewTracTaskEditor.java b/org.eclipse.mylyn.trac.ui/src/org/eclipse/mylyn/internal/trac/ui/editor/NewTracTaskEditor.java
index a8db97542..8e30240a6 100644
--- a/org.eclipse.mylyn.trac.ui/src/org/eclipse/mylyn/internal/trac/ui/editor/NewTracTaskEditor.java
+++ b/org.eclipse.mylyn.trac.ui/src/org/eclipse/mylyn/internal/trac/ui/editor/NewTracTaskEditor.java
@@ -29,9 +29,12 @@ public class NewTracTaskEditor extends AbstractNewRepositoryTaskEditor {
}
@Override
- public SearchHitCollector getDuplicateSearchCollector(String searchString) {
+ public SearchHitCollector getDuplicateSearchCollector(String name) {
TracSearchFilter filter = new TracSearchFilter("description");
filter.setOperator(CompareOperator.CONTAINS);
+
+ String searchString = AbstractNewRepositoryTaskEditor.getStackTraceFromDescription(taskData.getDescription());
+
filter.addValue(searchString);
TracSearch search = new TracSearch();

Back to the top