Tasks search improved for Mantis and Generic Connector

This commit is contained in:
Evgeny Zakrevsky
2012-10-10 02:11:13 +04:00
parent dc456792e3
commit a1497d73ab
22 changed files with 237 additions and 232 deletions
@@ -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 {
@@ -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<Task> 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<Task> getIssues(String query) throws Exception {
private List<Task> getIssues(@Nullable String query) throws Exception {
String path;
boolean noQuery = StringUtil.isEmpty(query);
if (!noQuery) {
@@ -53,11 +53,11 @@ public class JiraRepository extends BaseRepositoryImpl {
super(type);
}
public Task[] getIssues(String request, int max, long since) throws Exception {
public List<Task> 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<Task> 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<Task> 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<Element> children = channel.getChildren("item");
LOG.info("JIRA: " + children.size() + " issues found");
return ContainerUtil.map2Array(children, Task.class, new Function<Element, Task>() {
return ContainerUtil.map(children, new Function<Element, Task>() {
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<Task> tasks = processRSS(url.toString(), login());
return tasks.size() == 0 ? null : tasks.get(0);
}
catch (Exception e) {
LOG.warn("Cannot get issue " + id + ": " + e.getMessage());
@@ -43,8 +43,7 @@ public abstract class TaskManager {
public abstract List<Task> getIssues(@Nullable String query, boolean forceRequest);
public abstract List<Task> getIssues(String query, int max, long since, boolean forceRequest);
public abstract List<Task> 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<Task> getCachedIssues();
@Nullable
public abstract Task updateIssue(String id);
public abstract Task updateIssue(@NotNull String id);
public abstract LocalTask[] getLocalTasks();
@@ -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<Task> 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<Exception> {
public abstract static class CancellableConnection implements Callable<Exception> {
@Nullable
@Override
@@ -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");
}
@@ -62,7 +62,7 @@ public class GotoTaskAction extends GotoActionBase {
boolean everywhere,
@NotNull ProgressIndicator cancelled,
@NotNull Processor<Object> consumer) {
List<Task> cachedTasks = new TaskSearchSupport(project).getLocalAndCachedTasks(pattern);
List<Task> cachedTasks = TaskSearchSupport.getLocalAndCachedTasks(TaskManager.getManager(project), pattern);
List<TaskPsiElement> taskPsiElements = ContainerUtil.map(cachedTasks, new Function<Task, TaskPsiElement>() {
@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<Task> 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<Task, TaskPsiElement>() {
@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<Task> tasks =
TaskSearchSupport.getRepositoriesTasks(TaskManager.getManager(project), pattern, base.getMaximumListSizeLimit(), 0, true);
tasks.removeAll(cachedTasks);
taskPsiElements = ContainerUtil.map(tasks, new Function<Task, TaskPsiElement>() {
@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);
@@ -311,7 +311,7 @@ public class OpenTaskDialog extends DialogWrapper {
@NotNull
@Override
public List<Task> 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
@@ -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<Task> getLocalAndCachedTasks(String pattern) {
public static List<Task> getLocalAndCachedTasks(final TaskManager myManager, String pattern) {
List<Task> tasks = new ArrayList<Task>();
ContainerUtil.addAll(tasks, myManager.getLocalTasks());
ContainerUtil.addAll(tasks, ContainerUtil.filter(myManager.getCachedIssues(), new Condition<Task>() {
@@ -63,15 +59,18 @@ public class TaskSearchSupport {
});
}
public List<Task> getRepositoryTasks(String pattern, int max, long since, boolean forceRequest) {
public static List<Task> getRepositoriesTasks(final TaskManager myManager, String pattern, int max, long since, boolean forceRequest) {
List<Task> tasks = myManager.getIssues(pattern, max, since, forceRequest);
ContainerUtil.sort(tasks, TaskManagerImpl.TASK_UPDATE_COMPARATOR);
return tasks;
}
public List<Task> getItems(String pattern, boolean cached, boolean autopopup) {
public static List<Task> getItems(final TaskManager myManager,
String pattern,
boolean cached,
boolean autopopup) {
final Matcher matcher = getMatcher(pattern);
return ContainerUtil.mapNotNull(getTasks(pattern, cached, autopopup), new NullableFunction<Task, Task>() {
return ContainerUtil.mapNotNull(getTasks(pattern, cached, autopopup, myManager), new NullableFunction<Task, Task>() {
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<Task> getTasks(String pattern, boolean cached, boolean autopopup) {
private static List<Task> getTasks(String pattern, boolean cached, boolean autopopup, final TaskManager myManager) {
return cached ? myManager.getCachedIssues() : myManager.getIssues(pattern, !autopopup);
}
}
@@ -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<String, String> myPlaceholder2Value = new HashMap<String, String>();
@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<Task> 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<Task> tasks = new ArrayList<Task>();
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<String> 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<Task> issues = getIssues("", 1, 0);
if (issues.size() == 0) throw new Exception("Tasks not found. Probably, you don't login.");
}
@Override
@@ -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<WebRepository> {
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<WebRepository> {
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();
}
@@ -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;
}
}
@@ -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<Task> 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<Task> 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<Element> nodes = (List<Element>)path.selectNodes(document);
List<Task> tasks = ContainerUtil.mapNotNull(nodes, new NotNullFunction<Element, Task>() {
return ContainerUtil.mapNotNull(nodes, new NotNullFunction<Element, Task>() {
@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<Task> 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);
}
}
@@ -247,24 +247,25 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
return myTasks.get(id);
}
@NotNull
@Override
public List<Task> getIssues(String query) {
public List<Task> getIssues(@Nullable final String query) {
return getIssues(query, true);
}
@Override
public List<Task> getIssues(String query, int max, long since, boolean forceRequest) {
public List<Task> getIssues(@Nullable final String query, final boolean forceRequest) {
return getIssues(query, 50, 0, forceRequest);
}
@Override
public List<Task> getIssues(@Nullable String query, int max, long since, boolean forceRequest) {
List<Task> tasks = getIssuesFromRepositories(query, max, since, forceRequest);
if (tasks == null) return getCachedIssues();
myIssueCache.putAll(ContainerUtil.newMapFromValues(tasks.iterator(), KEY_CONVERTOR));
return tasks;
}
@Override
public List<Task> getIssues(String query, boolean forceRequest) {
return getIssues(query, 50, 0, forceRequest);
}
@Override
public List<Task> getCachedIssues() {
return new ArrayList<Task>(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<Task> tasks = repository.getIssues(request, max, since);
myBadRepositories.remove(repository);
if (issues == null) issues = new ArrayList<Task>(tasks.length);
if (issues == null) issues = new ArrayList<Task>(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<ChangeListInfo> getOpenChangelists(Task task) {
public List<ChangeListInfo> getOpenChangelists(@NotNull Task task) {
if (task instanceof LocalTaskImpl) {
List<ChangeListInfo> changeLists = ((LocalTaskImpl)task).getChangeLists();
for (Iterator<ChangeListInfo> it = changeLists.iterator(); it.hasNext();) {
@@ -77,7 +77,7 @@ public class LighthouseRepository extends BaseRepositoryImpl {
}
@Override
public Task[] getIssues(@Nullable String query, int max, long since) throws Exception {
public List<Task> 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
@@ -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<MantisProject, List<MantisFilter>> myProject2FiltersCachedData;
@@ -59,55 +57,55 @@ public class MantisRepository extends BaseRepositoryImpl {
}
@Override
public Task[] getIssues(String request, int max, long since) throws Exception {
public List<Task> getIssues(@Nullable String request, int max, long since) throws Exception {
MantisConnectPortType soap = createSoap();
List<Task> result = new ArrayList<Task>(max);
int page = 0;
int issuesOnPage = StringUtils.isEmpty(request) ? max : max * 2;
while (true) {
final List<Task> issuesFromPage = getIssues(page, issuesOnPage, soap);
final List<Task> 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<Task> 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<Task> filteredTasks =
TaskSearchSupport
.filterTasks(request == null ? "" : request, ContainerUtil.mapNotNull(issues, new NullableFunction<IssueData, Task>() {
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<IssueData, Task>() {
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<Task> filteredTasks =
TaskSearchSupport
.filterTasks(request == null ? "" : request, ContainerUtil.mapNotNull(issues, new NullableFunction<IssueHeaderData, Task>() {
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<IssueHeaderData, Task>() {
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();
@@ -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<Task> getIssues(@Nullable final String query, final int max, final long since) throws Exception {
@SuppressWarnings({"unchecked"}) List<Object> children = getStories(query, max);
List<Task> taskList = ContainerUtil.mapNotNull(children, new NullableFunction<Object, Task>() {
return ContainerUtil.mapNotNull(children, new NullableFunction<Object, Task>() {
public Task fun(Object o) {
return createIssue((Element)o);
}
});
return taskList.toArray(new Task[taskList.size()]);
}
@SuppressWarnings({"unchecked"})
private List<Object> getStories(final String query, final int max) throws Exception {
private List<Object> 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)) {
@@ -66,15 +66,14 @@ public class RedmineRepository extends BaseRepositoryImpl {
}
@Override
public Task[] getIssues(@Nullable String query, int max, long since) throws Exception {
public List<Task> getIssues(@Nullable String query, int max, long since) throws Exception {
@SuppressWarnings({"unchecked"}) List<Object> children = getIssues(query, max);
List<Task> taskList = ContainerUtil.mapNotNull(children, new NullableFunction<Object, Task>() {
return ContainerUtil.mapNotNull(children, new NullableFunction<Object, Task>() {
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<Object> getIssues(String query, int max) throws Exception {
private List<Object> getIssues(@Nullable String query, int max) throws Exception {
String url = "/projects/" + myProjectId + "/issues.xml?";
final boolean hasKey = !StringUtil.isEmpty(myAPIKey) && !isUseHttpAuthentication();
if (hasKey) {
@@ -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<Task> 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<Task> getIssues(@Nullable String query, int max, final Transport transport) throws Exception {
final XmlRpcClient client = getRpcClient();
Vector<Object> 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<Object> runQuery(String query, Transport transport, XmlRpcClient client, String search)
private Vector<Object> runQuery(@Nullable String query, Transport transport, XmlRpcClient client, String search)
throws XmlRpcException, IOException {
if (query != null) {
search = search.replace("{query}", query);
@@ -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<Task> 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<Object> children = element.getChildren("issue");
List<Task> taskList = ContainerUtil.mapNotNull(children, new Function<Object, Task>() {
return ContainerUtil.mapNotNull(children, new Function<Object, Task>() {
public Task fun(Object o) {
return createIssue((Element)o);
}
});
return taskList.toArray(new Task[taskList.size()]);
}
@Override
@@ -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<Task> getIssues(@Nullable String query, int max, long since) throws Exception {
throw new Exception();
}
};
@@ -121,7 +121,7 @@ public class TaskManagerTest extends TaskManagerTestCase {
final Ref<Boolean> stopper = new Ref<Boolean>(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<Task> getIssues(@Nullable String query, int max, long since) throws Exception {
if (stopper.get()) throw new Exception();
return super.getIssues(query, max, since);
}
@@ -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<Task> getIssues(@Nullable String query, int max, long since) throws Exception {
return ContainerUtil.newArrayList(myTasks);
}
@Override