Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.mylyn.tasks.index.core/src/org/eclipse/mylyn/internal/tasks/index/core/messages.properties6
-rw-r--r--org.eclipse.mylyn.tasks.index.tests/.classpath1
-rw-r--r--org.eclipse.mylyn.tasks.index.tests/META-INF/MANIFEST.MF6
-rw-r--r--org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/AbstractTaskListIndexTest.java75
-rw-r--r--org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/TaskListIndexTest.java77
-rw-r--r--org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/ui/ContentProposalProviderTest.java184
-rw-r--r--org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/util/MockTestContext.java14
-rw-r--r--org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/AbstractIndexReference.java22
-rw-r--r--org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/ContentProposal.java4
-rw-r--r--org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/ContentProposalProvider.java221
-rw-r--r--org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/IndexReference.java3
-rw-r--r--org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/IndexSearchHandler.java158
12 files changed, 535 insertions, 236 deletions
diff --git a/org.eclipse.mylyn.tasks.index.core/src/org/eclipse/mylyn/internal/tasks/index/core/messages.properties b/org.eclipse.mylyn.tasks.index.core/src/org/eclipse/mylyn/internal/tasks/index/core/messages.properties
index a45088488..e7e5e641a 100644
--- a/org.eclipse.mylyn.tasks.index.core/src/org/eclipse/mylyn/internal/tasks/index/core/messages.properties
+++ b/org.eclipse.mylyn.tasks.index.core/src/org/eclipse/mylyn/internal/tasks/index/core/messages.properties
@@ -8,9 +8,9 @@
# Contributors:
# Tasktop Technologies - initial API and implementation
###############################################################################
-TaskListIndex_field_content=Content
-TaskListIndex_indexerJob=Task List Indexer
-TaskListIndex_task_rebuilding_index=Indexing tasks
+TaskListIndex_field_content=Content
+TaskListIndex_indexerJob=Task List Indexer
+TaskListIndex_task_rebuilding_index=Indexing tasks
TaskListIndex_task_rebuildingIndex=Rebuilding Task List Index
TaskListIndex_field_identifier=Identifier
TaskListIndex_field_person=Person
diff --git a/org.eclipse.mylyn.tasks.index.tests/.classpath b/org.eclipse.mylyn.tasks.index.tests/.classpath
index e3b5ced49..10fbec0c3 100644
--- a/org.eclipse.mylyn.tasks.index.tests/.classpath
+++ b/org.eclipse.mylyn.tasks.index.tests/.classpath
@@ -5,6 +5,7 @@
<accessrules>
<accessrule kind="accessible" pattern="org/eclipse/mylyn/internal/**"/>
<accessrule kind="accessible" pattern="org/eclipse/mylyn/tasks/tests/**"/>
+ <accessrule kind="accessible" pattern="org/eclipse/mylyn/commons/sdk/**"/>
</accessrules>
</classpathentry>
<classpathentry kind="src" path="src"/>
diff --git a/org.eclipse.mylyn.tasks.index.tests/META-INF/MANIFEST.MF b/org.eclipse.mylyn.tasks.index.tests/META-INF/MANIFEST.MF
index 2f3faa0ba..2d84fbcfa 100644
--- a/org.eclipse.mylyn.tasks.index.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.mylyn.tasks.index.tests/META-INF/MANIFEST.MF
@@ -5,13 +5,15 @@ Bundle-SymbolicName: org.eclipse.mylyn.tasks.index.tests
Bundle-Version: 3.7.0.qualifier
Bundle-Vendor: Eclipse.org
Bundle-RequiredExecutionEnvironment: J2SE-1.5
-Require-Bundle: org.junit;bundle-version="4.5.0",
+Require-Bundle: org.junit;bundle-version="4.5.0",
org.eclipse.core.runtime,
org.eclipse.mylyn.commons.core,
+ org.eclipse.mylyn.commons.sdk.util,
org.eclipse.mylyn.tasks.core,
org.eclipse.mylyn.tasks.index.core,
org.eclipse.mylyn.tasks.index.ui,
- org.eclipse.mylyn.tasks.tests
+ org.eclipse.mylyn.tasks.tests,
+ org.eclipse.jface
Export-Package: org.eclipse.mylyn.internal.tasks.index.tests;x-internal:=true,
org.eclipse.mylyn.internal.tasks.index.tests.util;x-internal:=true
diff --git a/org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/AbstractTaskListIndexTest.java b/org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/AbstractTaskListIndexTest.java
new file mode 100644
index 000000000..8e4973604
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/AbstractTaskListIndexTest.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.index.tests;
+
+import static org.eclipse.mylyn.commons.sdk.util.CommonTestUtil.createTempFolder;
+import static org.eclipse.mylyn.commons.sdk.util.CommonTestUtil.deleteFolderRecursively;
+import static org.junit.Assert.assertFalse;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.mylyn.internal.tasks.index.core.TaskListIndex;
+import org.eclipse.mylyn.internal.tasks.index.tests.util.MockTestContext;
+import org.eclipse.mylyn.tasks.core.IRepositoryManager;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+
+@Ignore
+public abstract class AbstractTaskListIndexTest {
+
+ protected MockTestContext context;
+
+ protected TaskListIndex index;
+
+ protected File tempDir;
+
+ @Before
+ public void setup() throws IOException {
+ tempDir = createTempFolder(getClass().getSimpleName());
+
+ context = new MockTestContext();
+ }
+
+ @After
+ public void tearDown() {
+ disposeIndex();
+ if (tempDir != null) {
+ deleteFolderRecursively(tempDir);
+ assertFalse(tempDir.exists());
+ }
+ if (context != null) {
+ context.dispose();
+ context = null;
+ }
+ }
+
+ protected void disposeIndex() {
+ if (index != null) {
+ try {
+ index.waitUntilIdle();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ index.close();
+ index = null;
+ }
+ }
+
+ protected void setupIndex() {
+ index = new TaskListIndex(context.getTaskList(), context.getDataManager(),
+ (IRepositoryManager) context.getRepositoryManager(), tempDir, 0L);
+ index.setDefaultField(TaskListIndex.FIELD_CONTENT);
+ index.setReindexDelay(0L);
+ }
+}
diff --git a/org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/TaskListIndexTest.java b/org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/TaskListIndexTest.java
index c647c3d59..dfe671b9e 100644
--- a/org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/TaskListIndexTest.java
+++ b/org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/TaskListIndexTest.java
@@ -12,6 +12,8 @@
package org.eclipse.mylyn.internal.tasks.index.tests;
import static junit.framework.Assert.assertEquals;
+import static org.eclipse.mylyn.commons.sdk.util.CommonTestUtil.createTempFolder;
+import static org.eclipse.mylyn.commons.sdk.util.CommonTestUtil.deleteFolderRecursively;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -30,7 +32,6 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
-import java.util.logging.Logger;
import junit.framework.Assert;
@@ -40,21 +41,17 @@ import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
import org.eclipse.mylyn.internal.tasks.core.LocalTask;
import org.eclipse.mylyn.internal.tasks.index.core.TaskListIndex;
import org.eclipse.mylyn.internal.tasks.index.core.TaskListIndex.TaskCollector;
-import org.eclipse.mylyn.internal.tasks.index.tests.util.MockTestContext;
-import org.eclipse.mylyn.tasks.core.IRepositoryManager;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.mylyn.tasks.core.data.DefaultTaskSchema;
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
import org.eclipse.mylyn.tasks.core.data.TaskData;
import org.eclipse.mylyn.tasks.core.data.TaskMapper;
-import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
/**
* @author David Green
*/
-public class TaskListIndexTest {
+public class TaskListIndexTest extends AbstractTaskListIndexTest {
private static final org.eclipse.mylyn.tasks.core.data.AbstractTaskSchema.Field FIELD_SUMMARY = DefaultTaskSchema.getInstance().SUMMARY;
@@ -74,70 +71,6 @@ public class TaskListIndexTest {
}
}
- private MockTestContext context;
-
- private TaskListIndex index;
-
- private File tempDir;
-
- @Before
- public void setup() throws IOException {
- tempDir = createTmpDir();
-
- context = new MockTestContext();
- }
-
- private File createTmpDir() throws IOException {
- File tempDir = File.createTempFile(TaskListIndexTest.class.getSimpleName(), ".tmp");
- tempDir.delete();
- tempDir.mkdirs();
-
- assertTrue(tempDir.exists() && tempDir.isDirectory());
- return tempDir;
- }
-
- @After
- public void tearDown() {
- disposeIndex();
- if (tempDir != null) {
- delete(tempDir);
- assertFalse(tempDir.exists());
- }
- }
-
- private void disposeIndex() {
- if (index != null) {
- try {
- index.waitUntilIdle();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- index.close();
- index = null;
- }
- }
-
- private void delete(File file) {
- if (file.isDirectory()) {
- File[] children = file.listFiles();
- if (children != null) {
- for (File child : children) {
- delete(child);
- }
- }
- }
- if (!file.delete()) {
- Logger.getLogger(TaskListIndexTest.class.getName()).severe("Cannot delete: " + file);
- }
- }
-
- private void setupIndex() {
- index = new TaskListIndex(context.getTaskList(), context.getDataManager(),
- (IRepositoryManager) context.getRepositoryManager(), tempDir, 0L);
- index.setDefaultField(TaskListIndex.FIELD_CONTENT);
- index.setReindexDelay(0L);
- }
-
@Test
public void testMatchesLocalTaskOnSummary() throws InterruptedException {
setupIndex();
@@ -428,7 +361,7 @@ public class TaskListIndexTest {
assertCanFindTask(task);
- File newLocation = createTmpDir();
+ File newLocation = createTempFolder(TaskListIndexTest.class.getSimpleName());
try {
assertEquals(0, newLocation.list().length);
@@ -440,7 +373,7 @@ public class TaskListIndexTest {
assertFalse(newLocation.list().length == 0);
} finally {
disposeIndex();
- delete(newLocation);
+ deleteFolderRecursively(newLocation);
assertFalse(newLocation.exists());
}
}
diff --git a/org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/ui/ContentProposalProviderTest.java b/org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/ui/ContentProposalProviderTest.java
new file mode 100644
index 000000000..6215edfb2
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/ui/ContentProposalProviderTest.java
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.index.tests.ui;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.Collections;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.fieldassist.IContentProposal;
+import org.eclipse.mylyn.commons.core.DelegatingProgressMonitor;
+import org.eclipse.mylyn.internal.tasks.index.core.TaskListIndex;
+import org.eclipse.mylyn.internal.tasks.index.tests.AbstractTaskListIndexTest;
+import org.eclipse.mylyn.internal.tasks.index.ui.AbstractIndexReference;
+import org.eclipse.mylyn.internal.tasks.index.ui.ContentProposalProvider;
+import org.eclipse.mylyn.internal.tasks.index.ui.ContentProposalProvider.ProposalContentState;
+import org.eclipse.mylyn.tasks.core.ITask;
+import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
+import org.eclipse.mylyn.tasks.core.data.TaskData;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for {@link ContentProposalProvider}
+ *
+ * @author David Green
+ */
+public class ContentProposalProviderTest extends AbstractTaskListIndexTest {
+
+ private ContentProposalProvider proposalProvider;
+
+ @Override
+ @Before
+ public void setup() throws IOException {
+ super.setup();
+
+ setupIndex();
+
+ proposalProvider = new ContentProposalProvider(context.getTaskList(), new AbstractIndexReference() {
+
+ @Override
+ public TaskListIndex index() {
+ return index;
+ }
+ });
+ }
+
+ @Test
+ public void testComputeProposalContentState_SimpleProposal() {
+ ProposalContentState state = proposalProvider.computeProposalContentState("one tw", 6);
+ assertNotNull(state);
+ assertEquals("one ", state.beforePrefixContent);
+ assertEquals("", state.fieldPrefix);
+ assertEquals("tw", state.prefix);
+ assertEquals("", state.suffix);
+ }
+
+ @Test
+ public void testComputeProposalContentState_FieldValueProposal() {
+ String content = "one person:";
+ ProposalContentState state = proposalProvider.computeProposalContentState(content, content.length());
+ assertNotNull(state);
+ assertEquals("one person:", state.beforePrefixContent);
+ assertEquals("person", state.fieldPrefix);
+ assertEquals("", state.prefix);
+ assertEquals("", state.suffix);
+ }
+
+ @Test
+ public void testComputeProposalContentState_FieldValueProposalMidRange() {
+ String content = "one person:";
+ String content2 = " foo";
+ ProposalContentState state = proposalProvider.computeProposalContentState(content + content2, content.length());
+ assertNotNull(state);
+ assertEquals("one person:", state.beforePrefixContent);
+ assertEquals("person", state.fieldPrefix);
+ assertEquals("", state.prefix);
+ assertEquals(" foo", state.suffix);
+ }
+
+ @Test
+ public void testComputeProposalContentState_SimpleProposalMidRange() {
+ String content = "one tw";
+ String content2 = " foo";
+ ProposalContentState state = proposalProvider.computeProposalContentState(content + content2, content.length());
+ assertNotNull(state);
+ assertEquals("one ", state.beforePrefixContent);
+ assertEquals("", state.fieldPrefix);
+ assertEquals("tw", state.prefix);
+ assertEquals(" foo", state.suffix);
+ }
+
+ @Test
+ public void testGetProposals_FieldName() {
+ IContentProposal[] proposals = proposalProvider.getProposals("per", 3);
+ assertNotNull(proposals);
+ assertEquals(1, proposals.length);
+ assertEquals("person:", proposals[0].getContent());
+ assertEquals(7, proposals[0].getCursorPosition());
+ }
+
+ @Test
+ public void testGetProposals_PersonSuggest() throws CoreException {
+ ITask task = context.createRepositoryTask();
+ String owner = task.getOwner();
+ assertNotNull(owner);
+ assertTrue(owner.trim().length() > 0);
+ assertEquals(owner.trim(), owner);
+
+ IContentProposal[] proposals = proposalProvider.getProposals("person:", 7);
+ assertNotNull(proposals);
+ assertEquals(1, proposals.length);
+ final String expectedValue = "person:" + owner;
+ assertEquals(expectedValue, proposals[0].getContent());
+ assertEquals(expectedValue.length(), proposals[0].getCursorPosition());
+ assertEquals(owner, proposals[0].getLabel());
+ }
+
+ @Test
+ public void testGetProposals_PersonSuggestWithSpace() throws CoreException, InterruptedException {
+ ITask task = context.createRepositoryTask();
+
+ TaskData taskData = context.getDataManager().getTaskData(task);
+
+ // sanity
+ assertNotNull(taskData);
+ assertNotNull(taskData.getRepositoryUrl());
+
+ // setup owner with space
+ final String ownerName = "Jane Doe";
+ taskData.getRoot().getMappedAttribute(TaskAttribute.USER_ASSIGNED).setValue(ownerName);
+
+ context.getDataManager().putSubmittedTaskData(task, taskData, new DelegatingProgressMonitor());
+
+ context.getTaskList().notifyElementsChanged(Collections.singleton(task));
+
+ index.waitUntilIdle();
+
+ String owner = task.getOwner();
+ assertNotNull(owner);
+ assertTrue(owner.trim().length() > 0);
+ assertEquals(owner.trim(), owner);
+ assertEquals(ownerName, owner);
+
+ IContentProposal[] proposals = proposalProvider.getProposals("person:", 7);
+ assertNotNull(proposals);
+ assertEquals(1, proposals.length);
+ final String expectedValue = "person:\"" + owner + "\"";
+ assertEquals(expectedValue, proposals[0].getContent());
+ assertEquals(expectedValue.length(), proposals[0].getCursorPosition());
+ assertEquals(owner, proposals[0].getLabel());
+ }
+
+ @Test
+ public void testGetProposals_PersonSuggest_MidStream() throws CoreException {
+ ITask task = context.createRepositoryTask();
+ String owner = task.getOwner();
+ assertNotNull(owner);
+ assertTrue(owner.trim().length() > 0);
+ assertEquals(owner.trim(), owner);
+
+ final String content = "person:";
+ String content2 = " after";
+ IContentProposal[] proposals = proposalProvider.getProposals(content + content2, content.length());
+ assertNotNull(proposals);
+ assertEquals(1, proposals.length);
+ final String expectedValue = content + owner + content2;
+ assertEquals(expectedValue, proposals[0].getContent());
+ assertEquals((content + owner).length(), proposals[0].getCursorPosition());
+ assertEquals(owner, proposals[0].getLabel());
+ }
+}
diff --git a/org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/util/MockTestContext.java b/org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/util/MockTestContext.java
index 8921cb045..d183ab944 100644
--- a/org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/util/MockTestContext.java
+++ b/org.eclipse.mylyn.tasks.index.tests/src/org/eclipse/mylyn/internal/tasks/index/tests/util/MockTestContext.java
@@ -11,12 +11,15 @@
package org.eclipse.mylyn.internal.tasks.index.tests.util;
+import java.io.File;
+import java.io.IOException;
import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.mylyn.commons.core.DelegatingProgressMonitor;
+import org.eclipse.mylyn.commons.sdk.util.CommonTestUtil;
import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
import org.eclipse.mylyn.internal.tasks.core.LocalRepositoryConnector;
import org.eclipse.mylyn.internal.tasks.core.LocalTask;
@@ -63,7 +66,9 @@ public class MockTestContext {
private final FullMockRepositoryConnector mockRepositoryConnector;
- public MockTestContext() {
+ private final File dataDir;
+
+ public MockTestContext() throws IOException {
taskList = new TaskList();
repositoryManager = new TaskRepositoryManager();
@@ -79,12 +84,15 @@ public class MockTestContext {
repositoryManager.addRepository(localRepository);
dataStore = new TaskDataStore(repositoryManager);
+
activityManager = new TaskActivityManager(repositoryManager, taskList);
repositoryModel = new RepositoryModel(taskList, repositoryManager);
synchronizationManger = new SynchronizationManger(repositoryModel);
dataManager = new TaskDataManager(dataStore, repositoryManager, taskList, activityManager,
synchronizationManger);
+ dataDir = CommonTestUtil.createTempFolder(MockTestContext.class.getSimpleName());
+ dataManager.setDataPath(dataDir.getAbsolutePath());
}
public TaskList getTaskList() {
@@ -174,4 +182,8 @@ public class MockTestContext {
getMockRepository().setRepositoryUrl(newUrl);
getRepositoryManager().notifyRepositoryUrlChanged(getMockRepository(), oldUrl);
}
+
+ public void dispose() {
+ CommonTestUtil.deleteFolderRecursively(dataDir);
+ }
}
diff --git a/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/AbstractIndexReference.java b/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/AbstractIndexReference.java
new file mode 100644
index 000000000..6e3fc8062
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/AbstractIndexReference.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.index.ui;
+
+import org.eclipse.mylyn.internal.tasks.index.core.TaskListIndex;
+
+/**
+ * @author David Green
+ */
+public abstract class AbstractIndexReference {
+
+ public abstract TaskListIndex index();
+}
diff --git a/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/ContentProposal.java b/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/ContentProposal.java
index b84387678..daed4fd54 100644
--- a/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/ContentProposal.java
+++ b/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/ContentProposal.java
@@ -30,6 +30,10 @@ class ContentProposal implements IContentProposal {
this(content, label, description, content.length());
}
+ public ContentProposal(String content, String contentSuffix, String label, String description) {
+ this(content + contentSuffix, label, description, content.length());
+ }
+
public ContentProposal(String content, String label, String description, int cursorPosition) {
this.content = content;
this.cursorPosition = cursorPosition;
diff --git a/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/ContentProposalProvider.java b/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/ContentProposalProvider.java
new file mode 100644
index 000000000..19d004098
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/ContentProposalProvider.java
@@ -0,0 +1,221 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.index.ui;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.regex.Pattern;
+
+import org.eclipse.jface.fieldassist.IContentProposal;
+import org.eclipse.jface.fieldassist.IContentProposalProvider;
+import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
+import org.eclipse.mylyn.internal.tasks.core.TaskList;
+import org.eclipse.mylyn.internal.tasks.index.core.TaskListIndex;
+import org.eclipse.mylyn.tasks.core.data.AbstractTaskSchema;
+import org.eclipse.mylyn.tasks.core.data.AbstractTaskSchema.Field;
+import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * A content proposal provider for proposals on a task list index and task list.
+ *
+ * @author David Green
+ */
+public class ContentProposalProvider implements IContentProposalProvider {
+
+ private static final Pattern PATTERN_WHITESPACE = Pattern.compile("\\s"); //$NON-NLS-1$
+
+ private static final Pattern PATTERN_SPECIAL_CHARACTERS = Pattern.compile("([+&\\|!\\(\\)\\{\\}\\[\\]^\"~\\*\\?:\\\\-])"); //$NON-NLS-1$
+
+ private final AbstractIndexReference reference;
+
+ private final TaskList taskList;
+
+ public ContentProposalProvider(TaskList taskList, AbstractIndexReference reference) {
+ this.taskList = taskList;
+ this.reference = reference;
+ }
+
+ public static class ProposalContentState {
+
+ public String beforePrefixContent;
+
+ public String fieldPrefix = ""; //$NON-NLS-1$
+
+ public String prefix = ""; //$NON-NLS-1$
+
+ public String suffix = ""; //$NON-NLS-1$
+
+ public ProposalContentState(String contents) {
+ beforePrefixContent = contents;
+ }
+
+ }
+
+ public IContentProposal[] getProposals(String contents, int position) {
+ List<IContentProposal> proposals = new ArrayList<IContentProposal>(10);
+
+ ProposalContentState contentState = computeProposalContentState(contents, position);
+
+ // if we have a field prefix
+ if (contentState.fieldPrefix.length() > 0) {
+ AbstractTaskSchema.Field indexField = computeIndexField(contentState.fieldPrefix);
+
+ // if it's a person field then suggest
+ // people from the task list
+ if (indexField != null && TaskAttribute.TYPE_PERSON.equals(indexField.getType())) {
+ computePersonProposals(proposals, contentState);
+ }
+
+ } else {
+
+ // suggest field name prefixes
+ for (Field field : reference.index().getIndexedFields()) {
+
+ // searching on URL is not useful
+ if (field.equals(TaskListIndex.FIELD_IDENTIFIER)) {
+ continue;
+ }
+
+ String indexKey = field.getIndexKey();
+ if (indexKey.startsWith(contentState.prefix)) {
+ String description;
+ if (TaskListIndex.FIELD_CONTENT.equals(field)) {
+ description = Messages.IndexSearchHandler_hint_content;
+ } else if (TaskListIndex.FIELD_PERSON.equals(field)) {
+ description = Messages.IndexSearchHandler_hint_person;
+ } else {
+ description = NLS.bind(Messages.IndexSearchHandler_hint_generic, field.getLabel());
+ }
+ proposals.add(new ContentProposal(contentState.beforePrefixContent + indexKey + ":", //$NON-NLS-1$
+ contentState.suffix, indexKey, description));
+
+ if (TaskAttribute.TYPE_DATE.equals(field.getType())
+ || TaskAttribute.TYPE_DATETIME.equals(field.getType())) {
+ computeDateRangeProposals(proposals, contentState, field);
+ }
+ }
+ }
+ }
+
+ return proposals.toArray(new IContentProposal[proposals.size()]);
+ }
+
+ public ProposalContentState computeProposalContentState(String contents, int position) {
+ ProposalContentState contentState = new ProposalContentState(contents);
+
+ if (position >= 0 && position <= contents.length()) {
+ int i = position;
+ while (i > 0 && !Character.isWhitespace(contents.charAt(i - 1)) && contents.charAt(i - 1) != ':') {
+ --i;
+ }
+ if (i > 0 && contents.charAt(i - 1) == ':') {
+ int fieldEnd = i - 1;
+ int fieldStart = i - 1;
+ while (fieldStart > 0 && Character.isLetter(contents.charAt(fieldStart - 1))) {
+ --fieldStart;
+ }
+ contentState.fieldPrefix = contents.substring(fieldStart, fieldEnd);
+ }
+
+ contentState.prefix = contents.substring(i, position);
+ contentState.beforePrefixContent = contents.substring(0, i);
+
+ if (position < contents.length()) {
+ i = position;
+ while (i < contents.length()) {
+ if (Character.isWhitespace(contents.charAt(i))) {
+ break;
+ }
+ ++i;
+ }
+ contentState.suffix = contents.substring(i);
+ }
+ }
+ return contentState;
+ }
+
+ public Field computeIndexField(String fieldPrefix) {
+ for (Field field : reference.index().getIndexedFields()) {
+ if (field.getIndexKey().equals(fieldPrefix)) {
+ return field;
+ }
+ }
+ return null;
+ }
+
+ public void computeDateRangeProposals(List<IContentProposal> proposals, ProposalContentState contentState,
+ Field field) {
+ // for date fields give suggestion of date range search
+ String description;
+ final Date now = new Date();
+ final Date dateSearchUpperBound;
+ final Date dateSearchOneWeekLowerBound;
+ {
+ GregorianCalendar calendar = new GregorianCalendar();
+
+ calendar.setTime(now);
+ calendar.add(Calendar.DAY_OF_WEEK, 1); // one day in future due to GMT conversion in index
+ dateSearchUpperBound = calendar.getTime();
+
+ calendar.setTime(now);
+ calendar.add(Calendar.DAY_OF_WEEK, -7);
+ dateSearchOneWeekLowerBound = calendar.getTime();
+ }
+
+ description = NLS.bind(Messages.IndexSearchHandler_Generic_date_range_search_1_week, field.getLabel());
+
+ String label = NLS.bind(Messages.IndexSearchHandler_Past_week_date_range_label, field.getIndexKey());
+
+ String queryText = reference.index().computeQueryFieldDateRange(field, dateSearchOneWeekLowerBound,
+ dateSearchUpperBound);
+
+ if (queryText.startsWith(contentState.prefix)) {
+ proposals.add(new ContentProposal(contentState.beforePrefixContent + queryText, contentState.suffix, label,
+ description));
+ }
+ }
+
+ public void computePersonProposals(List<IContentProposal> proposals, ProposalContentState contentState) {
+ Set<String> addresses = new TreeSet<String>();
+
+ Collection<AbstractTask> allTasks = taskList.getAllTasks();
+ for (AbstractTask task : allTasks) {
+ addAddresses(addresses, task);
+ }
+
+ for (String address : addresses) {
+ if (address.startsWith(contentState.prefix)) {
+ String proposalContent = address;
+ proposalContent = PATTERN_SPECIAL_CHARACTERS.matcher(proposalContent).replaceAll("\\\\$1"); //$NON-NLS-1$
+ if (PATTERN_WHITESPACE.matcher(proposalContent).find()) {
+ proposalContent = "\"" + proposalContent + "\""; //$NON-NLS-1$//$NON-NLS-2$
+ }
+ proposals.add(new ContentProposal(contentState.beforePrefixContent + proposalContent,
+ contentState.suffix, address, null));
+ }
+ }
+ }
+
+ private void addAddresses(Set<String> addresses, AbstractTask task) {
+ String name = task.getOwner();
+ if (name != null && name.trim().length() > 0) {
+ addresses.add(name.trim());
+ }
+ }
+}
diff --git a/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/IndexReference.java b/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/IndexReference.java
index 5181cbf43..bfdc8001e 100644
--- a/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/IndexReference.java
+++ b/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/IndexReference.java
@@ -23,7 +23,7 @@ import org.eclipse.mylyn.tasks.core.IRepositoryManager;
* @author David Green
* @author Steffen Pingel
*/
-public class IndexReference {
+public class IndexReference extends AbstractIndexReference {
private static TaskListIndex theIndex;
@@ -49,6 +49,7 @@ public class IndexReference {
*/
private TaskListIndex index;
+ @Override
public TaskListIndex index() {
synchronized (IndexReference.class) {
if (index == null) {
diff --git a/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/IndexSearchHandler.java b/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/IndexSearchHandler.java
index 61beb9d35..0a2dce97c 100644
--- a/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/IndexSearchHandler.java
+++ b/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/IndexSearchHandler.java
@@ -11,29 +11,15 @@
package org.eclipse.mylyn.internal.tasks.index.ui;
import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.regex.Pattern;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
-import org.eclipse.jface.fieldassist.IContentProposal;
import org.eclipse.jface.fieldassist.IContentProposalProvider;
import org.eclipse.jface.fieldassist.TextContentAdapter;
import org.eclipse.jface.layout.GridLayoutFactory;
-import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
import org.eclipse.mylyn.internal.tasks.index.core.TaskListIndex;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.internal.tasks.ui.search.AbstractSearchHandler;
-import org.eclipse.mylyn.tasks.core.data.AbstractTaskSchema;
import org.eclipse.mylyn.tasks.core.data.AbstractTaskSchema.Field;
-import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
-import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
@@ -52,154 +38,12 @@ import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter;
*/
public class IndexSearchHandler extends AbstractSearchHandler {
- private static final Pattern PATTERN_WHITESPACE = Pattern.compile("\\s"); //$NON-NLS-1$
-
- private static final Pattern PATTERN_SPECIAL_CHARACTERS = Pattern.compile("([+&\\|!\\(\\)\\{\\}\\[\\]^\"~\\*\\?:\\\\-])"); //$NON-NLS-1$
-
- private class ContentProposalProvider implements IContentProposalProvider {
-
- public IContentProposal[] getProposals(String contents, int position) {
- List<IContentProposal> proposals = new ArrayList<IContentProposal>(10);
-
- String beforePrefixContent = contents;
- String fieldPrefix = ""; //$NON-NLS-1$
- String prefix = ""; //$NON-NLS-1$
- if (position >= 0 && position <= contents.length()) {
- int i = position;
- while (i > 0 && !Character.isWhitespace(contents.charAt(i - 1)) && contents.charAt(i - 1) != ':') {
- --i;
- }
- if (i > 0 && contents.charAt(i - 1) == ':') {
- int fieldEnd = i - 1;
- int fieldStart = i - 1;
- while (fieldStart > 0 && Character.isLetter(contents.charAt(fieldStart - 1))) {
- --fieldStart;
- }
- fieldPrefix = contents.substring(fieldStart, fieldEnd);
- }
-
- prefix = contents.substring(i, position);
- beforePrefixContent = contents.substring(0, i);
- }
-
- // if we have a field prefix
- if (fieldPrefix.length() > 0) {
- AbstractTaskSchema.Field indexField = computeIndexField(fieldPrefix);
-
- // if it's a person field then suggest
- // people from the task list
- if (indexField != null && TaskAttribute.TYPE_PERSON.equals(indexField.getType())) {
- computePersonProposals(proposals, beforePrefixContent, prefix);
- }
-
- } else {
-
- // suggest field name prefixes
- for (Field field : reference.index().getIndexedFields()) {
-
- // searching on URL is not useful
- if (field.equals(TaskListIndex.FIELD_IDENTIFIER)) {
- continue;
- }
-
- String indexKey = field.getIndexKey();
- if (indexKey.startsWith(prefix)) {
- String description;
- if (TaskListIndex.FIELD_CONTENT.equals(field)) {
- description = Messages.IndexSearchHandler_hint_content;
- } else if (TaskListIndex.FIELD_PERSON.equals(field)) {
- description = Messages.IndexSearchHandler_hint_person;
- } else {
- description = NLS.bind(Messages.IndexSearchHandler_hint_generic, field.getLabel());
- }
- proposals.add(new ContentProposal(beforePrefixContent + indexKey + ":", //$NON-NLS-1$
- indexKey, description));
-
- if (TaskAttribute.TYPE_DATE.equals(field.getType())
- || TaskAttribute.TYPE_DATETIME.equals(field.getType())) {
- computeDateRangeProposals(proposals, beforePrefixContent, prefix, field);
- }
- }
- }
- }
-
- return proposals.toArray(new IContentProposal[proposals.size()]);
- }
-
- public void computeDateRangeProposals(List<IContentProposal> proposals, String beforePrefixContent,
- String prefix, Field field) {
- // for date fields give suggestion of date range search
- String description;
- final Date now = new Date();
- final Date dateSearchUpperBound;
- final Date dateSearchOneWeekLowerBound;
- {
- GregorianCalendar calendar = new GregorianCalendar();
-
- calendar.setTime(now);
- calendar.add(Calendar.DAY_OF_WEEK, 1); // one day in future due to GMT conversion in index
- dateSearchUpperBound = calendar.getTime();
-
- calendar.setTime(now);
- calendar.add(Calendar.DAY_OF_WEEK, -7);
- dateSearchOneWeekLowerBound = calendar.getTime();
- }
-
- description = NLS.bind(Messages.IndexSearchHandler_Generic_date_range_search_1_week, field.getLabel());
-
- String label = NLS.bind(Messages.IndexSearchHandler_Past_week_date_range_label, field.getIndexKey());
-
- String queryText = reference.index().computeQueryFieldDateRange(field, dateSearchOneWeekLowerBound,
- dateSearchUpperBound);
-
- if (queryText.startsWith(prefix)) {
- proposals.add(new ContentProposal(beforePrefixContent + queryText, label, description));
- }
- }
-
- public void computePersonProposals(List<IContentProposal> proposals, String beforePrefixContent, String prefix) {
- Set<String> addresses = new TreeSet<String>();
-
- Collection<AbstractTask> allTasks = TasksUiPlugin.getTaskList().getAllTasks();
- for (AbstractTask task : allTasks) {
- addAddresses(addresses, task);
- }
-
- for (String address : addresses) {
- if (address.startsWith(prefix)) {
- String proposalContent = address;
- proposalContent = PATTERN_SPECIAL_CHARACTERS.matcher(proposalContent).replaceAll("\\\\$1"); //$NON-NLS-1$
- if (PATTERN_WHITESPACE.matcher(proposalContent).find()) {
- proposalContent = "\"" + proposalContent + "\""; //$NON-NLS-1$//$NON-NLS-2$
- }
- proposals.add(new ContentProposal(beforePrefixContent + proposalContent, address, null));
- }
- }
- }
-
- private void addAddresses(Set<String> addresses, AbstractTask task) {
- String name = task.getOwner();
- if (name != null && name.trim().length() > 0) {
- addresses.add(name.trim());
- }
- }
- }
-
private IndexReference reference;
public IndexSearchHandler() {
reference = new IndexReference();
}
- public Field computeIndexField(String fieldPrefix) {
- for (Field field : reference.index().getIndexedFields()) {
- if (field.getIndexKey().equals(fieldPrefix)) {
- return field;
- }
- }
- return null;
- }
-
@Override
public Composite createSearchComposite(Composite parent) {
Composite container = new Composite(parent, SWT.NULL);
@@ -231,7 +75,7 @@ public class IndexSearchHandler extends AbstractSearchHandler {
@Override
public void adaptTextSearchControl(Text textControl) {
- IContentProposalProvider proposalProvider = new ContentProposalProvider();
+ IContentProposalProvider proposalProvider = new ContentProposalProvider(TasksUiPlugin.getTaskList(), reference);
final ContentAssistCommandAdapter adapter = new ContentAssistCommandAdapter(textControl,
new TextContentAdapter(), proposalProvider, null, new char[0], true);
adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);

Back to the top