From 3e635f19ad42227510e9bc300ad7e975481a772c Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Sun, 19 May 2013 11:04:21 +0400 Subject: [PATCH] IDEA-107420 Gradle: Correct tasks representation 1. Local external system settings are processed now (tool window tree 'expanded' state is correctly stored and restored now; last projects/tasks are cached as well); 2. Minor refactorings; --- .../resources/icons/task.png | Bin .../externalSystem/ExternalSystemUiAware.java | 3 + .../project/ExternalConfigPathAware.java | 28 +++ .../model/project/ModuleData.java | 5 +- .../model/project/ProjectData.java | 2 +- .../serialization/ExternalProjectPojo.java | 89 +++++++++ .../model/serialization/ExternalTaskPojo.java | 108 +++++++++++ .../task/ExternalSystemTaskDescriptor.java | 109 ----------- .../externalSystem/model/task/TaskData.java | 73 ++++++-- .../AbstractExternalSystemLocalSettings.java | 58 +++--- .../util/ExternalSystemApiUtil.java | 39 ++-- .../util/ExternalSystemConstants.java | 2 + ...stractImportFromExternalSystemControl.java | 3 +- .../task/AbstractToolWindowService.java | 7 +- .../service/task/ToolWindowModuleService.java | 40 ++-- .../task/ToolWindowProjectService.java | 55 ------ .../service/task/ToolWindowTaskService.java | 55 +++++- ...stractExternalSystemToolWindowFactory.java | 7 +- .../task/ui/ExternalSystemTasksPanel.java | 11 +- .../task/ui/ExternalSystemTasksTree.java | 21 ++- .../task/ui/ExternalSystemTasksTreeModel.java | 175 +++++++++++------- .../ui/DefaultExternalSystemUiAware.java | 7 + .../util/ExternalSystemUiUtil.java | 27 +++ .../util/ExternalSystemUtil.java | 4 +- .../src/META-INF/ExternalSystemExtensions.xml | 1 - plugins/gradle/src/icons/GradleIcons.java | 9 +- .../plugins/gradle/GradleManager.java | 7 + .../project/GradleProjectResolver.java | 74 ++++++-- .../plugins/gradle/tasks/GradleTasksList.java | 139 +++++++------- .../gradle/tasks/GradleTasksModel.java | 112 +++++------ .../gradle/tasks/GradleTasksPanel.java | 27 +-- .../plugins/gradle/util/GradleUtil.java | 28 +++ 32 files changed, 847 insertions(+), 478 deletions(-) rename {plugins/gradle => platform/external-system-api}/resources/icons/task.png (100%) create mode 100644 platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalConfigPathAware.java create mode 100644 platform/external-system-api/src/com/intellij/openapi/externalSystem/model/serialization/ExternalProjectPojo.java create mode 100644 platform/external-system-api/src/com/intellij/openapi/externalSystem/model/serialization/ExternalTaskPojo.java delete mode 100644 platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskDescriptor.java delete mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ToolWindowProjectService.java diff --git a/plugins/gradle/resources/icons/task.png b/platform/external-system-api/resources/icons/task.png similarity index 100% rename from plugins/gradle/resources/icons/task.png rename to platform/external-system-api/resources/icons/task.png diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemUiAware.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemUiAware.java index b4729ee54f90..a00badaa9b5e 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemUiAware.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemUiAware.java @@ -27,4 +27,7 @@ public interface ExternalSystemUiAware { @Nullable Icon getProjectIcon(); + + @Nullable + Icon getTaskIcon(); } diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalConfigPathAware.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalConfigPathAware.java new file mode 100644 index 000000000000..06d44c5e5623 --- /dev/null +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalConfigPathAware.java @@ -0,0 +1,28 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.externalSystem.model.project; + +import org.jetbrains.annotations.NotNull; + +/** + * @author Denis Zhdanov + * @since 5/18/13 8:01 PM + */ +public interface ExternalConfigPathAware { + + @NotNull + String getLinkedExternalProjectPath(); +} diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ModuleData.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ModuleData.java index 4ba64b965d92..12b707ad57e5 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ModuleData.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ModuleData.java @@ -13,7 +13,7 @@ import java.util.Map; * @author Denis Zhdanov * @since 8/8/11 12:11 PM */ -public class ModuleData extends AbstractNamedData implements Named { +public class ModuleData extends AbstractNamedData implements Named, ExternalConfigPathAware { private static final long serialVersionUID = 1L; @@ -42,7 +42,8 @@ public class ModuleData extends AbstractNamedData implements Named { } @NotNull - public String getExternalConfigPath() { + @Override + public String getLinkedExternalProjectPath() { return myExternalConfigPath; } diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ProjectData.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ProjectData.java index 5355a7b4a26c..71ef9b0a54a6 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ProjectData.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ProjectData.java @@ -10,7 +10,7 @@ import org.jetbrains.annotations.NotNull; * @author Denis Zhdanov * @since 8/1/11 1:30 PM */ -public class ProjectData extends AbstractNamedData { +public class ProjectData extends AbstractNamedData implements ExternalConfigPathAware { private static final long serialVersionUID = 1L; diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/serialization/ExternalProjectPojo.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/serialization/ExternalProjectPojo.java new file mode 100644 index 000000000000..a7a76b645026 --- /dev/null +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/serialization/ExternalProjectPojo.java @@ -0,0 +1,89 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.externalSystem.model.serialization; + +import com.intellij.openapi.externalSystem.model.project.ExternalConfigPathAware; +import com.intellij.openapi.externalSystem.model.project.Named; +import org.jetbrains.annotations.NotNull; + +/** +* @author Denis Zhdanov +* @since 5/18/13 10:51 PM +*/ +public class ExternalProjectPojo { + + @NotNull private String myName; + @NotNull private String myPath; + + @SuppressWarnings("UnusedDeclaration") + public ExternalProjectPojo() { + // Used by IJ serialization + this("___DUMMY___", "___DUMMY___"); + } + + public ExternalProjectPojo(@NotNull String name, @NotNull String path) { + myName = name; + myPath = path; + } + + @NotNull + public static ExternalProjectPojo from(@NotNull T data) { + return new ExternalProjectPojo(data.getName(), data.getLinkedExternalProjectPath()); + } + + @NotNull + public String getName() { + return myName; + } + + public void setName(@NotNull String name) { + myName = name; + } + + @NotNull + public String getPath() { + return myPath; + } + + public void setPath(@NotNull String path) { + myPath = path; + } + + @Override + public int hashCode() { + int result = myName.hashCode(); + result = 31 * result + myPath.hashCode(); + return result; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ExternalProjectPojo pojo = (ExternalProjectPojo)o; + + if (!myName.equals(pojo.myName)) return false; + if (!myPath.equals(pojo.myPath)) return false; + + return true; + } + + @Override + public String toString() { + return myName; + } +} diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/serialization/ExternalTaskPojo.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/serialization/ExternalTaskPojo.java new file mode 100644 index 000000000000..a06c292bc5b4 --- /dev/null +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/serialization/ExternalTaskPojo.java @@ -0,0 +1,108 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.externalSystem.model.serialization; + +import com.intellij.openapi.externalSystem.model.task.TaskData; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Denis Zhdanov + * @since 5/18/13 11:28 PM + */ +public class ExternalTaskPojo implements Comparable { + + @NotNull private String myName; + @NotNull private String myLinkedExternalProjectPath; + + @Nullable private String myDescription; + + @SuppressWarnings("UnusedDeclaration") + public ExternalTaskPojo() { + // Required for IJ serialization. + this("___DUMMY___", "___DUMMY___", null); + } + + public ExternalTaskPojo(@NotNull String name, @NotNull String linkedExternalProjectPath, @Nullable String description) { + myName = name; + myLinkedExternalProjectPath = linkedExternalProjectPath; + myDescription = description; + } + + @NotNull + public static ExternalTaskPojo from(@NotNull TaskData data) { + return new ExternalTaskPojo(data.getName(), data.getLinkedExternalProjectPath(), data.getDescription()); + } + + @NotNull + public String getName() { + return myName; + } + + public void setName(@NotNull String name) { + myName = name; + } + + @Nullable + public String getDescription() { + return myDescription; + } + + public void setDescription(@Nullable String description) { + myDescription = description; + } + + @NotNull + public String getLinkedExternalProjectPath() { + return myLinkedExternalProjectPath; + } + + @SuppressWarnings("UnusedDeclaration") + public void setLinkedExternalProjectPath(@NotNull String linkedExternalProjectPath) { + // Required for IJ serialization. + myLinkedExternalProjectPath = linkedExternalProjectPath; + } + + @Override + public int hashCode() { + int result = myName.hashCode(); + result = 31 * result + myLinkedExternalProjectPath.hashCode(); + return result; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ExternalTaskPojo pojo = (ExternalTaskPojo)o; + + if (!myLinkedExternalProjectPath.equals(pojo.myLinkedExternalProjectPath)) return false; + if (!myName.equals(pojo.myName)) return false; + + return true; + } + + @Override + public int compareTo(@NotNull ExternalTaskPojo that) { + return myName.compareTo(that.getName()); + } + + @Override + public String toString() { + return myName; + } +} diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskDescriptor.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskDescriptor.java deleted file mode 100644 index 1171dae9b012..000000000000 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskDescriptor.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2000-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.openapi.externalSystem.model.task; - -import com.intellij.openapi.util.Comparing; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.Serializable; - -/** - * @author Denis Zhdanov - * @since 3/15/13 1:01 PM - */ -public class ExternalSystemTaskDescriptor implements Serializable, Comparable { - - private static final long serialVersionUID = 1L; - - // The fields are mutable in order to ease IJ default xml serialization. - private String myName; - - @Nullable private String myDescription; - @Nullable private String myExecutorId; - - @SuppressWarnings("UnusedDeclaration") - public ExternalSystemTaskDescriptor() { - // Necessary for IJ serialization - } - - public ExternalSystemTaskDescriptor(@NotNull String name, @Nullable String description) { - setName(name); - setDescription(description); - } - - @Nullable - public String getDescription() { - return myDescription; - } - - public void setDescription(@Nullable String description) { - myDescription = description; - } - - public String getName() { - return myName; - } - - public void setName(@NotNull String name) { - myName = name; - } - - @Nullable - public String getExecutorId() { - return myExecutorId; - } - - public void setExecutorId(@Nullable String executorId) { - myExecutorId = executorId; - } - - @Override - public int compareTo(@NotNull ExternalSystemTaskDescriptor that) { - int cmp = myName.compareTo(that.myName); - if (cmp == 0) { - return Comparing.compare(myExecutorId, that.myExecutorId); - } - return cmp; - } - - @Override - public int hashCode() { - int result = myName.hashCode(); - result = 31 * result + (myExecutorId != null ? myExecutorId.hashCode() : 0); - result = 31 * result + (myDescription != null ? myDescription.hashCode() : 0); - return result; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - ExternalSystemTaskDescriptor that = (ExternalSystemTaskDescriptor)o; - - if (!myName.equals(that.myName)) return false; - if (myExecutorId != null ? !myExecutorId.equals(that.myExecutorId) : that.myExecutorId != null) return false; - if (myDescription != null ? !myDescription.equals(that.myDescription) : that.myDescription != null) return false; - - return true; - } - - @Override - public String toString() { - return myName; - } -} diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/TaskData.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/TaskData.java index 2b32a58ecd6e..d5279404c8e3 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/TaskData.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/TaskData.java @@ -17,10 +17,9 @@ package com.intellij.openapi.externalSystem.model.task; import com.intellij.openapi.externalSystem.model.ProjectSystemId; import com.intellij.openapi.externalSystem.model.project.AbstractExternalEntityData; -import com.intellij.util.containers.ContainerUtilRt; +import com.intellij.openapi.externalSystem.model.project.ExternalConfigPathAware; import org.jetbrains.annotations.NotNull; - -import java.util.List; +import org.jetbrains.annotations.Nullable; /** * Container for external system task information. @@ -28,28 +27,68 @@ import java.util.List; * @author Denis Zhdanov * @since 5/15/13 10:59 AM */ -public class TaskData extends AbstractExternalEntityData { +public class TaskData extends AbstractExternalEntityData implements ExternalConfigPathAware, Comparable { - @NotNull private final List myTasks = ContainerUtilRt.newArrayList(); - - @NotNull private final String myLinkedProjectPath; + private static final long serialVersionUID = 1L; - public TaskData(@NotNull ProjectSystemId owner, @NotNull String linkedProjectPath) { + @NotNull private final String myName; + @NotNull private final String myLinkedExternalProjectPath; + + @Nullable private final String myDescription; + + public TaskData(@NotNull ProjectSystemId owner, @NotNull String name, @NotNull String path, @Nullable String description) { super(owner); - myLinkedProjectPath = linkedProjectPath; + myName = name; + myLinkedExternalProjectPath = path; + myDescription = description; } @NotNull - public String getLinkedProjectPath() { - return myLinkedProjectPath; - } - - public void addTask(@NotNull ExternalSystemTaskDescriptor task) { - myTasks.add(task); + public String getName() { + return myName; } @NotNull - public List getTasks() { - return myTasks; + public String getLinkedExternalProjectPath() { + return myLinkedExternalProjectPath; + } + + @Nullable + public String getDescription() { + return myDescription; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + myName.hashCode(); + result = 31 * result + myLinkedExternalProjectPath.hashCode(); + result = 31 * result + (myDescription != null ? myDescription.hashCode() : 0); + return result; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + TaskData data = (TaskData)o; + + if (myDescription != null ? !myDescription.equals(data.myDescription) : data.myDescription != null) return false; + if (!myLinkedExternalProjectPath.equals(data.myLinkedExternalProjectPath)) return false; + if (!myName.equals(data.myName)) return false; + + return true; + } + + @Override + public int compareTo(@NotNull TaskData that) { + return myName.compareTo(that.getName()); + } + + @Override + public String toString() { + return myName; } } diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/AbstractExternalSystemLocalSettings.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/AbstractExternalSystemLocalSettings.java index 63b890c8aa6b..53426ff23732 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/AbstractExternalSystemLocalSettings.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/AbstractExternalSystemLocalSettings.java @@ -15,16 +15,15 @@ */ package com.intellij.openapi.externalSystem.settings; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskDescriptor; +import com.intellij.openapi.externalSystem.model.serialization.ExternalProjectPojo; +import com.intellij.openapi.externalSystem.model.serialization.ExternalTaskPojo; +import com.intellij.openapi.externalSystem.model.task.TaskData; import com.intellij.util.SystemProperties; import com.intellij.util.containers.ContainerUtilRt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.atomic.AtomicReference; /** @@ -43,15 +42,20 @@ public abstract class AbstractExternalSystemLocalSettings { private static final boolean PRESERVE_EXPAND_STATE = !SystemProperties.getBooleanProperty("external.system.forget.expand.nodes.state", false); - private final AtomicReference> myExpandStates - = new AtomicReference>(new HashMap()); - private final AtomicReference>> myRecentTasks = - new AtomicReference>>( - ContainerUtilRt.>newHashMap() + private final AtomicReference> myExpandStates + = + new AtomicReference>(new HashMap()); + private final AtomicReference>> myRecentTasks = + new AtomicReference>>( + ContainerUtilRt.>newHashMap() ); - private final AtomicReference>> myAvailableTasks = - new AtomicReference>>( - ContainerUtilRt.>newHashMap() + private final AtomicReference>> myAvailableProjects = + new AtomicReference>>( + ContainerUtilRt.>newHashMap() + ); + private final AtomicReference>> myAvailableTasks = + new AtomicReference>>( + ContainerUtilRt.>newHashMap() ); @SuppressWarnings("UnusedDeclaration") @@ -61,16 +65,25 @@ public abstract class AbstractExternalSystemLocalSettings { } @NotNull - public Map> getAvailableTasks() { + public Map> getAvailableProjects() { + return myAvailableProjects.get(); + } + + public void setAvailableProjects(@NotNull Map> projects) { + myAvailableProjects.set(projects); + } + + @NotNull + public Map> getAvailableTasks() { return myAvailableTasks.get(); } - - public void setAvailableTasks(@NotNull Map> tasks) { + + public void setAvailableTasks(@NotNull Map> tasks) { myAvailableTasks.set(tasks); } @NotNull - public Map> getRecentTasks() { + public Map> getRecentTasks() { return myRecentTasks.get(); } @@ -82,12 +95,14 @@ public abstract class AbstractExternalSystemLocalSettings { state.tasksExpandState = Collections.emptyMap(); } state.recentTasks = myRecentTasks.get(); + state.availableProjects = myAvailableProjects.get(); state.availableTasks = myAvailableTasks.get(); } public void loadState(@NotNull State state) { setIfNotNull(myExpandStates, state.tasksExpandState); setIfNotNull(myRecentTasks, state.recentTasks); + setIfNotNull(myAvailableProjects, state.availableProjects); setIfNotNull(myAvailableTasks, state.availableTasks); } @@ -98,10 +113,11 @@ public abstract class AbstractExternalSystemLocalSettings { map.putAll(candidate); } } - + public static class State { - public Map tasksExpandState = ContainerUtilRt.newHashMap(); - public Map> recentTasks = ContainerUtilRt.newHashMap(); - public Map> availableTasks = ContainerUtilRt.newHashMap(); + public Map tasksExpandState = ContainerUtilRt.newHashMap(); + public Map> recentTasks = ContainerUtilRt.newHashMap(); + public Map> availableProjects = ContainerUtilRt.newHashMap(); + public Map> availableTasks = ContainerUtilRt.newHashMap(); } } diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java index eeb3a1289ae2..a2d28f0f3c4b 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java @@ -32,9 +32,7 @@ import com.intellij.openapi.util.NotNullLazyValue; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.BooleanFunction; -import com.intellij.util.PathUtil; -import com.intellij.util.PathsList; +import com.intellij.util.*; import com.intellij.util.containers.ContainerUtilRt; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; @@ -200,20 +198,33 @@ public class ExternalSystemApiUtil { } @NotNull - public static Map, List>> groupBy(@NotNull Collection> nodes, @NotNull Key key) { - Map, List>> result = ContainerUtilRt.newHashMap(); + public static Map, List>> groupBy(@NotNull Collection> nodes, @NotNull final Key key) { + return groupBy(nodes, new Function, DataNode>() { + @Override + public DataNode fun(DataNode node) { + return node.getDataNode(key); + } + }); + } + + @NotNull + public static Map>> groupBy(@NotNull Collection> nodes, + @NotNull Function, K> grouper) + { + Map>> result = ContainerUtilRt.newHashMap(); for (DataNode data : nodes) { - DataNode grouper = data.getDataNode(key); - if (grouper == null) { + K key = grouper.fun(data); + if (key == null) { LOG.warn(String.format( - "Skipping entry '%s' during grouping. Reason: it doesn't provide a value for key %s. Given entries: %s", - data, key, nodes + "Skipping entry '%s' during grouping. Reason: it's not possible to build a grouping key with grouping strategy '%s'. " + + "Given entries: %s", + data, grouper.getClass(), nodes )); continue; } - List> grouped = result.get(grouper); + List> grouped = result.get(key); if (grouped == null) { - result.put(grouper, grouped = ContainerUtilRt.newArrayList()); + result.put(key, grouped = ContainerUtilRt.newArrayList()); } grouped.add(data); } @@ -352,9 +363,9 @@ public class ExternalSystemApiUtil { classPath.add(PathManager.getResourceRoot(contextClass, pathToUse)); } - @Nullable - public static String normalizePath(@Nullable String s) { - return StringUtil.isEmpty(s) ? null : s; + @SuppressWarnings("ConstantConditions") + public static String normalizePath(String s) { + return StringUtil.isEmpty(s) ? null : s.replace('\\', ExternalSystemConstants.PATH_SEPARATOR); } /** diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemConstants.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemConstants.java index baa991790034..1be2f1553b2c 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemConstants.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemConstants.java @@ -31,6 +31,8 @@ public class ExternalSystemConstants { @NonNls @NotNull public static final String TOOL_WINDOW_PLACE = "ExternalSystem.ToolWindow"; + public static final char PATH_SEPARATOR = '/'; + // Order. public static final int BUILTIN_SERVICE_ORDER = 42; public static final int BUILTIN_TOOL_WINDOW_SERVICE_ORDER = 62; diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractImportFromExternalSystemControl.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractImportFromExternalSystemControl.java index feeff6f69970..5beb51011bf4 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractImportFromExternalSystemControl.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractImportFromExternalSystemControl.java @@ -19,6 +19,7 @@ import com.intellij.openapi.externalSystem.model.ProjectSystemId; import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings; import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings; import com.intellij.openapi.externalSystem.settings.ExternalSystemSettingsListener; +import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemBundle; import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil; import com.intellij.openapi.externalSystem.util.PaintAwarePanel; @@ -160,7 +161,7 @@ public abstract class AbstractImportFromExternalSystemControl< if (StringUtil.isEmpty(linkedProjectPath)) { throw new ConfigurationException(ExternalSystemBundle.message("error.project.undefined")); } - myProjectSettings.setExternalProjectPath(linkedProjectPath); + myProjectSettings.setExternalProjectPath(ExternalSystemApiUtil.normalizePath(linkedProjectPath)); String errorMessage = myProjectSettingsControl.apply(myProjectSettings); if (errorMessage != null) { diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/AbstractToolWindowService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/AbstractToolWindowService.java index 5652e5e8f074..399bbba852b6 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/AbstractToolWindowService.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/AbstractToolWindowService.java @@ -42,11 +42,14 @@ public abstract class AbstractToolWindowService im ExternalSystemDataKeys.ALL_TASKS_MODEL, toImport.iterator().next().getData().getOwner()); if (model != null) { - processData(toImport, model); + processData(toImport, project, model); } + } - protected abstract void processData(@NotNull Collection> nodes, @NotNull ExternalSystemTasksTreeModel model); + protected abstract void processData(@NotNull Collection> nodes, + @NotNull Project project, + @NotNull ExternalSystemTasksTreeModel model); @Override public void removeData(@NotNull Collection toRemove, @NotNull Project project, boolean synchronous) { diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ToolWindowModuleService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ToolWindowModuleService.java index 8632df6876b4..d7a4fa8c7313 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ToolWindowModuleService.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ToolWindowModuleService.java @@ -15,18 +15,22 @@ */ package com.intellij.openapi.externalSystem.service.task; +import com.intellij.openapi.externalSystem.ExternalSystemManager; import com.intellij.openapi.externalSystem.model.DataNode; import com.intellij.openapi.externalSystem.model.Key; import com.intellij.openapi.externalSystem.model.ProjectKeys; +import com.intellij.openapi.externalSystem.model.ProjectSystemId; import com.intellij.openapi.externalSystem.model.project.ModuleData; import com.intellij.openapi.externalSystem.model.project.ProjectData; +import com.intellij.openapi.externalSystem.model.serialization.ExternalProjectPojo; import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTreeModel; +import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings; import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemConstants; import com.intellij.openapi.externalSystem.util.Order; +import com.intellij.openapi.project.Project; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtilRt; -import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import java.util.Collection; @@ -43,10 +47,11 @@ import java.util.Map; public class ToolWindowModuleService extends AbstractToolWindowService { @NotNull - public static final Function, ModuleData> MAPPER = new Function, ModuleData>() { + public static final Function, ExternalProjectPojo> MAPPER + = new Function, ExternalProjectPojo>() { @Override - public ModuleData fun(DataNode node) { - return node.getData(); + public ExternalProjectPojo fun(DataNode node) { + return ExternalProjectPojo.from(node.getData()); } }; @@ -57,15 +62,24 @@ public class ToolWindowModuleService extends AbstractToolWindowService> nodes, @NotNull final ExternalSystemTasksTreeModel model) { + protected void processData(@NotNull final Collection> nodes, + @NotNull Project project, + @NotNull final ExternalSystemTasksTreeModel model) + { + if (nodes.isEmpty()) { + return; + } + ProjectSystemId externalSystemId = nodes.iterator().next().getData().getOwner(); + ExternalSystemManager manager = ExternalSystemApiUtil.getManager(externalSystemId); + assert manager != null; + final Map, List>> grouped = ExternalSystemApiUtil.groupBy(nodes, ProjectKeys.PROJECT); - UIUtil.invokeLaterIfNeeded(new Runnable() { - @Override - public void run() { - for (Map.Entry, List>> entry : grouped.entrySet()) { - model.ensureSubProjectsStructure(entry.getKey().getData(), ContainerUtilRt.map2List(entry.getValue(), MAPPER)); - } - } - }); + Map> data = ContainerUtilRt.newHashMap(); + for (Map.Entry, List>> entry : grouped.entrySet()) { + data.put(ExternalProjectPojo.from(entry.getKey().getData()), ContainerUtilRt.map2List(entry.getValue(), MAPPER)); + } + + AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project); + settings.setAvailableProjects(data); } } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ToolWindowProjectService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ToolWindowProjectService.java deleted file mode 100644 index 2fdc17936aa3..000000000000 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ToolWindowProjectService.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2000-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.openapi.externalSystem.service.task; - -import com.intellij.openapi.externalSystem.model.DataNode; -import com.intellij.openapi.externalSystem.model.Key; -import com.intellij.openapi.externalSystem.model.ProjectKeys; -import com.intellij.openapi.externalSystem.model.project.ProjectData; -import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTreeModel; -import com.intellij.openapi.externalSystem.util.ExternalSystemConstants; -import com.intellij.openapi.externalSystem.util.Order; -import com.intellij.util.ui.UIUtil; -import org.jetbrains.annotations.NotNull; - -import java.util.Collection; - -/** - * @author Denis Zhdanov - * @since 5/15/13 11:46 AM - */ -@Order(ExternalSystemConstants.BUILTIN_TOOL_WINDOW_SERVICE_ORDER) -public class ToolWindowProjectService extends AbstractToolWindowService { - - @NotNull - @Override - public Key getTargetDataKey() { - return ProjectKeys.PROJECT; - } - - @Override - protected void processData(@NotNull final Collection> nodes, @NotNull final ExternalSystemTasksTreeModel model) { - UIUtil.invokeLaterIfNeeded(new Runnable() { - @Override - public void run() { - for (DataNode node : nodes) { - model.ensureProjectNodeExists(node.getData()); - } - } - }); - - } -} diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ToolWindowTaskService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ToolWindowTaskService.java index 01e877e34f73..afcb06e29938 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ToolWindowTaskService.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ToolWindowTaskService.java @@ -15,16 +15,29 @@ */ package com.intellij.openapi.externalSystem.service.task; +import com.intellij.openapi.externalSystem.ExternalSystemManager; import com.intellij.openapi.externalSystem.model.DataNode; import com.intellij.openapi.externalSystem.model.Key; import com.intellij.openapi.externalSystem.model.ProjectKeys; +import com.intellij.openapi.externalSystem.model.ProjectSystemId; +import com.intellij.openapi.externalSystem.model.project.ExternalConfigPathAware; +import com.intellij.openapi.externalSystem.model.project.ModuleData; +import com.intellij.openapi.externalSystem.model.serialization.ExternalTaskPojo; import com.intellij.openapi.externalSystem.model.task.TaskData; import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTreeModel; +import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings; +import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemConstants; +import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil; import com.intellij.openapi.externalSystem.util.Order; +import com.intellij.openapi.project.Project; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtilRt; import org.jetbrains.annotations.NotNull; import java.util.Collection; +import java.util.List; +import java.util.Map; /** * @author Denis Zhdanov @@ -33,6 +46,23 @@ import java.util.Collection; @Order(ExternalSystemConstants.BUILTIN_TOOL_WINDOW_SERVICE_ORDER) public class ToolWindowTaskService extends AbstractToolWindowService { + @NotNull + public static final Function, ExternalTaskPojo> MAPPER = new Function, ExternalTaskPojo>() { + @Override + public ExternalTaskPojo fun(DataNode node) { + return ExternalTaskPojo.from(node.getData()); + } + }; + + public static final Function, ExternalConfigPathAware> TASK_HOLDER_RETRIEVAL_STRATEGY = + new Function, ExternalConfigPathAware>() { + @Override + public ExternalConfigPathAware fun(DataNode node) { + ModuleData moduleData = node.getData(ProjectKeys.MODULE); + return moduleData == null ? node.getData(ProjectKeys.PROJECT) : moduleData; + } + }; + @NotNull @Override public Key getTargetDataKey() { @@ -40,7 +70,28 @@ public class ToolWindowTaskService extends AbstractToolWindowService { } @Override - protected void processData(@NotNull Collection> nodes, @NotNull ExternalSystemTasksTreeModel model) { - // TODO den implement + protected void processData(@NotNull Collection> nodes, + @NotNull Project project, + @NotNull final ExternalSystemTasksTreeModel model) + { + if (nodes.isEmpty()) { + return; + } + ProjectSystemId externalSystemId = nodes.iterator().next().getData().getOwner(); + ExternalSystemManager manager = ExternalSystemApiUtil.getManager(externalSystemId); + assert manager != null; + + Map>> grouped = ExternalSystemApiUtil.groupBy(nodes, TASK_HOLDER_RETRIEVAL_STRATEGY); + Map> data = ContainerUtilRt.newHashMap(); + for (Map.Entry>> entry : grouped.entrySet()) { + data.put(entry.getKey().getLinkedExternalProjectPath(), ContainerUtilRt.map2List(entry.getValue(), MAPPER)); + } + + AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project); + Map> availableTasks = ContainerUtilRt.newHashMap(settings.getAvailableTasks()); + availableTasks.putAll(data); + settings.setAvailableTasks(availableTasks); + + ExternalSystemUiUtil.apply(settings, model); } } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/AbstractExternalSystemToolWindowFactory.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/AbstractExternalSystemToolWindowFactory.java index 2c8887b15095..8c3ef0099e0d 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/AbstractExternalSystemToolWindowFactory.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/AbstractExternalSystemToolWindowFactory.java @@ -18,7 +18,6 @@ package com.intellij.openapi.externalSystem.service.task.ui; import com.intellij.notification.NotificationGroup; import com.intellij.openapi.externalSystem.ExternalSystemManager; import com.intellij.openapi.externalSystem.model.ProjectSystemId; -import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings; import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemBundle; import com.intellij.openapi.project.DumbAware; @@ -52,11 +51,7 @@ public abstract class AbstractExternalSystemToolWindowFactory implements ToolWin String tasksTitle = ExternalSystemBundle.message("tool.window.title.tasks"); ExternalSystemManager manager = ExternalSystemApiUtil.getManager(myExternalSystemId); assert manager != null; - AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project); - ExternalSystemTasksPanel panel = new ExternalSystemTasksPanel(settings.getAvailableTasks(), - project, - myExternalSystemId, - myNotificationGroup); + ExternalSystemTasksPanel panel = new ExternalSystemTasksPanel(project, myExternalSystemId, myNotificationGroup); ContentImpl tasksContent = new ContentImpl(panel, tasksTitle, true); contentManager.addContent(tasksContent); } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksPanel.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksPanel.java index fceb03be7122..a2d06237938a 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksPanel.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksPanel.java @@ -23,10 +23,10 @@ import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.externalSystem.ExternalSystemManager; import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys; import com.intellij.openapi.externalSystem.model.ProjectSystemId; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskDescriptor; import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings; import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemConstants; +import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.SimpleToolWindowPanel; import com.intellij.ui.components.JBScrollPane; @@ -34,9 +34,6 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.List; -import java.util.Map; - /** * @author Denis Zhdanov * @since 5/12/13 10:18 PM @@ -48,8 +45,7 @@ public class ExternalSystemTasksPanel extends SimpleToolWindowPanel implements D @NotNull private final ProjectSystemId myExternalSystemId; @NotNull private final NotificationGroup myNotificationGroup; - public ExternalSystemTasksPanel(@NotNull Map> tasks, - @NotNull Project project, + public ExternalSystemTasksPanel(@NotNull Project project, @NotNull ProjectSystemId externalSystemId, @NotNull NotificationGroup notificationGroup) { @@ -71,8 +67,7 @@ public class ExternalSystemTasksPanel extends SimpleToolWindowPanel implements D setContent(new JBScrollPane(myAllTasksTree)); - // TODO den implement -// myAllTasksModel.updateTasks(tasks); + ExternalSystemUiUtil.apply(settings, myAllTasksModel); } @Nullable diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTree.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTree.java index be86d1aed4d5..220cc52e699b 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTree.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTree.java @@ -21,7 +21,10 @@ import com.intellij.util.containers.ContainerUtilRt; import com.intellij.util.ui.tree.TreeModelAdapter; import org.jetbrains.annotations.NotNull; +import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeModelEvent; +import javax.swing.event.TreeWillExpandListener; +import javax.swing.tree.ExpandVetoException; import javax.swing.tree.TreePath; import java.util.*; @@ -56,6 +59,22 @@ public class ExternalSystemTasksTree extends Tree { myExpandedStateHolder = expandedStateHolder; setRootVisible(false); + addTreeWillExpandListener(new TreeWillExpandListener() { + @Override + public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException { + if (!mySuppressCollapseTracking) { + myExpandedStateHolder.put(getPath(event.getPath()), true); + } + } + + @Override + public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException { + if (!mySuppressCollapseTracking) { + myExpandedStateHolder.put(getPath(event.getPath()), false); + } + } + }); + model.addTreeModelListener(new TreeModelAdapter() { @Override public void treeStructureChanged(TreeModelEvent e) { @@ -86,7 +105,7 @@ public class ExternalSystemTasksTree extends Tree { // a chance. // Another thing is that we sort the paths in order to process the longest first. That is related to the JTree specifics // that it automatically expands parent paths on child path expansion. - List paths = new ArrayList(myPathsToProcessCollapseState); + List paths = ContainerUtilRt.newArrayList(myPathsToProcessCollapseState); myPathsToProcessCollapseState.clear(); Collections.sort(paths, PATH_COMPARATOR); for (TreePath treePath : paths) { diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTreeModel.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTreeModel.java index 86fe87379502..cb08bd18efe4 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTreeModel.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTreeModel.java @@ -15,12 +15,12 @@ */ package com.intellij.openapi.externalSystem.service.task.ui; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.externalSystem.ExternalSystemManager; import com.intellij.openapi.externalSystem.ExternalSystemUiAware; import com.intellij.openapi.externalSystem.model.ProjectSystemId; -import com.intellij.openapi.externalSystem.model.project.ModuleData; -import com.intellij.openapi.externalSystem.model.project.ProjectData; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskDescriptor; +import com.intellij.openapi.externalSystem.model.serialization.ExternalProjectPojo; +import com.intellij.openapi.externalSystem.model.serialization.ExternalTaskPojo; import com.intellij.openapi.externalSystem.service.ui.DefaultExternalSystemUiAware; import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil; @@ -32,9 +32,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; -import java.util.Comparator; -import java.util.List; -import java.util.Map; +import java.util.*; /** * @author Denis Zhdanov @@ -42,13 +40,39 @@ import java.util.Map; */ public class ExternalSystemTasksTreeModel extends DefaultTreeModel { + private static final Logger LOG = Logger.getInstance("#" + ExternalSystemTasksTreeModel.class.getName()); + + @NotNull private static final Comparator NODE_COMPARATOR = new Comparator() { + @Override + public int compare(TreeNode t1, TreeNode t2) { + Object e1 = ((ExternalSystemNode)t1).getDescriptor().getElement(); + Object e2 = ((ExternalSystemNode)t2).getDescriptor().getElement(); + if (e1 instanceof ExternalProjectPojo) { + if (e2 instanceof ExternalTaskPojo) { + return 1; + } + else { + return ((ExternalProjectPojo)e1).getName().compareTo(((ExternalProjectPojo)e2).getName()); + } + } + else { + if (e2 instanceof ExternalProjectPojo) { + return -1; + } + else { + return ((ExternalTaskPojo)e1).getName().compareTo(((ExternalTaskPojo)e2).getName()); + } + } + } + }; + @NotNull private final TreeNode[] myNodeHolder = new TreeNode[1]; @NotNull private final int[] myIndexHolder = new int[1]; @NotNull private final ExternalSystemUiAware myUiAware; public ExternalSystemTasksTreeModel(@NotNull ProjectSystemId externalSystemId) { super(new ExternalSystemNode(new ExternalSystemNodeDescriptor("", "", null))); - ExternalSystemManager manager = ExternalSystemApiUtil.getManager(externalSystemId); + ExternalSystemManager manager = ExternalSystemApiUtil.getManager(externalSystemId); if (manager instanceof ExternalSystemUiAware) { myUiAware = (ExternalSystemUiAware)manager; } @@ -60,52 +84,52 @@ public class ExternalSystemTasksTreeModel extends DefaultTreeModel { /** * Ensures that current model has a top-level node which corresponds to the given external project info holder * - * @param externalProject target external project info holder + * @param project target external project info holder */ @SuppressWarnings("unchecked") @NotNull - public ExternalSystemNode ensureProjectNodeExists(@NotNull ProjectData externalProject) { + public ExternalSystemNode ensureProjectNodeExists(@NotNull ExternalProjectPojo project) { ExternalSystemNode root = getRoot(); // Remove outdated projects. for (int i = root.getChildCount() - 1; i >= 0; i--) { ExternalSystemNode child = root.getChildAt(i); Object element = child.getDescriptor().getElement(); - if (element instanceof ProjectNodeElement - && ((ProjectNodeElement)element).path.equals(externalProject.getLinkedExternalProjectPath())) + if (element instanceof ExternalProjectPojo + && ((ExternalProjectPojo)element).getPath().equals(project.getPath())) { - return (ExternalSystemNode)child; + return (ExternalSystemNode)child; } } - ProjectNodeElement element = new ProjectNodeElement(externalProject.getName(), externalProject.getLinkedExternalProjectPath()); - ExternalSystemNodeDescriptor descriptor = descriptor(element, myUiAware.getProjectIcon()); + ExternalProjectPojo element = new ExternalProjectPojo(project.getName(), project.getPath()); + ExternalSystemNodeDescriptor descriptor = descriptor(element, myUiAware.getProjectIcon()); myIndexHolder[0] = root.getChildCount(); - ExternalSystemNode result = new ExternalSystemNode(descriptor); + ExternalSystemNode result = new ExternalSystemNode(descriptor); root.add(result); nodesWereInserted(root, myIndexHolder); return result; } - public void ensureSubProjectsStructure(@NotNull ProjectData topLevelProject, @NotNull List subProjects) { - ExternalSystemNode topLevelProjectNode = ensureProjectNodeExists(topLevelProject); - Map toAdd = ContainerUtilRt.newHashMap(); - final TObjectIntHashMap subProjectWeights = new TObjectIntHashMap(); - int w = 0; - for (ModuleData subProject : subProjects) { - toAdd.put(subProject.getExternalConfigPath(), subProject); - subProjectWeights.put(subProject.getExternalConfigPath(), w++); + public void ensureSubProjectsStructure(@NotNull ExternalProjectPojo topLevelProject, + @NotNull Collection subProjects) + { + ExternalSystemNode topLevelProjectNode = ensureProjectNodeExists(topLevelProject); + Map toAdd = ContainerUtilRt.newHashMap(); + for (ExternalProjectPojo subProject : subProjects) { + toAdd.put(subProject.getPath(), subProject); } + toAdd.remove(topLevelProject.getPath()); final TObjectIntHashMap taskWeights = new TObjectIntHashMap(); for (int i = 0; i < topLevelProjectNode.getChildCount(); i++) { ExternalSystemNode child = topLevelProjectNode.getChildAt(i); Object childElement = child.getDescriptor().getElement(); - if (childElement instanceof ExternalSystemTaskDescriptor) { + if (childElement instanceof ExternalTaskPojo) { taskWeights.put(childElement, subProjects.size() + i); continue; } - if (toAdd.remove(((ProjectNodeElement)childElement).path) == null) { + if (toAdd.remove(((ExternalProjectPojo)childElement).getPath()) == null) { topLevelProjectNode.remove(child); myIndexHolder[0] = i; myNodeHolder[0] = child; @@ -115,39 +139,71 @@ public class ExternalSystemTasksTreeModel extends DefaultTreeModel { } } if (!toAdd.isEmpty()) { - for (Map.Entry entry : toAdd.entrySet()) { - ProjectNodeElement element = new ProjectNodeElement(entry.getValue().getName(), entry.getValue().getExternalConfigPath()); - topLevelProjectNode.add(new ExternalSystemNode(descriptor(element, myUiAware.getProjectIcon()))); + for (Map.Entry entry : toAdd.entrySet()) { + ExternalProjectPojo + element = new ExternalProjectPojo(entry.getValue().getName(), entry.getValue().getPath()); + topLevelProjectNode.add(new ExternalSystemNode(descriptor(element, myUiAware.getProjectIcon()))); + myIndexHolder[0] = topLevelProjectNode.getChildCount() - 1; + nodesWereInserted(topLevelProjectNode, myIndexHolder); } } - - ExternalSystemUiUtil.sort(topLevelProjectNode, this, new Comparator() { - @Override - public int compare(TreeNode o1, TreeNode o2) { - // A node might be one of the following: - // 1. Sub-project node; - // 2. Top-level project's task node; - // We want to put top-level project's tasks before sub-projects and preserve relative order between them. - return getWeight(o1) - getWeight(o2); - } + ExternalSystemUiUtil.sort(topLevelProjectNode, this, NODE_COMPARATOR); + } - private int getWeight(@NotNull TreeNode node) { - if (!(node instanceof ExternalSystemNode)) { - return 0; - } - Object element = ((ExternalSystemNode)node).getDescriptor().getElement(); - if (element instanceof ProjectNodeElement) { - return subProjectWeights.get(((ProjectNodeElement)element).path); - } - else if (element instanceof ExternalSystemTaskDescriptor) { - return taskWeights.get(element); - } - else { - return 0; + public void ensureTasks(@NotNull String externalProjectConfigPath, @NotNull Collection tasks) { + ExternalSystemNode moduleNode = findProjectNode(externalProjectConfigPath); + if (moduleNode == null) { + LOG.warn(String.format( + "Can't proceed tasks for module which external config path is '%s'. Reason: no such module node is found. Tasks: %s", + externalProjectConfigPath, tasks + )); + return; + } + Set toAdd = ContainerUtilRt.newHashSet(tasks); + for (int i = 0; i < moduleNode.getChildCount(); i++) { + ExternalSystemNode childNode = moduleNode.getChildAt(i); + Object element = childNode.getDescriptor().getElement(); + if (element instanceof ExternalTaskPojo) { + if (!toAdd.remove(element)) { + moduleNode.remove(childNode); + myIndexHolder[0] = i; + myNodeHolder[0] = childNode; + nodesWereRemoved(moduleNode, myIndexHolder, myNodeHolder); } } - }); + } + + if (!toAdd.isEmpty()) { + for (ExternalTaskPojo pojo : toAdd) { + moduleNode.add(new ExternalSystemNode(descriptor(pojo, myUiAware.getTaskIcon()))); + myIndexHolder[0] = moduleNode.getChildCount() - 1; + nodesWereInserted(moduleNode, myIndexHolder); + } + } + ExternalSystemUiUtil.sort(moduleNode, this, NODE_COMPARATOR); + } + + @SuppressWarnings("unchecked") + @Nullable + private ExternalSystemNode findProjectNode(@NotNull String configPath) { + for (int i = getRoot().getChildCount() - 1; i >= 0; i--) { + ExternalSystemNode child = getRoot().getChildAt(i); + Object childElement = child.getDescriptor().getElement(); + if (childElement instanceof ExternalProjectPojo && ((ExternalProjectPojo)childElement).getPath().equals(configPath)) { + return (ExternalSystemNode)child; + } + for (int j = child.getChildCount() - 1; j >= 0; j--) { + ExternalSystemNode grandChild = child.getChildAt(j); + Object grandChildElement = grandChild.getDescriptor().getElement(); + if (grandChildElement instanceof ExternalProjectPojo + && ((ExternalProjectPojo)grandChildElement).getPath().equals(configPath)) + { + return (ExternalSystemNode)grandChild; + } + } + } + return null; } @NotNull @@ -159,19 +215,4 @@ public class ExternalSystemTasksTreeModel extends DefaultTreeModel { public ExternalSystemNode getRoot() { return (ExternalSystemNode)super.getRoot(); } - - private static class ProjectNodeElement { - @NotNull public final String name; - @NotNull public final String path; - - ProjectNodeElement(@NotNull String name, @NotNull String path) { - this.name = name; - this.path = path; - } - - @Override - public String toString() { - return name; - } - } } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/DefaultExternalSystemUiAware.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/DefaultExternalSystemUiAware.java index cae629c170d1..8ba262f44c10 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/DefaultExternalSystemUiAware.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/DefaultExternalSystemUiAware.java @@ -17,6 +17,7 @@ package com.intellij.openapi.externalSystem.service.ui; import com.intellij.icons.AllIcons; import com.intellij.openapi.externalSystem.ExternalSystemUiAware; +import com.intellij.openapi.util.IconLoader; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -37,4 +38,10 @@ public class DefaultExternalSystemUiAware implements ExternalSystemUiAware { public Icon getProjectIcon() { return AllIcons.Nodes.IdeaProject; } + + @Nullable + @Override + public Icon getTaskIcon() { + return IconLoader.getIcon("/icons/task.png", getClass()); + } } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUiUtil.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUiUtil.java index 4f26dbfed481..b7d29734320c 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUiUtil.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUiUtil.java @@ -16,6 +16,10 @@ package com.intellij.openapi.externalSystem.util; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.externalSystem.model.serialization.ExternalProjectPojo; +import com.intellij.openapi.externalSystem.model.serialization.ExternalTaskPojo; +import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTreeModel; +import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.ui.popup.BalloonBuilder; @@ -24,6 +28,7 @@ import com.intellij.ui.awt.RelativePoint; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.ContainerUtilRt; import com.intellij.util.ui.GridBag; +import com.intellij.util.ui.UIUtil; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; @@ -117,4 +122,26 @@ public class ExternalSystemUiUtil { } } } + + /** + * Applies data from the given settings object to the given model. + * + * @param settings target settings to use + * @param model UI model to be synced with the given settings + */ + public static void apply(@NotNull final AbstractExternalSystemLocalSettings settings, @NotNull final ExternalSystemTasksTreeModel model) { + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + Map> projects = settings.getAvailableProjects(); + for (Map.Entry> entry : projects.entrySet()) { + model.ensureSubProjectsStructure(entry.getKey(), entry.getValue()); + } + Map> tasks = settings.getAvailableTasks(); + for (Map.Entry> entry : tasks.entrySet()) { + model.ensureTasks(entry.getKey(), entry.getValue()); + } + } + }); + } } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java index cbe3bf3157a7..154f60653f58 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java @@ -200,9 +200,7 @@ public class ExternalSystemUtil { @Override public void onFailure(@NotNull String errorMessage, @Nullable String errorDetails) { - if (--myCounter <= 0 && !project.isDisposed() && project.isOpen()) { - processOrphanModules(); - } + myCounter = Integer.MAX_VALUE; // Don't process orphan modules if there was an error on refresh. } private void processOrphanModules() { diff --git a/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml b/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml index 36f56d78c004..cd05f9f16989 100644 --- a/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml +++ b/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml @@ -27,7 +27,6 @@ - diff --git a/plugins/gradle/src/icons/GradleIcons.java b/plugins/gradle/src/icons/GradleIcons.java index 8e6ccb10cd0e..395071b46fc3 100644 --- a/plugins/gradle/src/icons/GradleIcons.java +++ b/plugins/gradle/src/icons/GradleIcons.java @@ -13,10 +13,9 @@ public class GradleIcons { return IconLoader.getIcon(path, GradleIcons.class); } - public static final Icon Gradle = load("/icons/gradle.png"); // 16x16 - public static final Icon GradleImport = load("/icons/gradleImport.png"); // 16x16 - public static final Icon GradleNavigate = load("/icons/gradleNavigate.png"); // 16x16 - public static final Icon GradleSync = load("/icons/gradleSync.png"); // 16x16 - public static final Icon Task = load("/icons/task.png"); // 16x16 + public static final Icon Gradle = load("/icons/gradle.png"); // 16x16 + public static final Icon GradleImport = load("/icons/gradleImport.png"); // 16x16 + public static final Icon GradleNavigate = load("/icons/gradleNavigate.png"); // 16x16 + public static final Icon GradleSync = load("/icons/gradleSync.png"); // 16x16 public static final Icon ToolWindowGradle = load("/icons/toolWindowGradle.png"); // 13x13 } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java index 3f19025b9e48..9efe71ba942d 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java @@ -26,6 +26,7 @@ import com.intellij.openapi.externalSystem.ExternalSystemUiAware; import com.intellij.openapi.externalSystem.build.ExternalSystemTaskManager; import com.intellij.openapi.externalSystem.model.ProjectSystemId; import com.intellij.openapi.externalSystem.service.project.ExternalSystemProjectResolver; +import com.intellij.openapi.externalSystem.service.ui.DefaultExternalSystemUiAware; import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.module.EmptyModuleType; import com.intellij.openapi.module.JavaModuleType; @@ -229,4 +230,10 @@ public class GradleManager implements ExternalSystemConfigurableAware, ExternalS public Icon getProjectIcon() { return GradleIcons.Gradle; } + + @Nullable + @Override + public Icon getTaskIcon() { + return DefaultExternalSystemUiAware.INSTANCE.getTaskIcon(); + } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java index 030d2398cdca..72457e47f300 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java @@ -5,7 +5,6 @@ import com.intellij.openapi.externalSystem.model.DataNode; import com.intellij.openapi.externalSystem.model.ExternalSystemException; import com.intellij.openapi.externalSystem.model.ProjectKeys; import com.intellij.openapi.externalSystem.model.project.*; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskDescriptor; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; import com.intellij.openapi.externalSystem.model.task.TaskData; import com.intellij.openapi.externalSystem.service.project.ExternalSystemProjectResolver; @@ -18,6 +17,8 @@ import com.intellij.util.BooleanFunction; import com.intellij.util.Function; import com.intellij.util.PathUtil; import com.intellij.util.containers.ContainerUtilRt; +import gnu.trove.TObjectIntHashMap; +import gnu.trove.TObjectIntProcedure; import org.gradle.tooling.ModelBuilder; import org.gradle.tooling.ProjectConnection; import org.gradle.tooling.model.DomainObjectSet; @@ -28,6 +29,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.remote.impl.GradleLibraryNamesMixer; import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings; import org.jetbrains.plugins.gradle.util.GradleConstants; +import org.jetbrains.plugins.gradle.util.GradleUtil; import java.io.File; import java.util.*; @@ -143,11 +145,13 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver, IdeaModule> previouslyParsedModule = result.get(moduleName); if (previouslyParsedModule != null) { throw new IllegalStateException( @@ -385,10 +389,28 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver parent, @NotNull IdeaProject project) { - Map tasksByModule = ContainerUtilRt.newHashMap(); - for (IdeaModule module : project.getModules()) { - TaskData taskData = new TaskData(GradleConstants.SYSTEM_ID, module.getGradleProject().getPath()); + private static void parseTasks(@NotNull DataNode rootProjectNode, @NotNull IdeaProject project) { + + // So, the general idea is to fill target nodes by nodes with TaskData. Specifics: + // 1. Gradle tooling api doesn't explicitly provide information about root project tasks, e.g. when a root project + // contains code block like below: + // subprojects { + // apply plugin: 'java' + // } + // 2. Gradle tooling api provides an IdeaModule object for every IdeaProject among IdeaModule objects which correspond + // to real sub-projects; + // + // Our aim is to make sub-project nodes contain corresponding TaskData nodes and add root project tasks to ProjectData node. + // The later is achieved by composing all tasks from IdeaModule which corresponds to the IdeaProject plus all tasks + // which are shared between all sub-projects. + + final String rootProjectPath = rootProjectNode.getData().getLinkedExternalProjectPath(); + Map> tasksByModule = ContainerUtilRt.newHashMap(); + TObjectIntHashMap> rootProjectTaskCandidates + = new TObjectIntHashMap>(); + final Collection rootProjectTasks = ContainerUtilRt.newArrayList(); + final DomainObjectSet modules = project.getModules(); + for (IdeaModule module : modules) { for (GradleTask task : module.getGradleProject().getTasks()) { String name = task.getName(); if (name == null || name.trim().isEmpty()) { @@ -400,17 +422,43 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver tasks = tasksByModule.get(module.getName()); + if (tasks == null) { + tasksByModule.put(module.getName(), tasks = ContainerUtilRt.newArrayList()); + } + tasks.add(taskData); + Pair key = Pair.create(name, task.getDescription()); + rootProjectTaskCandidates.put(key, rootProjectTaskCandidates.get(key) + 1); + } } - Collections.sort(taskData.getTasks()); - tasksByModule.put(module.getName(), taskData); + } + rootProjectTaskCandidates.forEachEntry(new TObjectIntProcedure>() { + @Override + public boolean execute(Pair p, int occurrenceNumber) { + if (occurrenceNumber >= modules.size() - 1) { + rootProjectTasks.add(new TaskData(GradleConstants.SYSTEM_ID, p.first, rootProjectPath, p.second)); + } + return true; + } + }); + for (TaskData task : rootProjectTasks) { + rootProjectNode.createChild(ProjectKeys.TASK, task); } - Collection> moduleNodes = ExternalSystemApiUtil.findAll(parent, ProjectKeys.MODULE); + Collection> moduleNodes = ExternalSystemApiUtil.findAll(rootProjectNode, ProjectKeys.MODULE); for (DataNode moduleNode : moduleNodes) { - TaskData taskData = tasksByModule.get(moduleNode.getData().getName()); - if (taskData != null && !taskData.getTasks().isEmpty()) { - moduleNode.createChild(ProjectKeys.TASK, taskData); + Collection tasks = tasksByModule.get(moduleNode.getData().getName()); + if (tasks != null && !tasks.isEmpty()) { + for (TaskData task : tasks) { + moduleNode.createChild(ProjectKeys.TASK, task); + } } } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/tasks/GradleTasksList.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/tasks/GradleTasksList.java index 705438b67f24..186357307074 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/tasks/GradleTasksList.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/tasks/GradleTasksList.java @@ -17,7 +17,6 @@ package org.jetbrains.plugins.gradle.tasks; import com.intellij.execution.Executor; import com.intellij.execution.ExecutorRegistry; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskDescriptor; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.components.JBList; import com.intellij.util.containers.ContainerUtilRt; @@ -33,14 +32,15 @@ import java.util.Set; * @author Denis Zhdanov * @since 3/15/13 7:38 PM */ +// TODO den remove public class GradleTasksList extends JBList { - - @NotNull private static final MyRenderer RENDERER = new MyRenderer(); + +// @NotNull private static final MyRenderer RENDERER = new MyRenderer(); @NotNull private static final JLabel EMPTY_RENDERER = new JLabel(" "); public GradleTasksList(@NotNull GradleTasksModel model) { super(model); - setCellRenderer(RENDERER); +// setCellRenderer(RENDERER); } @Override @@ -48,71 +48,72 @@ public class GradleTasksList extends JBList { return (GradleTasksModel)super.getModel(); } - public void setFirst(@NotNull ExternalSystemTaskDescriptor descriptor) { - Set selected = getSelectedDescriptors(); - GradleTasksModel model = getModel(); - model.setFirst(descriptor); - clearSelection(); - for (int i = 0; i < model.size(); i++) { - //noinspection SuspiciousMethodCalls - if (selected.contains(model.getElementAt(i))) { - addSelectionInterval(i, i); - } - } - } - - @NotNull - public Set getSelectedDescriptors() { - int[] indices = getSelectedIndices(); - if (indices == null || indices.length <= 0) { - return Collections.emptySet(); - } - Set result = ContainerUtilRt.newHashSet(); - GradleTasksModel model = getModel(); - for (int i : indices) { - Object e = model.getElementAt(i); - if (e instanceof ExternalSystemTaskDescriptor) { - result.add((ExternalSystemTaskDescriptor)e); - } - } - return result; - } - - private static class MyRenderer extends DefaultListCellRenderer { - - @Override - public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - if (value instanceof GradleTasksModel.MyEmptyDescriptor) { - return EMPTY_RENDERER; - } - else if (value instanceof ExternalSystemTaskDescriptor) { - ExternalSystemTaskDescriptor descriptor = (ExternalSystemTaskDescriptor)value; - setText(descriptor.getName()); - Icon icon = null; - String executorId = descriptor.getExecutorId(); - if (!StringUtil.isEmpty(executorId)) { - Executor executor = ExecutorRegistry.getInstance().getExecutorById(executorId); - if (executor != null) { - icon = executor.getIcon(); - } - } - - if (icon == null) { - icon = GradleIcons.Task; - } - setIcon(icon); - } - return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - } - - @Override - public void setIcon(Icon icon) { - if (icon != null) { - // Don't allow to reset icon. - super.setIcon(icon); - } - } - } +// public void setFirst(@NotNull ExternalSystemTaskDescriptor descriptor) { +// Set selected = getSelectedDescriptors(); +// GradleTasksModel model = getModel(); +// model.setFirst(descriptor); +// clearSelection(); +// for (int i = 0; i < model.size(); i++) { +// //noinspection SuspiciousMethodCalls +// if (selected.contains(model.getElementAt(i))) { +// addSelectionInterval(i, i); +// } +// } +// } +// +// @NotNull +// public Set getSelectedDescriptors() { +// int[] indices = getSelectedIndices(); +// if (indices == null || indices.length <= 0) { +// return Collections.emptySet(); +// } +// Set result = ContainerUtilRt.newHashSet(); +// GradleTasksModel model = getModel(); +// for (int i : indices) { +// Object e = model.getElementAt(i); +// if (e instanceof ExternalSystemTaskDescriptor) { +// result.add((ExternalSystemTaskDescriptor)e); +// } +// } +// return result; +// } +// +// private static class MyRenderer extends DefaultListCellRenderer { +// +// @Override +// public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { +// if (value instanceof GradleTasksModel.MyEmptyDescriptor) { +// return EMPTY_RENDERER; +// } +// else if (value instanceof ExternalSystemTaskDescriptor) { +// ExternalSystemTaskDescriptor descriptor = (ExternalSystemTaskDescriptor)value; +// setText(descriptor.getName()); +// Icon icon = null; +// String executorId = descriptor.getExecutorId(); +// if (!StringUtil.isEmpty(executorId)) { +// Executor executor = ExecutorRegistry.getInstance().getExecutorById(executorId); +// if (executor != null) { +// icon = executor.getIcon(); +// } +// } +// +// // TODO den implement +// //if (icon == null) { +// // icon = GradleIcons.Task; +// //} +// setIcon(icon); +// } +// return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); +// } +// +// @Override +// public void setIcon(Icon icon) { +// if (icon != null) { +// // Don't allow to reset icon. +// super.setIcon(icon); +// } +// } +// } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/tasks/GradleTasksModel.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/tasks/GradleTasksModel.java index 73036a1fd49e..550aa3a405ac 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/tasks/GradleTasksModel.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/tasks/GradleTasksModel.java @@ -15,7 +15,6 @@ */ package org.jetbrains.plugins.gradle.tasks; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskDescriptor; import com.intellij.util.containers.ContainerUtilRt; import org.jetbrains.annotations.NotNull; @@ -26,60 +25,61 @@ import java.util.*; * @author Denis Zhdanov * @since 3/15/13 12:50 PM */ +// TODO den remove public class GradleTasksModel extends DefaultListModel { - - public static final Comparator BY_NAME_COMPARATOR = new Comparator() { - @Override - public int compare(ExternalSystemTaskDescriptor d1, ExternalSystemTaskDescriptor d2) { - return d1.getName().compareTo(d2.getName()); - } - }; - - public void setTasks(@NotNull Collection taskDescriptors) { - clear(); - ArrayList descriptorsToUse = ContainerUtilRt.newArrayList(taskDescriptors); - Collections.sort(descriptorsToUse, BY_NAME_COMPARATOR); - for (ExternalSystemTaskDescriptor descriptor : descriptorsToUse) { - addElement(descriptor); - } - } - - public void setFirst(@NotNull ExternalSystemTaskDescriptor descriptor) { - insertElementAt(descriptor, 0); - for (int i = 1; i < size(); i++) { - if (descriptor.equals(getElementAt(i))) { - remove(i); - return; - } - } - - if (size() > 1) { - remove(size() - 1); - } - } - - @NotNull - public List getTasks() { - List result = ContainerUtilRt.newArrayList(); - for (int i = 0; i < size(); i++) { - Object e = getElementAt(i); - if (e instanceof ExternalSystemTaskDescriptor) { - result.add((ExternalSystemTaskDescriptor)e); - } - } - return result; - } - - public void ensureSize(int elementsNumber) { - int toAdd = elementsNumber - size(); - if (toAdd <= 0) { - return; - } - while (--toAdd >= 0) { - addElement(new MyEmptyDescriptor()); - } - } - - static class MyEmptyDescriptor { - } + +// public static final Comparator BY_NAME_COMPARATOR = new Comparator() { +// @Override +// public int compare(ExternalSystemTaskDescriptor d1, ExternalSystemTaskDescriptor d2) { +// return d1.getName().compareTo(d2.getName()); +// } +// }; +// +// public void setTasks(@NotNull Collection taskDescriptors) { +// clear(); +// ArrayList descriptorsToUse = ContainerUtilRt.newArrayList(taskDescriptors); +// Collections.sort(descriptorsToUse, BY_NAME_COMPARATOR); +// for (ExternalSystemTaskDescriptor descriptor : descriptorsToUse) { +// addElement(descriptor); +// } +// } +// +// public void setFirst(@NotNull ExternalSystemTaskDescriptor descriptor) { +// insertElementAt(descriptor, 0); +// for (int i = 1; i < size(); i++) { +// if (descriptor.equals(getElementAt(i))) { +// remove(i); +// return; +// } +// } +// +// if (size() > 1) { +// remove(size() - 1); +// } +// } +// +// @NotNull +// public List getTasks() { +// List result = ContainerUtilRt.newArrayList(); +// for (int i = 0; i < size(); i++) { +// Object e = getElementAt(i); +// if (e instanceof ExternalSystemTaskDescriptor) { +// result.add((ExternalSystemTaskDescriptor)e); +// } +// } +// return result; +// } +// +// public void ensureSize(int elementsNumber) { +// int toAdd = elementsNumber - size(); +// if (toAdd <= 0) { +// return; +// } +// while (--toAdd >= 0) { +// addElement(new MyEmptyDescriptor()); +// } +// } +// +// static class MyEmptyDescriptor { +// } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/tasks/GradleTasksPanel.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/tasks/GradleTasksPanel.java index eb0a33b2e8a0..002d77bac15a 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/tasks/GradleTasksPanel.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/tasks/GradleTasksPanel.java @@ -22,7 +22,6 @@ import com.intellij.execution.executors.DefaultRunExecutor; import com.intellij.ide.DataManager; import com.intellij.ide.ui.customization.CustomizationUtil; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskDescriptor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; @@ -55,6 +54,7 @@ import java.util.List; * @author Denis Zhdanov * @since 3/14/13 4:36 PM */ +// TODO den remove public class GradleTasksPanel extends GradleToolWindowPanel { @NotNull private final GradleTasksModel myRecentTasksModel = new GradleTasksModel(); @@ -98,10 +98,9 @@ public class GradleTasksPanel extends GradleToolWindowPanel { myRecentTasksModel.clear(); // TODO den implement //myRecentTasksModel.setTasks(myLocalSettings.getRecentTasks()); - int recentTasksNumber = Registry.intValue(GradleConstants.REGISTRY_RECENT_TASKS_NUMBER_KEY, 5); - myRecentTasksModel.ensureSize(recentTasksNumber); - myRecentTasksList.setVisibleRowCount(recentTasksNumber); - // TODO den implement +// int recentTasksNumber = Registry.intValue(GradleConstants.REGISTRY_RECENT_TASKS_NUMBER_KEY, 5); +// myRecentTasksModel.ensureSize(recentTasksNumber); +// myRecentTasksList.setVisibleRowCount(recentTasksNumber); // addListPanel(myRecentTasksList, result, ExternalSystemBundle.message("gradle.task.recent.title"), false); myAllTasksModel.clear(); @@ -162,11 +161,14 @@ public class GradleTasksPanel extends GradleToolWindowPanel { } Object element = model.getElementAt(row); - if (!(element instanceof ExternalSystemTaskDescriptor)) { - return; - } + // TODO den implement +// if (!(element instanceof ExternalSystemTaskDescriptor)) { +// return; +// } - String executorId = ((ExternalSystemTaskDescriptor)element).getExecutorId(); + // TODO den implement + String executorId = null; +// String executorId = ((ExternalSystemTaskDescriptor)element).getExecutorId(); if (StringUtil.isEmpty(executorId)) { executorId = DefaultRunExecutor.EXECUTOR_ID; } @@ -262,9 +264,10 @@ public class GradleTasksPanel extends GradleToolWindowPanel { final List tasks = ContainerUtilRt.newArrayList(); for (int index : selectedIndices) { Object data = list.getModel().getElementAt(index); - if (data instanceof ExternalSystemTaskDescriptor) { - tasks.add(((ExternalSystemTaskDescriptor)data).getName()); - } + // TODO den implement +// if (data instanceof ExternalSystemTaskDescriptor) { +// tasks.add(((ExternalSystemTaskDescriptor)data).getName()); +// } } return tasks.isEmpty() ? null : tasks; } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java index 094bb90ff21c..4e5faff21ad4 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java @@ -1,10 +1,15 @@ package org.jetbrains.plugins.gradle.util; import com.intellij.ide.actions.OpenProjectFileChooserDescriptor; +import com.intellij.openapi.externalSystem.util.ExternalSystemConstants; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.fileChooser.FileTypeDescriptor; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.containers.ContainerUtilRt; +import com.intellij.util.containers.Stack; +import org.gradle.tooling.model.GradleProject; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -148,4 +153,27 @@ public class GradleUtil { public static final FileChooserDescriptor GRADLE_HOME_FILE_CHOOSER_DESCRIPTOR = new FileChooserDescriptor(false, true, false, false, false, false); } + + /** + * Allows to build file system path to the target gradle sub-project given the root project path. + * + * @param subProject target sub-project which 'build.gradle' path we're interested in + * @param rootProjectPath root project's 'build.gradle' path + * @return path to the given sub-project's 'build.gradle' + */ + @NotNull + public static String getConfigPath(@NotNull GradleProject subProject, @NotNull String rootProjectPath) { + File rootProjectParent = new File(rootProjectPath).getParentFile().getParentFile(); + StringBuilder buffer = new StringBuilder(FileUtil.toCanonicalPath(rootProjectParent.getAbsolutePath())); + Stack stack = ContainerUtilRt.newStack(); + for (GradleProject p = subProject; p != null; p = p.getParent()) { + stack.push(p.getName()); + } + while (!stack.isEmpty()) { + buffer.append(ExternalSystemConstants.PATH_SEPARATOR).append(stack.pop()); + } + buffer.append(ExternalSystemConstants.PATH_SEPARATOR).append(GradleConstants.DEFAULT_SCRIPT_NAME); + return buffer.toString(); + } + }