From a1497d73abdcc8d14ffa6d1e1f822e1b1e601e55 Mon Sep 17 00:00:00 2001 From: Evgeny Zakrevsky Date: Wed, 10 Oct 2012 02:11:13 +0400 Subject: [PATCH] Tasks search improved for Mantis and Generic Connector --- .../ide/util/gotoByName/ChooseByNameBase.java | 4 + .../github/tasks/GitHubRepository.java | 6 +- .../intellij/tasks/jira/JiraRepository.java | 14 +-- .../src/com/intellij/tasks/TaskManager.java | 5 +- .../com/intellij/tasks/TaskRepository.java | 6 +- .../tasks/impl/BaseRepositoryImpl.java | 3 +- .../tasks/actions/GotoTaskAction.java | 40 ++++---- .../tasks/actions/OpenTaskDialog.java | 2 +- .../tasks/actions/TaskSearchSupport.java | 21 ++--- .../tasks/connector/WebRepository.java | 93 +++---------------- .../tasks/connector/WebRepositoryEditor.java | 22 +---- .../com/intellij/tasks/connector/WebTask.java | 85 +++++++++++++++++ .../tasks/fogbugz/FogBugzRepository.java | 17 ++-- .../intellij/tasks/impl/TaskManagerImpl.java | 29 +++--- .../lighthouse/LighthouseRepository.java | 4 +- .../tasks/mantis/MantisRepository.java | 74 +++++++-------- .../pivotal/PivotalTrackerRepository.java | 9 +- .../tasks/redmine/RedmineRepository.java | 9 +- .../intellij/tasks/trac/TracRepository.java | 8 +- .../tasks/youtrack/YouTrackRepository.java | 8 +- .../com/intellij/tasks/TaskManagerTest.java | 4 +- .../com/intellij/tasks/TestRepository.java | 6 +- 22 files changed, 237 insertions(+), 232 deletions(-) create mode 100644 plugins/tasks/tasks-core/src/com/intellij/tasks/connector/WebTask.java diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java index 77774f33023c..feeb5e4dbf7e 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java @@ -1587,6 +1587,10 @@ public abstract class ChooseByNameBase { } } + public int getMaximumListSizeLimit() { + return myMaximumListSizeLimit; + } + private static final String ACTION_NAME = "Show All in View"; private abstract class ShowFindUsagesAction extends AnAction { diff --git a/plugins/github/src/org/jetbrains/plugins/github/tasks/GitHubRepository.java b/plugins/github/src/org/jetbrains/plugins/github/tasks/GitHubRepository.java index 4523de14c23b..6feefea3c957 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/tasks/GitHubRepository.java +++ b/plugins/github/src/org/jetbrains/plugins/github/tasks/GitHubRepository.java @@ -78,8 +78,8 @@ public class GitHubRepository extends BaseRepositoryImpl { } @Override - public Task[] getIssues(@Nullable String query, int max, long since) throws Exception { - return ArrayUtil.toObjectArray(getIssues(query), Task.class); + public List getIssues(@Nullable String query, int max, long since) throws Exception { + return getIssues(query); } @Override @@ -88,7 +88,7 @@ public class GitHubRepository extends BaseRepositoryImpl { } @NotNull - private List getIssues(String query) throws Exception { + private List getIssues(@Nullable String query) throws Exception { String path; boolean noQuery = StringUtil.isEmpty(query); if (!noQuery) { diff --git a/plugins/tasks/jira-connector/src/main/java/com/intellij/tasks/jira/JiraRepository.java b/plugins/tasks/jira-connector/src/main/java/com/intellij/tasks/jira/JiraRepository.java index 41e691da2a79..3bfb79ca56fb 100644 --- a/plugins/tasks/jira-connector/src/main/java/com/intellij/tasks/jira/JiraRepository.java +++ b/plugins/tasks/jira-connector/src/main/java/com/intellij/tasks/jira/JiraRepository.java @@ -53,11 +53,11 @@ public class JiraRepository extends BaseRepositoryImpl { super(type); } - public Task[] getIssues(String request, int max, long since) throws Exception { + public List getIssues(@Nullable String request, int max, long since) throws Exception { return getIssues(max, login()); } - private Task[] getIssues(int max, HttpClient httpClient) throws IOException, JDOMException { + private List getIssues(int max, HttpClient httpClient) throws IOException, JDOMException { StringBuilder url = new StringBuilder(getUrl()); url.append("/sr/jira.issueviews:searchrequest-xml/temp/SearchRequest.xml?"); url.append("tempMax=").append(max); @@ -75,7 +75,7 @@ public class JiraRepository extends BaseRepositoryImpl { public void setTaskState(Task task, TaskState state) throws Exception { } - private Task[] processRSS(String url, HttpClient client) throws IOException, JDOMException { + private List processRSS(String url, HttpClient client) throws IOException, JDOMException { GetMethod method = new GetMethod(url); configureHttpMethod(method); client.executeMethod(method); @@ -92,7 +92,7 @@ public class JiraRepository extends BaseRepositoryImpl { if (channel != null) { @SuppressWarnings({"unchecked"}) List children = channel.getChildren("item"); LOG.info("JIRA: " + children.size() + " issues found"); - return ContainerUtil.map2Array(children, Task.class, new Function() { + return ContainerUtil.map(children, new Function() { public Task fun(Element o) { return new JiraTask(new JIRAIssueBean(getUrl(), o, false)) { @Override @@ -106,7 +106,7 @@ public class JiraRepository extends BaseRepositoryImpl { else { LOG.warn("JIRA channel not found"); } - return Task.EMPTY_ARRAY; + return ContainerUtil.emptyList(); } private HttpClient login() throws Exception { @@ -201,8 +201,8 @@ public class JiraRepository extends BaseRepositoryImpl { url.append("/si/jira.issueviews:issue-xml/"); url.append(id).append('/').append(id).append(".xml"); - Task[] tasks = processRSS(url.toString(), login()); - return tasks.length == 0 ? null : tasks[0]; + List tasks = processRSS(url.toString(), login()); + return tasks.size() == 0 ? null : tasks.get(0); } catch (Exception e) { LOG.warn("Cannot get issue " + id + ": " + e.getMessage()); diff --git a/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskManager.java b/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskManager.java index dd7a3b3b904c..f13912b0dbdc 100644 --- a/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskManager.java +++ b/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskManager.java @@ -43,8 +43,7 @@ public abstract class TaskManager { public abstract List getIssues(@Nullable String query, boolean forceRequest); - - public abstract List getIssues(String query, int max, long since, boolean forceRequest); + public abstract List getIssues(@Nullable String query, int max, long since, boolean forceRequest); /** * Returns already cached issues. * @return cached issues. @@ -52,7 +51,7 @@ public abstract class TaskManager { public abstract List getCachedIssues(); @Nullable - public abstract Task updateIssue(String id); + public abstract Task updateIssue(@NotNull String id); public abstract LocalTask[] getLocalTasks(); diff --git a/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepository.java b/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepository.java index b252af4cae4c..11e1703801f4 100644 --- a/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepository.java +++ b/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepository.java @@ -22,6 +22,7 @@ import com.intellij.util.xmlb.annotations.Tag; import com.intellij.util.xmlb.annotations.Transient; import org.jetbrains.annotations.Nullable; +import java.util.List; import java.util.concurrent.Callable; /** @@ -75,13 +76,14 @@ public abstract class TaskRepository { /** * Get issues from the repository. If query is null, return issues should assigned to current user only. * + * * @param query repository specific. * @param max maximum issues number to return * @param since last updated timestamp. If 0, all issues should be returned. * @return found issues * @throws Exception */ - public abstract Task[] getIssues(@Nullable String query, int max, long since) throws Exception; + public abstract List getIssues(@Nullable String query, int max, long since) throws Exception; @Nullable public abstract Task findTask(String id) throws Exception; @@ -179,7 +181,7 @@ public abstract class TaskRepository { return "{id} (e.g. FOO-001), {summary}, {number} (e.g. 001), {project} (e.g. FOO)"; } - public abstract class CancellableConnection implements Callable { + public abstract static class CancellableConnection implements Callable { @Nullable @Override diff --git a/plugins/tasks/tasks-api/src/com/intellij/tasks/impl/BaseRepositoryImpl.java b/plugins/tasks/tasks-api/src/com/intellij/tasks/impl/BaseRepositoryImpl.java index ae8d53dfa9e5..764e5f15961d 100644 --- a/plugins/tasks/tasks-api/src/com/intellij/tasks/impl/BaseRepositoryImpl.java +++ b/plugins/tasks/tasks-api/src/com/intellij/tasks/impl/BaseRepositoryImpl.java @@ -8,6 +8,7 @@ import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSocketFactory; import org.apache.commons.httpclient.protocol.Protocol; import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.UnsupportedEncodingException; @@ -36,7 +37,7 @@ public abstract class BaseRepositoryImpl extends BaseRepository { super(other); } - protected static String encodeUrl(String s) { + protected static String encodeUrl(@NotNull String s) { try { return URLEncoder.encode(s, "UTF-8"); } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java index 20fd5a04902c..da7c67007df0 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java @@ -62,7 +62,7 @@ public class GotoTaskAction extends GotoActionBase { boolean everywhere, @NotNull ProgressIndicator cancelled, @NotNull Processor consumer) { - List cachedTasks = new TaskSearchSupport(project).getLocalAndCachedTasks(pattern); + List cachedTasks = TaskSearchSupport.getLocalAndCachedTasks(TaskManager.getManager(project), pattern); List taskPsiElements = ContainerUtil.map(cachedTasks, new Function() { @Override public TaskPsiElement fun(Task task) { @@ -85,29 +85,25 @@ public class GotoTaskAction extends GotoActionBase { if (!consumer.process(element)) return false; } - //int i = 0; - //while (true) { - List tasks = new TaskSearchSupport(project).getRepositoryTasks(pattern, ChooseByNameBase.MAXIMUM_LIST_SIZE_LIMIT, 0, true); - if (tasks.size() == 0) return true; - tasks.removeAll(cachedTasks); - taskPsiElements = ContainerUtil.map(tasks, new Function() { - @Override - public TaskPsiElement fun(Task task) { - return new TaskPsiElement(PsiManager.getInstance(project), task); - } - }); - - if (!cachedTasksFound && taskPsiElements.size() != 0) { - cancelled.checkCanceled(); - if (!consumer.process(ChooseByNameBase.NON_PREFIX_SEPARATOR)) return false; + List tasks = + TaskSearchSupport.getRepositoriesTasks(TaskManager.getManager(project), pattern, base.getMaximumListSizeLimit(), 0, true); + tasks.removeAll(cachedTasks); + taskPsiElements = ContainerUtil.map(tasks, new Function() { + @Override + public TaskPsiElement fun(Task task) { + return new TaskPsiElement(PsiManager.getInstance(project), task); } + }); - for (Object element : taskPsiElements) { - cancelled.checkCanceled(); - if (!consumer.process(element)) return false; - } - //i += ChooseByNameBase.MAXIMUM_LIST_SIZE_LIMIT; - //} + if (!cachedTasksFound && taskPsiElements.size() != 0) { + cancelled.checkCanceled(); + if (!consumer.process(ChooseByNameBase.NON_PREFIX_SEPARATOR)) return false; + } + + for (Object element : taskPsiElements) { + cancelled.checkCanceled(); + if (!consumer.process(element)) return false; + } return true; } }, "", false, 0); diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java index 0954036c05c4..5897a393695e 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java @@ -311,7 +311,7 @@ public class OpenTaskDialog extends DialogWrapper { @NotNull @Override public List getItems(final String prefix, final boolean cached, CompletionParameters parameters) { - return new TaskSearchSupport(myProject).getItems(prefix, cached, parameters.isAutoPopup()); + return TaskSearchSupport.getItems(TaskManager.getManager(myProject), prefix, cached, parameters.isAutoPopup()); } @Override diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskSearchSupport.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskSearchSupport.java index d102b2fde5f8..65bba6aef60d 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskSearchSupport.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskSearchSupport.java @@ -16,7 +16,6 @@ package com.intellij.tasks.actions; -import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.psi.codeStyle.NameUtil; import com.intellij.tasks.Task; @@ -34,13 +33,10 @@ import java.util.StringTokenizer; * @author Dmitry Avdeev */ public class TaskSearchSupport { - private final TaskManagerImpl myManager; - - public TaskSearchSupport(final Project project) { - myManager = (TaskManagerImpl)TaskManager.getManager(project); + private TaskSearchSupport() { } - public List getLocalAndCachedTasks(String pattern) { + public static List getLocalAndCachedTasks(final TaskManager myManager, String pattern) { List tasks = new ArrayList(); ContainerUtil.addAll(tasks, myManager.getLocalTasks()); ContainerUtil.addAll(tasks, ContainerUtil.filter(myManager.getCachedIssues(), new Condition() { @@ -63,15 +59,18 @@ public class TaskSearchSupport { }); } - public List getRepositoryTasks(String pattern, int max, long since, boolean forceRequest) { + public static List getRepositoriesTasks(final TaskManager myManager, String pattern, int max, long since, boolean forceRequest) { List tasks = myManager.getIssues(pattern, max, since, forceRequest); ContainerUtil.sort(tasks, TaskManagerImpl.TASK_UPDATE_COMPARATOR); return tasks; } - public List getItems(String pattern, boolean cached, boolean autopopup) { + public static List getItems(final TaskManager myManager, + String pattern, + boolean cached, + boolean autopopup) { final Matcher matcher = getMatcher(pattern); - return ContainerUtil.mapNotNull(getTasks(pattern, cached, autopopup), new NullableFunction() { + return ContainerUtil.mapNotNull(getTasks(pattern, cached, autopopup, myManager), new NullableFunction() { public Task fun(Task task) { return matcher.matches(task.getId()) || matcher.matches(task.getSummary()) ? task : null; } @@ -89,10 +88,10 @@ public class TaskSearchSupport { builder.append("* "); } - return NameUtil.buildMatcher(builder.toString(), 0, true, true, pattern.toLowerCase().equals(pattern)); + return NameUtil.buildMatcher(builder.toString(), NameUtil.MatchingCaseSensitivity.NONE); } - private List getTasks(String pattern, boolean cached, boolean autopopup) { + private static List getTasks(String pattern, boolean cached, boolean autopopup, final TaskManager myManager) { return cached ? myManager.getCachedIssues() : myManager.getIssues(pattern, !autopopup); } } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/connector/WebRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/connector/WebRepository.java index 27ba880ebc6c..f5fd0ac24ec3 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/connector/WebRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/connector/WebRepository.java @@ -1,24 +1,18 @@ package com.intellij.tasks.connector; import com.intellij.openapi.util.Comparing; -import com.intellij.tasks.Comment; import com.intellij.tasks.Task; import com.intellij.tasks.TaskRepositoryType; -import com.intellij.tasks.TaskType; +import com.intellij.tasks.actions.TaskSearchSupport; import com.intellij.tasks.impl.BaseRepository; import com.intellij.tasks.impl.BaseRepositoryImpl; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.xmlb.annotations.Tag; -import icons.TasksIcons; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.methods.GetMethod; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.*; -import java.io.IOException; import java.util.ArrayList; -import java.util.Date; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -41,8 +35,6 @@ public class WebRepository extends BaseRepositoryImpl { final static String DESCRIPTION_PLACEHOLDER = "{description}"; final static String PAGE_PLACEHOLDER = "{page}"; - //final Map myPlaceholder2Value = new HashMap(); - @SuppressWarnings({"UnusedDeclaration"}) public WebRepository() { } @@ -59,7 +51,7 @@ public class WebRepository extends BaseRepositoryImpl { } @Override - public Task[] getIssues(@Nullable final String query, final int max, final long since) throws Exception { + public List getIssues(@Nullable final String query, final int max, final long since) throws Exception { final HttpClient httpClient = getHttpClient(); if (!isLoginAnonymously()) login(httpClient); @@ -82,81 +74,22 @@ public class WebRepository extends BaseRepositoryImpl { List tasks = new ArrayList(); while (matcher.find()) { final String id = matcher.group(placeholders.indexOf(ID_PLACEHOLDER) + 1); - final String description = matcher.group(placeholders.indexOf(SUMMARY_PLACEHOLDER) + 1); - tasks.add(new Task() { - @NotNull - @Override - public String getId() { - return id; - } - - @NotNull - @Override - public String getSummary() { - return description; - } - - @Nullable - @Override - public String getDescription() { - return null; - } - - @NotNull - @Override - public Comment[] getComments() { - return new Comment[0]; - } - - @Nullable - @Override - public Icon getIcon() { - return TasksIcons.Other; - } - - @NotNull - @Override - public TaskType getType() { - return TaskType.OTHER; - } - - @Nullable - @Override - public Date getUpdated() { - return null; - } - - @Nullable - @Override - public Date getCreated() { - return null; - } - - @Override - public boolean isClosed() { - return false; - } - - @Override - public boolean isIssue() { - return true; - } - - @Nullable - @Override - public String getIssueUrl() { - return null; - } - }); + final String summary = matcher.group(placeholders.indexOf(SUMMARY_PLACEHOLDER) + 1); + tasks.add(new WebTask(id, summary)); } + tasks = TaskSearchSupport.filterTasks(query != null ? query : "", tasks); + tasks = tasks.subList(0, Math.min(max, tasks.size())); - return tasks.toArray(new Task[tasks.size()]); + return tasks; } - private void login(final HttpClient httpClient) throws IOException { + private void login(final HttpClient httpClient) throws Exception { final GetMethod method = new GetMethod(getFullLoginUrl()); httpClient.executeMethod(method); + if (method.getStatusCode() != 200) { + throw new Exception("Cannot login: HTTP status code " + method.getStatusCode()); + } } private static List getPlaceholders(String value) { @@ -233,8 +166,8 @@ public class WebRepository extends BaseRepositoryImpl { return new CancellableConnection() { @Override protected void doTest() throws Exception { - final Task[] issues = getIssues("", 0, 0); - if (issues.length == 0) throw new Exception("Tasks not found. Probably, you don't login."); + final List issues = getIssues("", 1, 0); + if (issues.size() == 0) throw new Exception("Tasks not found. Probably, you don't login."); } @Override diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/connector/WebRepositoryEditor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/connector/WebRepositoryEditor.java index 5d0b44ea4d26..bc63af82cc86 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/connector/WebRepositoryEditor.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/connector/WebRepositoryEditor.java @@ -8,8 +8,6 @@ import com.intellij.util.ui.FormBuilder; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; /** * User: Evgeny.Zakrevsky @@ -28,14 +26,6 @@ public class WebRepositoryEditor extends BaseRepositoryEditor { myUrlLabel.setText("{serverUrl}:"); myUsernameLabel.setText("{username}:"); myPasswordLabel.setText("{password}:"); - - myLoginAnonymouslyJBCheckBox.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - } - }); - - //setAnchor(myUsernameLabel); } @Override @@ -66,15 +56,13 @@ public class WebRepositoryEditor extends BaseRepositoryEditor { myLoginURLText = new JTextField(myRepository.getLoginURL()); installListener(myLoginURLText); return FormBuilder.createFormBuilder().setAlignLabelOnRight(true) - .addVerticalGap(8) - .addLabeledComponent(myTasksListURLLabel, myTasksListURLText) - .addTooltip("Available placeholders: " + WebRepository.SERVER_URL_PLACEHOLDER) - .addLabeledComponent(myTaskPatternLabel, myTaskPatternText, 8) - .addTooltip("Task pattern should be a regexp with two matching group: ({id}.+?) and ({summary}.+?)") - .addLabeledComponent(myLoginURLLabel, myLoginURLText, 8) + .addLabeledComponent(myLoginURLLabel, myLoginURLText) .addTooltip("Available placeholders: " + WebRepository.SERVER_URL_PLACEHOLDER + ", " + WebRepository.USERNAME_PLACEHOLDER + ", " + WebRepository.PASSWORD_PLACEHOLDER) - .addVerticalGap(8) + .addLabeledComponent(myTasksListURLLabel, myTasksListURLText) + .addTooltip("Available placeholders: " + WebRepository.SERVER_URL_PLACEHOLDER) + .addLabeledComponent(myTaskPatternLabel, myTaskPatternText) + .addTooltip("Task pattern should be a regexp with two matching group: ({id}.+?) and ({summary}.+?)") .getPanel(); } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/connector/WebTask.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/connector/WebTask.java new file mode 100644 index 000000000000..f665b4989fb8 --- /dev/null +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/connector/WebTask.java @@ -0,0 +1,85 @@ +package com.intellij.tasks.connector; + +import com.intellij.tasks.Comment; +import com.intellij.tasks.Task; +import com.intellij.tasks.TaskType; +import icons.TasksIcons; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.Date; + +public class WebTask extends Task { + private final String myId; + private final String myDescription; + + public WebTask(final String id, final String description) { + myId = id; + myDescription = description; + } + + @NotNull + @Override + public String getId() { + return myId; + } + + @NotNull + @Override + public String getSummary() { + return myDescription; + } + + @Nullable + @Override + public String getDescription() { + return null; + } + + @NotNull + @Override + public Comment[] getComments() { + return new Comment[0]; + } + + @Nullable + @Override + public Icon getIcon() { + return TasksIcons.Other; + } + + @NotNull + @Override + public TaskType getType() { + return TaskType.OTHER; + } + + @Nullable + @Override + public Date getUpdated() { + return null; + } + + @Nullable + @Override + public Date getCreated() { + return null; + } + + @Override + public boolean isClosed() { + return false; + } + + @Override + public boolean isIssue() { + return true; + } + + @Nullable + @Override + public String getIssueUrl() { + return null; + } +} \ No newline at end of file diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/fogbugz/FogBugzRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/fogbugz/FogBugzRepository.java index 0ca29d3f1b6e..1fbcdaec3535 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/fogbugz/FogBugzRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/fogbugz/FogBugzRepository.java @@ -64,11 +64,11 @@ public class FogBugzRepository extends BaseRepositoryImpl { } @Override - public Task[] getIssues(@Nullable String query, int max, final long since) throws Exception { + public List getIssues(@Nullable String query, int max, final long since) throws Exception { return getCases(StringUtil.notNullize(query)); } - private Task[] getCases(String q) throws Exception { + private List getCases(String q) throws Exception { HttpClient client = login(getLoginMethod()); PostMethod method = new PostMethod(getUrl() + "/api.asp"); method.addParameter("token", token); @@ -83,7 +83,7 @@ public class FogBugzRepository extends BaseRepositoryImpl { XPath path = XPath.newInstance("/response/cases/case"); final XPath commentPath = XPath.newInstance("events/event"); @SuppressWarnings("unchecked") final List nodes = (List)path.selectNodes(document); - List tasks = ContainerUtil.mapNotNull(nodes, new NotNullFunction() { + return ContainerUtil.mapNotNull(nodes, new NotNullFunction() { @NotNull @Override public Task fun(Element element) { @@ -91,7 +91,6 @@ public class FogBugzRepository extends BaseRepositoryImpl { } }); - return tasks.toArray(new Task[tasks.size()]); } private static TaskType getType(Element element) { @@ -195,15 +194,15 @@ public class FogBugzRepository extends BaseRepositoryImpl { @Nullable @Override public Task findTask(String id) throws Exception { - Task[] tasks = getCases(id); - switch (tasks.length) { + List tasks = getCases(id); + switch (tasks.size()) { case 0: return null; case 1: - return tasks[0]; + return tasks.get(0); default: - LOG.warn("Expected unique case for case id: " + id + ", got " + tasks.length + " instead. Using the first one."); - return tasks[0]; + LOG.warn("Expected unique case for case id: " + id + ", got " + tasks.size() + " instead. Using the first one."); + return tasks.get(0); } } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java index ac042ad89cdc..c618c2d71f94 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java @@ -247,24 +247,25 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe return myTasks.get(id); } + @NotNull @Override - public List getIssues(String query) { + public List getIssues(@Nullable final String query) { return getIssues(query, true); } @Override - public List getIssues(String query, int max, long since, boolean forceRequest) { + public List getIssues(@Nullable final String query, final boolean forceRequest) { + return getIssues(query, 50, 0, forceRequest); + } + + @Override + public List getIssues(@Nullable String query, int max, long since, boolean forceRequest) { List tasks = getIssuesFromRepositories(query, max, since, forceRequest); if (tasks == null) return getCachedIssues(); myIssueCache.putAll(ContainerUtil.newMapFromValues(tasks.iterator(), KEY_CONVERTOR)); return tasks; } - @Override - public List getIssues(String query, boolean forceRequest) { - return getIssues(query, 50, 0, forceRequest); - } - @Override public List getCachedIssues() { return new ArrayList(myIssueCache.values()); @@ -272,7 +273,7 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe @Nullable @Override - public Task updateIssue(String id) { + public Task updateIssue(@NotNull String id) { for (TaskRepository repository : getAllRepositories()) { if (repository.extractId(id) == null) { continue; @@ -310,11 +311,11 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe } @Override - public LocalTaskImpl createLocalTask(String summary) { + public LocalTaskImpl createLocalTask(@NotNull String summary) { return createTask(LOCAL_TASK_ID_FORMAT.format(myConfig.localTasksCounter++), summary); } - private static LocalTaskImpl createTask(String id, String summary) { + private static LocalTaskImpl createTask(@NotNull String id, @NotNull String summary) { LocalTaskImpl task = new LocalTaskImpl(id, summary); Date date = new Date(); task.setCreated(date); @@ -753,9 +754,9 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe continue; } try { - Task[] tasks = repository.getIssues(request, max, since); + final List tasks = repository.getIssues(request, max, since); myBadRepositories.remove(repository); - if (issues == null) issues = new ArrayList(tasks.length); + if (issues == null) issues = new ArrayList(tasks.size()); ContainerUtil.addAll(issues, tasks); } catch (Exception e) { @@ -822,14 +823,14 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe } } String comment = changeList.getComment(); - LocalTaskImpl task = createLocalTask(StringUtil.isEmpty(comment) ? changeList.getName() : comment); + LocalTaskImpl task = createLocalTask(comment == null || comment.isEmpty() ? changeList.getName() : comment); task.getChangeLists().add(new ChangeListInfo(changeList)); task.setAssociatedChangelistId(id); } @NotNull @Override - public List getOpenChangelists(Task task) { + public List getOpenChangelists(@NotNull Task task) { if (task instanceof LocalTaskImpl) { List changeLists = ((LocalTaskImpl)task).getChangeLists(); for (Iterator it = changeLists.iterator(); it.hasNext();) { diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/lighthouse/LighthouseRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/lighthouse/LighthouseRepository.java index aae149c8f141..fe8437749d59 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/lighthouse/LighthouseRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/lighthouse/LighthouseRepository.java @@ -77,7 +77,7 @@ public class LighthouseRepository extends BaseRepositoryImpl { } @Override - public Task[] getIssues(@Nullable String query, int max, long since) throws Exception { + public List getIssues(@Nullable String query, int max, long since) throws Exception { String url = "/projects/" + myProjectId + "/tickets.xml"; url += "?q=" + encodeUrl("state:open sort:updated "); if (!StringUtil.isEmpty(query)) { @@ -107,7 +107,7 @@ public class LighthouseRepository extends BaseRepositoryImpl { result.addAll(taskList); page++; } - return result.toArray(new Task[result.size()]); + return result; } @Nullable diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisRepository.java index 52922dc04f8f..7574b07ced65 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisRepository.java @@ -1,6 +1,5 @@ package com.intellij.tasks.mantis; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Comparing; import com.intellij.tasks.Task; import com.intellij.tasks.TaskRepositoryType; @@ -14,6 +13,7 @@ import com.intellij.util.NullableFunction; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.xmlb.annotations.Tag; +import org.apache.axis.utils.StringUtils; import org.jetbrains.annotations.Nullable; import javax.xml.rpc.ServiceException; @@ -30,8 +30,6 @@ import java.util.Set; */ @Tag("Mantis") public class MantisRepository extends BaseRepositoryImpl { - private final static Logger LOG = Logger.getInstance("#com.intellij.tasks.mantis.MantisRepository"); - private final static String SOAP_API_LOCATION = "/api/soap/mantisconnect.php"; private Map> myProject2FiltersCachedData; @@ -59,55 +57,55 @@ public class MantisRepository extends BaseRepositoryImpl { } @Override - public Task[] getIssues(String request, int max, long since) throws Exception { + public List getIssues(@Nullable String request, int max, long since) throws Exception { MantisConnectPortType soap = createSoap(); + List result = new ArrayList(max); + int page = 0; + int issuesOnPage = StringUtils.isEmpty(request) ? max : max * 2; + while (true) { + final List issuesFromPage = getIssues(page, issuesOnPage, soap); + final List filteredTasks = TaskSearchSupport.filterTasks(request != null ? request : "", issuesFromPage); + result.addAll(filteredTasks); + if (issuesFromPage.size() < issuesOnPage || result.size() >= max) { + break; + } + } + result = result.subList(0, Math.min(max, result.size())); + return result; + } + + private List getIssues(final int page, final int issuesOnPage, final MantisConnectPortType soap) throws Exception { try { IssueData[] issues; if (MantisFilter.LAST_TASKS.equals(myFilter)) { - issues = soap.mc_project_get_issues(getUsername(), getPassword(), BigInteger.valueOf(myProject.getId()), BigInteger.ZERO, - BigInteger.valueOf(max)); + issues = soap.mc_project_get_issues(getUsername(), getPassword(), BigInteger.valueOf(myProject.getId()), BigInteger.valueOf(page), + BigInteger.valueOf(issuesOnPage)); } else { issues = soap.mc_filter_get_issues(getUsername(), getPassword(), BigInteger.valueOf(myProject.getId()), - BigInteger.valueOf(myFilter.getId()), BigInteger.ZERO, BigInteger.valueOf(max)); + BigInteger.valueOf(myFilter.getId()), BigInteger.valueOf(page), BigInteger.valueOf(issuesOnPage)); } - final List filteredTasks = - TaskSearchSupport - .filterTasks(request == null ? "" : request, ContainerUtil.mapNotNull(issues, new NullableFunction() { - public Task fun(IssueData issueData) { - try { - return createIssue(issueData); - } - catch (Exception e) { - return null; - } - } - })); - return filteredTasks.toArray(new Task[filteredTasks.size()]); + return ContainerUtil.mapNotNull(issues, new NullableFunction() { + public Task fun(IssueData issueData) { + return createIssue(issueData); + } + }); } catch (Exception e) { IssueHeaderData[] issues; if (MantisFilter.LAST_TASKS.equals(myFilter)) { - issues = soap.mc_project_get_issue_headers(getUsername(), getPassword(), BigInteger.valueOf(myProject.getId()), BigInteger.ZERO, - BigInteger.valueOf(max)); + issues = soap.mc_project_get_issue_headers(getUsername(), getPassword(), BigInteger.valueOf(myProject.getId()), BigInteger.valueOf(page), + BigInteger.valueOf(issuesOnPage)); } else { issues = soap.mc_filter_get_issue_headers(getUsername(), getPassword(), BigInteger.valueOf(myProject.getId()), - BigInteger.valueOf(myFilter.getId()), BigInteger.ZERO, BigInteger.valueOf(max)); + BigInteger.valueOf(myFilter.getId()), BigInteger.valueOf(page), BigInteger.valueOf(issuesOnPage)); } - final List filteredTasks = - TaskSearchSupport - .filterTasks(request == null ? "" : request, ContainerUtil.mapNotNull(issues, new NullableFunction() { - public Task fun(IssueHeaderData issueHeaderData) { - try { - return createIssue(issueHeaderData); - } - catch (Exception e) { - return null; - } - } - })); - return filteredTasks.toArray(new Task[filteredTasks.size()]); + return ContainerUtil.mapNotNull(issues, new NullableFunction() { + public Task fun(IssueHeaderData issueData) { + return createIssue(issueData); + } + }); } } @@ -133,7 +131,7 @@ public class MantisRepository extends BaseRepositoryImpl { } @Nullable - private Task createIssue(final IssueData data) throws Exception { + private Task createIssue(final IssueData data) { String id = String.valueOf(data.getId()); if (id == null) return null; String summary = data.getSummary(); @@ -151,7 +149,7 @@ public class MantisRepository extends BaseRepositoryImpl { } @Nullable - private Task createIssue(final IssueHeaderData data) throws Exception { + private Task createIssue(final IssueHeaderData data) { String id = String.valueOf(data.getId()); if (id == null) return null; String summary = data.getSummary(); diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/pivotal/PivotalTrackerRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/pivotal/PivotalTrackerRepository.java index 52f2fb019f5b..2cadcdebb9d1 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/pivotal/PivotalTrackerRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/pivotal/PivotalTrackerRepository.java @@ -82,19 +82,18 @@ public class PivotalTrackerRepository extends BaseRepositoryImpl { } @Override - public Task[] getIssues(@Nullable final String query, final int max, final long since) throws Exception { + public List getIssues(@Nullable final String query, final int max, final long since) throws Exception { @SuppressWarnings({"unchecked"}) List children = getStories(query, max); - List taskList = ContainerUtil.mapNotNull(children, new NullableFunction() { + + return ContainerUtil.mapNotNull(children, new NullableFunction() { public Task fun(Object o) { return createIssue((Element)o); } }); - - return taskList.toArray(new Task[taskList.size()]); } @SuppressWarnings({"unchecked"}) - private List getStories(final String query, final int max) throws Exception { + private List getStories(@Nullable final String query, final int max) throws Exception { String url = API_URL + "/projects/" + myProjectId + "/stories"; url += "?filter=" + encodeUrl("state:started,unstarted,unscheduled,rejected"); if (!StringUtil.isEmpty(query)) { diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java index f74533ee9786..d891a30f2b54 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java @@ -66,15 +66,14 @@ public class RedmineRepository extends BaseRepositoryImpl { } @Override - public Task[] getIssues(@Nullable String query, int max, long since) throws Exception { + public List getIssues(@Nullable String query, int max, long since) throws Exception { @SuppressWarnings({"unchecked"}) List children = getIssues(query, max); - List taskList = ContainerUtil.mapNotNull(children, new NullableFunction() { + + return ContainerUtil.mapNotNull(children, new NullableFunction() { public Task fun(Object o) { return createIssue((Element)o); } }); - - return taskList.toArray(new Task[taskList.size()]); } @Nullable @@ -188,7 +187,7 @@ public class RedmineRepository extends BaseRepositoryImpl { } @SuppressWarnings({"unchecked"}) - private List getIssues(String query, int max) throws Exception { + private List getIssues(@Nullable String query, int max) throws Exception { String url = "/projects/" + myProjectId + "/issues.xml?"; final boolean hasKey = !StringUtil.isEmpty(myAPIKey) && !isUseHttpAuthentication(); if (hasKey) { diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/trac/TracRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/trac/TracRepository.java index a4cb3f78ca89..e43f7e0b024f 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/trac/TracRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/trac/TracRepository.java @@ -46,12 +46,12 @@ public class TracRepository extends BaseRepositoryImpl { private Boolean myMaxSupported; @Override - public Task[] getIssues(@Nullable String query, int max, long since) throws Exception { + public List getIssues(@Nullable String query, int max, long since) throws Exception { Transport transport = new Transport(); return getIssues(query, max, transport); } - private Task[] getIssues(String query, int max, final Transport transport) throws Exception { + private List getIssues(@Nullable String query, int max, final Transport transport) throws Exception { final XmlRpcClient client = getRpcClient(); Vector result = null; @@ -83,10 +83,10 @@ public class TracRepository extends BaseRepositoryImpl { Task task = getTask((Integer)result.get(i), client, transport); ContainerUtil.addIfNotNull(tasks, task); } - return tasks.toArray(new Task[tasks.size()]); + return tasks; } - private Vector runQuery(String query, Transport transport, XmlRpcClient client, String search) + private Vector runQuery(@Nullable String query, Transport transport, XmlRpcClient client, String search) throws XmlRpcException, IOException { if (query != null) { search = search.replace("{query}", query); diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackRepository.java index cd1520e3890c..7d6016c2908f 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackRepository.java @@ -20,6 +20,7 @@ import org.apache.commons.httpclient.methods.PostMethod; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; +import org.jetbrains.annotations.Nullable; import java.io.InputStream; import java.io.StringReader; @@ -53,13 +54,13 @@ public class YouTrackRepository extends BaseRepositoryImpl { myDefaultSearch = other.getDefaultSearch(); } - public Task[] getIssues(String request, int max, long since) throws Exception { + public List getIssues(@Nullable String request, int max, long since) throws Exception { String query = getDefaultSearch(); if (request != null) { query += " " + request; } - String requestUrl = "/rest/project/issues/?filter=" + encodeUrl(query) + "&max=" + max + "&after" + since; + String requestUrl = "/rest/project/issues/?filter=" + encodeUrl(query) + "&max=" + max + "&updatedAfter" + since; HttpMethod method = doREST(requestUrl, false); InputStream stream = method.getResponseBodyAsStream(); @@ -88,12 +89,11 @@ public class YouTrackRepository extends BaseRepositoryImpl { @SuppressWarnings({"unchecked"}) List children = element.getChildren("issue"); - List taskList = ContainerUtil.mapNotNull(children, new Function() { + return ContainerUtil.mapNotNull(children, new Function() { public Task fun(Object o) { return createIssue((Element)o); } }); - return taskList.toArray(new Task[taskList.size()]); } @Override diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskManagerTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskManagerTest.java index cf4d09679e21..47543ad07a26 100644 --- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskManagerTest.java +++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskManagerTest.java @@ -79,7 +79,7 @@ public class TaskManagerTest extends TaskManagerTestCase { TestRepository repository = new TestRepository() { @Override - public Task[] getIssues(@Nullable String query, int max, long since) throws Exception { + public List getIssues(@Nullable String query, int max, long since) throws Exception { throw new Exception(); } }; @@ -121,7 +121,7 @@ public class TaskManagerTest extends TaskManagerTestCase { final Ref stopper = new Ref(Boolean.FALSE); TestRepository repository = new TestRepository(new LocalTaskImpl("foo", "bar")) { @Override - public Task[] getIssues(@Nullable String query, int max, long since) throws Exception { + public List getIssues(@Nullable String query, int max, long since) throws Exception { if (stopper.get()) throw new Exception(); return super.getIssues(query, max, since); } diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/TestRepository.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/TestRepository.java index 7731a833aba5..8055c90109ee 100644 --- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/TestRepository.java +++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/TestRepository.java @@ -5,6 +5,8 @@ import com.intellij.tasks.impl.BaseRepository; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.Nullable; +import java.util.List; + /** * @author Dmitry Avdeev */ @@ -29,8 +31,8 @@ class TestRepository extends BaseRepository { } @Override - public Task[] getIssues(@Nullable String query, int max, long since) throws Exception { - return myTasks; + public List getIssues(@Nullable String query, int max, long since) throws Exception { + return ContainerUtil.newArrayList(myTasks); } @Override