diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskUiUtil.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskUiUtil.java index e1fad1045b2e..9f28f8868ae7 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskUiUtil.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskUiUtil.java @@ -2,6 +2,7 @@ package com.intellij.tasks.impl; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; @@ -19,6 +20,8 @@ import java.util.List; */ public class TaskUiUtil { + private static Logger LOG = Logger.getInstance(TaskUiUtil.class); + private TaskUiUtil() { // Utility class } @@ -45,6 +48,7 @@ public class TaskUiUtil { myResult = fetch(indicator); } catch (Exception e) { + LOG.error(e); myException = e; } } @@ -127,13 +131,12 @@ public class TaskUiUtil { } else { // Some error occurred - myComboBox.removeAllItems(); handleError(); } } protected void handleError() { - // empty + myComboBox.removeAllItems(); } } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisFilter.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisFilter.java index 69058e2df1d2..dc1870c1aad3 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisFilter.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisFilter.java @@ -1,5 +1,6 @@ package com.intellij.tasks.mantis; +import com.intellij.tasks.mantis.model.FilterData; import com.intellij.util.xmlb.annotations.Attribute; import org.jetbrains.annotations.NotNull; @@ -15,34 +16,39 @@ public final class MantisFilter implements Comparable { return new MantisFilter(0, "-- all issues --"); } - private int id; - private String name; + private int myId; + private String myName; @SuppressWarnings({"UnusedDeclaration"}) public MantisFilter() { } - public MantisFilter(final int id, final String name) { - this.id = id; - this.name = name; + public MantisFilter(int id, String name) { + myId = id; + myName = name; + } + + public MantisFilter(@NotNull FilterData data) { + myId = data.getId().intValue(); + myName = data.getName(); } @Attribute("id") public int getId() { - return id; + return myId; } public void setId(final int id) { - this.id = id; + this.myId = id; } @Attribute("name") public String getName() { - return name; + return myName; } public void setName(final String name) { - this.name = name; + this.myName = name; } public final boolean isUnspecified() { @@ -54,12 +60,12 @@ public final class MantisFilter implements Comparable { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - return id == ((MantisFilter)o).id; + return myId == ((MantisFilter)o).myId; } @Override public final int hashCode() { - return id; + return myId; } @Override diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisProject.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisProject.java index 34bd3e199478..e1aa0b1119c7 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisProject.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisProject.java @@ -1,5 +1,6 @@ package com.intellij.tasks.mantis; +import com.intellij.tasks.mantis.model.ProjectData; import com.intellij.util.xmlb.annotations.Attribute; import com.intellij.util.xmlb.annotations.Transient; import org.jetbrains.annotations.NotNull; @@ -22,8 +23,8 @@ public final class MantisProject { private List myFilters = new ArrayList(); - private int id; - private String name; + private int myId; + private String myName; @SuppressWarnings({"UnusedDeclaration"}) public MantisProject() { @@ -31,27 +32,32 @@ public final class MantisProject { } public MantisProject(int id, @NotNull String name) { - this.id = id; - this.name = name; + this.myId = id; + this.myName = name; + } + + public MantisProject(@NotNull ProjectData data) { + myId = data.getId().intValue(); + myName = data.getName(); } @Attribute("id") public int getId() { - return id; + return myId; } public void setId(final int id) { - this.id = id; + this.myId = id; } @Attribute("name") @NotNull public String getName() { - return name; + return myName; } public void setName(@NotNull String name) { - this.name = name; + this.myName = name; } @@ -84,14 +90,14 @@ public final class MantisProject { MantisProject project = (MantisProject)o; - if (id != project.id) return false; + if (myId != project.myId) return false; return true; } @Override public final int hashCode() { - return id; + return myId; } @Override 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 8ab4d15293d3..3275efcdda42 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,7 +1,9 @@ package com.intellij.tasks.mantis; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.KeyValue; import com.intellij.openapi.util.text.StringUtil; import com.intellij.tasks.Task; import com.intellij.tasks.TaskBundle; @@ -12,9 +14,12 @@ import com.intellij.tasks.mantis.model.*; import com.intellij.util.Function; import com.intellij.util.NullableFunction; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.net.HttpConfigurable; +import com.intellij.util.proxy.JavaProxyProperty; import com.intellij.util.text.VersionComparatorUtil; import com.intellij.util.xmlb.annotations.Tag; import org.apache.axis.AxisFault; +import org.apache.axis.AxisProperties; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -40,6 +45,8 @@ public class MantisRepository extends BaseRepositoryImpl { private static final String SOAP_API_LOCATION = "/api/soap/mantisconnect.php"; private static final Pattern ID_PATTERN = Pattern.compile("\\d+"); + private static final Logger LOG = Logger.getInstance(MantisRepository.class); + // Projects fetched from server last time is cached, so workaround for IDEA-105413 could work. private List myProjects = null; // It means that special pseudo-project "All Projects" is supported on server side. @@ -110,27 +117,21 @@ public class MantisRepository extends BaseRepositoryImpl { boolean isWorkaround = myCurrentProject.isUnspecified() && !myAllProjectsAvailable; // Projects to iterate over, actually needed only when "All Projects" pseudo-project is selected // and is unsupported on server side. - List projects = isWorkaround? myProjects : Collections.singletonList(myCurrentProject); + List projects = isWorkaround ? myProjects : Collections.singletonList(myCurrentProject); for (MantisProject project : projects) { if (isWorkaround && project.isUnspecified()) { continue; } assert !project.isUnspecified() || myAllProjectsAvailable; - IssueHeaderData[] headers; - if (myCurrentFilter.isUnspecified()) { - headers = soap.mc_project_get_issue_headers(getUsername(), getPassword(), - bigInteger(project.getId()), bigInteger(pageNumber), bigInteger(pageSize)); - } - else { - headers = soap.mc_filter_get_issue_headers(getUsername(), getPassword(), - bigInteger(project.getId()), bigInteger(myCurrentFilter.getId()), - bigInteger(pageNumber), bigInteger(pageSize)); - } + IssueHeaderData[] headers = fetchProjectIssues(soap, project, myCurrentFilter, pageNumber, pageSize); ContainerUtil.addAll(collectedHeaders, headers); } return ContainerUtil.mapNotNull(collectedHeaders, new NullableFunction() { public Task fun(IssueHeaderData issueData) { - return createIssue(issueData); + if (issueData.getId() == null || issueData.getSummary() == null) { + return null; + } + return new MantisTask(issueData, MantisRepository.this); } }); } @@ -138,8 +139,12 @@ public class MantisRepository extends BaseRepositoryImpl { @Nullable @Override public Task findTask(String id) throws Exception { - IssueData data = createSoap().mc_issue_get(getUsername(), getPassword(), bigInteger(Integer.valueOf(id))); - return data == null ? null : createIssue(data); + IssueData data = fetchIssueById(createSoap(), id); + // sanity check + if (data == null || data.getId() == null || data.getSummary() == null) { + return null; + } + return new MantisTask(data, this); } @Nullable @@ -151,8 +156,8 @@ public class MantisRepository extends BaseRepositoryImpl { try { createSoap().mc_enum_access_levels(getUsername(), getPassword()); } - catch (AxisFault e) { - throw new Exception(TaskBundle.message("failure.server.message", e.getMessage())); + catch (Exception e) { + throw wrapException(e); } } @@ -162,22 +167,6 @@ public class MantisRepository extends BaseRepositoryImpl { }; } - @Nullable - private Task createIssue(IssueData data) { - if (data.getId() == null || data.getSummary() == null) { - return null; - } - return new MantisTask(data, this); - } - - @Nullable - private Task createIssue(IssueHeaderData data) { - if (data.getId() == null || data.getSummary() == null) { - return null; - } - return new MantisTask(data, myCurrentProject, this); - } - @NotNull public List getProjects() throws Exception { ensureProjectsRefreshed(); @@ -190,24 +179,23 @@ public class MantisRepository extends BaseRepositoryImpl { } } - public void refreshProjects() throws Exception { + void refreshProjects() throws Exception { MantisConnectPortType soap = createSoap(); myAllProjectsAvailable = checkAllProjectsAvailable(soap); - ProjectData[] projectDatas = soap.mc_projects_get_user_accessible(getUsername(), getPassword()); List projects = - new ArrayList(ContainerUtil.map(projectDatas, new Function() { + new ArrayList(ContainerUtil.map(fetchUserProjects(soap), new Function() { @Override public MantisProject fun(final ProjectData data) { - return new MantisProject(data.getId().intValue(), data.getName()); + return new MantisProject(data); } })); List commonFilters = new LinkedList(); for (MantisProject project : projects) { - FilterData[] filterDatas = soap.mc_filter_get(getUsername(), getPassword(), bigInteger(project.getId())); + FilterData[] rawFilters = fetchProjectFilters(soap, project); List projectFilters = new LinkedList(); - for (FilterData data : filterDatas) { - MantisFilter filter = new MantisFilter(data.getId().intValue(), data.getName()); + for (FilterData data : rawFilters) { + MantisFilter filter = new MantisFilter(data); if (data.getProject_id().intValue() == 0) { commonFilters.add(filter); } @@ -228,22 +216,100 @@ public class MantisRepository extends BaseRepositoryImpl { myProjects = projects; } + private static boolean checkAllProjectsAvailable(MantisConnectPortType soap) throws Exception { + // Check whether All Projects is available supported by server + try { + String version = soap.mc_version(); + boolean available = !DEBUG_ALL_PROJECTS && VersionComparatorUtil.compare(version, "1.2.9") >= 0; + if (!available) { + LOG.info("Using Mantis version without 'All Projects' support: " + version); + } + return available; + } + catch (Exception e) { + throw wrapException(e); + } + } + + private static Exception wrapException(@NotNull Exception e) throws Exception { + if (e instanceof AxisFault) { + throw new Exception(TaskBundle.message("failure.server.message", ((AxisFault)e).getFaultString()), e); + } + throw e; + } + @NotNull private MantisConnectPortType createSoap() throws Exception { + if (isUseProxy()) { + for (KeyValue pair : HttpConfigurable.getJvmPropertiesList(false, null)) { + String key = pair.getKey(), value = pair.getValue(); + // Axis uses another names for username and password properties + // see http://axis.apache.org/axis/java/client-side-axis.html for complete list + if (key.equals(JavaProxyProperty.HTTP_USERNAME)) { + AxisProperties.setProperty("http.proxyUser", value); + } + else if (key.equals(JavaProxyProperty.HTTP_PASSWORD)) { + AxisProperties.setProperty("http.proxyPassword", value); + } + else { + AxisProperties.setProperty(key, value); + } + } + } return new MantisConnectLocator().getMantisConnectPort(new URL(getUrl() + SOAP_API_LOCATION)); } - private static boolean checkAllProjectsAvailable(MantisConnectPortType soap) throws RemoteException { - // Check whether All Projects is available supported by server - String version = soap.mc_version(); - return !DEBUG_ALL_PROJECTS && VersionComparatorUtil.compare(version, "1.2.9") >= 0; + @Nullable + private IssueData fetchIssueById(@NotNull MantisConnectPortType soap, @NotNull String id) throws Exception { + try { + return soap.mc_issue_get(getUsername(), getPassword(), BigInteger.valueOf(Integer.valueOf(id))); + } + catch (RemoteException e) { + throw wrapException(e); + } } @NotNull - private static BigInteger bigInteger(int id) { - return BigInteger.valueOf(id); + private ProjectData[] fetchUserProjects(@NotNull MantisConnectPortType soap) throws Exception { + try { + return soap.mc_projects_get_user_accessible(getUsername(), getPassword()); + } + catch (RemoteException e) { + throw wrapException(e); + } } + @NotNull + private FilterData[] fetchProjectFilters(@NotNull MantisConnectPortType soap, @NotNull MantisProject project) throws Exception { + try { + return soap.mc_filter_get(getUsername(), getPassword(), BigInteger.valueOf(project.getId())); + } + catch (RemoteException e) { + throw wrapException(e); + } + } + + @NotNull + private IssueHeaderData[] fetchProjectIssues(@NotNull MantisConnectPortType soap, @NotNull MantisProject project, + @NotNull MantisFilter filter, int pageNumber, int pageSize) throws Exception { + try { + if (filter.isUnspecified()) { + return soap.mc_project_get_issue_headers(getUsername(), getPassword(), + BigInteger.valueOf(project.getId()), BigInteger.valueOf(pageNumber), + BigInteger.valueOf(pageSize)); + } + else { + return soap.mc_filter_get_issue_headers(getUsername(), getPassword(), + BigInteger.valueOf(project.getId()), BigInteger.valueOf(filter.getId()), + BigInteger.valueOf(pageNumber), BigInteger.valueOf(pageSize)); + } + } + catch (RemoteException e) { + throw wrapException(e); + } + } + + @Nullable public MantisProject getCurrentProject() { return myCurrentProject; diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisRepositoryEditor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisRepositoryEditor.java index f1ea172c2335..2fa02e5f178d 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisRepositoryEditor.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisRepositoryEditor.java @@ -149,6 +149,7 @@ public class MantisRepositoryEditor extends BaseRepositoryEditor= 90; myDescription = null; // unavailable from header myCreated = null; // unavailable from header diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/MantisIntegrationTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/MantisIntegrationTest.java index ab8693c9169e..464aa3e249f9 100644 --- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/MantisIntegrationTest.java +++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/MantisIntegrationTest.java @@ -39,7 +39,8 @@ public class MantisIntegrationTest extends TaskManagerTestCase { assertTrue(issues.length >= 1); final Task task = issues[0]; assertEquals("1", task.getId()); - assertEquals("Mantis 1.2 project 1", task.getProject()); + // not available here, but is defined in practice, after task has been activated and thus updated from server + //assertEquals("Mantis 1.2 project 1", task.getProject()); assertEquals("1", task.getNumber()); assertEquals("M12P1I1", task.getSummary());