From 9d804d108cdc45ebaffb7e64e8864641c811f619 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Thu, 16 May 2013 17:32:59 +0400 Subject: [PATCH] IDEA-104500 Gradle: Allow to reuse common logic for other external systems 1. 'external system' tool window is introduced; 2. It's possible to refresh all external projects from the corresponding tool window now; 3. New tasks infrastructure is defined; --- .../externalSystem/JavaProjectData.java | 4 +- .../i18n/ExternalSystemBundle.properties | 12 +- .../ExternalSystemConfigurableAware.java | 30 +++ .../externalSystem/ExternalSystemManager.java | 4 +- .../ExternalSystemUiAware.java} | 18 +- ...er.java => ExternalSystemTaskManager.java} | 21 +-- .../externalSystem/model/ProjectKeys.java | 3 + .../externalSystem/model/ProjectSystemId.java | 12 ++ .../model/project/AbstractDependencyData.java | 37 +--- .../project/AbstractExternalEntityData.java | 43 +++++ .../model/project/AbstractNamedData.java | 4 +- .../project/AbstractProjectEntityData.java | 65 ------- .../model/project/ContentRootData.java | 2 +- .../model/project/DependencyData.java | 2 +- ...ntityData.java => ExternalEntityData.java} | 11 +- .../model/project/ModuleData.java | 14 +- .../model/task/ExternalSystemTaskId.java | 40 +++- .../externalSystem/model/task/TaskData.java | 55 ++++++ .../AbstractExternalSystemLocalSettings.java | 4 + .../util/ExternalSystemApiUtil.java | 23 ++- .../util/ExternalSystemConstants.java | 9 +- .../RefreshAllExternalProjectsAction.java | 65 +++++++ .../model/ExternalSystemDataKeys.java | 23 ++- .../model/settings/LocationSettingType.java | 3 +- .../service/ExternalSystemFacadeImpl.java | 20 +- .../service/ExternalSystemFacadeManager.java | 4 +- .../service/RemoteExternalSystemFacade.java | 10 +- .../service/RemoteExternalSystemService.java | 2 +- .../internal}/AbstractExternalSystemTask.java | 8 +- .../ExternalSystemExecuteTaskTask.java | 5 +- .../ExternalSystemProcessingManager.java} | 16 +- .../ExternalSystemResolveProjectTask.java | 31 +-- .../internal}/ExternalSystemTaskAware.java | 4 +- .../ExternalSystemIdeNotificationManager.java | 90 +++++++++ .../manage/ContentRootDataService.java | 6 +- .../manage/LibraryDependencyDataService.java | 6 +- .../manage/ModuleDependencyDataService.java | 5 +- .../project/manage/ProjectDataManager.java | 4 +- .../AbstractExternalProjectImportBuilder.java | 7 +- ...a => RemoteExternalSystemTaskManager.java} | 31 +-- ... RemoteExternalSystemTaskManagerImpl.java} | 33 +--- .../wrapper/ExternalSystemFacadeWrapper.java | 6 +- ... => ExternalSystemTaskManagerWrapper.java} | 33 +--- .../AbstractExternalSystemConfigurable.java | 7 +- ...stractImportFromExternalSystemControl.java | 7 +- .../task/AbstractToolWindowService.java | 54 ++++++ .../task/ExternalSystemTasksPanel.java | 53 ------ .../service/task/ToolWindowModuleService.java | 71 +++++++ .../task/ToolWindowProjectService.java | 55 ++++++ .../service/task/ToolWindowTaskService.java | 46 +++++ ...stractExternalSystemToolWindowFactory.java | 63 +++++++ .../service/task/ui/ExternalSystemNode.java | 42 +++++ .../task/ui/ExternalSystemNodeDescriptor.java | 51 +++++ .../task/ui/ExternalSystemTasksPanel.java | 92 +++++++++ .../task/ui/ExternalSystemTasksTree.java | 139 ++++++++++++++ .../task/ui/ExternalSystemTasksTreeModel.java | 177 ++++++++++++++++++ .../ui/DefaultExternalSystemUiAware.java | 40 ++++ .../util/ExternalSystemUiUtil.java | 35 ++++ .../util/ExternalSystemUtil.java | 35 ++-- .../src/META-INF/ExternalSystemExtensions.xml | 10 +- .../src/idea/ExternalSystemActions.xml | 13 ++ plugins/gradle/src/META-INF/plugin.xml | 26 +-- .../plugins/gradle/GradleManager.java | 29 ++- .../action/GradleRefreshProjectAction.java | 74 -------- .../ExternalSystemRefreshTasksListTask.java | 90 --------- .../GradleConfigNotificationManager.java | 117 ------------ .../remote/impl/GradleBuildManager.java | 103 ---------- .../gradle/remote/impl/GradleTaskManager.java | 57 ++++++ .../project/GradleProjectResolver.java | 47 ++++- .../gradle/ui/GradleToolWindowFactory.java | 23 +-- resources/src/idea/RichPlatformActions.xml | 1 + 71 files changed, 1549 insertions(+), 833 deletions(-) create mode 100644 platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemConfigurableAware.java rename platform/{external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ExternalSystemTasksTreeModel.java => external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemUiAware.java} (68%) rename platform/external-system-api/src/com/intellij/openapi/externalSystem/build/{ExternalSystemBuildManager.java => ExternalSystemTaskManager.java} (55%) create mode 100644 platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/AbstractExternalEntityData.java delete mode 100644 platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/AbstractProjectEntityData.java rename platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/{ProjectEntityData.java => ExternalEntityData.java} (67%) create mode 100644 platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/TaskData.java create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/RefreshAllExternalProjectsAction.java rename platform/external-system-impl/src/com/intellij/openapi/externalSystem/{model/task => service/internal}/AbstractExternalSystemTask.java (94%) rename {plugins/gradle/src/org/jetbrains/plugins/gradle/internal/task => platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal}/ExternalSystemExecuteTaskTask.java (92%) rename platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/{task/ExternalSystemTaskManager.java => internal/ExternalSystemProcessingManager.java} (88%) rename platform/external-system-impl/src/com/intellij/openapi/externalSystem/{model/task => service/internal}/ExternalSystemResolveProjectTask.java (74%) rename platform/external-system-impl/src/com/intellij/openapi/externalSystem/{model/task => service/internal}/ExternalSystemTaskAware.java (83%) create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemIdeNotificationManager.java rename platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/{RemoteExternalSystemBuildManager.java => RemoteExternalSystemTaskManager.java} (67%) rename platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/{RemoteExternalSystemBuildManagerImpl.java => RemoteExternalSystemTaskManagerImpl.java} (59%) rename platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/wrapper/{ExternalSystemBuildManagerWrapper.java => ExternalSystemTaskManagerWrapper.java} (64%) create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/AbstractToolWindowService.java delete mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ExternalSystemTasksPanel.java create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ToolWindowModuleService.java create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ToolWindowProjectService.java create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ToolWindowTaskService.java create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/AbstractExternalSystemToolWindowFactory.java create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemNode.java create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemNodeDescriptor.java create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksPanel.java create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTree.java create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTreeModel.java create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/DefaultExternalSystemUiAware.java create mode 100644 platform/platform-resources/src/idea/ExternalSystemActions.xml delete mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleRefreshProjectAction.java delete mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/internal/task/ExternalSystemRefreshTasksListTask.java delete mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/notification/GradleConfigNotificationManager.java delete mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleBuildManager.java create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleTaskManager.java diff --git a/java/java-psi-impl/src/com/intellij/externalSystem/JavaProjectData.java b/java/java-psi-impl/src/com/intellij/externalSystem/JavaProjectData.java index d1f5bfa9503a..29f991c88712 100644 --- a/java/java-psi-impl/src/com/intellij/externalSystem/JavaProjectData.java +++ b/java/java-psi-impl/src/com/intellij/externalSystem/JavaProjectData.java @@ -18,7 +18,7 @@ package com.intellij.externalSystem; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.externalSystem.model.Key; import com.intellij.openapi.externalSystem.model.ProjectSystemId; -import com.intellij.openapi.externalSystem.model.project.AbstractProjectEntityData; +import com.intellij.openapi.externalSystem.model.project.AbstractExternalEntityData; import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.pom.java.LanguageLevel; @@ -32,7 +32,7 @@ import java.util.regex.Pattern; * @author Denis Zhdanov * @since 4/12/13 12:27 PM */ -public class JavaProjectData extends AbstractProjectEntityData { +public class JavaProjectData extends AbstractExternalEntityData { @NotNull public static final Key KEY = Key.create(JavaProjectData.class); diff --git a/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties b/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties index 81e7082cba2b..7cd2a7c64831 100644 --- a/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties +++ b/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties @@ -15,16 +15,24 @@ settings.title.system.settings=Global {0} settings # Progress. progress.import.text=Building ''{0}'' {1} project info +progress.refresh.tasks.text=Building ''{0}'' {1} tasks list progress.refresh.text=Refreshing ''{0}'' {1} project progress.resolve.libraries=Resolving {0} libraries progress.update.text={0}: {1} # Errors. error.project.undefined=No external project config file is defined -error.resolve.generic.without.reason=Can''t resolve target {0} project at ''{1}''.\nConsult IDE log for more details (Help | Show Log) error.cannot.parse.project=Can not parse {0} project error.resolve.with.reason={0}\n\nConsult IDE log for more details (Help | Show Log) error.resolve.generic=Resolve error # Tool window -tool.window.title.tasks=tasks \ No newline at end of file +tool.window.title.tasks=tasks + +# Action. +action.refresh.all.projects.text=Refresh all {0} projects +action.refresh.all.projects.description=Force refresh all linked {0} projects + +# Notification +notification.project.refresh.fail.description={0} ''{1}'' project refresh failed:\n{2} +notification.action.show.settings={0} settings \ No newline at end of file diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemConfigurableAware.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemConfigurableAware.java new file mode 100644 index 000000000000..023016977e5f --- /dev/null +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemConfigurableAware.java @@ -0,0 +1,30 @@ +/* + * 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; + +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; + +/** + * @author Denis Zhdanov + * @since 5/14/13 12:49 PM + */ +public interface ExternalSystemConfigurableAware { + + @NotNull + Configurable getConfigurable(@NotNull Project project); +} diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemManager.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemManager.java index 49b3bad7919e..952af8f8be34 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemManager.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemManager.java @@ -1,7 +1,7 @@ package com.intellij.openapi.externalSystem; import com.intellij.openapi.extensions.ExtensionPointName; -import com.intellij.openapi.externalSystem.build.ExternalSystemBuildManager; +import com.intellij.openapi.externalSystem.build.ExternalSystemTaskManager; import com.intellij.openapi.externalSystem.model.ProjectSystemId; import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings; import com.intellij.openapi.externalSystem.service.ParametersEnhancer; @@ -78,5 +78,5 @@ public interface ExternalSystemManager< * @return class of the build manager to use for the target external system * @see #getProjectResolverClass() */ - Class> getBuildManagerClass(); + Class> getTaskManagerClass(); } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ExternalSystemTasksTreeModel.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemUiAware.java similarity index 68% rename from platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ExternalSystemTasksTreeModel.java rename to platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemUiAware.java index e3542fcee3bd..b4729ee54f90 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ExternalSystemTasksTreeModel.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemUiAware.java @@ -13,18 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.openapi.externalSystem.service.task; +package com.intellij.openapi.externalSystem; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.TreeNode; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; /** * @author Denis Zhdanov - * @since 5/12/13 10:28 PM + * @since 5/15/13 12:37 PM */ -public class ExternalSystemTasksTreeModel extends DefaultTreeModel { - - public ExternalSystemTasksTreeModel() { - super(null); - } +public interface ExternalSystemUiAware { + + @Nullable + Icon getProjectIcon(); } diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/build/ExternalSystemBuildManager.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/build/ExternalSystemTaskManager.java similarity index 55% rename from platform/external-system-api/src/com/intellij/openapi/externalSystem/build/ExternalSystemBuildManager.java rename to platform/external-system-api/src/com/intellij/openapi/externalSystem/build/ExternalSystemTaskManager.java index bed318270b75..a5e3eb7e6131 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/build/ExternalSystemBuildManager.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/build/ExternalSystemTaskManager.java @@ -16,15 +16,12 @@ package com.intellij.openapi.externalSystem.build; import com.intellij.openapi.externalSystem.model.ExternalSystemException; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskDescriptor; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings; +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collection; import java.util.List; -import java.util.Map; /** * Abstraction layer for executing gradle tasks. @@ -32,22 +29,8 @@ import java.util.Map; * @author Denis Zhdanov * @since 3/14/13 5:04 PM */ -public interface ExternalSystemBuildManager { +public interface ExternalSystemTaskManager { - /** - * Refreshes available tasks for the target external project. - * - * @param id request task id - * @param projectPath target external project path - * @param settings settings to use during the refresh - * @return mappings like 'module name -> module tasks' - * @throws ExternalSystemException in case when unexpected exception occurs during project info construction - */ - Map> listTasks(@NotNull ExternalSystemTaskId id, - @NotNull String projectPath, - @Nullable S settings) - throws ExternalSystemException; - void executeTasks(@NotNull ExternalSystemTaskId id, @NotNull List taskNames, @NotNull String projectPath, @Nullable S settings) throws ExternalSystemException; } diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ProjectKeys.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ProjectKeys.java index f18da33ffbce..77d9df8c9151 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ProjectKeys.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ProjectKeys.java @@ -16,6 +16,7 @@ package com.intellij.openapi.externalSystem.model; import com.intellij.openapi.externalSystem.model.project.*; +import com.intellij.openapi.externalSystem.model.task.TaskData; import org.jetbrains.annotations.NotNull; /** @@ -33,6 +34,8 @@ public class ProjectKeys { @NotNull public static final Key MODULE_DEPENDENCY = Key.create(ModuleDependencyData.class); @NotNull public static final Key LIBRARY_DEPENDENCY = Key.create(LibraryDependencyData.class); + @NotNull public static final Key TASK = Key.create(TaskData.class); + private ProjectKeys() { } } diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ProjectSystemId.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ProjectSystemId.java index 3b3d3b5e900b..5b52ddff98b1 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ProjectSystemId.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ProjectSystemId.java @@ -1,5 +1,6 @@ package com.intellij.openapi.externalSystem.model; +import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; import java.io.Serializable; @@ -20,9 +21,15 @@ public class ProjectSystemId implements Serializable { @NotNull public static final ProjectSystemId IDE = new ProjectSystemId("IDE"); @NotNull private final String myId; + @NotNull private final String myReadableName; public ProjectSystemId(@NotNull String id) { + this(id, StringUtil.capitalize(id.toLowerCase())); + } + + public ProjectSystemId(@NotNull String id, @NotNull String readableName) { myId = id; + myReadableName = readableName; } @Override @@ -40,6 +47,11 @@ public class ProjectSystemId implements Serializable { return myId.equals(owner.myId); } + @NotNull + public String getReadableName() { + return myReadableName; + } + @Override public String toString() { return myId; diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/AbstractDependencyData.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/AbstractDependencyData.java index a18cfed9a589..a765ef5a8fd0 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/AbstractDependencyData.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/AbstractDependencyData.java @@ -3,8 +3,6 @@ package com.intellij.openapi.externalSystem.model.project; import com.intellij.openapi.roots.DependencyScope; import org.jetbrains.annotations.NotNull; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; import java.io.IOException; import java.io.ObjectInputStream; @@ -12,7 +10,7 @@ import java.io.ObjectInputStream; * @author Denis Zhdanov * @since 8/10/11 6:41 PM */ -public abstract class AbstractDependencyData extends AbstractProjectEntityData +public abstract class AbstractDependencyData extends AbstractExternalEntityData implements DependencyData, Named { @@ -23,14 +21,12 @@ public abstract class AbstractDependencyData extends ProjectEntityData { +public interface DependencyData extends ExternalEntityData { boolean isExported(); diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ProjectEntityData.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalEntityData.java similarity index 67% rename from platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ProjectEntityData.java rename to platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalEntityData.java index bd42a60ac872..ec5e63bb7d48 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ProjectEntityData.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalEntityData.java @@ -3,8 +3,6 @@ package com.intellij.openapi.externalSystem.model.project; import com.intellij.openapi.externalSystem.model.ProjectSystemId; import org.jetbrains.annotations.NotNull; -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; import java.io.Serializable; /** @@ -18,15 +16,8 @@ import java.io.Serializable; * @author Denis Zhdanov * @since 8/12/11 12:50 PM */ -public interface ProjectEntityData extends Serializable { +public interface ExternalEntityData extends Serializable { @NotNull ProjectSystemId getOwner(); - - /** - * Follows contract of {@link PropertyChangeSupport#addPropertyChangeListener(PropertyChangeListener)} - * - * @param listener target listener - */ - void addPropertyChangeListener(@NotNull PropertyChangeListener listener); } 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 5ea0f8aef7d7..4ba64b965d92 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 @@ -20,12 +20,19 @@ public class ModuleData extends AbstractNamedData implements Named { @NotNull private final Map myCompileOutputPaths = ContainerUtilRt.newHashMap(); @NotNull private final String myModuleTypeId; + @NotNull private final String myExternalConfigPath; @NotNull private String myModuleFilePath; private boolean myInheritProjectCompileOutputPath = true; - public ModuleData(@NotNull ProjectSystemId owner, @NotNull String typeId, @NotNull String name, @NotNull String moduleFileDirectoryPath) { + public ModuleData(@NotNull ProjectSystemId owner, + @NotNull String typeId, + @NotNull String name, + @NotNull String moduleFileDirectoryPath, + @NotNull String externalConfigPath) + { super(owner, name); myModuleTypeId = typeId; + myExternalConfigPath = externalConfigPath; setModuleFileDirectoryPath(moduleFileDirectoryPath); } @@ -34,6 +41,11 @@ public class ModuleData extends AbstractNamedData implements Named { return myModuleTypeId; } + @NotNull + public String getExternalConfigPath() { + return myExternalConfigPath; + } + @NotNull public String getModuleFilePath() { return myModuleFilePath; diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskId.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskId.java index d4aac2673ba7..87615da45715 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskId.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskId.java @@ -1,5 +1,6 @@ package com.intellij.openapi.externalSystem.model.task; +import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; import java.io.Serializable; @@ -13,26 +14,45 @@ import java.util.concurrent.atomic.AtomicLong; */ public class ExternalSystemTaskId implements Serializable { - private static final long serialVersionUID = 1L; - private static final AtomicLong COUNTER = new AtomicLong(); + @NotNull private static final AtomicLong COUNTER = new AtomicLong(); + private static final long serialVersionUID = 1L; - private final ExternalSystemTaskType myType; - private final long myId; + @NotNull private final ExternalSystemTaskType myType; + @NotNull private final String myProjectId; - private ExternalSystemTaskId(@NotNull ExternalSystemTaskType type, long id) { + private final long myId; + + private ExternalSystemTaskId(@NotNull ExternalSystemTaskType type, @NotNull String projectId, long taskId) { myType = type; - myId = id; + myProjectId = projectId; + myId = taskId; + } + + @NotNull + public String getIdeProjectId() { + return myProjectId; } /** * Allows to retrieve distinct task id object of the given type. * - * @param type target task type - * @return distinct task id object of the given type + * @param type target task type + * @param project target ide project + * @return distinct task id object of the given type */ @NotNull - public static ExternalSystemTaskId create(@NotNull ExternalSystemTaskType type) { - return new ExternalSystemTaskId(type, COUNTER.getAndIncrement()); + public static ExternalSystemTaskId create(@NotNull ExternalSystemTaskType type, @NotNull Project project) { + return create(type, getProjectId(project)); + } + + @NotNull + public static ExternalSystemTaskId create(@NotNull ExternalSystemTaskType type, @NotNull String ideProjectId) { + return new ExternalSystemTaskId(type, ideProjectId, COUNTER.getAndIncrement()); + } + + @NotNull + public static String getProjectId(@NotNull Project project) { + return project.getName() + ":" + project.getLocationHash(); } @NotNull 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 new file mode 100644 index 000000000000..2b32a58ecd6e --- /dev/null +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/TaskData.java @@ -0,0 +1,55 @@ +/* + * 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.externalSystem.model.ProjectSystemId; +import com.intellij.openapi.externalSystem.model.project.AbstractExternalEntityData; +import com.intellij.util.containers.ContainerUtilRt; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * Container for external system task information. + * + * @author Denis Zhdanov + * @since 5/15/13 10:59 AM + */ +public class TaskData extends AbstractExternalEntityData { + + @NotNull private final List myTasks = ContainerUtilRt.newArrayList(); + + @NotNull private final String myLinkedProjectPath; + + public TaskData(@NotNull ProjectSystemId owner, @NotNull String linkedProjectPath) { + super(owner); + myLinkedProjectPath = linkedProjectPath; + } + + @NotNull + public String getLinkedProjectPath() { + return myLinkedProjectPath; + } + + public void addTask(@NotNull ExternalSystemTaskDescriptor task) { + myTasks.add(task); + } + + @NotNull + public List getTasks() { + return myTasks; + } +} 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 1686b0514ee8..63b890c8aa6b 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 @@ -64,6 +64,10 @@ public abstract class AbstractExternalSystemLocalSettings { public Map> getAvailableTasks() { return myAvailableTasks.get(); } + + public void setAvailableTasks(@NotNull Map> tasks) { + myAvailableTasks.set(tasks); + } @NotNull public Map> getRecentTasks() { 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 74095e68c8d1..eeb3a1289ae2 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 @@ -184,13 +184,13 @@ public class ExternalSystemApiUtil { } @NotNull - public static Map, Collection>> group(@NotNull Collection> nodes) { + public static Map, List>> group(@NotNull Collection> nodes) { if (nodes.isEmpty()) { return Collections.emptyMap(); } - Map, Collection>> result = ContainerUtilRt.newHashMap(); + Map, List>> result = ContainerUtilRt.newHashMap(); for (DataNode node : nodes) { - Collection> n = result.get(node.getKey()); + List> n = result.get(node.getKey()); if (n == null) { result.put(node.getKey(), n = ContainerUtilRt.newArrayList()); } @@ -200,8 +200,8 @@ public class ExternalSystemApiUtil { } @NotNull - public static Map, Collection>> groupBy(@NotNull Collection> nodes, @NotNull Key key) { - Map, Collection>> result = ContainerUtilRt.newHashMap(); + public static Map, List>> groupBy(@NotNull Collection> nodes, @NotNull Key key) { + Map, List>> result = ContainerUtilRt.newHashMap(); for (DataNode data : nodes) { DataNode grouper = data.getDataNode(key); if (grouper == null) { @@ -211,7 +211,7 @@ public class ExternalSystemApiUtil { )); continue; } - Collection> grouped = result.get(grouper); + List> grouped = result.get(grouper); if (grouped == null) { result.put(grouper, grouped = ContainerUtilRt.newArrayList()); } @@ -373,4 +373,15 @@ public class ExternalSystemApiUtil { public static boolean isNewProjectConstruction() { return ProjectManager.getInstance().getOpenProjects().length == 0; } + + /** + * Tries to guess external project name given it's path. + * + * @param projectPath target external project path + * @return external project name on the basis of the given external project path + */ + @NotNull + public static String guessProjectName(@NotNull String projectPath) { + return new File(projectPath).getParentFile().getName(); + } } 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 b495879c378c..baa991790034 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 @@ -27,7 +27,12 @@ public class ExternalSystemConstants { @NonNls @NotNull public static final String EXTERNAL_SYSTEM_ID_KEY = "external.system.id"; @NonNls @NotNull public static final String LINKED_PROJECT_PATH_KEY = "external.linked.project.path"; + @NonNls @NotNull public static final String TOOL_WINDOW_TOOLBAR_ACTIONS_GROUP_ID = "ExternalSystem.ToolWindow.Toolbar"; + + @NonNls @NotNull public static final String TOOL_WINDOW_PLACE = "ExternalSystem.ToolWindow"; + // Order. - public static final int BUILTIN_SERVICE_ORDER = 42; - public static final int UNORDERED = 1000; + public static final int BUILTIN_SERVICE_ORDER = 42; + public static final int BUILTIN_TOOL_WINDOW_SERVICE_ORDER = 62; + public static final int UNORDERED = 1000; } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/RefreshAllExternalProjectsAction.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/RefreshAllExternalProjectsAction.java new file mode 100644 index 000000000000..9d88d5f1bc1f --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/RefreshAllExternalProjectsAction.java @@ -0,0 +1,65 @@ +package com.intellij.openapi.externalSystem.action; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys; +import com.intellij.openapi.externalSystem.model.ProjectSystemId; +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType; +import com.intellij.openapi.externalSystem.service.internal.ExternalSystemProcessingManager; +import com.intellij.openapi.externalSystem.util.ExternalSystemBundle; +import com.intellij.openapi.externalSystem.util.ExternalSystemUtil; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; + +/** + * Forces the ide to retrieve the most up-to-date info about the linked external projects and updates project state if necessary + * (e.g. imports missing libraries). + * + * @author Denis Zhdanov + * @since 1/23/12 3:48 PM + */ +public class RefreshAllExternalProjectsAction extends AnAction implements DumbAware, AnAction.TransparentUpdate { + + @Override + public void update(AnActionEvent e) { + ProjectSystemId externalSystemId = ExternalSystemDataKeys.EXTERNAL_SYSTEM_ID.getData(e.getDataContext()); + if (externalSystemId == null) { + e.getPresentation().setEnabled(false); + return; + } + String name = externalSystemId.getReadableName(); + e.getPresentation().setText(ExternalSystemBundle.message("action.refresh.all.projects.text", name)); + e.getPresentation().setDescription(ExternalSystemBundle.message("action.refresh.all.projects.description", name)); + + Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + if (project == null) { + e.getPresentation().setEnabled(false); + return; + } + + ExternalSystemProcessingManager processingManager = ServiceManager.getService(ExternalSystemProcessingManager.class); + e.getPresentation().setEnabled(!processingManager.hasTaskOfTypeInProgress(ExternalSystemTaskType.RESOLVE_PROJECT, project)); + } + + @Override + public void actionPerformed(AnActionEvent e) { + ProjectSystemId externalSystemId = ExternalSystemDataKeys.EXTERNAL_SYSTEM_ID.getData(e.getDataContext()); + if (externalSystemId == null) { + return; + } + + Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + if (project == null) { + e.getPresentation().setEnabled(false); + return; + } + + // We save all documents because there is a possible case that there is an external system config file changed inside the ide. + FileDocumentManager.getInstance().saveAllDocuments(); + + ExternalSystemUtil.refreshProjects(project, externalSystemId); + } +} diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/ExternalSystemDataKeys.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/ExternalSystemDataKeys.java index c24dc9d1fcff..6f185872c109 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/ExternalSystemDataKeys.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/ExternalSystemDataKeys.java @@ -1,7 +1,24 @@ +/* + * 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; +import com.intellij.notification.NotificationGroup; import com.intellij.openapi.actionSystem.DataKey; -import com.intellij.openapi.externalSystem.service.task.ExternalSystemTasksTreeModel; +import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTreeModel; +import org.jetbrains.annotations.NotNull; /** * @author Denis Zhdanov @@ -9,7 +26,9 @@ import com.intellij.openapi.externalSystem.service.task.ExternalSystemTasksTreeM */ public class ExternalSystemDataKeys { - public static final DataKey ALL_TASKS_MODEL = DataKey.create("external.system.all.tasks.model"); + @NotNull public static final DataKey EXTERNAL_SYSTEM_ID = DataKey.create("external.system.id"); + @NotNull public static final DataKey NOTIFICATION_GROUP = DataKey.create("external.system.notification"); + @NotNull public static final DataKey ALL_TASKS_MODEL = DataKey.create("external.system.all.tasks.model"); private ExternalSystemDataKeys() { } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/settings/LocationSettingType.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/settings/LocationSettingType.java index 113ed090c4f4..32ef4e77966d 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/settings/LocationSettingType.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/settings/LocationSettingType.java @@ -1,7 +1,6 @@ package com.intellij.openapi.externalSystem.model.settings; import com.intellij.openapi.externalSystem.model.ProjectSystemId; -import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemBundle; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.PropertyKey; @@ -46,7 +45,7 @@ public enum LocationSettingType { * @return human-readable description of the current setting type */ public String getDescription(@NotNull ProjectSystemId externalSystemId) { - return ExternalSystemBundle.message(myDescriptionKey, ExternalSystemApiUtil.toReadableName(externalSystemId)); + return ExternalSystemBundle.message(myDescriptionKey, externalSystemId.getReadableName()); } @NotNull diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ExternalSystemFacadeImpl.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ExternalSystemFacadeImpl.java index e7825a111748..bacd1722fdd3 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ExternalSystemFacadeImpl.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ExternalSystemFacadeImpl.java @@ -1,11 +1,11 @@ package com.intellij.openapi.externalSystem.service; import com.intellij.execution.rmi.RemoteServer; +import com.intellij.openapi.externalSystem.build.ExternalSystemTaskManager; import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationEvent; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType; -import com.intellij.openapi.externalSystem.build.ExternalSystemBuildManager; import com.intellij.openapi.externalSystem.service.project.ExternalSystemProjectResolver; import com.intellij.openapi.externalSystem.service.remote.*; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener; @@ -47,14 +47,14 @@ public class ExternalSystemFacadeImpl = new AtomicReference(); @NotNull private final RemoteExternalSystemProjectResolverImpl myProjectResolver; - @NotNull private final RemoteExternalSystemBuildManagerImpl myBuildManager; + @NotNull private final RemoteExternalSystemTaskManagerImpl myTaskManager; public ExternalSystemFacadeImpl(@NotNull Class> projectResolverClass, - @NotNull Class> buildManagerClass) + @NotNull Class> buildManagerClass) throws IllegalAccessException, InstantiationException { myProjectResolver = new RemoteExternalSystemProjectResolverImpl(projectResolverClass.newInstance()); - myBuildManager = new RemoteExternalSystemBuildManagerImpl(buildManagerClass.newInstance()); + myTaskManager = new RemoteExternalSystemTaskManagerImpl(buildManagerClass.newInstance()); updateAutoShutdownTime(); } @@ -78,11 +78,11 @@ public class ExternalSystemFacadeImpl "Can't create external system facade. Reason: given arguments don't contain information about external system build manager to use" ); } - final Class> buildManagerClass = (Class>)Class.forName(args[1]); + final Class> buildManagerClass = (Class>)Class.forName(args[1]); if (!ExternalSystemProjectResolver.class.isAssignableFrom(resolverClass)) { throw new IllegalArgumentException(String.format( "Can't create external system facade. Reason: given external system build manager (%s) must be IS-A '%s'", - buildManagerClass, ExternalSystemBuildManager.class + buildManagerClass, ExternalSystemTaskManager.class )); } @@ -111,12 +111,12 @@ public class ExternalSystemFacadeImpl @SuppressWarnings("unchecked") @NotNull @Override - public RemoteExternalSystemBuildManager getBuildManager() throws RemoteException { + public RemoteExternalSystemTaskManager getTaskManager() throws RemoteException { try { - return getRemote(RemoteExternalSystemBuildManager.class, myBuildManager); + return getRemote(RemoteExternalSystemTaskManager.class, myTaskManager); } catch (Exception e) { - throw new IllegalStateException(String.format("Can't create '%s' service", ExternalSystemBuildManager.class.getName()), e); + throw new IllegalStateException(String.format("Can't create '%s' service", ExternalSystemTaskManager.class.getName()), e); } } @@ -237,7 +237,7 @@ public class ExternalSystemFacadeImpl ExternalSystemTaskNotificationListener listener = new SwallowingNotificationListener(progressManager); myNotificationListener.set(listener); myProjectResolver.setNotificationListener(listener); - myBuildManager.setNotificationListener(listener); + myTaskManager.setNotificationListener(listener); } /** diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ExternalSystemFacadeManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ExternalSystemFacadeManager.java index acb1aadf7e46..32ea5f65464c 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ExternalSystemFacadeManager.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ExternalSystemFacadeManager.java @@ -170,7 +170,7 @@ public class ExternalSystemFacadeManager { params.getVMParametersList().addParametersString( "-Dsun.rmi.transport.connectionTimeout=" + String.valueOf(TimeUnit.HOURS.toMillis(1)) ); - //params.getVMParametersList().addParametersString("-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5009"); +// params.getVMParametersList().addParametersString("-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5009"); ProjectSystemId externalSystemId = myTargetExternalSystemId.get(); if (externalSystemId != null) { @@ -178,7 +178,7 @@ public class ExternalSystemFacadeManager { if (manager != null) { params.getClassPath().add(PathUtil.getJarPathForClass(manager.getProjectResolverClass().getClass())); params.getProgramParametersList().add(manager.getProjectResolverClass().getName()); - params.getProgramParametersList().add(manager.getBuildManagerClass().getName()); + params.getProgramParametersList().add(manager.getTaskManagerClass().getName()); manager.enhanceParameters(params); } } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemFacade.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemFacade.java index 1560144e2314..10c2e42d87c5 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemFacade.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemFacade.java @@ -1,10 +1,10 @@ package com.intellij.openapi.externalSystem.service; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskAware; +import com.intellij.openapi.externalSystem.service.internal.ExternalSystemTaskAware; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType; import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings; -import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemBuildManager; +import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemTaskManager; import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProgressNotificationManager; import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProjectResolver; import org.jetbrains.annotations.NotNull; @@ -39,8 +39,8 @@ public interface RemoteExternalSystemFacade getBuildManager() throws RemoteException { - return RemoteExternalSystemBuildManager.NULL_OBJECT; + public RemoteExternalSystemTaskManager getTaskManager() throws RemoteException { + return RemoteExternalSystemTaskManager.NULL_OBJECT; } @Override @@ -80,7 +80,7 @@ public interface RemoteExternalSystemFacade getBuildManager() throws RemoteException; + RemoteExternalSystemTaskManager getTaskManager() throws RemoteException; /** * Asks remote external system process to apply given settings. diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemService.java index d33419323b4e..20161b122dd8 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemService.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemService.java @@ -1,6 +1,6 @@ package com.intellij.openapi.externalSystem.service; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskAware; +import com.intellij.openapi.externalSystem.service.internal.ExternalSystemTaskAware; import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener; import org.jetbrains.annotations.NotNull; diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/task/AbstractExternalSystemTask.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/AbstractExternalSystemTask.java similarity index 94% rename from platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/task/AbstractExternalSystemTask.java rename to platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/AbstractExternalSystemTask.java index abbc694b451e..71563ca9c50b 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/task/AbstractExternalSystemTask.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/AbstractExternalSystemTask.java @@ -1,12 +1,12 @@ -package com.intellij.openapi.externalSystem.model.task; +package com.intellij.openapi.externalSystem.service.internal; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.externalSystem.model.ProjectSystemId; +import com.intellij.openapi.externalSystem.model.task.*; import com.intellij.openapi.externalSystem.service.ExternalSystemFacadeManager; import com.intellij.openapi.externalSystem.service.RemoteExternalSystemFacade; import com.intellij.openapi.externalSystem.service.notification.ExternalSystemProgressNotificationManager; -import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemBundle; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; @@ -44,7 +44,7 @@ public abstract class AbstractExternalSystemTask implements ExternalSystemTask { { myExternalSystemId = id; myIdeProject = project; - myId = ExternalSystemTaskId.create(type); + myId = ExternalSystemTaskId.create(type, myIdeProject); myExernalProjectPath = externalProjectPath; } @@ -159,6 +159,6 @@ public abstract class AbstractExternalSystemTask implements ExternalSystemTask { @Override public String toString() { - return String.format("%s task %s: %s", ExternalSystemApiUtil.toReadableName(myExternalSystemId), myId, myState); + return String.format("%s task %s: %s", myExternalSystemId.getReadableName(), myId, myState); } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/internal/task/ExternalSystemExecuteTaskTask.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemExecuteTaskTask.java similarity index 92% rename from plugins/gradle/src/org/jetbrains/plugins/gradle/internal/task/ExternalSystemExecuteTaskTask.java rename to platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemExecuteTaskTask.java index 6fa7cabd241c..0bcfa95c59a8 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/internal/task/ExternalSystemExecuteTaskTask.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemExecuteTaskTask.java @@ -13,16 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.gradle.internal.task; +package com.intellij.openapi.externalSystem.service.internal; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.externalSystem.model.ProjectSystemId; -import com.intellij.openapi.externalSystem.model.task.AbstractExternalSystemTask; +import com.intellij.openapi.externalSystem.service.internal.AbstractExternalSystemTask; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType; import com.intellij.openapi.externalSystem.service.ExternalSystemFacadeManager; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.List; diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ExternalSystemTaskManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemProcessingManager.java similarity index 88% rename from platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ExternalSystemTaskManager.java rename to platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemProcessingManager.java index 39c5525e0ba2..05743ef6bf2b 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ExternalSystemTaskManager.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemProcessingManager.java @@ -1,4 +1,4 @@ -package com.intellij.openapi.externalSystem.service.task; +package com.intellij.openapi.externalSystem.service.internal; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; @@ -8,6 +8,7 @@ import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotifica import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType; import com.intellij.openapi.externalSystem.service.ExternalSystemFacadeManager; import com.intellij.openapi.externalSystem.service.notification.ExternalSystemProgressNotificationManager; +import com.intellij.openapi.project.Project; import com.intellij.util.Alarm; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.ContainerUtilRt; @@ -25,7 +26,7 @@ import java.util.concurrent.TimeUnit; * @author Denis Zhdanov * @since 2/8/12 1:52 PM */ -public class ExternalSystemTaskManager implements ExternalSystemTaskNotificationListener, Disposable { +public class ExternalSystemProcessingManager implements ExternalSystemTaskNotificationListener, Disposable { /** * We receive information about the tasks being enqueued to the slave processes which work directly with external systems here. @@ -40,7 +41,7 @@ public class ExternalSystemTaskManager implements ExternalSystemTaskNotification * We need to distinguish between them, so, we perform 'task pings' if any task is executed too long. Current constant holds * criteria of 'too long execution'. */ - private static final long TOO_LONG_EXECUTION_MS = TimeUnit.SECONDS.toMillis(10); + private static final long TOO_LONG_EXECUTION_MS = TimeUnit.SECONDS.toMillis(10); @NotNull private final ConcurrentMap myTasksInProgress = ContainerUtil.newConcurrentMap(); @NotNull private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); @@ -48,8 +49,8 @@ public class ExternalSystemTaskManager implements ExternalSystemTaskNotification @NotNull private final ExternalSystemFacadeManager myFacadeManager; @NotNull private final ExternalSystemProgressNotificationManager myProgressNotificationManager; - public ExternalSystemTaskManager(@NotNull ExternalSystemFacadeManager facadeManager, - @NotNull ExternalSystemProgressNotificationManager notificationManager) + public ExternalSystemProcessingManager(@NotNull ExternalSystemFacadeManager facadeManager, + @NotNull ExternalSystemProgressNotificationManager notificationManager) { myFacadeManager = facadeManager; myProgressNotificationManager = notificationManager; @@ -73,9 +74,10 @@ public class ExternalSystemTaskManager implements ExternalSystemTaskNotification * @return true if any task of the given type is being executed at the moment; * false otherwise */ - public boolean hasTaskOfTypeInProgress(@NotNull ExternalSystemTaskType type) { + public boolean hasTaskOfTypeInProgress(@NotNull ExternalSystemTaskType type, @NotNull Project project) { + String projectId = ExternalSystemTaskId.getProjectId(project); for (ExternalSystemTaskId id : myTasksInProgress.keySet()) { - if (type.equals(id.getType())) { + if (type.equals(id.getType()) && projectId.equals(id.getIdeProjectId())) { return true; } } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemResolveProjectTask.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemResolveProjectTask.java similarity index 74% rename from platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemResolveProjectTask.java rename to platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemResolveProjectTask.java index 6b8a59ce0c8b..b37aac125b68 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemResolveProjectTask.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemResolveProjectTask.java @@ -1,14 +1,15 @@ -package com.intellij.openapi.externalSystem.model.task; +package com.intellij.openapi.externalSystem.service.internal; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.externalSystem.model.DataNode; import com.intellij.openapi.externalSystem.model.ProjectSystemId; import com.intellij.openapi.externalSystem.model.project.ProjectData; -import com.intellij.openapi.externalSystem.service.ExternalSystemFacadeManager; import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings; +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskState; +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType; +import com.intellij.openapi.externalSystem.service.ExternalSystemFacadeManager; import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProjectResolver; import com.intellij.openapi.externalSystem.settings.ExternalSystemSettingsManager; -import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemBundle; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; @@ -44,17 +45,21 @@ public class ExternalSystemResolveProjectTask extends AbstractExternalSystemTask final ExternalSystemFacadeManager manager = ServiceManager.getService(ExternalSystemFacadeManager.class); Project ideProject = getIdeProject(); RemoteExternalSystemProjectResolver resolver = manager.getFacade(ideProject, myProjectPath, getExternalSystemId()).getResolver(); - setState(ExternalSystemTaskState.IN_PROGRESS); - - ExternalSystemSettingsManager settingsManager = ServiceManager.getService(ExternalSystemSettingsManager.class); - ExternalSystemExecutionSettings settings = settingsManager.getExecutionSettings(ideProject, myProjectPath, getExternalSystemId()); - DataNode project = resolver.resolveProjectInfo(getId(), myProjectPath, myResolveLibraries, settings); - if (project == null) { - return; + setState(ExternalSystemTaskState.IN_PROGRESS); + try { + ExternalSystemSettingsManager settingsManager = ServiceManager.getService(ExternalSystemSettingsManager.class); + ExternalSystemExecutionSettings settings = settingsManager.getExecutionSettings(ideProject, myProjectPath, getExternalSystemId()); + DataNode project = resolver.resolveProjectInfo(getId(), myProjectPath, myResolveLibraries, settings); + + if (project == null) { + return; + } + myExternalProject.set(project); + } + finally { + setState(ExternalSystemTaskState.FINISHED); } - myExternalProject.set(project); - setState(ExternalSystemTaskState.FINISHED); } @Nullable @@ -65,6 +70,6 @@ public class ExternalSystemResolveProjectTask extends AbstractExternalSystemTask @Override @NotNull protected String wrapProgressText(@NotNull String text) { - return ExternalSystemBundle.message("progress.update.text", ExternalSystemApiUtil.toReadableName(getExternalSystemId()), text); + return ExternalSystemBundle.message("progress.update.text", getExternalSystemId().getReadableName(), text); } } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskAware.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemTaskAware.java similarity index 83% rename from platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskAware.java rename to platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemTaskAware.java index 327e7bc072b1..73947b4f82d1 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskAware.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemTaskAware.java @@ -1,5 +1,7 @@ -package com.intellij.openapi.externalSystem.model.task; +package com.intellij.openapi.externalSystem.service.internal; +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType; import org.jetbrains.annotations.NotNull; import java.rmi.RemoteException; diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemIdeNotificationManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemIdeNotificationManager.java new file mode 100644 index 000000000000..b004c8b2996a --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemIdeNotificationManager.java @@ -0,0 +1,90 @@ +package com.intellij.openapi.externalSystem.service.notification; + +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationGroup; +import com.intellij.notification.NotificationListener; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.externalSystem.ExternalSystemConfigurableAware; +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.util.ExternalSystemApiUtil; +import com.intellij.openapi.externalSystem.util.ExternalSystemBundle; +import com.intellij.openapi.externalSystem.util.ExternalSystemUtil; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ShowSettingsUtil; +import com.intellij.openapi.project.Project; +import com.intellij.ui.EditorNotifications; +import org.jetbrains.annotations.NotNull; + +import javax.swing.event.HyperlinkEvent; +import java.util.concurrent.atomic.AtomicReference; + +/** + * This class is responsible for ide user by external system integration-specific events. + *

+ * One example use-case is a situation when an error occurs during external project refresh. We need to + * show corresponding message to the end-user. + *

+ * Thread-safe. + * + * @author Denis Zhdanov + * @since 3/21/12 4:04 PM + */ +public class ExternalSystemIdeNotificationManager { + + @NotNull private final AtomicReference myNotification = new AtomicReference(); + + public void processExternalProjectRefreshError(@NotNull String message, + @NotNull final Project project, + @NotNull String externalProjectName, + @NotNull ProjectSystemId externalSystemId) + { + NotificationGroup group = ExternalSystemUtil.getToolWindowElement(NotificationGroup.class, + project, + ExternalSystemDataKeys.NOTIFICATION_GROUP, + externalSystemId); + if (group == null) { + return; + } + + ExternalSystemManager manager = ExternalSystemApiUtil.getManager(externalSystemId); + if (!(manager instanceof ExternalSystemConfigurableAware)) { + return; + } + final Configurable configurable = ((ExternalSystemConfigurableAware)manager).getConfigurable(project); + + EditorNotifications.getInstance(project).updateAllNotifications(); + + final Notification notification = group.createNotification( + ExternalSystemBundle.message("notification.project.refresh.fail.description", + externalSystemId.getReadableName(), externalProjectName, message), + ExternalSystemBundle.message("notification.action.show.settings", externalSystemId.getReadableName()), + NotificationType.WARNING, + new NotificationListener() { + @Override + public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) { + if (event.getEventType() != HyperlinkEvent.EventType.ACTIVATED) { + return; + } + ShowSettingsUtil.getInstance().editConfigurable(project, configurable); + } + } + ); + + applyNotification(notification, project); + } + + private void applyNotification(@NotNull Notification notification, @NotNull Project project) { + final Notification oldNotification = myNotification.get(); + if (oldNotification != null && myNotification.compareAndSet(oldNotification, null)) { + oldNotification.expire(); + } + if (!myNotification.compareAndSet(null, notification)) { + notification.expire(); + return; + } + + notification.notify(project); + } +} diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ContentRootDataService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ContentRootDataService.java index e0b67ac18d11..eb6bcb974bf6 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ContentRootDataService.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ContentRootDataService.java @@ -22,6 +22,7 @@ import com.intellij.util.containers.ContainerUtilRt; import org.jetbrains.annotations.NotNull; import java.util.Collection; +import java.util.List; import java.util.Map; /** @@ -56,9 +57,8 @@ public class ContentRootDataService implements ProjectDataService, Collection>> byModule - = ExternalSystemApiUtil.groupBy(toImport, ProjectKeys.MODULE); - for (Map.Entry, Collection>> entry : byModule.entrySet()) { + Map, List>> byModule = ExternalSystemApiUtil.groupBy(toImport, ProjectKeys.MODULE); + for (Map.Entry, List>> entry : byModule.entrySet()) { final Module module = myProjectStructureHelper.findIdeModule(entry.getKey().getData(), project); if (module == null) { LOG.warn(String.format( diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/LibraryDependencyDataService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/LibraryDependencyDataService.java index 1e00304dbb4c..dd7c535081fd 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/LibraryDependencyDataService.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/LibraryDependencyDataService.java @@ -15,7 +15,6 @@ */ package com.intellij.openapi.externalSystem.service.project.manage; -import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.externalSystem.model.DataNode; import com.intellij.openapi.externalSystem.model.Key; @@ -32,7 +31,6 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemConstants; import com.intellij.openapi.externalSystem.util.Order; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.ExportableOrderEntry; import com.intellij.openapi.roots.LibraryOrderEntry; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; @@ -86,8 +84,8 @@ public class LibraryDependencyDataService extends AbstractDependencyDataService< return; } - Map, Collection>> byModule = ExternalSystemApiUtil.groupBy(toImport, MODULE); - for (Map.Entry, Collection>> entry : byModule.entrySet()) { + Map, List>> byModule = ExternalSystemApiUtil.groupBy(toImport, MODULE); + for (Map.Entry, List>> entry : byModule.entrySet()) { Module module = myProjectStructureHelper.findIdeModule(entry.getKey().getData(), project); if (module == null) { myModuleManager.importData(Collections.singleton(entry.getKey()), project, true); diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDependencyDataService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDependencyDataService.java index 654bea020dfc..5b7ab3209ceb 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDependencyDataService.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDependencyDataService.java @@ -37,6 +37,7 @@ import org.jetbrains.annotations.NotNull; import java.util.Collection; import java.util.Collections; +import java.util.List; import java.util.Map; import static com.intellij.openapi.externalSystem.model.ProjectKeys.MODULE; @@ -66,8 +67,8 @@ public class ModuleDependencyDataService extends AbstractDependencyDataService> toImport, @NotNull Project project, boolean synchronous) { - Map, Collection>> byModule= ExternalSystemApiUtil.groupBy(toImport, MODULE); - for (Map.Entry, Collection>> entry : byModule.entrySet()) { + Map, List>> byModule= ExternalSystemApiUtil.groupBy(toImport, MODULE); + for (Map.Entry, List>> entry : byModule.entrySet()) { Module ideModule = myProjectStructureHelper.findIdeModule(entry.getKey().getData(), project); if (ideModule == null) { myModuleDataManager.importData(Collections.singleton(entry.getKey()), project, true); diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ProjectDataManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ProjectDataManager.java index cd267e193c94..6575ffb107f0 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ProjectDataManager.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ProjectDataManager.java @@ -64,8 +64,8 @@ public class ProjectDataManager { @SuppressWarnings("unchecked") public void importData(@NotNull Collection> nodes, @NotNull Project project, boolean synchronous) { - Map, Collection>> grouped = ExternalSystemApiUtil.group(nodes); - for (Map.Entry, Collection>> entry : grouped.entrySet()) { + Map, List>> grouped = ExternalSystemApiUtil.group(nodes); + for (Map.Entry, List>> entry : grouped.entrySet()) { // Simple class cast makes ide happy but compiler fails. Collection> dummy = ContainerUtilRt.newArrayList(); for (DataNode node : entry.getValue()) { diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/AbstractExternalProjectImportBuilder.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/AbstractExternalProjectImportBuilder.java index d5eb30635cde..f2e96fa6e63a 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/AbstractExternalProjectImportBuilder.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/AbstractExternalProjectImportBuilder.java @@ -7,7 +7,7 @@ import com.intellij.openapi.externalSystem.model.ProjectKeys; import com.intellij.openapi.externalSystem.model.ProjectSystemId; import com.intellij.openapi.externalSystem.model.project.LibraryData; import com.intellij.openapi.externalSystem.model.project.ProjectData; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemResolveProjectTask; +import com.intellij.openapi.externalSystem.service.internal.ExternalSystemResolveProjectTask; import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback; import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager; import com.intellij.openapi.externalSystem.service.settings.AbstractImportFromExternalSystemControl; @@ -152,8 +152,7 @@ public abstract class AbstractExternalProjectImportBuilder extends RemoteExternalSystemService { +public interface RemoteExternalSystemTaskManager extends RemoteExternalSystemService { /** Null object for {@link RemoteExternalSystemProjectResolverImpl}. */ - RemoteExternalSystemBuildManager NULL_OBJECT = - new RemoteExternalSystemBuildManager() { - - @Nullable - @Override - public Map> listTasks(@NotNull ExternalSystemTaskId id, - @NotNull String projectPath, - @Nullable ExternalSystemExecutionSettings settings) - throws RemoteException, ExternalSystemException - { - return ContainerUtilRt.newHashMap(); - } + RemoteExternalSystemTaskManager NULL_OBJECT = + new RemoteExternalSystemTaskManager() { @Override public void executeTasks(@NotNull ExternalSystemTaskId id, @@ -77,12 +68,6 @@ public interface RemoteExternalSystemBuildManager> listTasks(@NotNull ExternalSystemTaskId id, - @NotNull String projectPath, - @Nullable S settings) - throws RemoteException, ExternalSystemException; - void executeTasks(@NotNull ExternalSystemTaskId id, @NotNull List taskNames, @NotNull String projectPath, @Nullable S settings) throws RemoteException, ExternalSystemException; } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemBuildManagerImpl.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemTaskManagerImpl.java similarity index 59% rename from platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemBuildManagerImpl.java rename to platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemTaskManagerImpl.java index b6de995bf35e..de5ce33fe438 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemBuildManagerImpl.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemTaskManagerImpl.java @@ -15,50 +15,31 @@ */ package com.intellij.openapi.externalSystem.service.remote; -import com.intellij.openapi.externalSystem.build.ExternalSystemBuildManager; +import com.intellij.openapi.externalSystem.build.ExternalSystemTaskManager; import com.intellij.openapi.externalSystem.model.ExternalSystemException; import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskDescriptor; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; import com.intellij.util.Producer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.rmi.RemoteException; -import java.util.Collection; import java.util.List; -import java.util.Map; /** * @author Denis Zhdanov * @since 4/9/13 7:49 PM */ -public class RemoteExternalSystemBuildManagerImpl - extends AbstractRemoteExternalSystemService implements RemoteExternalSystemBuildManager +public class RemoteExternalSystemTaskManagerImpl + extends AbstractRemoteExternalSystemService implements RemoteExternalSystemTaskManager { - - @NotNull private final ExternalSystemBuildManager myDelegate; - public RemoteExternalSystemBuildManagerImpl(@NotNull ExternalSystemBuildManager delegate) { + @NotNull private final ExternalSystemTaskManager myDelegate; + + public RemoteExternalSystemTaskManagerImpl(@NotNull ExternalSystemTaskManager delegate) { myDelegate = delegate; } - @Override - public Map> listTasks(@NotNull final ExternalSystemTaskId id, - @NotNull final String projectPath, - @Nullable final S settings) - throws RemoteException, ExternalSystemException - { - - return execute(id, new Producer>>() { - @Nullable - @Override - public Map> produce() { - return myDelegate.listTasks(id, projectPath, settings); - } - }); - } - @Override public void executeTasks(@NotNull final ExternalSystemTaskId id, @NotNull final List taskNames, @@ -69,7 +50,7 @@ public class RemoteExternalSystemBuildManagerImpl getBuildManager() throws RemoteException { - return new ExternalSystemBuildManagerWrapper(myDelegate.getBuildManager(), myProgressManager); + public RemoteExternalSystemTaskManager getTaskManager() throws RemoteException { + return new ExternalSystemTaskManagerWrapper(myDelegate.getTaskManager(), myProgressManager); } @Override diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/wrapper/ExternalSystemBuildManagerWrapper.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/wrapper/ExternalSystemTaskManagerWrapper.java similarity index 64% rename from platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/wrapper/ExternalSystemBuildManagerWrapper.java rename to platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/wrapper/ExternalSystemTaskManagerWrapper.java index 16cfe022883b..1bf4e604271a 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/wrapper/ExternalSystemBuildManagerWrapper.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/wrapper/ExternalSystemTaskManagerWrapper.java @@ -16,53 +16,34 @@ package com.intellij.openapi.externalSystem.service.remote.wrapper; import com.intellij.openapi.externalSystem.model.ExternalSystemException; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskDescriptor; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings; -import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemBuildManager; +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProgressNotificationManager; +import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemTaskManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.rmi.RemoteException; -import java.util.Collection; import java.util.List; -import java.util.Map; /** * @author Denis Zhdanov * @since 3/14/13 5:53 PM */ -public class ExternalSystemBuildManagerWrapper - extends AbstractRemoteExternalSystemServiceWrapper> - implements RemoteExternalSystemBuildManager +public class ExternalSystemTaskManagerWrapper + extends AbstractRemoteExternalSystemServiceWrapper> + implements RemoteExternalSystemTaskManager { @NotNull private final RemoteExternalSystemProgressNotificationManager myProgressManager; - public ExternalSystemBuildManagerWrapper(@NotNull RemoteExternalSystemBuildManager delegate, - @NotNull RemoteExternalSystemProgressNotificationManager progressManager) + public ExternalSystemTaskManagerWrapper(@NotNull RemoteExternalSystemTaskManager delegate, + @NotNull RemoteExternalSystemProgressNotificationManager progressManager) { super(delegate); myProgressManager = progressManager; } - @Nullable - @Override - public Map> listTasks(@NotNull ExternalSystemTaskId id, - @NotNull String projectPath, - @Nullable S settings) - throws RemoteException, ExternalSystemException - { - myProgressManager.onQueued(id); - try { - return getDelegate().listTasks(id, projectPath, settings); - } - finally { - myProgressManager.onEnd(id); - } - } - @Override public void executeTasks(@NotNull ExternalSystemTaskId id, @NotNull List taskNames, diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalSystemConfigurable.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalSystemConfigurable.java index 8bdac116c1bb..19da5c8c7e4c 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalSystemConfigurable.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalSystemConfigurable.java @@ -95,7 +95,7 @@ public abstract class AbstractExternalSystemConfigurable< @Nls @Override public String getDisplayName() { - return ExternalSystemApiUtil.toReadableName(myExternalSystemId); + return myExternalSystemId.getReadableName(); } @Nullable @@ -126,8 +126,7 @@ public abstract class AbstractExternalSystemConfigurable< myProjectsList = new JBList(myProjectsModel); myProjectsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - String externalSystemName = ExternalSystemApiUtil.toReadableName(myExternalSystemId); - addTitle(ExternalSystemBundle.message("settings.title.linked.projects", externalSystemName)); + addTitle(ExternalSystemBundle.message("settings.title.linked.projects", myExternalSystemId.getReadableName())); myComponent.add(new JBScrollPane(myProjectsList), ExternalSystemUiUtil.getFillLineConstraints(1)); addTitle(ExternalSystemBundle.message("settings.title.project.settings")); @@ -170,7 +169,7 @@ public abstract class AbstractExternalSystemConfigurable< if (!myProjectsModel.isEmpty()) { - addTitle(ExternalSystemBundle.message("settings.title.system.settings", externalSystemName)); + addTitle(ExternalSystemBundle.message("settings.title.system.settings", myExternalSystemId.getReadableName())); myProjectsList.setSelectedIndex(0); } } 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 097e5cb7d02c..feeff6f69970 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,7 +19,6 @@ 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; @@ -66,13 +65,13 @@ public abstract class AbstractImportFromExternalSystemControl< myProjectSettingsControl = createProjectSettingsControl(myProjectSettings); mySystemSettingsControl = createSystemSettingsControl(mySystemSettings); - String name = ExternalSystemApiUtil.toReadableName(externalSystemId); - JLabel linkedProjectPathLabel = new JLabel(ExternalSystemBundle.message("settings.label.select.project", name)); + JLabel linkedProjectPathLabel + = new JLabel(ExternalSystemBundle.message("settings.label.select.project", externalSystemId.getReadableName())); FileChooserDescriptor fileChooserDescriptor = getLinkedProjectChooserDescriptor(); myLinkedProjectPathField.addBrowseFolderListener( "", - ExternalSystemBundle.message("settings.label.select.project", ExternalSystemApiUtil.toReadableName(externalSystemId)), + ExternalSystemBundle.message("settings.label.select.project", externalSystemId.getReadableName()), null, fileChooserDescriptor, TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT, 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 new file mode 100644 index 000000000000..5652e5e8f074 --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/AbstractToolWindowService.java @@ -0,0 +1,54 @@ +/* + * 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.ExternalSystemDataKeys; +import com.intellij.openapi.externalSystem.model.project.ExternalEntityData; +import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataService; +import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTreeModel; +import com.intellij.openapi.externalSystem.util.ExternalSystemUtil; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +/** + * @author Denis Zhdanov + * @since 5/15/13 1:32 PM + */ +public abstract class AbstractToolWindowService implements ProjectDataService { + + @Override + public void importData(@NotNull Collection> toImport, @NotNull Project project, boolean synchronous) { + if (toImport.isEmpty()) { + return; + } + ExternalSystemTasksTreeModel model = ExternalSystemUtil.getToolWindowElement(ExternalSystemTasksTreeModel.class, + project, + ExternalSystemDataKeys.ALL_TASKS_MODEL, + toImport.iterator().next().getData().getOwner()); + if (model != null) { + processData(toImport, model); + } + } + + protected abstract void processData(@NotNull Collection> nodes, @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/ExternalSystemTasksPanel.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ExternalSystemTasksPanel.java deleted file mode 100644 index 891aea20c1d3..000000000000 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ExternalSystemTasksPanel.java +++ /dev/null @@ -1,53 +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.actionSystem.DataProvider; -import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys; -import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil; -import com.intellij.ui.components.JBScrollPane; -import com.intellij.ui.treeStructure.Tree; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; -import java.awt.*; - -/** - * @author Denis Zhdanov - * @since 5/12/13 10:18 PM - */ -public class ExternalSystemTasksPanel extends JPanel implements DataProvider { - - @NotNull ExternalSystemTasksTreeModel myAllTasksModel = new ExternalSystemTasksTreeModel(); - @NotNull Tree myAllTasksTree = new Tree(myAllTasksModel); - - public ExternalSystemTasksPanel() { - super(new GridBagLayout()); - - add(new JBScrollPane(myAllTasksTree), ExternalSystemUiUtil.getFillLineConstraints(0)); - } - - @Nullable - @Override - public Object getData(@NonNls String dataId) { - if (ExternalSystemDataKeys.ALL_TASKS_MODEL.is(dataId)) { - return myAllTasksModel; - } - return null; - } -} 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 new file mode 100644 index 000000000000..8632df6876b4 --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ToolWindowModuleService.java @@ -0,0 +1,71 @@ +/* + * 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.ModuleData; +import com.intellij.openapi.externalSystem.model.project.ProjectData; +import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTreeModel; +import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; +import com.intellij.openapi.externalSystem.util.ExternalSystemConstants; +import com.intellij.openapi.externalSystem.util.Order; +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; +import java.util.List; +import java.util.Map; + +/** + * Ensures that all external system sub-projects are correctly represented at the external system tool window. + * + * @author Denis Zhdanov + * @since 5/15/13 1:02 PM + */ +@Order(ExternalSystemConstants.BUILTIN_TOOL_WINDOW_SERVICE_ORDER) +public class ToolWindowModuleService extends AbstractToolWindowService { + + @NotNull + public static final Function, ModuleData> MAPPER = new Function, ModuleData>() { + @Override + public ModuleData fun(DataNode node) { + return node.getData(); + } + }; + + @NotNull + @Override + public Key getTargetDataKey() { + return ProjectKeys.MODULE; + } + + @Override + protected void processData(@NotNull final Collection> nodes, @NotNull final ExternalSystemTasksTreeModel model) { + 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)); + } + } + }); + } +} 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 new file mode 100644 index 000000000000..2fdc17936aa3 --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ToolWindowProjectService.java @@ -0,0 +1,55 @@ +/* + * 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 new file mode 100644 index 000000000000..01e877e34f73 --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ToolWindowTaskService.java @@ -0,0 +1,46 @@ +/* + * 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.task.TaskData; +import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTreeModel; +import com.intellij.openapi.externalSystem.util.ExternalSystemConstants; +import com.intellij.openapi.externalSystem.util.Order; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +/** + * @author Denis Zhdanov + * @since 5/15/13 7:21 PM + */ +@Order(ExternalSystemConstants.BUILTIN_TOOL_WINDOW_SERVICE_ORDER) +public class ToolWindowTaskService extends AbstractToolWindowService { + + @NotNull + @Override + public Key getTargetDataKey() { + return ProjectKeys.TASK; + } + + @Override + protected void processData(@NotNull Collection> nodes, @NotNull ExternalSystemTasksTreeModel model) { + // TODO den implement + } +} 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 new file mode 100644 index 000000000000..2c8887b15095 --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/AbstractExternalSystemToolWindowFactory.java @@ -0,0 +1,63 @@ +/* + * 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.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; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowFactory; +import com.intellij.ui.content.ContentManager; +import com.intellij.ui.content.impl.ContentImpl; +import org.jetbrains.annotations.NotNull; + +/** + * @author Denis Zhdanov + * @since 5/13/13 4:15 PM + */ +public abstract class AbstractExternalSystemToolWindowFactory implements ToolWindowFactory, DumbAware { + + @NotNull private final ProjectSystemId myExternalSystemId; + @NotNull private final NotificationGroup myNotificationGroup; + + protected AbstractExternalSystemToolWindowFactory(@NotNull ProjectSystemId id) { + myExternalSystemId = id; + myNotificationGroup = NotificationGroup.toolWindowGroup("notification.group.id." + id.toString().toLowerCase(), + myExternalSystemId.getReadableName(), + true); + } + + @Override + public void createToolWindowContent(final Project project, final ToolWindow toolWindow) { + toolWindow.setTitle(myExternalSystemId.getReadableName()); + ContentManager contentManager = toolWindow.getContentManager(); + 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); + 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/ExternalSystemNode.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemNode.java new file mode 100644 index 000000000000..66e4a02fcd5c --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemNode.java @@ -0,0 +1,42 @@ +/* + * 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.ui; + +import org.jetbrains.annotations.NotNull; + +import javax.swing.tree.DefaultMutableTreeNode; + +/** + * @author Denis Zhdanov + * @since 5/14/13 2:42 PM + */ +@SuppressWarnings("unchecked") +public class ExternalSystemNode extends DefaultMutableTreeNode { + + public ExternalSystemNode(@NotNull ExternalSystemNodeDescriptor descriptor) { + super(descriptor); + } + + @NotNull + public ExternalSystemNodeDescriptor getDescriptor() { + return (ExternalSystemNodeDescriptor)getUserObject(); + } + + @Override + public ExternalSystemNode getChildAt(int index) { + return (ExternalSystemNode)super.getChildAt(index); + } +} diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemNodeDescriptor.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemNodeDescriptor.java new file mode 100644 index 000000000000..b3f0f9031b3f --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemNodeDescriptor.java @@ -0,0 +1,51 @@ +/* + * 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.ui; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.util.treeView.PresentableNodeDescriptor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +/** + * @author Denis Zhdanov + * @since 5/14/13 2:32 PM + */ +public class ExternalSystemNodeDescriptor extends PresentableNodeDescriptor { + + @NotNull private final T myElement; + + public ExternalSystemNodeDescriptor(@NotNull T element, @NotNull String text, @Nullable Icon icon) { + super(null, null); + myElement = element; + myName = text; + setIcon(icon); + } + + @Override + protected void update(PresentationData presentation) { + presentation.setPresentableText(myName); + presentation.setIcon(getIcon()); + } + + @NotNull + @Override + public T getElement() { + return myElement; + } +} 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 new file mode 100644 index 000000000000..fceb03be7122 --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksPanel.java @@ -0,0 +1,92 @@ +/* + * 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.ui; + +import com.intellij.notification.NotificationGroup; +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.ActionToolbar; +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.project.Project; +import com.intellij.openapi.ui.SimpleToolWindowPanel; +import com.intellij.ui.components.JBScrollPane; +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 + */ +public class ExternalSystemTasksPanel extends SimpleToolWindowPanel implements DataProvider { + + @NotNull private final ExternalSystemTasksTreeModel myAllTasksModel; + @NotNull private final ExternalSystemTasksTree myAllTasksTree; + @NotNull private final ProjectSystemId myExternalSystemId; + @NotNull private final NotificationGroup myNotificationGroup; + + public ExternalSystemTasksPanel(@NotNull Map> tasks, + @NotNull Project project, + @NotNull ProjectSystemId externalSystemId, + @NotNull NotificationGroup notificationGroup) + { + super(true); + myExternalSystemId = externalSystemId; + myNotificationGroup = notificationGroup; + myAllTasksModel = new ExternalSystemTasksTreeModel(externalSystemId); + + ExternalSystemManager manager = ExternalSystemApiUtil.getManager(externalSystemId); + assert manager != null; + AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project); + myAllTasksTree = new ExternalSystemTasksTree(myAllTasksModel, settings.getExpandStates()); + + ActionManager actionManager = ActionManager.getInstance(); + ActionGroup group = (ActionGroup)actionManager.getAction(ExternalSystemConstants.TOOL_WINDOW_TOOLBAR_ACTIONS_GROUP_ID); + ActionToolbar toolbar = actionManager.createActionToolbar(ExternalSystemConstants.TOOL_WINDOW_PLACE, group, true); + toolbar.setTargetComponent(this); + setToolbar(toolbar.getComponent()); + + setContent(new JBScrollPane(myAllTasksTree)); + + // TODO den implement +// myAllTasksModel.updateTasks(tasks); + } + + @Nullable + @Override + public Object getData(@NonNls String dataId) { + if (ExternalSystemDataKeys.ALL_TASKS_MODEL.is(dataId)) { + return myAllTasksModel; + } + else if (ExternalSystemDataKeys.EXTERNAL_SYSTEM_ID.is(dataId)) { + return myExternalSystemId; + } + else if (ExternalSystemDataKeys.NOTIFICATION_GROUP.is(dataId)) { + return myNotificationGroup; + } + return null; + } +} 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 new file mode 100644 index 000000000000..be86d1aed4d5 --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTree.java @@ -0,0 +1,139 @@ +/* + * 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.ui; + +import com.intellij.ui.treeStructure.Tree; +import com.intellij.util.Alarm; +import com.intellij.util.containers.ContainerUtilRt; +import com.intellij.util.ui.tree.TreeModelAdapter; +import org.jetbrains.annotations.NotNull; + +import javax.swing.event.TreeModelEvent; +import javax.swing.tree.TreePath; +import java.util.*; + +/** + * @author Denis Zhdanov + * @since 5/13/13 4:18 PM + */ +public class ExternalSystemTasksTree extends Tree { + + private static final int COLLAPSE_STATE_PROCESSING_DELAY_MILLIS = 200; + + @NotNull private static final Comparator PATH_COMPARATOR = new Comparator() { + @Override + public int compare(TreePath o1, TreePath o2) { + return o2.getPathCount() - o1.getPathCount(); + } + }; + + @NotNull private final Alarm myCollapseStateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); + + /** Holds list of paths which 'expand/collapse' state should be restored. */ + @NotNull private final Set myPathsToProcessCollapseState = ContainerUtilRt.newHashSet(); + + @NotNull private final Map myExpandedStateHolder; + + private boolean mySuppressCollapseTracking; + + public ExternalSystemTasksTree(@NotNull ExternalSystemTasksTreeModel model, + @NotNull Map expandedStateHolder) + { + super(model); + myExpandedStateHolder = expandedStateHolder; + setRootVisible(false); + + model.addTreeModelListener(new TreeModelAdapter() { + @Override + public void treeStructureChanged(TreeModelEvent e) { + scheduleCollapseStateAppliance(e.getTreePath()); + } + + @Override + public void treeNodesInserted(TreeModelEvent e) { + scheduleCollapseStateAppliance(e.getTreePath()); + } + }); + } + + /** + * Schedules 'collapse/expand' state restoring for the given path. We can't do that immediately from the tree model listener + * as there is a possible case that other listeners have not been notified about the model state change, hence, attempt to define + * 'collapse/expand' state may bring us to the inconsistent state. + * + * @param path target path + */ + private void scheduleCollapseStateAppliance(@NotNull TreePath path) { + myPathsToProcessCollapseState.add(path); + myCollapseStateAlarm.cancelAllRequests(); + myCollapseStateAlarm.addRequest(new Runnable() { + @Override + public void run() { + // We assume that the paths collection is modified only from the EDT, so, ConcurrentModificationException doesn't have + // 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); + myPathsToProcessCollapseState.clear(); + Collections.sort(paths, PATH_COMPARATOR); + for (TreePath treePath : paths) { + applyCollapseState(treePath); + } + final TreePath rootPath = new TreePath(getModel().getRoot()); + if (isCollapsed(rootPath)) { + expandPath(rootPath); + } + } + }, COLLAPSE_STATE_PROCESSING_DELAY_MILLIS); + } + + /** + * Applies stored 'collapse/expand' state to the node located at the given path. + * + * @param path target path + */ + private void applyCollapseState(@NotNull TreePath path) { + final String key = getPath(path); + final Boolean expanded = myExpandedStateHolder.get(key); + if (expanded == null) { + return; + } + boolean s = mySuppressCollapseTracking; + mySuppressCollapseTracking = true; + try { + if (expanded) { + expandPath(path); + } + else { + collapsePath(path); + } + } + finally { + mySuppressCollapseTracking = s; + } + } + + @NotNull + private static String getPath(@NotNull TreePath path) { + StringBuilder buffer = new StringBuilder(); + for (TreePath current = path; current != null; current = current.getParentPath()) { + buffer.append(current.getLastPathComponent().toString()).append('/'); + } + buffer.setLength(buffer.length() - 1); + return buffer.toString(); + } + +} 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 new file mode 100644 index 000000000000..86fe87379502 --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTreeModel.java @@ -0,0 +1,177 @@ +/* + * 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.ui; + +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.service.ui.DefaultExternalSystemUiAware; +import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; +import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil; +import com.intellij.util.containers.ContainerUtilRt; +import gnu.trove.TObjectIntHashMap; +import org.jetbrains.annotations.NotNull; +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; + +/** + * @author Denis Zhdanov + * @since 5/12/13 10:28 PM + */ +public class ExternalSystemTasksTreeModel extends DefaultTreeModel { + + @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); + if (manager instanceof ExternalSystemUiAware) { + myUiAware = (ExternalSystemUiAware)manager; + } + else { + myUiAware = DefaultExternalSystemUiAware.INSTANCE; + } + } + + /** + * 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 + */ + @SuppressWarnings("unchecked") + @NotNull + public ExternalSystemNode ensureProjectNodeExists(@NotNull ProjectData externalProject) { + 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())) + { + return (ExternalSystemNode)child; + } + } + ProjectNodeElement element = new ProjectNodeElement(externalProject.getName(), externalProject.getLinkedExternalProjectPath()); + ExternalSystemNodeDescriptor descriptor = descriptor(element, myUiAware.getProjectIcon()); + myIndexHolder[0] = root.getChildCount(); + 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++); + } + + 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) { + taskWeights.put(childElement, subProjects.size() + i); + continue; + } + + if (toAdd.remove(((ProjectNodeElement)childElement).path) == null) { + topLevelProjectNode.remove(child); + myIndexHolder[0] = i; + myNodeHolder[0] = child; + nodesWereRemoved(topLevelProjectNode, myIndexHolder, myNodeHolder); + //noinspection AssignmentToForLoopParameter + i--; + } + } + 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()))); + } + } + + + 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); + } + + 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; + } + } + }); + } + + @NotNull + private static ExternalSystemNodeDescriptor descriptor(@NotNull T element, @Nullable Icon icon) { + return new ExternalSystemNodeDescriptor(element, element.toString(), icon); + } + + @NotNull + 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 new file mode 100644 index 000000000000..cae629c170d1 --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/DefaultExternalSystemUiAware.java @@ -0,0 +1,40 @@ +/* + * 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.ui; + +import com.intellij.icons.AllIcons; +import com.intellij.openapi.externalSystem.ExternalSystemUiAware; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +/** + * This class is not singleton but offers single-point-of-usage field - {@link #INSTANCE}. + * + * @author Denis Zhdanov + * @since 5/15/13 12:45 PM + */ +public class DefaultExternalSystemUiAware implements ExternalSystemUiAware { + + @NotNull public static final DefaultExternalSystemUiAware INSTANCE = new DefaultExternalSystemUiAware(); + + @Nullable + @Override + public Icon getProjectIcon() { + return AllIcons.Nodes.IdeaProject; + } +} 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 d13b309aed5c..4f26dbfed481 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 @@ -21,11 +21,20 @@ import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.ui.popup.BalloonBuilder; import com.intellij.openapi.ui.popup.JBPopupFactory; 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 gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.MutableTreeNode; +import javax.swing.tree.TreeNode; import java.awt.*; +import java.util.*; +import java.util.List; import java.util.concurrent.TimeUnit; /** @@ -82,4 +91,30 @@ public class ExternalSystemUiUtil { public static void fillBottom(@NotNull JComponent component) { component.add(Box.createVerticalGlue(), new GridBag().weightx(1).weighty(1).fillCell().coverLine()); } + + public static void sort(@NotNull DefaultMutableTreeNode parent, + @NotNull DefaultTreeModel model, + @NotNull Comparator comparator) + { + List children = ContainerUtilRt.newArrayList(); + THashMap initialOrder = ContainerUtil.newIdentityTroveMap(); + for (int i = 0; i < parent.getChildCount(); i++) { + MutableTreeNode child = (MutableTreeNode)parent.getChildAt(i); + children.add(child); + initialOrder.put(child, i); + } + Collections.sort(children, comparator); + parent.removeAllChildren(); + + for (MutableTreeNode child : children) { + parent.add(child); + } + for (int i = 0; i < children.size(); i++) { + MutableTreeNode child = children.get(i); + Integer initialIndex = initialOrder.get(child); + if (initialIndex != i) { + model.nodeChanged(child); + } + } + } } 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 eb78b24db3ba..cbe3bf3157a7 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 @@ -28,7 +28,8 @@ 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.task.ExternalSystemResolveProjectTask; +import com.intellij.openapi.externalSystem.service.internal.ExternalSystemResolveProjectTask; +import com.intellij.openapi.externalSystem.service.notification.ExternalSystemIdeNotificationManager; import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback; import com.intellij.openapi.externalSystem.service.project.PlatformFacade; import com.intellij.openapi.externalSystem.service.project.manage.ModuleDataService; @@ -109,7 +110,7 @@ public class ExternalSystemUtil { if (toolWindowManager == null) { return null; } - final ToolWindow toolWindow = toolWindowManager.getToolWindow(ExternalSystemApiUtil.toReadableName(externalSystemId)); + final ToolWindow toolWindow = toolWindowManager.getToolWindow(externalSystemId.getReadableName()); if (toolWindow == null) { return null; } @@ -233,10 +234,9 @@ public class ExternalSystemUtil { UIUtil.invokeLaterIfNeeded(new Runnable() { @Override public void run() { - final String externalSystem = ExternalSystemApiUtil.toReadableName(externalSystemId); final JPanel content = new JPanel(new GridBagLayout()); - content.add(new JLabel(ExternalSystemBundle.message("orphan.modules.text", externalSystem)), + content.add(new JLabel(ExternalSystemBundle.message("orphan.modules.text", externalSystemId.getReadableName())), ExternalSystemUiUtil.getFillLineConstraints(0)); final CheckBoxList orphanModulesList = new CheckBoxList(); @@ -255,7 +255,7 @@ public class ExternalSystemUtil { DialogWrapper dialog = new DialogWrapper(project) { { - setTitle(ExternalSystemBundle.message("import.title", externalSystem)); + setTitle(ExternalSystemBundle.message("import.title", externalSystemId.getReadableName())); init(); } @@ -314,6 +314,7 @@ public class ExternalSystemUtil { final boolean resolveLibraries, final boolean modal) { + final String projectName = new File(externalProjectPath).getParentFile().getName(); final TaskUnderProgress refreshProjectStructureTask = new TaskUnderProgress() { @SuppressWarnings({"ThrowableResultOfMethodCallIgnored", "IOResourceOpenedButNotSafelyClosed"}) @Override @@ -331,26 +332,22 @@ public class ExternalSystemUtil { if (StringUtil.isEmpty(message)) { message = String.format( "Can't resolve %s project at '%s'. Reason: %s", - ExternalSystemApiUtil.toReadableName(externalSystemId), externalProjectPath, message + externalSystemId.getReadableName(), externalProjectPath, message ); } + callback.onFailure(message, extractDetails(error)); + + ExternalSystemIdeNotificationManager notificationManager = ServiceManager.getService(ExternalSystemIdeNotificationManager.class); + if (notificationManager != null) { + notificationManager.processExternalProjectRefreshError(message, project, projectName, externalSystemId); + } } }; - // TODO den implement - //final TaskUnderProgress refreshTasksTask = new TaskUnderProgress() { - // @Override - // public void execute(@NotNull ProgressIndicator indicator) { - // final ExternalSystemRefreshTasksListTask task = new ExternalSystemRefreshTasksListTask(project, externalProjectPath); - // task.execute(indicator); - // } - //}; - UIUtil.invokeAndWaitIfNeeded(new Runnable() { @Override public void run() { - final String projectName = new File(externalProjectPath).getParentFile().getName(); if (modal) { String title = ExternalSystemBundle.message("progress.import.text", projectName, @@ -359,9 +356,6 @@ public class ExternalSystemUtil { @Override public void run(@NotNull ProgressIndicator indicator) { refreshProjectStructureTask.execute(indicator); - // TODO den uncomment - //setTitle(ExternalSystemBundle.message("gradle.task.progress.initial.text")); - //refreshTasksTask.execute(indicator); } }); } @@ -372,9 +366,6 @@ public class ExternalSystemUtil { @Override public void run(@NotNull ProgressIndicator indicator) { refreshProjectStructureTask.execute(indicator); - // TODO den uncomment - //setTitle(ExternalSystemBundle.message("gradle.task.progress.initial.text")); - //refreshTasksTask.execute(indicator); } }); } diff --git a/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml b/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml index ecad7343dd01..36f56d78c004 100644 --- a/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml +++ b/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml @@ -14,6 +14,8 @@ serviceImplementation="com.intellij.openapi.externalSystem.service.project.ExternalLibraryPathTypeMapperImpl"/> + + @@ -23,7 +25,13 @@ - + + + + + + + diff --git a/platform/platform-resources/src/idea/ExternalSystemActions.xml b/platform/platform-resources/src/idea/ExternalSystemActions.xml new file mode 100644 index 000000000000..52fb84b2f48a --- /dev/null +++ b/platform/platform-resources/src/idea/ExternalSystemActions.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/gradle/src/META-INF/plugin.xml b/plugins/gradle/src/META-INF/plugin.xml index 8c2e3993a2a4..60b7be2ee257 100644 --- a/plugins/gradle/src/META-INF/plugin.xml +++ b/plugins/gradle/src/META-INF/plugin.xml @@ -45,30 +45,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - @@ -84,7 +60,7 @@ - + diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java index 901792c76411..3f19025b9e48 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java @@ -20,8 +20,10 @@ import com.intellij.execution.configurations.SimpleJavaParameters; import com.intellij.externalSystem.JavaProjectData; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.externalSystem.ExternalSystemConfigurableAware; import com.intellij.openapi.externalSystem.ExternalSystemManager; -import com.intellij.openapi.externalSystem.build.ExternalSystemBuildManager; +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.util.ExternalSystemApiUtil; @@ -29,6 +31,7 @@ import com.intellij.openapi.module.EmptyModuleType; import com.intellij.openapi.module.JavaModuleType; import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.module.StdModuleTypes; +import com.intellij.openapi.options.Configurable; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.NotNullLazyValue; import com.intellij.openapi.util.Pair; @@ -38,17 +41,21 @@ import com.intellij.util.Function; import com.intellij.util.PathUtil; import com.intellij.util.PathsList; import com.intellij.util.containers.ContainerUtilRt; +import icons.GradleIcons; import org.gradle.tooling.ProjectConnection; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.remote.GradleJavaHelper; -import org.jetbrains.plugins.gradle.remote.impl.GradleBuildManager; +import org.jetbrains.plugins.gradle.remote.impl.GradleTaskManager; import org.jetbrains.plugins.gradle.service.GradleInstallationManager; import org.jetbrains.plugins.gradle.service.project.GradleProjectResolver; import org.jetbrains.plugins.gradle.service.project.GradleProjectResolverExtension; +import org.jetbrains.plugins.gradle.service.settings.GradleConfigurable; import org.jetbrains.plugins.gradle.settings.*; import org.jetbrains.plugins.gradle.util.GradleBundle; import org.jetbrains.plugins.gradle.util.GradleConstants; +import javax.swing.*; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; @@ -59,7 +66,7 @@ import java.util.List; * @author Denis Zhdanov * @since 4/10/13 1:19 PM */ -public class GradleManager implements ExternalSystemManager< +public class GradleManager implements ExternalSystemConfigurableAware, ExternalSystemUiAware, ExternalSystemManager< GradleProjectSettings, GradleSettingsListener, GradleSettings, @@ -207,7 +214,19 @@ public class GradleManager implements ExternalSystemManager< } @Override - public Class> getBuildManagerClass() { - return GradleBuildManager.class; + public Class> getTaskManagerClass() { + return GradleTaskManager.class; + } + + @NotNull + @Override + public Configurable getConfigurable(@NotNull Project project) { + return new GradleConfigurable(project); + } + + @Nullable + @Override + public Icon getProjectIcon() { + return GradleIcons.Gradle; } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleRefreshProjectAction.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleRefreshProjectAction.java deleted file mode 100644 index 454917ca3c56..000000000000 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleRefreshProjectAction.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.jetbrains.plugins.gradle.action; - -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.components.ServiceManager; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType; -import com.intellij.openapi.externalSystem.util.ExternalSystemBundle; -import com.intellij.openapi.externalSystem.util.ExternalSystemUtil; -import com.intellij.openapi.fileEditor.FileDocumentManager; -import com.intellij.openapi.project.DumbAware; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Ref; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.gradle.settings.GradleSettings; -import com.intellij.openapi.externalSystem.service.task.ExternalSystemTaskManager; -import org.jetbrains.plugins.gradle.notification.GradleConfigNotificationManager; -import org.jetbrains.plugins.gradle.util.GradleConstants; -import org.jetbrains.plugins.gradle.util.GradleUtil; - -/** - * Forces the 'gradle' plugin to retrieve the most up-to-date info about the - * {@link GradleSettings#getLinkedExternalProjectPath() linked gradle project} and update all affected control if necessary - * (like project structure UI, tasks list etc). - * - * @author Denis Zhdanov - * @since 1/23/12 3:48 PM - */ -public class GradleRefreshProjectAction extends AbstractGradleLinkedProjectAction implements DumbAware, AnAction.TransparentUpdate { - - private final Ref myErrorMessage = new Ref(); - - public GradleRefreshProjectAction() { - // TODO den uncomment - //getTemplatePresentation().setText(ExternalSystemBundle.message("gradle.action.refresh.project.text")); - //getTemplatePresentation().setDescription(ExternalSystemBundle.message("gradle.action.refresh.project.description")); - } - - @Override - protected void doUpdate(@NotNull AnActionEvent event, @NotNull Project project, @NotNull String linkedProjectPath) { - String message = myErrorMessage.get(); - if (message != null) { - // TODO den implement -// ExternalProjectStructureTreeModel model = GradleUtil.getProjectStructureTreeModel(event.getDataContext()); -// if (model != null) { -// model.rebuild(); -// } - GradleConfigNotificationManager notificationManager = ServiceManager.getService(project, GradleConfigNotificationManager.class); - notificationManager.processRefreshError(message); - myErrorMessage.set(null); - } - boolean enabled = false; - final ExternalSystemTaskManager taskManager = ServiceManager.getService(project, ExternalSystemTaskManager.class); - if (taskManager != null) { - enabled = !taskManager.hasTaskOfTypeInProgress(ExternalSystemTaskType.RESOLVE_PROJECT); - } - event.getPresentation().setEnabled(enabled); - } - - @Override - protected void doActionPerformed(@NotNull AnActionEvent event, @NotNull final Project project, @NotNull final String linkedProjectPath) { - // We save all documents because there is more than one target 'build.gradle' file in case of multi-module gradle project. - FileDocumentManager.getInstance().saveAllDocuments(); - - GradleConfigNotificationManager notificationManager = ServiceManager.getService(project, GradleConfigNotificationManager.class); - // TODO den implement - //if (!GradleUtil.isGradleAvailable(project)) { - // notificationManager.processUnknownGradleHome(); - // return; - //} - - //myErrorMessage.set(null); - //ExternalSystemUtil.refreshProject(project, GradleConstants.SYSTEM_ID, myErrorMessage); - } -} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/internal/task/ExternalSystemRefreshTasksListTask.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/internal/task/ExternalSystemRefreshTasksListTask.java deleted file mode 100644 index 92e49b901e09..000000000000 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/internal/task/ExternalSystemRefreshTasksListTask.java +++ /dev/null @@ -1,90 +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 org.jetbrains.plugins.gradle.internal.task; - -import com.intellij.openapi.components.ServiceManager; -import com.intellij.openapi.externalSystem.build.ExternalSystemBuildManager; -import com.intellij.openapi.externalSystem.model.ProjectSystemId; -import com.intellij.openapi.externalSystem.model.task.AbstractExternalSystemTask; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskState; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType; -import com.intellij.openapi.externalSystem.service.ExternalSystemFacadeManager; -import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemBuildManager; -import com.intellij.openapi.project.Project; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * @author Denis Zhdanov - * @since 3/15/13 1:20 PM - */ -public class ExternalSystemRefreshTasksListTask extends AbstractExternalSystemTask { - - @NotNull private final String myProjectPath; - - public ExternalSystemRefreshTasksListTask(@NotNull ProjectSystemId externalSystemId, - @NotNull Project project, - @NotNull String projectPath) - { - super(externalSystemId, ExternalSystemTaskType.REFRESH_TASKS_LIST, project, projectPath); - myProjectPath = projectPath; - } - - @Override - protected void doExecute() throws Exception { - final ExternalSystemFacadeManager manager = ServiceManager.getService(ExternalSystemFacadeManager.class); - Project project = getIdeProject(); - RemoteExternalSystemBuildManager buildManager = manager.getFacade(project, myProjectPath, getExternalSystemId()).getBuildManager(); - setState(ExternalSystemTaskState.IN_PROGRESS); - // TODO den implement - //buildManager.listTasks() - //try { - // final Collection descriptors = buildManager.listTasks(getId(), myProjectPath); - // if (descriptors == null || descriptors.isEmpty()) { - // return; - // } - // - // if (project == null) { - // return; - // } - // - // GradleLocalSettings settings = GradleLocalSettings.getInstance(project); - // settings.setAvailableTasks(descriptors); - // - // final GradleTasksModel tasksModel = GradleUtil.getToolWindowElement(GradleTasksModel.class, project, ExternalSystemDataKeys.ALL_TASKS_MODEL); - // if (tasksModel == null) { - // return; - // } - // UIUtil.invokeLaterIfNeeded(new Runnable() { - // @Override - // public void run() { - // tasksModel.setTasks(descriptors); - // } - // }); - //} - //finally { - // setState(GradleTaskState.FINISHED); - //} - } - - @Override - @NotNull - protected String wrapProgressText(@NotNull String text) { - // TODO den implement - return ""; -// return ExternalSystemBundle.message("gradle.tasks.progress.update.text", text); - } -} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/notification/GradleConfigNotificationManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/notification/GradleConfigNotificationManager.java deleted file mode 100644 index 5475cba3cf18..000000000000 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/notification/GradleConfigNotificationManager.java +++ /dev/null @@ -1,117 +0,0 @@ -package org.jetbrains.plugins.gradle.notification; - -import com.intellij.notification.Notification; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectManager; -import com.intellij.ui.EditorNotifications; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.gradle.settings.GradleSettingsListener; -import org.jetbrains.plugins.gradle.config.GradleSettingsListenerAdapter; -import org.jetbrains.plugins.gradle.service.GradleInstallationManager; -import org.jetbrains.plugins.gradle.util.GradleUtil; - -import java.util.concurrent.atomic.AtomicReference; - -/** - * This class is responsible for notifying about the gradle config changes. - *

- * One example use-case is a situation when a user resets gradle home (e.g. project config dir has been (re)moved). We need to - * explain that we can't use the integration until gradle is properly configured then. - *

- * Thread-safe. - * - * @author Denis Zhdanov - * @since 3/21/12 4:04 PM - */ -public class GradleConfigNotificationManager { - - // TODO den implement -// @NotNull private static final NotificationGroup NOTIFICATION_GROUP = NotificationGroup.toolWindowGroup( -// ExternalSystemBundle.message("gradle.notification.group.display.warning"), GradleConstants.TOOL_WINDOW_ID, true -// ); - - @NotNull private final AtomicReference myNotification = new AtomicReference(); - - @NotNull private final GradleInstallationManager myLibraryManager; - @NotNull private final Project myProject; - - public GradleConfigNotificationManager(@NotNull final Project project, @NotNull GradleInstallationManager manager) { - myProject = project; - myLibraryManager = manager; - final GradleSettingsListenerAdapter handler = new GradleSettingsListenerAdapter() { - public void onGradleHomeChange(@Nullable String oldPath, @Nullable String newPath) { - processGradleHomeChange(); - } - }; - project.getMessageBus().connect(project).subscribe(GradleSettingsListener.TOPIC, handler); - ProjectManager.getInstance().getDefaultProject().getMessageBus().connect(project).subscribe(GradleSettingsListener.TOPIC, handler); - } - - private void processGradleHomeChange() { - EditorNotifications.getInstance(myProject).updateAllNotifications(); - - // TODO den implement - //if (!GradleUtil.isGradleAvailable(myProject)) { - // return; - //} - // - //final Notification notification = myNotification.get(); - //if (notification != null && myNotification.compareAndSet(notification, null)) { - // notification.expire(); - //} - } - - public void processRefreshError(@NotNull String message) { - // TODO den implement -// final Notification notification = NOTIFICATION_GROUP.createNotification( -// ExternalSystemBundle.message("gradle.notification.refresh.fail.description", message), -// ExternalSystemBundle.message("gradle.notification.action.show.settings"), -// NotificationType.WARNING, -// new NotificationListener() { -// @Override -// public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) { -// if (event.getEventType() != HyperlinkEvent.EventType.ACTIVATED) { -// return; -// } -// ShowSettingsUtil.getInstance().editConfigurable(myProject, new GradleConfigurable(myProject, myLibraryManager)); -// } -// } -// ); -// -// applyNotification(notification); - } - - public void processUnknownGradleHome() { - // TODO den implement -// final Notification notification = NOTIFICATION_GROUP.createNotification( -// ExternalSystemBundle.message("gradle.notification.gradle.home.undefined.description"), -// ExternalSystemBundle.message("gradle.notification.action.show.settings"), -// NotificationType.WARNING, -// new NotificationListener() { -// @Override -// public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) { -// if (event.getEventType() != HyperlinkEvent.EventType.ACTIVATED) { -// return; -// } -// ShowSettingsUtil.getInstance().editConfigurable(myProject, new GradleConfigurable(myProject, myLibraryManager)); -// } -// } -// ); -// -// applyNotification(notification); - } - - private void applyNotification(@NotNull Notification notification) { - final Notification oldNotification = myNotification.get(); - if (oldNotification != null && myNotification.compareAndSet(oldNotification, null)) { - oldNotification.expire(); - } - if (!myNotification.compareAndSet(null, notification)) { - notification.expire(); - return; - } - - notification.notify(myProject); - } -} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleBuildManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleBuildManager.java deleted file mode 100644 index 8f0e7c26932a..000000000000 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleBuildManager.java +++ /dev/null @@ -1,103 +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 org.jetbrains.plugins.gradle.remote.impl; - -import com.intellij.openapi.externalSystem.build.ExternalSystemBuildManager; -import com.intellij.openapi.externalSystem.model.ExternalSystemException; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskDescriptor; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; -import com.intellij.util.ArrayUtil; -import com.intellij.util.Function; -import org.gradle.tooling.BuildLauncher; -import org.gradle.tooling.ModelBuilder; -import org.gradle.tooling.ProjectConnection; -import org.gradle.tooling.model.DomainObjectSet; -import org.gradle.tooling.model.GradleTask; -import org.gradle.tooling.model.idea.IdeaModule; -import org.gradle.tooling.model.idea.IdeaProject; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.gradle.service.project.GradleExecutionHelper; -import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings; - -import java.util.*; - -/** - * @author Denis Zhdanov - * @since 3/14/13 5:09 PM - */ -public class GradleBuildManager implements ExternalSystemBuildManager { - - private final GradleExecutionHelper myHelper = new GradleExecutionHelper(); - - @Override - public Map> listTasks(@NotNull final ExternalSystemTaskId id, - @NotNull String projectPath, - @Nullable final GradleExecutionSettings settings) - throws ExternalSystemException - { - - // TODO den implement - return Collections.emptyMap(); - //Function> f = - // new Function>() { - // @Nullable - // @Override - // public Collection fun(ProjectConnection connection) { - // ModelBuilder modelBuilder = myHelper.getModelBuilder(id, settings, connection, false); - // IdeaProject project = modelBuilder.get(); - // DomainObjectSet modules = project.getModules(); - // if (modules == null) { - // return Collections.emptyList(); - // } - // Set result = new HashSet(); - // for (IdeaModule module : modules) { - // for (GradleTask task : module.getGradleProject().getTasks()) { - // String name = task.getName(); - // if (name == null || name.trim().isEmpty()) { - // continue; - // } - // String s = name.toLowerCase(); - // if (s.contains("idea") || s.contains("eclipse")) { - // continue; - // } - // result.add(new ExternalSystemTaskDescriptor(name, task.getDescription())); - // } - // } - // return result; - // } - // }; - //return myHelper.execute(projectPath, settings, f); - } - - @Override - public void executeTasks(@NotNull final ExternalSystemTaskId id, - @NotNull final List taskNames, - @NotNull String projectPath, - @Nullable final GradleExecutionSettings settings) throws ExternalSystemException - { - Function f = new Function() { - @Override - public Void fun(ProjectConnection connection) { - BuildLauncher launcher = myHelper.getBuildLauncher(id, connection, settings); - launcher.forTasks(ArrayUtil.toStringArray(taskNames)); - launcher.run(); - return null; - } - }; - myHelper.execute(projectPath, settings, f); - } -} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleTaskManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleTaskManager.java new file mode 100644 index 000000000000..1a5b758f9e74 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleTaskManager.java @@ -0,0 +1,57 @@ +/* + * 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 org.jetbrains.plugins.gradle.remote.impl; + +import com.intellij.openapi.externalSystem.build.ExternalSystemTaskManager; +import com.intellij.openapi.externalSystem.model.ExternalSystemException; +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; +import com.intellij.util.ArrayUtil; +import com.intellij.util.Function; +import org.gradle.tooling.BuildLauncher; +import org.gradle.tooling.ProjectConnection; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.gradle.service.project.GradleExecutionHelper; +import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings; + +import java.util.List; + +/** + * @author Denis Zhdanov + * @since 3/14/13 5:09 PM + */ +public class GradleTaskManager implements ExternalSystemTaskManager { + + private final GradleExecutionHelper myHelper = new GradleExecutionHelper(); + + @Override + public void executeTasks(@NotNull final ExternalSystemTaskId id, + @NotNull final List taskNames, + @NotNull String projectPath, + @Nullable final GradleExecutionSettings settings) throws ExternalSystemException + { + Function f = new Function() { + @Override + public Void fun(ProjectConnection connection) { + BuildLauncher launcher = myHelper.getBuildLauncher(id, connection, settings); + launcher.forTasks(ArrayUtil.toStringArray(taskNames)); + launcher.run(); + return null; + } + }; + myHelper.execute(projectPath, settings, f); + } +} 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 a72bbbfbf7f7..030d2398cdca 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,9 @@ 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; import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.module.StdModuleTypes; @@ -19,6 +21,7 @@ import com.intellij.util.containers.ContainerUtilRt; import org.gradle.tooling.ModelBuilder; import org.gradle.tooling.ProjectConnection; import org.gradle.tooling.model.DomainObjectSet; +import org.gradle.tooling.model.GradleTask; import org.gradle.tooling.model.idea.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -27,10 +30,7 @@ import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings; import org.jetbrains.plugins.gradle.util.GradleConstants; import java.io.File; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * @author Denis Zhdanov @@ -102,6 +102,7 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver> libraries = ExternalSystemApiUtil.getChildren(result, ProjectKeys.LIBRARY); myLibraryNamesMixer.mixNames(libraries); + parseTasks(result, project); return result; } @@ -142,9 +143,11 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver, IdeaModule> previouslyParsedModule = result.get(moduleName); if (previouslyParsedModule != null) { throw new IllegalStateException( @@ -381,4 +384,34 @@ 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()); + for (GradleTask task : module.getGradleProject().getTasks()) { + String name = task.getName(); + if (name == null || name.trim().isEmpty()) { + continue; + } + + String s = name.toLowerCase(); + if (s.contains("idea") || s.contains("eclipse")) { + continue; + } + + taskData.addTask(new ExternalSystemTaskDescriptor(name, task.getDescription())); + } + Collections.sort(taskData.getTasks()); + tasksByModule.put(module.getName(), taskData); + } + + Collection> moduleNodes = ExternalSystemApiUtil.findAll(parent, ProjectKeys.MODULE); + for (DataNode moduleNode : moduleNodes) { + TaskData taskData = tasksByModule.get(moduleNode.getData().getName()); + if (taskData != null && !taskData.getTasks().isEmpty()) { + moduleNode.createChild(ProjectKeys.TASK, taskData); + } + } + } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/GradleToolWindowFactory.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/GradleToolWindowFactory.java index 16a70552b823..7c473cc166ab 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/GradleToolWindowFactory.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/GradleToolWindowFactory.java @@ -1,23 +1,10 @@ package org.jetbrains.plugins.gradle.ui; -import com.intellij.openapi.externalSystem.service.task.ExternalSystemTasksPanel; -import com.intellij.openapi.externalSystem.util.ExternalSystemBundle; -import com.intellij.openapi.project.DumbAware; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.wm.ToolWindow; -import com.intellij.openapi.wm.ToolWindowFactory; -import com.intellij.ui.content.ContentManager; -import com.intellij.ui.content.impl.ContentImpl; -import org.jetbrains.plugins.gradle.util.GradleBundle; +import com.intellij.openapi.externalSystem.service.task.ui.AbstractExternalSystemToolWindowFactory; +import org.jetbrains.plugins.gradle.util.GradleConstants; -public class GradleToolWindowFactory implements ToolWindowFactory, DumbAware { - - @Override - public void createToolWindowContent(final Project project, final ToolWindow toolWindow) { - toolWindow.setTitle(GradleBundle.message("gradle.name")); - ContentManager contentManager = toolWindow.getContentManager(); - String tasksTitle = ExternalSystemBundle.message("tool.window.title.tasks"); - ContentImpl tasksContent = new ContentImpl(new ExternalSystemTasksPanel(), tasksTitle, true); - contentManager.addContent(tasksContent); +public class GradleToolWindowFactory extends AbstractExternalSystemToolWindowFactory { + public GradleToolWindowFactory() { + super(GradleConstants.SYSTEM_ID); } } diff --git a/resources/src/idea/RichPlatformActions.xml b/resources/src/idea/RichPlatformActions.xml index e8c09006be0a..5282df4a9ed7 100644 --- a/resources/src/idea/RichPlatformActions.xml +++ b/resources/src/idea/RichPlatformActions.xml @@ -25,6 +25,7 @@ +