From 676255110bc2d800c1e9a523ba97ea56c27b260b Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Mon, 27 May 2013 12:32:40 +0400 Subject: [PATCH] IDEA-104500 Gradle: Allow to reuse common logic for other external systems 1. ExternalSystemProjectResolver and ExternalSystemTaskManager are explicitly provided by ExternalSystemTaskNotificationListener (used for the processing output and status change notification); 2. ExternalSystemSettingsControl.disposeUIResources() and ExternalSystemSettingsControl.showUi() implementations are switched to reflection-based processing in order to remove boilerplate code; 3. Introduced external system tasks (with concrete gradle tasks implementation); --- .../i18n/ExternalSystemBundle.properties | 11 +- .../externalSystem/ExternalSystemManager.java | 2 +- .../externalSystem/ExternalSystemUiAware.java | 10 +- .../externalSystem/model/ProjectSystemId.java | 5 + .../ExternalSystemExecutionSettings.java | 10 - ...xternalSystemTaskNotificationListener.java | 11 +- ...SystemTaskNotificationListenerAdapter.java | 6 + .../ExternalSystemProjectResolver.java | 5 +- .../ExternalSystemTaskManager.java | 10 +- .../util/ExternalSystemApiUtil.java | 47 ++-- .../util/ExternalSystemConstants.java | 4 + .../action/AbstractExternalTaskAction.java | 100 +++++++++ .../action/RunExternalTaskAction.java | 36 +++ .../model/ExternalSystemDataKeys.java | 2 + .../ExternalSystemTaskExecutionSettings.java | 87 ++++++++ .../service/ExternalSystemFacadeImpl.java | 28 ++- .../service/ExternalSystemFacadeManager.java | 2 +- ...ctExternalSystemTaskConfigurationType.java | 86 ++++++++ .../ExternalSystemRunConfiguration.java | 169 ++++++++++++++ .../ExternalSystemRunConfigurationEditor.java | 48 ++++ .../execution/ExternalSystemTaskRunner.java | 63 ++++++ .../ExternalSystemTaskSettingsControl.java | 207 ++++++++++++++++++ .../internal/AbstractExternalSystemTask.java | 11 +- .../ExternalSystemExecuteTaskTask.java | 80 +++++-- .../ExternalSystemProcessingManager.java | 5 + .../AbstractExternalProjectImportBuilder.java | 2 +- .../AbstractRemoteExternalSystemService.java | 13 +- ...SystemProgressNotificationManagerImpl.java | 11 + ...rnalSystemProgressNotificationManager.java | 6 + ...moteExternalSystemProjectResolverImpl.java | 8 +- .../RemoteExternalSystemTaskManager.java | 10 +- .../RemoteExternalSystemTaskManagerImpl.java | 7 +- .../ExternalSystemTaskManagerWrapper.java | 5 +- ...bstractExternalProjectSettingsControl.java | 15 +- .../AbstractExternalSystemConfigurable.java | 31 ++- ...stractImportFromExternalSystemControl.java | 41 ++-- .../task/AbstractToolWindowService.java | 23 +- .../task/ui/ExternalSystemTasksPanel.java | 29 ++- .../task/ui/ExternalSystemTasksTree.java | 20 +- .../ui/DefaultExternalSystemUiAware.java | 16 +- .../service/ui/ExternalProjectPathField.java | 121 ++++++++++ .../ui/ExternalProjectPathLookupElement.java | 68 ++++++ .../ExternalSystemSettingsControl.java} | 4 +- .../util/ExternalSystemUiUtil.java | 31 +++ .../util/ExternalSystemUtil.java | 11 +- .../externalSystem/util/PaintAwarePanel.java | 2 +- .../util/TextFieldCompletionProvider.java | 23 +- .../src/META-INF/ExternalSystemExtensions.xml | 3 + .../src/idea/ExternalSystemActions.xml | 9 + plugins/gradle/src/META-INF/plugin.xml | 1 + .../plugins/gradle/GradleManager.java | 19 +- .../gradle/remote/impl/GradleTaskManager.java | 13 +- .../GradleExternalTaskConfigurationType.java | 30 +++ .../project/GradleExecutionHelper.java | 29 +-- .../project/GradleProjectResolver.java | 11 +- .../gradle/service/project/OutputWrapper.java | 36 +++ .../service/settings/GradleConfigurable.java | 6 +- .../GradleProjectSettingsControl.java | 18 -- .../settings/GradleSystemSettingsControl.java | 29 ++- .../settings/ImportFromGradleControl.java | 6 +- .../plugins/gradle/util/GradleUtil.java | 13 ++ 61 files changed, 1542 insertions(+), 223 deletions(-) rename platform/external-system-api/src/com/intellij/openapi/externalSystem/{build => task}/ExternalSystemTaskManager.java (71%) create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/AbstractExternalTaskAction.java create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/RunExternalTaskAction.java create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/execution/ExternalSystemTaskExecutionSettings.java create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/AbstractExternalSystemTaskConfigurationType.java create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfigurationEditor.java create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskRunner.java create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskSettingsControl.java create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectPathField.java create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectPathLookupElement.java rename platform/external-system-impl/src/com/intellij/openapi/externalSystem/{service/settings/ExternalSettingsControl.java => util/ExternalSystemSettingsControl.java} (95%) create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/service/execution/GradleExternalTaskConfigurationType.java create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/OutputWrapper.java diff --git a/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties b/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties index 7cd2a7c64831..b2c613b073da 100644 --- a/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties +++ b/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties @@ -32,7 +32,16 @@ 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 +action.task.run.text=Run +action.task.run.description=Run selected task # 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 +notification.action.show.settings={0} settings + +# Execution +run.configuration.description={0} build +run.configuration.settings.label.project={0} project: +run.configuration.settings.label.tasks=Tasks: +run.configuration.settings.label.vmoptions=VM options: +run.configuration.settings.caption.vmoptions=VM options: \ No newline at end of file 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 952af8f8be34..3d8294e8fb61 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.ExternalSystemTaskManager; +import com.intellij.openapi.externalSystem.task.ExternalSystemTaskManager; import com.intellij.openapi.externalSystem.model.ProjectSystemId; import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings; import com.intellij.openapi.externalSystem.service.ParametersEnhancer; diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemUiAware.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemUiAware.java index a00badaa9b5e..e503e8314e6e 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemUiAware.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemUiAware.java @@ -15,6 +15,8 @@ */ package com.intellij.openapi.externalSystem; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -24,7 +26,13 @@ import javax.swing.*; * @since 5/15/13 12:37 PM */ public interface ExternalSystemUiAware { - + + @NotNull + String getProjectRepresentationName(@NotNull String targetProjectPath, @Nullable String rootProjectPath); + + @Nullable + FileChooserDescriptor getExternalProjectConfigDescriptor(); + @Nullable Icon getProjectIcon(); 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 5b52ddff98b1..e140fc80bafa 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 @@ -47,6 +47,11 @@ public class ProjectSystemId implements Serializable { return myId.equals(owner.myId); } + @NotNull + public String getId() { + return myId; + } + @NotNull public String getReadableName() { return myReadableName; diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/settings/ExternalSystemExecutionSettings.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/settings/ExternalSystemExecutionSettings.java index d8376e508be5..5c59120ef33d 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/settings/ExternalSystemExecutionSettings.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/settings/ExternalSystemExecutionSettings.java @@ -3,7 +3,6 @@ package com.intellij.openapi.externalSystem.model.settings; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener; import com.intellij.util.SystemProperties; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.io.Serializable; import java.util.concurrent.atomic.AtomicBoolean; @@ -61,15 +60,6 @@ public class ExternalSystemExecutionSettings implements Serializable { myVerboseProcessing.set(verboseProcessing); } - @Nullable - public ExternalSystemTaskNotificationListener getNotificationListener() { - return myNotificationListener.get(); - } - - public void setNotificationListener(@NotNull ExternalSystemTaskNotificationListener listener) { - myNotificationListener.set(listener); - } - @Override public int hashCode() { int result = (int)(myRemoteProcessIdleTtlInMs.get() ^ (myRemoteProcessIdleTtlInMs.get() >>> 32)); diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskNotificationListener.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskNotificationListener.java index 8e3c062a1038..3c747fbe4372 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskNotificationListener.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskNotificationListener.java @@ -36,7 +36,16 @@ public interface ExternalSystemTaskNotificationListener { * {@link ExternalSystemTaskNotificationEvent#getId() target task} */ void onStatusChange(@NotNull ExternalSystemTaskNotificationEvent event); - + + /** + * Notifies about text written to stdout/stderr during the task execution + * + * @param id id of the task being executed + * @param text text produced by external system during the target task execution + * @param stdOut flag which identifies output type (stdout or stderr) + */ + void onTaskOutput(@NotNull ExternalSystemTaskId id, @NotNull String text, boolean stdOut); + /** * Notifies that task with the given id is finished. * diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskNotificationListenerAdapter.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskNotificationListenerAdapter.java index b9ad865b5344..30978f1fb329 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskNotificationListenerAdapter.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskNotificationListenerAdapter.java @@ -8,6 +8,8 @@ import org.jetbrains.annotations.NotNull; */ public abstract class ExternalSystemTaskNotificationListenerAdapter implements ExternalSystemTaskNotificationListener { + @NotNull public static final ExternalSystemTaskNotificationListener NULL_OBJECT = new ExternalSystemTaskNotificationListenerAdapter() { }; + @Override public void onQueued(@NotNull ExternalSystemTaskId id) { } @@ -20,6 +22,10 @@ public abstract class ExternalSystemTaskNotificationListenerAdapter implements E public void onStatusChange(@NotNull ExternalSystemTaskNotificationEvent event) { } + @Override + public void onTaskOutput(@NotNull ExternalSystemTaskId id, @NotNull String text, boolean stdOut) { + } + @Override public void onEnd(@NotNull ExternalSystemTaskId id) { } diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/service/project/ExternalSystemProjectResolver.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/service/project/ExternalSystemProjectResolver.java index 18753d475801..b29b95137c73 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/service/project/ExternalSystemProjectResolver.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/service/project/ExternalSystemProjectResolver.java @@ -20,6 +20,7 @@ import com.intellij.openapi.externalSystem.model.ExternalSystemException; import com.intellij.openapi.externalSystem.model.project.ProjectData; import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -39,6 +40,7 @@ public interface ExternalSystemProjectResolvernull as indication that no specific settings are required + * @param listener callback to be notified about the execution * @return object-level representation of the target external system project; * null if it's not possible to resolve the project due to the objective reasons * @throws ExternalSystemException in case when unexpected exception occurs during project info construction @@ -49,6 +51,7 @@ public interface ExternalSystemProjectResolver resolveProjectInfo(@NotNull ExternalSystemTaskId id, @NotNull String projectPath, boolean downloadLibraries, - @Nullable S settings) + @Nullable S settings, + @NotNull ExternalSystemTaskNotificationListener listener) throws ExternalSystemException, IllegalArgumentException, IllegalStateException; } diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/build/ExternalSystemTaskManager.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/task/ExternalSystemTaskManager.java similarity index 71% rename from platform/external-system-api/src/com/intellij/openapi/externalSystem/build/ExternalSystemTaskManager.java rename to platform/external-system-api/src/com/intellij/openapi/externalSystem/task/ExternalSystemTaskManager.java index a5e3eb7e6131..a8e04dcb8e6c 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/build/ExternalSystemTaskManager.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/task/ExternalSystemTaskManager.java @@ -13,11 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.openapi.externalSystem.build; +package com.intellij.openapi.externalSystem.task; import com.intellij.openapi.externalSystem.model.ExternalSystemException; import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -31,6 +32,11 @@ import java.util.List; */ public interface ExternalSystemTaskManager { - void executeTasks(@NotNull ExternalSystemTaskId id, @NotNull List taskNames, @NotNull String projectPath, @Nullable S settings) + void executeTasks(@NotNull ExternalSystemTaskId id, + @NotNull List taskNames, + @NotNull String projectPath, + @Nullable S settings, + @Nullable String vmOptions, + @NotNull ExternalSystemTaskNotificationListener listener) throws ExternalSystemException; } 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 222339e7f717..5263f813b18b 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 @@ -15,6 +15,7 @@ */ package com.intellij.openapi.externalSystem.util; +import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; @@ -52,6 +53,7 @@ import java.util.regex.Pattern; public class ExternalSystemApiUtil { private static final Logger LOG = Logger.getInstance("#" + ExternalSystemApiUtil.class.getName()); + private static final String LAST_USED_PROJECT_PATH_PREFIX = "LAST_EXTERNAL_PROJECT_PATH_"; @NotNull public static final String PATH_SEPARATOR = "/"; @@ -210,21 +212,20 @@ public class ExternalSystemApiUtil { } @NotNull - public static Map>> groupBy(@NotNull Collection> nodes, - @NotNull Function, K> grouper) - { - Map>> result = ContainerUtilRt.newHashMap(); - for (DataNode data : nodes) { + public static Map> groupBy(@NotNull Collection nodes, @NotNull Function grouper) { + Map> result = ContainerUtilRt.newHashMap(); + for (V data : nodes) { K key = grouper.fun(data); if (key == null) { LOG.warn(String.format( "Skipping entry '%s' during grouping. Reason: it's not possible to build a grouping key with grouping strategy '%s'. " + "Given entries: %s", - data, grouper.getClass(), nodes - )); + data, + grouper.getClass(), + nodes)); continue; } - List> grouped = result.get(key); + List grouped = result.get(key); if (grouped == null) { result.put(key, grouped = ContainerUtilRt.newArrayList()); } @@ -287,17 +288,12 @@ public class ExternalSystemApiUtil { return result == null ? Collections.>emptyList() : result; } - @NotNull - public static String toReadableName(@NotNull ProjectSystemId id) { - return StringUtil.capitalize(id.toString().toLowerCase()); - } - public static void executeProjectChangeAction(@NotNull final Runnable task) { executeProjectChangeAction(false, task); } public static void executeProjectChangeAction(boolean synchronous, @NotNull final Runnable task) { - Runnable wrappedTask = new Runnable() { + executeOnEdt(synchronous, new Runnable() { public void run() { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override @@ -306,18 +302,20 @@ public class ExternalSystemApiUtil { } }); } - }; - + }); + } + + public static void executeOnEdt(boolean synchronous, @NotNull Runnable task) { if (synchronous) { if (ApplicationManager.getApplication().isDispatchThread()) { - wrappedTask.run(); + task.run(); } else { - UIUtil.invokeAndWaitIfNeeded(wrappedTask); + UIUtil.invokeAndWaitIfNeeded(task); } } else { - UIUtil.invokeLaterIfNeeded(wrappedTask); + UIUtil.invokeLaterIfNeeded(task); } } @@ -360,4 +358,15 @@ public class ExternalSystemApiUtil { public static boolean isNewProjectConstruction() { return ProjectManager.getInstance().getOpenProjects().length == 0; } + + @NotNull + public static String getLastUsedExternalProjectPath(@NotNull ProjectSystemId externalSystemId) { + return PropertiesComponent.getInstance().getValue(LAST_USED_PROJECT_PATH_PREFIX + externalSystemId.getReadableName(), ""); + } + + public static void storeLastUsedExternalProjectPath(@Nullable String path, @NotNull ProjectSystemId externalSystemId) { + if (path != null) { + PropertiesComponent.getInstance().setValue(LAST_USED_PROJECT_PATH_PREFIX + externalSystemId.getReadableName(), path); + } + } } 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 1be2f1553b2c..1d7415d46cb3 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 @@ -28,8 +28,10 @@ public class ExternalSystemConstants { @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 TREE_ACTIONS_GROUP_ID = "ExternalSystem.Tree.Context"; @NonNls @NotNull public static final String TOOL_WINDOW_PLACE = "ExternalSystem.ToolWindow"; + @NonNls @NotNull public static final String TREE_PLACE = "ExternalSystem.Tree"; public static final char PATH_SEPARATOR = '/'; @@ -37,4 +39,6 @@ public class ExternalSystemConstants { public static final int BUILTIN_SERVICE_ORDER = 42; public static final int BUILTIN_TOOL_WINDOW_SERVICE_ORDER = 62; public static final int UNORDERED = 1000; + + public static final int TEXT_FIELD_WIDTH_IN_COLUMNS = 20; } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/AbstractExternalTaskAction.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/AbstractExternalTaskAction.java new file mode 100644 index 000000000000..027c1d464147 --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/AbstractExternalTaskAction.java @@ -0,0 +1,100 @@ +package com.intellij.openapi.externalSystem.action; + +import com.intellij.execution.ui.ConsoleViewContentType; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.application.ApplicationManager; +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.serialization.ExternalTaskPojo; +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListenerAdapter; +import com.intellij.openapi.externalSystem.service.internal.ExternalSystemExecuteTaskTask; +import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; +import com.intellij.openapi.externalSystem.util.ExternalSystemUtil; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; +import com.intellij.util.containers.ContainerUtilRt; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Denis Zhdanov + * @since 22.05.13 13:04 + */ +public abstract class AbstractExternalTaskAction extends AnAction implements DumbAware { + + @Override + public void update(AnActionEvent e) { + e.getPresentation().setVisible(getSelectedTask(e.getDataContext()) != null); + } + + @Override + public void actionPerformed(AnActionEvent e) { + Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + if (project == null) { + return; + } + + ProjectSystemId externalSystemId = ExternalSystemDataKeys.EXTERNAL_SYSTEM_ID.getData(e.getDataContext()); + if (externalSystemId == null) { + return; + } + + ExternalTaskPojo taskPojo = getSelectedTask(e.getDataContext(), externalSystemId); + if (taskPojo == null) { + return; + } + + ExternalSystemManager manager = ExternalSystemApiUtil.getManager(externalSystemId); + if (manager == null) { + return; + } + + final ExternalSystemExecuteTaskTask task + = new ExternalSystemExecuteTaskTask(externalSystemId, project, ContainerUtilRt.newArrayList(taskPojo), getVmOptions()); + final boolean interestedInTaskOutput = prepareForOutput(); + ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + @Override + public void run() { + if (interestedInTaskOutput) { + task.execute(new ExternalSystemTaskNotificationListenerAdapter() { + @Override + public void onTaskOutput(@NotNull ExternalSystemTaskId id, @NotNull String text, boolean stdOut) { + onOutput(text, stdOut ? ConsoleViewContentType.NORMAL_OUTPUT : ConsoleViewContentType.ERROR_OUTPUT); + } + }); + } + else { + task.execute(); + } + } + }); + } + + @Nullable + protected abstract String getVmOptions(); + + // TODO den add doc + protected abstract boolean prepareForOutput(); + + protected abstract void onOutput(@NotNull String text, @NotNull ConsoleViewContentType type); + + @Nullable + private static ExternalTaskPojo getSelectedTask(@NotNull DataContext dataContext) { + return getSelectedTask(dataContext, ExternalSystemDataKeys.EXTERNAL_SYSTEM_ID.getData(dataContext)); + } + + private static ExternalTaskPojo getSelectedTask(@NotNull DataContext dataContext, @Nullable ProjectSystemId externalSystemId) { + if (externalSystemId == null) { + return null; + } + return ExternalSystemUtil.getToolWindowElement(ExternalTaskPojo.class, + dataContext, + ExternalSystemDataKeys.SELECTED_TASK, + externalSystemId); + } +} diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/RunExternalTaskAction.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/RunExternalTaskAction.java new file mode 100644 index 000000000000..23ecb8fce188 --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/RunExternalTaskAction.java @@ -0,0 +1,36 @@ +package com.intellij.openapi.externalSystem.action; + +import com.intellij.execution.ui.ConsoleViewContentType; +import com.intellij.openapi.externalSystem.util.ExternalSystemBundle; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Denis Zhdanov + * @since 22.05.13 12:57 + */ +public class RunExternalTaskAction extends AbstractExternalTaskAction { + + public RunExternalTaskAction() { + getTemplatePresentation().setText(ExternalSystemBundle.message("action.task.run.text")); + getTemplatePresentation().setDescription(ExternalSystemBundle.message("action.task.run.description")); + } + + @Nullable + @Override + protected String getVmOptions() { + return null; + } + + @Override + protected boolean prepareForOutput() { + //RunnerAndConfigurationSettings settings = new RunnerAndConfigurationSettingsImpl(); + return true; + } + + @Override + protected void onOutput(@NotNull String text, @NotNull ConsoleViewContentType type) { + // TODO den remove + System.out.print(text); + } +} 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 6f185872c109..0f79532fd9e7 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 @@ -17,6 +17,7 @@ package com.intellij.openapi.externalSystem.model; import com.intellij.notification.NotificationGroup; import com.intellij.openapi.actionSystem.DataKey; +import com.intellij.openapi.externalSystem.model.serialization.ExternalTaskPojo; import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTreeModel; import org.jetbrains.annotations.NotNull; @@ -29,6 +30,7 @@ public class ExternalSystemDataKeys { @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"); + @NotNull public static final DataKey SELECTED_TASK = DataKey.create("external.system.selected.task"); private ExternalSystemDataKeys() { } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/execution/ExternalSystemTaskExecutionSettings.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/execution/ExternalSystemTaskExecutionSettings.java new file mode 100644 index 000000000000..66b3ef91ffac --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/execution/ExternalSystemTaskExecutionSettings.java @@ -0,0 +1,87 @@ +/* + * 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.execution; + +import com.intellij.openapi.externalSystem.model.ProjectSystemId; +import com.intellij.util.containers.ContainerUtilRt; +import com.intellij.util.xmlb.annotations.Tag; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * @author Denis Zhdanov + * @since 24.05.13 12:20 + */ +@Tag("ExternalSystemSettings") +public class ExternalSystemTaskExecutionSettings implements Cloneable { + + @NotNull @NonNls public static final String TAG_NAME = "ExternalSystemSettings"; + + private List myTaskNames = ContainerUtilRt.newArrayList(); + + private String myExternalSystemIdString; + private String myExternalProjectPath; + private String myVmOptions; + + public String getExternalSystemIdString() { + return myExternalSystemIdString; + } + + public ProjectSystemId getExternalSystemId() { + return new ProjectSystemId(myExternalSystemIdString); + } + + public void setExternalSystemIdString(String externalSystemIdString) { + myExternalSystemIdString = externalSystemIdString; + } + + public String getExternalProjectPath() { + return myExternalProjectPath; + } + + public void setExternalProjectPath(String externalProjectPath) { + myExternalProjectPath = externalProjectPath; + } + + public String getVmOptions() { + return myVmOptions; + } + + public void setVmOptions(String vmOptions) { + myVmOptions = vmOptions; + } + + public List getTaskNames() { + return myTaskNames; + } + + public void setTaskNames(List taskNames) { + myTaskNames.clear(); + myTaskNames.addAll(taskNames); + } + + @Override + public ExternalSystemTaskExecutionSettings clone() { + ExternalSystemTaskExecutionSettings result = new ExternalSystemTaskExecutionSettings(); + result.setExternalSystemIdString(getExternalSystemIdString()); + result.setExternalProjectPath(getExternalProjectPath()); + result.setVmOptions(getVmOptions()); + result.setTaskNames(ContainerUtilRt.newArrayList(getTaskNames())); + return result; + } +} 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 bacd1722fdd3..050dff9b9faa 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,14 +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.task.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.model.task.*; import com.intellij.openapi.externalSystem.service.project.ExternalSystemProjectResolver; import com.intellij.openapi.externalSystem.service.remote.*; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener; import com.intellij.util.Alarm; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.ContainerUtilRt; @@ -43,8 +40,8 @@ public class ExternalSystemFacadeImpl private final Alarm myShutdownAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); private final AtomicInteger myCallsInProgressNumber = new AtomicInteger(); - private final AtomicReference myNotificationListener - = new AtomicReference(); + private final AtomicReference myNotificationListener = + new AtomicReference(new ExternalSystemTaskNotificationListenerAdapter() {}); @NotNull private final RemoteExternalSystemProjectResolverImpl myProjectResolver; @NotNull private final RemoteExternalSystemTaskManagerImpl myTaskManager; @@ -62,15 +59,14 @@ public class ExternalSystemFacadeImpl public static void main(String[] args) throws Exception { if (args.length < 1) { throw new IllegalArgumentException( - "Can't create external system facade. Reason: given arguments don't contain information about external system resolver to use" - ); + "Can't create external system facade. Reason: given arguments don't contain information about external system resolver to use"); } final Class> resolverClass = (Class>)Class.forName(args[0]); if (!ExternalSystemProjectResolver.class.isAssignableFrom(resolverClass)) { throw new IllegalArgumentException(String.format( "Can't create external system facade. Reason: given external system resolver class (%s) must be IS-A '%s'", - resolverClass, ExternalSystemProjectResolver.class - )); + resolverClass, + ExternalSystemProjectResolver.class)); } if (args.length < 2) { @@ -292,6 +288,16 @@ public class ExternalSystemFacadeImpl } } + @Override + public void onTaskOutput(@NotNull ExternalSystemTaskId id, @NotNull String text, boolean stdOut) { + try { + myManager.onTaskOutput(id, text, stdOut); + } + catch (RemoteException e) { + // Ignore + } + } + @Override public void onEnd(@NotNull ExternalSystemTaskId id) { try { 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 32ea5f65464c..23fc785c76bb 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 @@ -186,8 +186,8 @@ public class ExternalSystemFacadeManager { return params; } - @NotNull @Override + @NotNull public ExecutionResult execute(@NotNull Executor executor, @NotNull ProgramRunner runner) throws ExecutionException { ProcessHandler processHandler = startProcess(); return new DefaultExecutionResult(null, processHandler, AnAction.EMPTY_ARRAY); diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/AbstractExternalSystemTaskConfigurationType.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/AbstractExternalSystemTaskConfigurationType.java new file mode 100644 index 000000000000..a6538f8a8dba --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/AbstractExternalSystemTaskConfigurationType.java @@ -0,0 +1,86 @@ +package com.intellij.openapi.externalSystem.service.execution; + +import com.intellij.execution.configurations.ConfigurationFactory; +import com.intellij.execution.configurations.ConfigurationType; +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.openapi.externalSystem.ExternalSystemManager; +import com.intellij.openapi.externalSystem.ExternalSystemUiAware; +import com.intellij.openapi.externalSystem.model.ProjectSystemId; +import com.intellij.openapi.externalSystem.service.ui.DefaultExternalSystemUiAware; +import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; +import com.intellij.openapi.externalSystem.util.ExternalSystemBundle; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.NotNullLazyValue; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; + +/** + * // TODO den add doc + * + * @author Denis Zhdanov + * @since 23.05.13 17:43 + */ +public abstract class AbstractExternalSystemTaskConfigurationType implements ConfigurationType { + + @NotNull private final ProjectSystemId myExternalSystemId; + @NotNull private final ConfigurationFactory[] myFactories = new ConfigurationFactory[1]; + + @NotNull private final NotNullLazyValue myIcon = new NotNullLazyValue() { + @NotNull + @Override + protected Icon compute() { + ExternalSystemManager manager = ExternalSystemApiUtil.getManager(myExternalSystemId); + Icon result = null; + if (manager instanceof ExternalSystemUiAware) { + result = ((ExternalSystemUiAware)manager).getProjectIcon(); + } + return result == null ? DefaultExternalSystemUiAware.INSTANCE.getTaskIcon() : result; + } + }; + + protected AbstractExternalSystemTaskConfigurationType(@NotNull final ProjectSystemId externalSystemId) { + myExternalSystemId = externalSystemId; + myFactories[0] = new ConfigurationFactory(this) { + @Override + public RunConfiguration createTemplateConfiguration(Project project) { + return doCreateConfiguration(myExternalSystemId, project, this, ""); + } + }; + } + + @NotNull + protected ExternalSystemRunConfiguration doCreateConfiguration(@NotNull ProjectSystemId externalSystemId, + @NotNull Project project, + @NotNull ConfigurationFactory factory, + @NotNull String name) + { + return new ExternalSystemRunConfiguration(externalSystemId, project, factory, name); + } + + @Override + public String getDisplayName() { + return myExternalSystemId.getReadableName(); + } + + @Override + public String getConfigurationTypeDescription() { + return ExternalSystemBundle.message("run.configuration.description", myExternalSystemId.getReadableName()); + } + + @Override + public Icon getIcon() { + return myIcon.getValue(); + } + + @NotNull + @Override + public String getId() { + return myExternalSystemId.getReadableName() + "RunConfiguration"; + } + + @Override + public ConfigurationFactory[] getConfigurationFactories() { + return myFactories; + } +} diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java new file mode 100644 index 000000000000..6401d55a4447 --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java @@ -0,0 +1,169 @@ +package com.intellij.openapi.externalSystem.service.execution; + +import com.intellij.execution.DefaultExecutionResult; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ExecutionResult; +import com.intellij.execution.Executor; +import com.intellij.execution.configurations.*; +import com.intellij.execution.filters.TextConsoleBuilderImpl; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.process.ProcessOutputTypes; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.runners.ProgramRunner; +import com.intellij.execution.ui.ConsoleView; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.externalSystem.model.ProjectSystemId; +import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings; +import com.intellij.openapi.externalSystem.model.serialization.ExternalTaskPojo; +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListenerAdapter; +import com.intellij.openapi.externalSystem.service.internal.ExternalSystemExecuteTaskTask; +import com.intellij.openapi.options.SettingsEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.util.containers.ContainerUtilRt; +import com.intellij.util.xmlb.XmlSerializer; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.OutputStream; +import java.util.List; + +/** + * @author Denis Zhdanov + * @since 23.05.13 18:30 + */ +public class ExternalSystemRunConfiguration extends RunConfigurationBase { + + private ExternalSystemTaskExecutionSettings mySettings = new ExternalSystemTaskExecutionSettings(); + + public ExternalSystemRunConfiguration(@NotNull ProjectSystemId externalSystemId, + Project project, + ConfigurationFactory factory, + String name) + { + super(project, factory, name); + mySettings.setExternalSystemIdString(externalSystemId.getId()); + } + + @Override + public RunConfiguration clone() { + ExternalSystemRunConfiguration result = (ExternalSystemRunConfiguration)super.clone(); + result.mySettings = mySettings.clone(); + return result; + } + + @Override + public void readExternal(Element element) throws InvalidDataException { + super.readExternal(element); + Element e = element.getChild(ExternalSystemTaskExecutionSettings.TAG_NAME); + if (e != null) { + mySettings = XmlSerializer.deserialize(e, ExternalSystemTaskExecutionSettings.class); + } + } + + @Override + public void writeExternal(Element element) throws WriteExternalException { + super.writeExternal(element); + element.addContent(XmlSerializer.serialize(mySettings)); + } + + @NotNull + public ExternalSystemTaskExecutionSettings getSettings() { + return mySettings; + } + + @Override + public SettingsEditor getConfigurationEditor() { + return new ExternalSystemRunConfigurationEditor(getProject(), mySettings.getExternalSystemId()); + } + + @Nullable + @Override + public JDOMExternalizable createRunnerSettings(ConfigurationInfoProvider provider) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Nullable + @Override + public SettingsEditor getRunnerSettingsEditor(ProgramRunner runner) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Nullable + @Override + public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment env) throws ExecutionException { + return new RunnableState() { + @Nullable + @Override + public ExecutionResult execute(Executor executor, @NotNull ProgramRunner runner) throws ExecutionException { + ConsoleView console = new TextConsoleBuilderImpl(getProject()).getConsole(); + final ProcessHandler processHandler = new ProcessHandler() { + @Override + protected void destroyProcessImpl() { + } + + @Override + protected void detachProcessImpl() { + notifyProcessDetached(); + } + + @Override + public boolean detachIsDefault() { + return true; + } + + @Nullable + @Override + public OutputStream getProcessInput() { + return null; + } + }; + console.attachToProcess(processHandler); + List tasks = ContainerUtilRt.newArrayList(); + for (String taskName : mySettings.getTaskNames()) { + tasks.add(new ExternalTaskPojo(taskName, mySettings.getExternalProjectPath(), null)); + } + final ExternalSystemExecuteTaskTask task = new ExternalSystemExecuteTaskTask(mySettings.getExternalSystemId(), + getProject(), + tasks, + mySettings.getVmOptions()); + ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + @Override + public void run() { + task.execute(new ExternalSystemTaskNotificationListenerAdapter() { + @Override + public void onTaskOutput(@NotNull ExternalSystemTaskId id, @NotNull String text, boolean stdOut) { + processHandler.notifyTextAvailable(text, stdOut ? ProcessOutputTypes.STDOUT : ProcessOutputTypes.STDERR); + } + + @Override + public void onEnd(@NotNull ExternalSystemTaskId id) { + processHandler.destroyProcess(); + } + }); + } + }); + return new DefaultExecutionResult(console, processHandler); + } + + @Override + public RunnerSettings getRunnerSettings() { + return null; + } + + @Override + public ConfigurationPerRunnerSettings getConfigurationSettings() { + return null; + } + }; + } + + @Override + public void checkConfiguration() throws RuntimeConfigurationException { + //To change body of implemented methods use File | Settings | File Templates. + } +} diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfigurationEditor.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfigurationEditor.java new file mode 100644 index 000000000000..7769c9011482 --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfigurationEditor.java @@ -0,0 +1,48 @@ +package com.intellij.openapi.externalSystem.service.execution; + +import com.intellij.openapi.externalSystem.model.ProjectSystemId; +import com.intellij.openapi.externalSystem.util.PaintAwarePanel; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.options.SettingsEditor; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Denis Zhdanov + * @since 23.05.13 18:34 + */ +public class ExternalSystemRunConfigurationEditor extends SettingsEditor { + + @NotNull private final ExternalSystemTaskSettingsControl myControl; + + public ExternalSystemRunConfigurationEditor(@NotNull Project project, @NotNull ProjectSystemId externalSystemId) { + myControl = new ExternalSystemTaskSettingsControl(project, externalSystemId); + } + + @Override + protected void resetEditorFrom(ExternalSystemRunConfiguration s) { + myControl.setOriginalSettings(s.getSettings()); + myControl.reset(); + } + + @Override + protected void applyEditorTo(ExternalSystemRunConfiguration s) throws ConfigurationException { + myControl.apply(s.getSettings()); + } + + @NotNull + @Override + protected JComponent createEditor() { + PaintAwarePanel result = new PaintAwarePanel(new GridBagLayout()); + myControl.fillUi(result, 0); + return result; + } + + @Override + protected void disposeEditor() { + myControl.disposeUIResources(); + } +} diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskRunner.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskRunner.java new file mode 100644 index 000000000000..1c8dfab2074f --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskRunner.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.execution; + +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ExecutionResult; +import com.intellij.execution.Executor; +import com.intellij.execution.configurations.RunProfile; +import com.intellij.execution.configurations.RunProfileState; +import com.intellij.execution.executors.DefaultRunExecutor; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.runners.GenericProgramRunner; +import com.intellij.execution.runners.RunContentBuilder; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Denis Zhdanov + * @since 5/26/13 11:20 PM + */ +public class ExternalSystemTaskRunner extends GenericProgramRunner { + + @NotNull + @Override + public String getRunnerId() { + return "ExternalSystemTaskRunner"; + } + + @Override + public boolean canRun(@NotNull String executorId, @NotNull RunProfile profile) { + return DefaultRunExecutor.EXECUTOR_ID.equals(executorId) && profile instanceof ExternalSystemRunConfiguration; + } + + @Nullable + @Override + protected RunContentDescriptor doExecute(Project project, + Executor executor, + RunProfileState state, + RunContentDescriptor contentToReuse, + ExecutionEnvironment env) throws ExecutionException + { + ExecutionResult executionResult = state.execute(executor, this); + if (executionResult == null) return null; + + final RunContentBuilder contentBuilder = new RunContentBuilder(project, this, executor, executionResult, env); + return contentBuilder.showRunContent(contentToReuse); + } +} diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskSettingsControl.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskSettingsControl.java new file mode 100644 index 000000000000..c36d1a623711 --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskSettingsControl.java @@ -0,0 +1,207 @@ +/* + * 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.execution; + +import com.intellij.openapi.editor.Editor; +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.execution.ExternalSystemTaskExecutionSettings; +import com.intellij.openapi.externalSystem.service.ui.ExternalProjectPathField; +import com.intellij.openapi.externalSystem.util.*; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.RawCommandLineEditor; +import com.intellij.ui.components.JBLabel; +import com.intellij.ui.components.JBTextField; +import com.intellij.util.Consumer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.awt.*; + +import static com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil.normalizePath; + +/** + * @author Denis Zhdanov + * @since 23.05.13 18:46 + */ +public class ExternalSystemTaskSettingsControl implements ExternalSystemSettingsControl { + + @NotNull private final ProjectSystemId myExternalSystemId; + @NotNull private final Project myProject; + + @SuppressWarnings("FieldCanBeLocal") // Used via reflection at showUi() and disposeResources() + private JBLabel myProjectPathLabel; + private ExternalProjectPathField myProjectPathField; + @SuppressWarnings("FieldCanBeLocal") // Used via reflection at showUi() and disposeResources() + private JBLabel myTasksLabel; + private JBTextField myTasksTextField; + @SuppressWarnings("FieldCanBeLocal") // Used via reflection at showUi() and disposeResources() + private JBLabel myVmOptionsLabel; + private RawCommandLineEditor myVmOptionsEditor; + + @Nullable private ExternalSystemTaskExecutionSettings myOriginalSettings; + + public ExternalSystemTaskSettingsControl(@NotNull Project project, @NotNull ProjectSystemId externalSystemId) { + myProject = project; + myExternalSystemId = externalSystemId; + } + + public void setOriginalSettings(@Nullable ExternalSystemTaskExecutionSettings originalSettings) { + myOriginalSettings = originalSettings; + } + + @Override + public void fillUi(@NotNull final PaintAwarePanel canvas, int indentLevel) { + myProjectPathLabel = + new JBLabel(ExternalSystemBundle.message("run.configuration.settings.label.project", myExternalSystemId.getReadableName())); + ExternalSystemManager manager = ExternalSystemApiUtil.getManager(myExternalSystemId); + FileChooserDescriptor projectPathChooserDescriptor = null; + if (manager instanceof ExternalSystemUiAware) { + projectPathChooserDescriptor = ((ExternalSystemUiAware)manager).getExternalProjectConfigDescriptor(); + } + if (projectPathChooserDescriptor == null) { + projectPathChooserDescriptor = FileChooserDescriptorFactory.createSingleLocalFileDescriptor(); + } + String title = ExternalSystemBundle.message("settings.label.select.project", myExternalSystemId.getReadableName()); + myProjectPathField = new ExternalProjectPathField(myProject, myExternalSystemId, projectPathChooserDescriptor, title) { + @Override + public Dimension getPreferredSize() { + return myVmOptionsEditor == null ? super.getPreferredSize() : myVmOptionsEditor.getTextField().getPreferredSize(); + } + }; + canvas.add(myProjectPathLabel, ExternalSystemUiUtil.getLabelConstraints(0)); + canvas.add(myProjectPathField, ExternalSystemUiUtil.getFillLineConstraints(0)); + + myTasksLabel = new JBLabel(ExternalSystemBundle.message("run.configuration.settings.label.tasks")); + myTasksTextField = new JBTextField(ExternalSystemConstants.TEXT_FIELD_WIDTH_IN_COLUMNS); + canvas.add(myTasksLabel, ExternalSystemUiUtil.getLabelConstraints(0)); + canvas.add(myTasksTextField, ExternalSystemUiUtil.getFillLineConstraints(0)); + + myVmOptionsLabel = new JBLabel(ExternalSystemBundle.message("run.configuration.settings.label.vmoptions")); + myVmOptionsEditor = new RawCommandLineEditor(); + myVmOptionsEditor.setDialogCaption(ExternalSystemBundle.message("run.configuration.settings.caption.vmoptions")); + canvas.add(myVmOptionsLabel, ExternalSystemUiUtil.getLabelConstraints(0)); + canvas.add(myVmOptionsEditor, ExternalSystemUiUtil.getFillLineConstraints(0)); + + canvas.setPaintCallback(new Consumer() { + + @Nullable private Dimension myDimension; + @Nullable private Dimension myBounds; + private boolean myBorderReset; + + @Override + public void consume(Graphics graphics) { + if (!myBorderReset) { + Editor editor = myProjectPathField.getChildComponent().getEditor(); + if (editor != null) { + myBorderReset = true; + editor.setBorder(null); + } + } + Dimension size = myVmOptionsEditor.getTextField().getPreferredSize(); + Rectangle bounds = myVmOptionsEditor.getTextField().getBounds(); + if (!size.equals(myDimension)) { + myDimension = size; + } + if (myBounds == null || myBounds.width != bounds.width || myBounds.height == bounds.height) { + myBounds = bounds.getSize(); + } + + applyDimension(myProjectPathField.getChildComponent(), false); + applyDimension(myTasksTextField, true); + } + + private void applyDimension(@NotNull JComponent component, boolean processBounds) { + Rectangle bounds = component.getBounds(); + if (bounds != null && myBounds != null && (bounds.width != myBounds.width || bounds.height != myBounds.height)) { + component.setPreferredSize(myDimension); + if (processBounds) { + component.setBounds(bounds.x, bounds.y, myBounds.width, myBounds.height); + } + } + } + }); + } + + @Override + public void reset() { + myProjectPathField.setText(""); + myTasksTextField.setText(""); + myVmOptionsEditor.setText(""); + showUi(true); + + if (myOriginalSettings == null) { + return; + } + + String path = myOriginalSettings.getExternalProjectPath(); + if (StringUtil.isEmpty(path)) { + path = ExternalSystemApiUtil.getLastUsedExternalProjectPath(myExternalSystemId); + } + myProjectPathField.setText(path); + myTasksTextField.setText(StringUtil.join(myOriginalSettings.getTaskNames(), " ")); + myVmOptionsEditor.setText(myOriginalSettings.getVmOptions()); + } + + @Override + public boolean isModified() { + if (myOriginalSettings == null) { + return false; + } + + return !Comparing.equal(normalizePath(myProjectPathField.getText()), + normalizePath(myOriginalSettings.getExternalProjectPath())) + || !Comparing.equal(normalizePath(myTasksTextField.getText()), + normalizePath(StringUtil.join(myOriginalSettings.getTaskNames(), " "))) + || !Comparing.equal(normalizePath(myVmOptionsEditor.getText()), + normalizePath(myOriginalSettings.getVmOptions())); + } + + @Nullable + @Override + public String apply(@NotNull ExternalSystemTaskExecutionSettings settings) { + String projectPath = myProjectPathField.getText(); + if (myOriginalSettings == null) { + return String.format( + "Can't store external task settings into run configuration. Reason: target run configuration is undefined. Tasks: '%s', " + + "external project: '%s', vm options: '%s'", myTasksTextField.getText(), projectPath, myVmOptionsEditor.getText() + ); + } + settings.setExternalProjectPath(projectPath); + if (!StringUtil.isEmpty(projectPath)) { + ExternalSystemApiUtil.storeLastUsedExternalProjectPath(projectPath, myExternalSystemId); + } + settings.setTaskNames(StringUtil.split(myTasksTextField.getText(), " ")); + settings.setVmOptions(myVmOptionsEditor.getText()); + return null; + } + + @Override + public void disposeUIResources() { + ExternalSystemUiUtil.disposeUi(this); + } + + @Override + public void showUi(boolean show) { + ExternalSystemUiUtil.showUi(this, show); + } +} diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/AbstractExternalSystemTask.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/AbstractExternalSystemTask.java index 71563ca9c50b..806db99d8c0a 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/AbstractExternalSystemTask.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/AbstractExternalSystemTask.java @@ -35,7 +35,7 @@ public abstract class AbstractExternalSystemTask implements ExternalSystemTask { @NotNull private final ExternalSystemTaskId myId; @NotNull private final ProjectSystemId myExternalSystemId; - @NotNull private final String myExernalProjectPath; + @NotNull private final String myExternalProjectPath; protected AbstractExternalSystemTask(@NotNull ProjectSystemId id, @NotNull ExternalSystemTaskType type, @@ -45,7 +45,7 @@ public abstract class AbstractExternalSystemTask implements ExternalSystemTask { myExternalSystemId = id; myIdeProject = project; myId = ExternalSystemTaskId.create(type, myIdeProject); - myExernalProjectPath = externalProjectPath; + myExternalProjectPath = externalProjectPath; } @NotNull @@ -77,13 +77,18 @@ public abstract class AbstractExternalSystemTask implements ExternalSystemTask { return myIdeProject; } + @NotNull + public String getExternalProjectPath() { + return myExternalProjectPath; + } + public void refreshState() { if (getState() != ExternalSystemTaskState.IN_PROGRESS) { return; } final ExternalSystemFacadeManager manager = ServiceManager.getService(ExternalSystemFacadeManager.class); try { - final RemoteExternalSystemFacade facade = manager.getFacade(myIdeProject, myExernalProjectPath, myExternalSystemId); + final RemoteExternalSystemFacade facade = manager.getFacade(myIdeProject, myExternalProjectPath, myExternalSystemId); setState(facade.isTaskInProgress(getId()) ? ExternalSystemTaskState.IN_PROGRESS : ExternalSystemTaskState.FAILED); } catch (Throwable e) { diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemExecuteTaskTask.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemExecuteTaskTask.java index 0bcfa95c59a8..2c20df8cb3fb 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemExecuteTaskTask.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemExecuteTaskTask.java @@ -17,12 +17,21 @@ 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.service.internal.AbstractExternalSystemTask; +import com.intellij.openapi.externalSystem.model.serialization.ExternalTaskPojo; +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.RemoteExternalSystemFacade; +import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemTaskManager; +import com.intellij.openapi.externalSystem.settings.ExternalSystemSettingsManager; import com.intellij.openapi.project.Project; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtilRt; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import java.util.Collection; import java.util.List; /** @@ -31,31 +40,68 @@ import java.util.List; */ public class ExternalSystemExecuteTaskTask extends AbstractExternalSystemTask { - @NotNull private final List myTasksToExecute; - @NotNull private final String myGradleProjectPath; + @NotNull private static final Function MAPPER = new Function() { + @Override + public String fun(ExternalTaskPojo task) { + return task.getName(); + } + }; + + @NotNull private final List myTasksToExecute; + @Nullable private final String myVmOptions; public ExternalSystemExecuteTaskTask(@NotNull ProjectSystemId externalSystemId, @NotNull Project project, - @NotNull String gradleProjectPath, - @NotNull List tasksToExecute) + @NotNull List tasksToExecute, + @Nullable String vmOptions) throws IllegalArgumentException { - super(externalSystemId, ExternalSystemTaskType.EXECUTE_TASK, project, gradleProjectPath); - myGradleProjectPath = gradleProjectPath; + super(externalSystemId, ExternalSystemTaskType.EXECUTE_TASK, project, getLinkedExternalProjectPath(tasksToExecute)); myTasksToExecute = tasksToExecute; + myVmOptions = vmOptions; } + @NotNull + private static String getLinkedExternalProjectPath(@NotNull Collection tasks) throws IllegalArgumentException { + if (tasks.isEmpty()) { + throw new IllegalArgumentException("Can't execute external tasks. Reason: given tasks list is empty"); + } + String result = null; + for (ExternalTaskPojo task : tasks) { + String path = task.getLinkedExternalProjectPath(); + if (result == null) { + result = path; + } + else if (!result.equals(path)) { + throw new IllegalArgumentException(String.format( + "Can't execute given external system tasks. Reason: expected that all of them belong to the same external project " + + "but they are not (at least two different projects detected - '%s' and '%s'). Tasks: %s", + result, + task.getLinkedExternalProjectPath(), + tasks)); + } + } + assert result != null; + return result; + } + + @SuppressWarnings("unchecked") @Override protected void doExecute() throws Exception { final ExternalSystemFacadeManager manager = ServiceManager.getService(ExternalSystemFacadeManager.class); - Project project = getIdeProject(); - // TODO den implement -// ExternalSystemBuildManager buildManager = manager.getFacade(project).getBuildManager(); -// setState(GradleTaskState.IN_PROGRESS); -// try { -// buildManager.executeTasks(getId(), myTasksToExecute, myGradleProjectPath); -// } -// finally { -// setState(GradleTaskState.FINISHED); -// } + ExternalSystemSettingsManager settingsManager = ServiceManager.getService(ExternalSystemSettingsManager.class); + ExternalSystemExecutionSettings settings = settingsManager.getExecutionSettings(getIdeProject(), + getExternalProjectPath(), + getExternalSystemId()); + RemoteExternalSystemFacade facade = manager.getFacade(getIdeProject(), getExternalProjectPath(), getExternalSystemId()); + RemoteExternalSystemTaskManager taskManager = facade.getTaskManager(); + List taskNames = ContainerUtilRt.map2List(myTasksToExecute, MAPPER); + + setState(ExternalSystemTaskState.IN_PROGRESS); + try { + taskManager.executeTasks(getId(), taskNames, getExternalProjectPath(), settings, myVmOptions); + } + finally { + setState(ExternalSystemTaskState.FINISHED); + } } } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemProcessingManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemProcessingManager.java index 05743ef6bf2b..49502284eb01 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemProcessingManager.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemProcessingManager.java @@ -107,6 +107,11 @@ public class ExternalSystemProcessingManager implements ExternalSystemTaskNotifi myTasksInProgress.put(event.getId(), System.currentTimeMillis() + TOO_LONG_EXECUTION_MS); } + @Override + public void onTaskOutput(@NotNull ExternalSystemTaskId id, @NotNull String text, boolean stdOut) { + myTasksInProgress.put(id, System.currentTimeMillis() + TOO_LONG_EXECUTION_MS); + } + @Override public void onEnd(@NotNull ExternalSystemTaskId id) { myTasksInProgress.remove(id); 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 93f8f747c169..123cecf95f14 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 @@ -309,7 +309,7 @@ public abstract class AbstractExternalProjectImportBuilder> entry : myListeners.entrySet()) { + final Set ids = entry.getValue(); + if (Collections.EMPTY_SET == ids || ids.contains(id)) { + entry.getKey().onTaskOutput(id, text, stdOut); + } + } + } + @Override public void onEnd(@NotNull ExternalSystemTaskId id) { for (Map.Entry> entry : myListeners.entrySet()) { diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemProgressNotificationManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemProgressNotificationManager.java index 8f65369ce1f0..a3ba55c430b3 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemProgressNotificationManager.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemProgressNotificationManager.java @@ -30,6 +30,10 @@ public interface RemoteExternalSystemProgressNotificationManager extends Remote public void onStatusChange(@NotNull ExternalSystemTaskNotificationEvent event) { } + @Override + public void onTaskOutput(@NotNull ExternalSystemTaskId id, @NotNull String text, boolean stdOut) { + } + @Override public void onEnd(@NotNull ExternalSystemTaskId id) { } @@ -41,5 +45,7 @@ public interface RemoteExternalSystemProgressNotificationManager extends Remote void onStatusChange(@NotNull ExternalSystemTaskNotificationEvent event) throws RemoteException; + void onTaskOutput(@NotNull ExternalSystemTaskId id, @NotNull String text, boolean stdOut) throws RemoteException; + void onEnd(@NotNull ExternalSystemTaskId id) throws RemoteException; } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemProjectResolverImpl.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemProjectResolverImpl.java index e90dd2288437..e8125bdbb281 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemProjectResolverImpl.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemProjectResolverImpl.java @@ -29,16 +29,16 @@ public class RemoteExternalSystemProjectResolverImpl resolveProjectInfo(@NotNull final ExternalSystemTaskId id, - @NotNull final String projectPath, - final boolean downloadLibraries, - ExternalSystemExecutionSettings settings) + @NotNull final String projectPath, + final boolean downloadLibraries, + ExternalSystemExecutionSettings settings) throws ExternalSystemException, IllegalArgumentException, IllegalStateException { return execute(id, new Producer>() { @Nullable @Override public DataNode produce() { - return myDelegate.resolveProjectInfo(id, projectPath, downloadLibraries, getSettings()); + return myDelegate.resolveProjectInfo(id, projectPath, downloadLibraries, getSettings(), getNotificationListener()); } }); } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemTaskManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemTaskManager.java index 01dbc5b925f0..e7a4612daebd 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemTaskManager.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemTaskManager.java @@ -44,7 +44,8 @@ public interface RemoteExternalSystemTaskManager taskNames, @NotNull String projectPath, - @Nullable ExternalSystemExecutionSettings settings) throws RemoteException, ExternalSystemException + @Nullable ExternalSystemExecutionSettings settings, + @Nullable String vmOptions) throws RemoteException, ExternalSystemException { } @@ -68,6 +69,9 @@ public interface RemoteExternalSystemTaskManager taskNames, @NotNull String projectPath, @Nullable S settings) - throws RemoteException, ExternalSystemException; + void executeTasks(@NotNull ExternalSystemTaskId id, + @NotNull List taskNames, + @NotNull String projectPath, + @Nullable S settings, + @Nullable String vmOptions) throws RemoteException, ExternalSystemException; } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemTaskManagerImpl.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemTaskManagerImpl.java index de5ce33fe438..763ca22da1fa 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemTaskManagerImpl.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemTaskManagerImpl.java @@ -15,7 +15,7 @@ */ package com.intellij.openapi.externalSystem.service.remote; -import com.intellij.openapi.externalSystem.build.ExternalSystemTaskManager; +import com.intellij.openapi.externalSystem.task.ExternalSystemTaskManager; import com.intellij.openapi.externalSystem.model.ExternalSystemException; import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; @@ -44,13 +44,14 @@ public class RemoteExternalSystemTaskManagerImpl taskNames, @NotNull final String projectPath, - @Nullable final S settings) throws RemoteException, ExternalSystemException + @Nullable final S settings, + @Nullable final String vmOptions) throws RemoteException, ExternalSystemException { execute(id, new Producer() { @Nullable @Override public Object produce() { - myDelegate.executeTasks(id, taskNames, projectPath, settings); + myDelegate.executeTasks(id, taskNames, projectPath, settings, vmOptions, getNotificationListener()); return null; } }); diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/wrapper/ExternalSystemTaskManagerWrapper.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/wrapper/ExternalSystemTaskManagerWrapper.java index 1bf4e604271a..b4f5eea5f01c 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/wrapper/ExternalSystemTaskManagerWrapper.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/wrapper/ExternalSystemTaskManagerWrapper.java @@ -48,11 +48,12 @@ public class ExternalSystemTaskManagerWrapper taskNames, @NotNull String projectPath, - @Nullable S settings) throws RemoteException, ExternalSystemException + @Nullable S settings, + @Nullable String vmOptions) throws RemoteException, ExternalSystemException { myProgressManager.onQueued(id); try { - getDelegate().executeTasks(id, taskNames, projectPath, settings); + getDelegate().executeTasks(id, taskNames, projectPath, settings, vmOptions); } finally { myProgressManager.onEnd(id); diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalProjectSettingsControl.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalProjectSettingsControl.java index dd01eeca0c98..0103c69a4b22 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalProjectSettingsControl.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalProjectSettingsControl.java @@ -16,6 +16,7 @@ package com.intellij.openapi.externalSystem.service.settings; import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings; +import com.intellij.openapi.externalSystem.util.ExternalSystemSettingsControl; import com.intellij.openapi.externalSystem.util.ExternalSystemBundle; import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil; import com.intellij.openapi.externalSystem.util.PaintAwarePanel; @@ -30,7 +31,9 @@ import org.jetbrains.annotations.Nullable; * @author Denis Zhdanov * @since 4/24/13 1:19 PM */ -public abstract class AbstractExternalProjectSettingsControl implements ExternalSettingsControl { +public abstract class AbstractExternalProjectSettingsControl + implements ExternalSystemSettingsControl +{ @NotNull private S myInitialSettings; @@ -79,17 +82,11 @@ public abstract class AbstractExternalProjectSettingsControl implements SearchableConfigurable, Configurable.NoScroll { - @NotNull private final List> myProjectSettingsControls = ContainerUtilRt.newArrayList(); + @NotNull private final List> myProjectSettingsControls = ContainerUtilRt.newArrayList(); @NotNull private final ProjectSystemId myExternalSystemId; @NotNull private final Project myProject; - @Nullable private ExternalSettingsControl mySystemSettingsControl; - @Nullable private ExternalSettingsControl myActiveProjectSettingsControl; + @Nullable private ExternalSystemSettingsControl mySystemSettingsControl; + @Nullable private ExternalSystemSettingsControl myActiveProjectSettingsControl; private PaintAwarePanel myComponent; private JBList myProjectsList; @@ -114,8 +111,8 @@ public abstract class AbstractExternalSystemConfigurable< @SuppressWarnings("unchecked") @NotNull private SystemSettings getSettings() { - ExternalSystemManager manager - = (ExternalSystemManager)ExternalSystemApiUtil.getManager(myExternalSystemId); + ExternalSystemManager manager = + (ExternalSystemManager)ExternalSystemApiUtil.getManager(myExternalSystemId); assert manager != null; return manager.getSettingsProvider().fun(myProject); } @@ -128,7 +125,7 @@ public abstract class AbstractExternalSystemConfigurable< addTitle(ExternalSystemBundle.message("settings.title.linked.projects", myExternalSystemId.getReadableName())); myComponent.add(new JBScrollPane(myProjectsList), ExternalSystemUiUtil.getFillLineConstraints(1)); - + addTitle(ExternalSystemBundle.message("settings.title.project.settings")); List settings = ContainerUtilRt.newArrayList(s.getLinkedProjectsSettings()); myProjectsList.setVisibleRowCount(Math.max(3, Math.min(5, settings.size()))); @@ -141,7 +138,7 @@ public abstract class AbstractExternalSystemConfigurable< myProjectSettingsControls.clear(); for (ProjectSettings setting : settings) { - ExternalSettingsControl control = createProjectSettingsControl(setting); + ExternalSystemSettingsControl control = createProjectSettingsControl(setting); control.fillUi(myComponent, 1); myProjectsModel.addElement(getProjectName(setting.getExternalProjectPath())); myProjectSettingsControls.add(control); @@ -187,7 +184,7 @@ public abstract class AbstractExternalSystemConfigurable< * @return control for managing given project settings */ @NotNull - protected abstract ExternalSettingsControl createProjectSettingsControl(@NotNull ProjectSettings settings); + protected abstract ExternalSystemSettingsControl createProjectSettingsControl(@NotNull ProjectSettings settings); @NotNull protected String getProjectName(@NotNull String path) { @@ -209,11 +206,11 @@ public abstract class AbstractExternalSystemConfigurable< * null if current external system doesn't have system-level settings (only project-level settings) */ @Nullable - protected abstract ExternalSettingsControl createSystemSettingsControl(@NotNull SystemSettings settings); + protected abstract ExternalSystemSettingsControl createSystemSettingsControl(@NotNull SystemSettings settings); @Override public boolean isModified() { - for (ExternalSettingsControl control : myProjectSettingsControls) { + for (ExternalSystemSettingsControl control : myProjectSettingsControls) { if (control.isModified()) { return true; } @@ -228,7 +225,7 @@ public abstract class AbstractExternalSystemConfigurable< publisher.onBulkChangeStart(); try { List projectSettings = ContainerUtilRt.newArrayList(); - for (ExternalSettingsControl control : myProjectSettingsControls) { + for (ExternalSystemSettingsControl control : myProjectSettingsControls) { ProjectSettings s = newProjectSettings(); control.apply(s); projectSettings.add(s); @@ -251,7 +248,7 @@ public abstract class AbstractExternalSystemConfigurable< @Override public void reset() { - for (ExternalSettingsControl control : myProjectSettingsControls) { + for (ExternalSystemSettingsControl control : myProjectSettingsControls) { control.reset(); } if (mySystemSettingsControl != null) { @@ -261,7 +258,7 @@ public abstract class AbstractExternalSystemConfigurable< @Override public void disposeUIResources() { - for (ExternalSettingsControl control : myProjectSettingsControls) { + for (ExternalSystemSettingsControl control : myProjectSettingsControls) { control.disposeUIResources(); } myProjectSettingsControls.clear(); 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 5beb51011bf4..aa6297402e15 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,10 +19,7 @@ import com.intellij.openapi.externalSystem.model.ProjectSystemId; import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings; import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings; import com.intellij.openapi.externalSystem.settings.ExternalSystemSettingsListener; -import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; -import com.intellij.openapi.externalSystem.util.ExternalSystemBundle; -import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil; -import com.intellij.openapi.externalSystem.util.PaintAwarePanel; +import com.intellij.openapi.externalSystem.util.*; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.ui.TextComponentAccessor; @@ -53,31 +50,32 @@ public abstract class AbstractImportFromExternalSystemControl< @NotNull private final PaintAwarePanel myComponent = new PaintAwarePanel(new GridBagLayout()); @NotNull private final TextFieldWithBrowseButton myLinkedProjectPathField = new TextFieldWithBrowseButton(); - @NotNull private final ExternalSettingsControl myProjectSettingsControl; - @Nullable private final ExternalSettingsControl mySystemSettingsControl; + @NotNull private final ExternalSystemSettingsControl myProjectSettingsControl; + @NotNull private final ProjectSystemId myExternalSystemId; + @Nullable private final ExternalSystemSettingsControl mySystemSettingsControl; @SuppressWarnings("AbstractMethodCallInConstructor") protected AbstractImportFromExternalSystemControl(@NotNull ProjectSystemId externalSystemId, @NotNull SystemSettings systemSettings, @NotNull ProjectSettings projectSettings) { + myExternalSystemId = externalSystemId; mySystemSettings = systemSettings; myProjectSettings = projectSettings; myProjectSettingsControl = createProjectSettingsControl(myProjectSettings); mySystemSettingsControl = createSystemSettingsControl(mySystemSettings); - JLabel linkedProjectPathLabel - = new JLabel(ExternalSystemBundle.message("settings.label.select.project", externalSystemId.getReadableName())); + JLabel linkedProjectPathLabel = + new JLabel(ExternalSystemBundle.message("settings.label.select.project", externalSystemId.getReadableName())); FileChooserDescriptor fileChooserDescriptor = getLinkedProjectChooserDescriptor(); - myLinkedProjectPathField.addBrowseFolderListener( - "", - ExternalSystemBundle.message("settings.label.select.project", externalSystemId.getReadableName()), - null, - fileChooserDescriptor, - TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT, - false - ); + myLinkedProjectPathField.addBrowseFolderListener("", + ExternalSystemBundle + .message("settings.label.select.project", externalSystemId.getReadableName()), + null, + fileChooserDescriptor, + TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT, + false); myLinkedProjectPathField.getTextField().getDocument().addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { @@ -94,7 +92,7 @@ public abstract class AbstractImportFromExternalSystemControl< onLinkedProjectPathChange(myLinkedProjectPathField.getText()); } }); - + myComponent.add(linkedProjectPathLabel, ExternalSystemUiUtil.getLabelConstraints(0)); myComponent.add(myLinkedProjectPathField, ExternalSystemUiUtil.getFillLineConstraints(0)); myProjectSettingsControl.fillUi(myComponent, 0); @@ -116,7 +114,7 @@ public abstract class AbstractImportFromExternalSystemControl< * @return control for managing given project settings */ @NotNull - protected abstract ExternalSettingsControl createProjectSettingsControl(@NotNull ProjectSettings settings); + protected abstract ExternalSystemSettingsControl createProjectSettingsControl(@NotNull ProjectSettings settings); /** * Creates a control for managing given system-level settings (if any). @@ -126,7 +124,7 @@ public abstract class AbstractImportFromExternalSystemControl< * null if current external system doesn't have system-level settings (only project-level settings) */ @Nullable - protected abstract ExternalSettingsControl createSystemSettingsControl(@NotNull SystemSettings settings); + protected abstract ExternalSystemSettingsControl createSystemSettingsControl(@NotNull SystemSettings settings); @NotNull public JComponent getComponent() { @@ -134,7 +132,7 @@ public abstract class AbstractImportFromExternalSystemControl< } @NotNull - public ExternalSettingsControl getProjectSettingsControl() { + public ExternalSystemSettingsControl getProjectSettingsControl() { return myProjectSettingsControl; } @@ -161,6 +159,9 @@ public abstract class AbstractImportFromExternalSystemControl< if (StringUtil.isEmpty(linkedProjectPath)) { throw new ConfigurationException(ExternalSystemBundle.message("error.project.undefined")); } + else { + ExternalSystemApiUtil.storeLastUsedExternalProjectPath(linkedProjectPath, myExternalSystemId); + } myProjectSettings.setExternalProjectPath(ExternalSystemApiUtil.normalizePath(linkedProjectPath)); String errorMessage = myProjectSettingsControl.apply(myProjectSettings); diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/AbstractToolWindowService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/AbstractToolWindowService.java index 399bbba852b6..188430d03c7b 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/AbstractToolWindowService.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/AbstractToolWindowService.java @@ -20,6 +20,7 @@ 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.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemUtil; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; @@ -33,18 +34,22 @@ import java.util.Collection; public abstract class AbstractToolWindowService implements ProjectDataService { @Override - public void importData(@NotNull Collection> toImport, @NotNull Project project, boolean synchronous) { + public void importData(@NotNull final Collection> toImport, @NotNull final 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, project, model); - } - + ExternalSystemApiUtil.executeOnEdt(false, new Runnable() { + @Override + public void run() { + ExternalSystemTasksTreeModel model = ExternalSystemUtil.getToolWindowElement(ExternalSystemTasksTreeModel.class, + project, + ExternalSystemDataKeys.ALL_TASKS_MODEL, + toImport.iterator().next().getData().getOwner()); + if (model != null) { + processData(toImport, project, model); + } + } + }); } protected abstract void processData(@NotNull Collection> nodes, diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksPanel.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksPanel.java index a2d06237938a..df0969fa3054 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksPanel.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksPanel.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.externalSystem.service.task.ui; +import com.intellij.ide.ui.customization.CustomizationUtil; import com.intellij.notification.NotificationGroup; import com.intellij.openapi.actionSystem.ActionGroup; import com.intellij.openapi.actionSystem.ActionManager; @@ -23,17 +24,22 @@ 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.serialization.ExternalTaskPojo; import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings; import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; -import com.intellij.openapi.externalSystem.util.ExternalSystemConstants; import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.SimpleToolWindowPanel; import com.intellij.ui.components.JBScrollPane; +import com.intellij.util.Producer; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.awt.event.MouseEvent; + +import static com.intellij.openapi.externalSystem.util.ExternalSystemConstants.*; + /** * @author Denis Zhdanov * @since 5/12/13 10:18 PM @@ -45,6 +51,8 @@ public class ExternalSystemTasksPanel extends SimpleToolWindowPanel implements D @NotNull private final ProjectSystemId myExternalSystemId; @NotNull private final NotificationGroup myNotificationGroup; + @Nullable private Producer mySelectedTaskProvider; + public ExternalSystemTasksPanel(@NotNull Project project, @NotNull ProjectSystemId externalSystemId, @NotNull NotificationGroup notificationGroup) @@ -54,20 +62,28 @@ public class ExternalSystemTasksPanel extends SimpleToolWindowPanel implements D myNotificationGroup = notificationGroup; myAllTasksModel = new ExternalSystemTasksTreeModel(externalSystemId); - ExternalSystemManager manager = ExternalSystemApiUtil.getManager(externalSystemId); + ExternalSystemManager manager = ExternalSystemApiUtil.getManager(externalSystemId); assert manager != null; AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project); - myAllTasksTree = new ExternalSystemTasksTree(myAllTasksModel, settings.getExpandStates()); + myAllTasksTree = new ExternalSystemTasksTree(myAllTasksModel, settings.getExpandStates()) { + @Override + protected void processMouseEvent(MouseEvent e) { + mySelectedTaskProvider = myAllTasksTree; + super.processMouseEvent(e); + } + }; 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); + ActionGroup group = (ActionGroup)actionManager.getAction(TOOL_WINDOW_TOOLBAR_ACTIONS_GROUP_ID); + ActionToolbar toolbar = actionManager.createActionToolbar(TOOL_WINDOW_PLACE, group, true); toolbar.setTargetComponent(this); setToolbar(toolbar.getComponent()); setContent(new JBScrollPane(myAllTasksTree)); ExternalSystemUiUtil.apply(settings, myAllTasksModel); + + CustomizationUtil.installPopupHandler(myAllTasksTree, TREE_ACTIONS_GROUP_ID, TREE_PLACE); } @Nullable @@ -82,6 +98,9 @@ public class ExternalSystemTasksPanel extends SimpleToolWindowPanel implements D else if (ExternalSystemDataKeys.NOTIFICATION_GROUP.is(dataId)) { return myNotificationGroup; } + else if (ExternalSystemDataKeys.SELECTED_TASK.is(dataId)) { + return mySelectedTaskProvider == null ? null : mySelectedTaskProvider.produce(); + } 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 index 220cc52e699b..0e0db4e669a2 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTree.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTree.java @@ -15,11 +15,14 @@ */ package com.intellij.openapi.externalSystem.service.task.ui; +import com.intellij.openapi.externalSystem.model.serialization.ExternalTaskPojo; import com.intellij.ui.treeStructure.Tree; import com.intellij.util.Alarm; +import com.intellij.util.Producer; import com.intellij.util.containers.ContainerUtilRt; import com.intellij.util.ui.tree.TreeModelAdapter; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeModelEvent; @@ -32,7 +35,7 @@ import java.util.*; * @author Denis Zhdanov * @since 5/13/13 4:18 PM */ -public class ExternalSystemTasksTree extends Tree { +public class ExternalSystemTasksTree extends Tree implements Producer { private static final int COLLAPSE_STATE_PROCESSING_DELAY_MILLIS = 200; @@ -155,4 +158,19 @@ public class ExternalSystemTasksTree extends Tree { return buffer.toString(); } + @Nullable + @Override + public ExternalTaskPojo produce() { + TreePath selectionPath = getLeadSelectionPath(); + if (selectionPath == null) { + return null; + } + Object component = selectionPath.getLastPathComponent(); + if (!(component instanceof ExternalSystemNode)) { + return null; + } + + Object element = ((ExternalSystemNode)component).getDescriptor().getElement(); + return element instanceof ExternalTaskPojo ? ((ExternalTaskPojo)element) : null; + } } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/DefaultExternalSystemUiAware.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/DefaultExternalSystemUiAware.java index 8ba262f44c10..77a00c10a28c 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/DefaultExternalSystemUiAware.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/DefaultExternalSystemUiAware.java @@ -17,11 +17,13 @@ package com.intellij.openapi.externalSystem.service.ui; import com.intellij.icons.AllIcons; import com.intellij.openapi.externalSystem.ExternalSystemUiAware; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.util.IconLoader; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.io.File; /** * This class is not singleton but offers single-point-of-usage field - {@link #INSTANCE}. @@ -33,13 +35,25 @@ public class DefaultExternalSystemUiAware implements ExternalSystemUiAware { @NotNull public static final DefaultExternalSystemUiAware INSTANCE = new DefaultExternalSystemUiAware(); + @NotNull + @Override + public String getProjectRepresentationName(@NotNull String targetProjectPath, @Nullable String rootProjectPath) { + return new File(targetProjectPath).getParentFile().getName(); + } + @Nullable @Override + public FileChooserDescriptor getExternalProjectConfigDescriptor() { + return null; + } + + @NotNull + @Override public Icon getProjectIcon() { return AllIcons.Nodes.IdeaProject; } - @Nullable + @NotNull @Override public Icon getTaskIcon() { return IconLoader.getIcon("/icons/task.png", getClass()); diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectPathField.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectPathField.java new file mode 100644 index 000000000000..fa36d88c3f86 --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectPathField.java @@ -0,0 +1,121 @@ +/* + * 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.codeInsight.completion.CompletionResultSet; +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.serialization.ExternalProjectPojo; +import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings; +import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.ComponentWithBrowseButton; +import com.intellij.ui.EditorTextField; +import com.intellij.ui.TextAccessor; +import com.intellij.util.TextFieldCompletionProvider; +import com.intellij.util.TextFieldCompletionProviderDumbAware; +import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Collection; +import java.util.Map; + +/** + * @author Denis Zhdanov + * @since 24.05.13 19:13 + */ +public class ExternalProjectPathField extends ComponentWithBrowseButton implements TextAccessor { + + public ExternalProjectPathField(@NotNull Project project, + @NotNull ProjectSystemId externalSystemId, + @NotNull FileChooserDescriptor descriptor, + @NotNull String fileChooserTitle) + { + super(createTextField(project, externalSystemId), createBrowseListener(descriptor, fileChooserTitle)); + } + + @NotNull + private static EditorTextField createTextField(@NotNull Project project, @NotNull ProjectSystemId externalSystemId) { + ExternalSystemManager manager = ExternalSystemApiUtil.getManager(externalSystemId); + assert manager != null; + final AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project); + final ExternalSystemUiAware uiAware; + if (manager instanceof ExternalSystemUiAware) { + uiAware = (ExternalSystemUiAware)manager; + } + else { + uiAware = DefaultExternalSystemUiAware.INSTANCE; + } + TextFieldCompletionProvider provider = new TextFieldCompletionProviderDumbAware() { + @Override + protected void addCompletionVariants(@NotNull String text, int offset, @NotNull String prefix, @NotNull CompletionResultSet result) { + for (Map.Entry> entry : settings.getAvailableProjects().entrySet()) { + String rootProjectPath = entry.getKey().getPath(); + String rootProjectName = uiAware.getProjectRepresentationName(rootProjectPath, null); + ExternalProjectPathLookupElement rootProjectElement = new ExternalProjectPathLookupElement(rootProjectName, rootProjectPath); + result.addElement(rootProjectElement); + for (ExternalProjectPojo subProject : entry.getValue()) { + String p = subProject.getPath(); + if (rootProjectPath.equals(p)) { + continue; + } + String subProjectName = uiAware.getProjectRepresentationName(p, rootProjectPath); + ExternalProjectPathLookupElement subProjectElement = new ExternalProjectPathLookupElement(subProjectName, p); + result.addElement(subProjectElement); + } + } + result.stopHere(); + } + }; + EditorTextField result = provider.createEditor(project, false); + result.setBorder(UIUtil.getTextFieldBorder()); + result.setOneLineMode(true); + result.setOpaque(true); + result.setBackground(UIUtil.getTextFieldBackground()); + return result; + } + + @NotNull + private static ActionListener createBrowseListener(@NotNull final FileChooserDescriptor descriptor, + final @NotNull String fileChooserTitle) + { + return new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + descriptor.setTitle(fileChooserTitle); + // TODO den implement + //VirtualFile file = FileChooser.chooseFile(descriptor, get, null); + //if (file != null) { + // setWorkingDirectory(file.getPresentableUrl()); + //} + } + }; + } + + @Override + public void setText(String text) { + getChildComponent().setText(text); + } + + @Override + public String getText() { + return getChildComponent().getText(); + } +} diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectPathLookupElement.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectPathLookupElement.java new file mode 100644 index 000000000000..8490eb4d8513 --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectPathLookupElement.java @@ -0,0 +1,68 @@ +/* + * 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.codeInsight.completion.InsertionContext; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementPresentation; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.FoldRegion; +import com.intellij.openapi.editor.FoldingModel; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import org.jetbrains.annotations.NotNull; + +/** + * @author Denis Zhdanov + * @since 5/25/13 7:26 PM + */ +public class ExternalProjectPathLookupElement extends LookupElement { + + @NotNull private final String myProjectName; + @NotNull private final String myProjectPath; + + public ExternalProjectPathLookupElement(@NotNull String projectName, @NotNull String projectPath) { + myProjectName = projectName; + myProjectPath = projectPath; + } + + @NotNull + @Override + public String getLookupString() { + return myProjectName; + } + + @Override + public void handleInsert(InsertionContext context) { + Editor editor = context.getEditor(); + final Document document = editor.getDocument(); + final int startOffset = context.getStartOffset(); + document.replaceString(startOffset, context.getTailOffset(), myProjectPath); + final Project project = context.getProject(); + PsiDocumentManager.getInstance(project).commitDocument(document); + final FoldingModel foldingModel = editor.getFoldingModel(); + foldingModel.runBatchFoldingOperationDoNotCollapseCaret(new Runnable() { + @Override + public void run() { + FoldRegion region = foldingModel.addFoldRegion(startOffset, startOffset + myProjectPath.length(), myProjectName); + if (region != null) { + region.setExpanded(false); + } + } + }); + } +} diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/ExternalSettingsControl.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemSettingsControl.java similarity index 95% rename from platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/ExternalSettingsControl.java rename to platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemSettingsControl.java index b3f5a93e361d..4536790c731e 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/ExternalSettingsControl.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemSettingsControl.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.openapi.externalSystem.service.settings; +package com.intellij.openapi.externalSystem.util; import com.intellij.openapi.externalSystem.util.PaintAwarePanel; import org.jetbrains.annotations.NotNull; @@ -28,7 +28,7 @@ import java.awt.*; * @since 4/28/13 12:15 AM * @param settings type */ -public interface ExternalSettingsControl { +public interface ExternalSystemSettingsControl { /** * Adds current control-specific UI controls to the given canvas. 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 b7d29734320c..927a8dba6a23 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 @@ -38,6 +38,7 @@ import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.MutableTreeNode; import javax.swing.tree.TreeNode; import java.awt.*; +import java.lang.reflect.Field; import java.util.*; import java.util.List; import java.util.concurrent.TimeUnit; @@ -144,4 +145,34 @@ public class ExternalSystemUiUtil { } }); } + + public static void showUi(@NotNull Object o, boolean show) { + for (Field field : o.getClass().getFields()) { + field.setAccessible(true); + try { + Object v = field.get(o); + if (v instanceof JComponent) { + ((JComponent)v).setVisible(show); + } + } + catch (IllegalAccessException e) { + // Ignore + } + } + } + + public static void disposeUi(@NotNull Object o) { + for (Field field : o.getClass().getFields()) { + field.setAccessible(true); + try { + Object v = field.get(o); + if (v instanceof JComponent) { + field.set(o, null); + } + } + catch (IllegalAccessException e) { + // Ignore + } + } + } } 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 6f4f7949b93b..544417322437 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 @@ -45,6 +45,7 @@ import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.impl.ToolWindowImpl; import com.intellij.ui.CheckBoxList; import com.intellij.ui.components.JBScrollPane; import com.intellij.ui.content.Content; @@ -116,6 +117,9 @@ public class ExternalSystemUtil { if (toolWindow == null) { return null; } + if (toolWindow instanceof ToolWindowImpl) { + ((ToolWindowImpl)toolWindow).ensureContentInitialized(); + } final ContentManager contentManager = toolWindow.getContentManager(); if (contentManager == null) { @@ -349,9 +353,7 @@ public class ExternalSystemUtil { @Override public void run() { if (modal) { - String title = ExternalSystemBundle.message("progress.import.text", - projectName, - ExternalSystemApiUtil.toReadableName(externalSystemId)); + String title = ExternalSystemBundle.message("progress.import.text", projectName, externalSystemId.getReadableName()); ProgressManager.getInstance().run(new Task.Modal(project, title, false) { @Override public void run(@NotNull ProgressIndicator indicator) { @@ -360,8 +362,7 @@ public class ExternalSystemUtil { }); } else { - String title = ExternalSystemBundle.message("progress.refresh.text", - projectName, ExternalSystemApiUtil.toReadableName(externalSystemId)); + String title = ExternalSystemBundle.message("progress.refresh.text", projectName, externalSystemId.getReadableName()); ProgressManager.getInstance().run(new Task.Backgroundable(project, title) { @Override public void run(@NotNull ProgressIndicator indicator) { diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/PaintAwarePanel.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/PaintAwarePanel.java index 6d3d34d8cbc0..1abf691a905e 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/PaintAwarePanel.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/PaintAwarePanel.java @@ -42,10 +42,10 @@ public class PaintAwarePanel extends JPanel { @Override public void paint(Graphics g) { - super.paint(g); if (myPaintCallback != null) { myPaintCallback.consume(g); } + super.paint(g); } @Nullable diff --git a/platform/lang-impl/src/com/intellij/util/TextFieldCompletionProvider.java b/platform/lang-impl/src/com/intellij/util/TextFieldCompletionProvider.java index 8a531c2444be..5b50c48bb6ed 100644 --- a/platform/lang-impl/src/com/intellij/util/TextFieldCompletionProvider.java +++ b/platform/lang-impl/src/com/intellij/util/TextFieldCompletionProvider.java @@ -2,6 +2,8 @@ package com.intellij.util; import com.intellij.codeInsight.completion.CompletionResultSet; import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.PlainTextLanguage; import com.intellij.openapi.project.Project; @@ -67,6 +69,25 @@ public abstract class TextFieldCompletionProvider { protected abstract void addCompletionVariants(@NotNull String text, int offset, @NotNull String prefix, @NotNull CompletionResultSet result); public EditorTextField createEditor(Project project) { - return new EditorTextField(createDocument(project, ""), project, PlainTextLanguage.INSTANCE.getAssociatedFileType()); + return createEditor(project, true); + } + + public EditorTextField createEditor(Project project, final boolean shouldHaveBorder) { + return new EditorTextField(createDocument(project, ""), project, PlainTextLanguage.INSTANCE.getAssociatedFileType()) { + @Override + protected boolean shouldHaveBorder() { + return shouldHaveBorder; + } + + @Override + protected void updateBorder(@NotNull EditorEx editor) { + if (shouldHaveBorder) { + super.updateBorder(editor); + } + else { + editor.setBorder(null); + } + } + }; } } diff --git a/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml b/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml index cd05f9f16989..0ea927e385ec 100644 --- a/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml +++ b/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml @@ -30,6 +30,9 @@ + + + diff --git a/platform/platform-resources/src/idea/ExternalSystemActions.xml b/platform/platform-resources/src/idea/ExternalSystemActions.xml index 52fb84b2f48a..f923ed184ccb 100644 --- a/platform/platform-resources/src/idea/ExternalSystemActions.xml +++ b/platform/platform-resources/src/idea/ExternalSystemActions.xml @@ -5,9 +5,18 @@ + + + + + + + \ 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 60b7be2ee257..dfbc72e67337 100644 --- a/plugins/gradle/src/META-INF/plugin.xml +++ b/plugins/gradle/src/META-INF/plugin.xml @@ -37,6 +37,7 @@ + diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java index 9efe71ba942d..d369c3f951fe 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java @@ -23,11 +23,12 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.externalSystem.ExternalSystemConfigurableAware; import com.intellij.openapi.externalSystem.ExternalSystemManager; import com.intellij.openapi.externalSystem.ExternalSystemUiAware; -import com.intellij.openapi.externalSystem.build.ExternalSystemTaskManager; +import com.intellij.openapi.externalSystem.task.ExternalSystemTaskManager; import com.intellij.openapi.externalSystem.model.ProjectSystemId; import com.intellij.openapi.externalSystem.service.project.ExternalSystemProjectResolver; import com.intellij.openapi.externalSystem.service.ui.DefaultExternalSystemUiAware; import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.module.EmptyModuleType; import com.intellij.openapi.module.JavaModuleType; import com.intellij.openapi.module.ModuleType; @@ -55,6 +56,7 @@ 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 org.jetbrains.plugins.gradle.util.GradleUtil; import javax.swing.*; import java.io.File; @@ -72,8 +74,7 @@ public class GradleManager implements ExternalSystemConfigurableAware, ExternalS GradleSettingsListener, GradleSettings, GradleLocalSettings, - GradleExecutionSettings> -{ + GradleExecutionSettings> { private static final Logger LOG = Logger.getInstance("#" + GradleManager.class.getName()); @@ -225,6 +226,12 @@ public class GradleManager implements ExternalSystemConfigurableAware, ExternalS return new GradleConfigurable(project); } + @Nullable + @Override + public FileChooserDescriptor getExternalProjectConfigDescriptor() { + return GradleUtil.getGradleProjectFileChooserDescriptor(); + } + @Nullable @Override public Icon getProjectIcon() { @@ -236,4 +243,10 @@ public class GradleManager implements ExternalSystemConfigurableAware, ExternalS public Icon getTaskIcon() { return DefaultExternalSystemUiAware.INSTANCE.getTaskIcon(); } + + @NotNull + @Override + public String getProjectRepresentationName(@NotNull String targetProjectPath, @Nullable String rootProjectPath) { + return GradleUtil.getProjectRepresentationName(targetProjectPath, rootProjectPath); + } } 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 index 1a5b758f9e74..4dc6fc050fea 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleTaskManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleTaskManager.java @@ -15,9 +15,11 @@ */ package org.jetbrains.plugins.gradle.remote.impl; -import com.intellij.openapi.externalSystem.build.ExternalSystemTaskManager; +import com.intellij.openapi.externalSystem.task.ExternalSystemTaskManager; import com.intellij.openapi.externalSystem.model.ExternalSystemException; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.Function; import org.gradle.tooling.BuildLauncher; @@ -41,12 +43,17 @@ public class GradleTaskManager implements ExternalSystemTaskManager taskNames, @NotNull String projectPath, - @Nullable final GradleExecutionSettings settings) throws ExternalSystemException + @Nullable final GradleExecutionSettings settings, + @Nullable final String vmOptions, + @NotNull final ExternalSystemTaskNotificationListener listener) throws ExternalSystemException { Function f = new Function() { @Override public Void fun(ProjectConnection connection) { - BuildLauncher launcher = myHelper.getBuildLauncher(id, connection, settings); + BuildLauncher launcher = myHelper.getBuildLauncher(id, connection, settings, listener); + if (!StringUtil.isEmpty(vmOptions)) { + launcher.setJvmArguments(vmOptions); + } launcher.forTasks(ArrayUtil.toStringArray(taskNames)); launcher.run(); return null; diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/execution/GradleExternalTaskConfigurationType.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/execution/GradleExternalTaskConfigurationType.java new file mode 100644 index 000000000000..c0322eafa624 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/execution/GradleExternalTaskConfigurationType.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 org.jetbrains.plugins.gradle.service.execution; + +import com.intellij.openapi.externalSystem.service.execution.AbstractExternalSystemTaskConfigurationType; +import org.jetbrains.plugins.gradle.util.GradleConstants; + +/** + * @author Denis Zhdanov + * @since 23.05.13 17:56 + */ +public class GradleExternalTaskConfigurationType extends AbstractExternalSystemTaskConfigurationType { + + public GradleExternalTaskConfigurationType() { + super(GradleConstants.SYSTEM_ID); + } +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java index 9f28154a4360..a3d22a36b7a1 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java @@ -43,45 +43,46 @@ public class GradleExecutionHelper { public ModelBuilder getModelBuilder(@NotNull final ExternalSystemTaskId id, @Nullable GradleExecutionSettings settings, @NotNull ProjectConnection connection, + @NotNull ExternalSystemTaskNotificationListener listener, boolean downloadLibraries) { - return getModelBuilder(downloadLibraries ? IdeaProject.class : BasicIdeaProject.class, id, settings, connection); + return getModelBuilder(downloadLibraries ? IdeaProject.class : BasicIdeaProject.class, id, settings, connection, listener); } @NotNull public ModelBuilder getModelBuilder(@NotNull Class modelType, @NotNull final ExternalSystemTaskId id, @Nullable GradleExecutionSettings settings, - @NotNull ProjectConnection connection) + @NotNull ProjectConnection connection, + @NotNull ExternalSystemTaskNotificationListener listener) { ModelBuilder result = connection.model(modelType); - prepare(result, id, settings); + prepare(result, id, settings, listener); return result; } @NotNull public BuildLauncher getBuildLauncher(@NotNull final ExternalSystemTaskId id, @NotNull ProjectConnection connection, - @Nullable GradleExecutionSettings settings) + @Nullable GradleExecutionSettings settings, + @NotNull ExternalSystemTaskNotificationListener listener) { BuildLauncher result = connection.newBuild(); - prepare(result, id, settings); + prepare(result, id, settings, listener); return result; } - private static void prepare(LongRunningOperation operation, + @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") + private static void prepare(@NotNull LongRunningOperation operation, @NotNull final ExternalSystemTaskId id, - @Nullable GradleExecutionSettings settings) + @Nullable GradleExecutionSettings settings, + @NotNull final ExternalSystemTaskNotificationListener listener) { if (settings == null) { return; } - final ExternalSystemTaskNotificationListener notificationListener = settings.getNotificationListener(); - if (notificationListener == null) { - return; - } - notificationListener.onStart(id); + listener.onStart(id); final String javaHome = settings.getJavaHome(); if (javaHome != null && new File(javaHome).isDirectory()) { operation.setJavaHome(new File(javaHome)); @@ -89,9 +90,11 @@ public class GradleExecutionHelper { operation.addProgressListener(new ProgressListener() { @Override public void statusChanged(ProgressEvent event) { - notificationListener.onStatusChange(new ExternalSystemTaskNotificationEvent(id, event.getDescription())); + listener.onStatusChange(new ExternalSystemTaskNotificationEvent(id, event.getDescription())); } }); + operation.setStandardOutput(new OutputWrapper(listener, id, true)); + operation.setStandardError(new OutputWrapper(listener, id, false)); } public T execute(@NotNull String projectPath, @Nullable GradleExecutionSettings settings, @NotNull Function 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 72457e47f300..7c0d0a03e408 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 @@ -6,6 +6,7 @@ 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.ExternalSystemTaskId; +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener; import com.intellij.openapi.externalSystem.model.task.TaskData; import com.intellij.openapi.externalSystem.service.project.ExternalSystemProjectResolver; import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; @@ -51,7 +52,8 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver resolveProjectInfo(@NotNull final ExternalSystemTaskId id, @NotNull final String projectPath, final boolean downloadLibraries, - @Nullable final GradleExecutionSettings settings) + @Nullable final GradleExecutionSettings settings, + @NotNull final ExternalSystemTaskNotificationListener listener) throws ExternalSystemException, IllegalArgumentException, IllegalStateException { if (settings != null) { @@ -70,7 +72,7 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver result = extension.resolveProjectInfo(id, projectPath, downloadLibraries, settings); + DataNode result = extension.resolveProjectInfo(id, projectPath, downloadLibraries, settings, listener); if (result != null) { return result; } @@ -80,7 +82,7 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver>() { @Override public DataNode fun(ProjectConnection connection) { - return doResolveProjectInfo(id, projectPath, settings, connection, downloadLibraries); + return doResolveProjectInfo(id, projectPath, settings, connection, listener, downloadLibraries); } }); } @@ -90,10 +92,11 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver modelBuilder = myHelper.getModelBuilder(id, settings, connection, downloadLibraries); + ModelBuilder modelBuilder = myHelper.getModelBuilder(id, settings, connection, listener, downloadLibraries); IdeaProject project = modelBuilder.get(); DataNode result = populateProject(project, projectPath); diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/OutputWrapper.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/OutputWrapper.java new file mode 100644 index 000000000000..ce7e493b560f --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/OutputWrapper.java @@ -0,0 +1,36 @@ +package org.jetbrains.plugins.gradle.service.project; + +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * @author Denis Zhdanov + * @since 23.05.13 15:50 + */ +public class OutputWrapper extends OutputStream { + + @NotNull private final ExternalSystemTaskNotificationListener myListener; + @NotNull private final ExternalSystemTaskId myTaskId; + + private final boolean myStdOut; + + public OutputWrapper(@NotNull ExternalSystemTaskNotificationListener listener, @NotNull ExternalSystemTaskId taskId, boolean stdOut) { + myListener = listener; + myTaskId = taskId; + myStdOut = stdOut; + } + + @Override + public void write(int b) throws IOException { + myListener.onTaskOutput(myTaskId, Character.toString((char)b), myStdOut); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + myListener.onTaskOutput(myTaskId, new String(b, off, len), myStdOut); + } +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleConfigurable.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleConfigurable.java index 2aa5532e3375..5bd644d24e8d 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleConfigurable.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleConfigurable.java @@ -16,7 +16,7 @@ package org.jetbrains.plugins.gradle.service.settings; import com.intellij.openapi.externalSystem.service.settings.AbstractExternalSystemConfigurable; -import com.intellij.openapi.externalSystem.service.settings.ExternalSettingsControl; +import com.intellij.openapi.externalSystem.util.ExternalSystemSettingsControl; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -40,13 +40,13 @@ public class GradleConfigurable extends AbstractExternalSystemConfigurable createProjectSettingsControl(@NotNull GradleProjectSettings settings) { + protected ExternalSystemSettingsControl createProjectSettingsControl(@NotNull GradleProjectSettings settings) { return new GradleProjectSettingsControl(settings); } @Nullable @Override - protected ExternalSettingsControl createSystemSettingsControl(@NotNull GradleSettings settings) { + protected ExternalSystemSettingsControl createSystemSettingsControl(@NotNull GradleSettings settings) { return new GradleSystemSettingsControl(settings); } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java index 141722c521ac..57f1b9cdfad2 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java @@ -112,16 +112,6 @@ public class GradleProjectSettingsControl extends AbstractExternalProjectSetting content.add(myGradleHomePathField, ExternalSystemUiUtil.getFillLineConstraints(0)); } - @Override - protected void showExtraUi(boolean show) { - myGradleHomeLabel.setVisible(show); - myGradleHomePathField.setVisible(show); - myUseWrapperButton.setVisible(show); - myUseLocalDistributionButton.setVisible(show); - myGradleHomeLabel.setVisible(show); - myGradleHomePathField.setVisible(show); - } - private void initWrapperControls() { ActionListener listener = new ActionListener() { @Override @@ -280,14 +270,6 @@ public class GradleProjectSettingsControl extends AbstractExternalProjectSetting myGradleHomeModifiedByUser = false; } - @Override - protected void disposeExtraUIControls() { - myGradleHomeLabel = null; - myGradleHomePathField = null; - myUseWrapperButton = null; - myUseLocalDistributionButton = null; - } - void showBalloonIfNecessary() { if (!myShowBalloonIfNecessary || !myGradleHomePathField.isEnabled()) { return; diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleSystemSettingsControl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleSystemSettingsControl.java index 27545bc5c0c4..5d2a6de15ca3 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleSystemSettingsControl.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleSystemSettingsControl.java @@ -16,7 +16,7 @@ package org.jetbrains.plugins.gradle.service.settings; import com.intellij.openapi.externalSystem.model.settings.LocationSettingType; -import com.intellij.openapi.externalSystem.service.settings.ExternalSettingsControl; +import com.intellij.openapi.externalSystem.util.ExternalSystemSettingsControl; import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil; import com.intellij.openapi.externalSystem.util.PaintAwarePanel; @@ -43,10 +43,11 @@ import java.io.File; * @author Denis Zhdanov * @since 4/28/13 11:06 AM */ -public class GradleSystemSettingsControl implements ExternalSettingsControl { - +public class GradleSystemSettingsControl implements ExternalSystemSettingsControl { + @NotNull private final GradleSettings myInitialSettings; - + + @SuppressWarnings("FieldCanBeLocal") // Used by reflection at showUi() and disposeUiResources() private JLabel myServiceDirectoryLabel; private TextFieldWithBrowseButton myServiceDirectoryPathField; private boolean myServiceDirectoryPathModifiedByUser; @@ -65,20 +66,17 @@ public class GradleSystemSettingsControl implements ExternalSettingsControl createProjectSettingsControl(@NotNull GradleProjectSettings settings) { + protected ExternalSystemSettingsControl createProjectSettingsControl(@NotNull GradleProjectSettings settings) { return new GradleProjectSettingsControl(settings); } @Nullable @Override - protected ExternalSettingsControl createSystemSettingsControl(@NotNull GradleSettings settings) { + protected ExternalSystemSettingsControl createSystemSettingsControl(@NotNull GradleSettings settings) { return new GradleSystemSettingsControl(settings); } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java index 4e5faff21ad4..fdfa487d0eea 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java @@ -176,4 +176,17 @@ public class GradleUtil { return buffer.toString(); } + @NotNull + public static String getProjectRepresentationName(@NotNull String targetProjectPath, @Nullable String rootProjectPath) { + if (rootProjectPath == null) { + return new File(targetProjectPath).getParentFile().getName(); + } + File rootProjectDir = new File(rootProjectPath).getParentFile(); + StringBuilder buffer = new StringBuilder(); + for (File f = new File(targetProjectPath).getParentFile(); f != null && !FileUtil.filesEqual(f, rootProjectDir); f = f.getParentFile()) { + buffer.insert(0, f.getName()).insert(0, ":"); + } + buffer.insert(0, rootProjectDir.getName()); + return buffer.toString(); + } }