From f04c971f7d10e59afba91ac0ea7983ade879b8b5 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 5 Apr 2017 13:36:58 +0200 Subject: [PATCH] beforeTasks (cherry picked from commit ce2f2f0ec065ac3b32e0789bbecc4a35132daf53) --- .../BuildArtifactsBeforeRunTaskProvider.java | 4 +- .../execution/ConfigurationsTest.java | 4 +- .../execution/impl/RunConfigurableTest.java | 7 +- .../com/intellij/execution/RunManager.java | 6 +- .../LocatableConfigurationBase.java | 6 +- .../configurations/RunConfiguration.java | 3 +- .../configurations/RunConfigurationBase.java | 9 +- .../com/intellij/execution/RunManagerEx.java | 29 +- .../actions/CopyConfigurationAction.java | 5 +- .../ConfigurationSettingsEditorWrapper.java | 4 +- .../intellij/execution/impl/RunManagerImpl.kt | 544 +++++++++--------- .../RunnerAndConfigurationSettingsImpl.kt | 6 +- .../execution/impl/WorkspaceRunManager.kt | 73 --- .../src/componentSets/Execution.xml | 2 +- .../src/com/intellij/util/containers/util.kt | 57 +- .../DeploymentConfigurationManagerImpl.java | 2 +- .../src/com/intellij/mock/MockRunManager.kt | 12 +- 17 files changed, 375 insertions(+), 398 deletions(-) delete mode 100644 platform/lang-impl/src/com/intellij/execution/impl/WorkspaceRunManager.kt diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProvider.java b/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProvider.java index cc93721f97fd..bfb1aefbefd3 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProvider.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -99,7 +99,7 @@ public class BuildArtifactsBeforeRunTaskProvider extends BuildArtifactsBeforeRun buildArtifactsTasks.add(task); List tasks = runManager.getBeforeRunTasks(configuration); tasks.add(task); - runManager.setBeforeRunTasks(configuration, tasks, false); + runManager.setBeforeRunTasks(configuration, tasks); } for (BuildArtifactsBeforeRunTask task : buildArtifactsTasks) { diff --git a/java/java-tests/testSrc/com/intellij/execution/ConfigurationsTest.java b/java/java-tests/testSrc/com/intellij/execution/ConfigurationsTest.java index 494351cad10c..0e5218ddf92f 100644 --- a/java/java-tests/testSrc/com/intellij/execution/ConfigurationsTest.java +++ b/java/java-tests/testSrc/com/intellij/execution/ConfigurationsTest.java @@ -22,7 +22,6 @@ import com.intellij.execution.configurations.*; import com.intellij.execution.executors.DefaultRunExecutor; import com.intellij.execution.impl.RunManagerImpl; import com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl; -import com.intellij.execution.impl.WorkspaceRunManager; import com.intellij.execution.junit.*; import com.intellij.execution.junit2.configuration.JUnitConfigurable; import com.intellij.execution.junit2.configuration.JUnitConfigurationModel; @@ -30,7 +29,6 @@ import com.intellij.execution.runners.ExecutionEnvironmentBuilder; import com.intellij.execution.testframework.SearchForTestsTask; import com.intellij.execution.testframework.TestSearchScope; import com.intellij.execution.ui.CommonJavaParametersPanel; -import com.intellij.ide.util.AppPropertiesComponentImpl; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.options.Configurable; @@ -262,7 +260,7 @@ public class ConfigurationsTest extends BaseConfigurationTestCase { JUnitConfiguration oldRc = createConfiguration(findTestA(module)); oldRc.setWorkingDirectory(module.getModuleFilePath()); - RunManagerImpl runManager = new WorkspaceRunManager(myProject, new AppPropertiesComponentImpl()); + RunManagerImpl runManager = new RunManagerImpl(myProject); Element element = new Element("configuration"); new RunnerAndConfigurationSettingsImpl(runManager, oldRc, false).writeExternal(element); diff --git a/java/java-tests/testSrc/com/intellij/execution/impl/RunConfigurableTest.java b/java/java-tests/testSrc/com/intellij/execution/impl/RunConfigurableTest.java index 5d60f478a49a..3a7065e091d2 100644 --- a/java/java-tests/testSrc/com/intellij/execution/impl/RunConfigurableTest.java +++ b/java/java-tests/testSrc/com/intellij/execution/impl/RunConfigurableTest.java @@ -17,9 +17,7 @@ package com.intellij.execution.impl; import com.intellij.execution.application.ApplicationConfigurationType; import com.intellij.execution.configurations.ConfigurationType; -import com.intellij.execution.configurations.UnknownConfigurationType; import com.intellij.execution.junit.JUnitConfigurationType; -import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Trinity; import com.intellij.testFramework.LightIdeaTestCase; @@ -197,9 +195,8 @@ public class RunConfigurableTest extends LightIdeaTestCase { private static RunManagerImpl createRunManager(Element element) { Project project = getProject(); - RunManagerImpl runManager = new WorkspaceRunManager(project, PropertiesComponent.getInstance(project)); - runManager.initializeConfigurationTypes(new ConfigurationType[]{ApplicationConfigurationType.getInstance(), - JUnitConfigurationType.getInstance(), UnknownConfigurationType.INSTANCE}); + RunManagerImpl runManager = new RunManagerImpl(project); + runManager.initializeConfigurationTypes(new ConfigurationType[]{ApplicationConfigurationType.getInstance(), JUnitConfigurationType.getInstance()}); runManager.loadState(element); return runManager; } diff --git a/platform/lang-api/src/com/intellij/execution/RunManager.java b/platform/lang-api/src/com/intellij/execution/RunManager.java index bf45b13f8282..1f6974fae333 100644 --- a/platform/lang-api/src/com/intellij/execution/RunManager.java +++ b/platform/lang-api/src/com/intellij/execution/RunManager.java @@ -165,7 +165,11 @@ public abstract class RunManager { * @see RunManager#suggestUniqueName(String, Collection) */ @NotNull - public abstract RunnerAndConfigurationSettings createRunConfiguration(@NotNull String name, @NotNull ConfigurationFactory factory); + public abstract RunnerAndConfigurationSettings createConfiguration(@NotNull String name, @NotNull ConfigurationFactory factory); + + public final RunnerAndConfigurationSettings createRunConfiguration(@NotNull String name, @NotNull ConfigurationFactory factory) { + return createConfiguration(name, factory); + } /** * Creates a configuration settings object based on a specified {@link RunConfiguration}. Note that you need to call diff --git a/platform/lang-api/src/com/intellij/execution/configurations/LocatableConfigurationBase.java b/platform/lang-api/src/com/intellij/execution/configurations/LocatableConfigurationBase.java index 342d561f8aab..21c15b0f27bf 100644 --- a/platform/lang-api/src/com/intellij/execution/configurations/LocatableConfigurationBase.java +++ b/platform/lang-api/src/com/intellij/execution/configurations/LocatableConfigurationBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -75,10 +75,6 @@ public abstract class LocatableConfigurationBase extends RunConfigurationBase im } } - @Override - public void checkConfiguration() throws RuntimeConfigurationException { - } - /** * Returns the text of the context menu action to start this run configuration. This can be different from the run configuration name * (for example, for a Java unit test method, the context menu shows just the name of the method, whereas the name of the run diff --git a/platform/lang-api/src/com/intellij/execution/configurations/RunConfiguration.java b/platform/lang-api/src/com/intellij/execution/configurations/RunConfiguration.java index a1fe0f6afe02..4954fba83c6b 100644 --- a/platform/lang-api/src/com/intellij/execution/configurations/RunConfiguration.java +++ b/platform/lang-api/src/com/intellij/execution/configurations/RunConfiguration.java @@ -141,10 +141,11 @@ public interface RunConfiguration extends RunProfile, Cloneable { default void writeExternal(Element element) { } + @NotNull default List getBeforeRunTasks() { return Collections.emptyList(); } - default void setBeforeRunTasks(@Nullable List value) { + default void setBeforeRunTasks(@NotNull List value) { } } diff --git a/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationBase.java b/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationBase.java index 0ad90fd294ff..bcc8f1ac99ce 100644 --- a/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationBase.java +++ b/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationBase.java @@ -34,6 +34,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -62,7 +63,7 @@ public abstract class RunConfigurationBase extends UserDataHolderBase implements private boolean myShowConsoleOnStdErr = false; private String myFileOutputPath = null; - private List myBeforeRunTasks; + private List myBeforeRunTasks = Collections.emptyList(); protected RunConfigurationBase(@NotNull Project project, @NotNull ConfigurationFactory factory, final String name) { myProject = project; @@ -71,13 +72,13 @@ public abstract class RunConfigurationBase extends UserDataHolderBase implements myIcon = factory.getIcon(); } - @Nullable + @NotNull @Transient public List getBeforeRunTasks() { return myBeforeRunTasks; } - public void setBeforeRunTasks(@Nullable List value) { + public void setBeforeRunTasks(@NotNull List value) { myBeforeRunTasks = value; } @@ -145,6 +146,8 @@ public abstract class RunConfigurationBase extends UserDataHolderBase implements runConfiguration.myShowConsoleOnStdOut = myShowConsoleOnStdOut; runConfiguration.myShowConsoleOnStdErr = myShowConsoleOnStdErr; copyCopyableDataTo(runConfiguration); + + myBeforeRunTasks = myBeforeRunTasks.isEmpty() ? Collections.emptyList() : new SmartList<>(myBeforeRunTasks); return runConfiguration; } diff --git a/platform/lang-impl/src/com/intellij/execution/RunManagerEx.java b/platform/lang-impl/src/com/intellij/execution/RunManagerEx.java index 41c7b6def03a..67bf89ee0bfe 100644 --- a/platform/lang-impl/src/com/intellij/execution/RunManagerEx.java +++ b/platform/lang-impl/src/com/intellij/execution/RunManagerEx.java @@ -15,7 +15,6 @@ */ package com.intellij.execution; -import com.intellij.execution.configurations.ConfigurationFactory; import com.intellij.execution.configurations.ConfigurationType; import com.intellij.execution.configurations.RunConfiguration; import com.intellij.openapi.project.Project; @@ -44,19 +43,15 @@ public abstract class RunManagerEx extends RunManager { public abstract void setTemporaryConfiguration(@Nullable RunnerAndConfigurationSettings tempConfiguration); + @NotNull public abstract RunManagerConfig getConfig(); - /** - * @deprecated use {@link RunManager#createRunConfiguration(String, ConfigurationFactory)} instead - * @param name - * @param type - * @return - */ - @NotNull - public abstract RunnerAndConfigurationSettings createConfiguration(String name, ConfigurationFactory type); + public void addConfiguration(@NotNull RunnerAndConfigurationSettings settings) { + addConfiguration(settings, isConfigurationShared(settings), null, false); + } - public void addConfiguration(RunnerAndConfigurationSettings settings, boolean isShared, List tasks) { - addConfiguration(settings, isShared, tasks, false); + public void addConfiguration(@NotNull RunnerAndConfigurationSettings settings, boolean isShared) { + addConfiguration(settings, isShared, null, false); } public abstract void addConfiguration(RunnerAndConfigurationSettings settings, @@ -67,15 +62,19 @@ public abstract class RunManagerEx extends RunManager { public abstract boolean isConfigurationShared(RunnerAndConfigurationSettings settings); @NotNull - public abstract List getBeforeRunTasks(@NotNull RunConfiguration settings); + public abstract List getBeforeRunTasks(@NotNull RunConfiguration configuration); - public abstract void setBeforeRunTasks(@NotNull RunConfiguration runConfiguration, @NotNull List tasks, boolean addEnabledTemplateTasksIfAbsent); + public void setBeforeRunTasks(@NotNull RunConfiguration configuration, @NotNull List tasks) { + setBeforeRunTasks(configuration, tasks, false); + } + + public abstract void setBeforeRunTasks(@NotNull RunConfiguration configuration, @NotNull List tasks, boolean addEnabledTemplateTasksIfAbsent); @NotNull - public abstract List getBeforeRunTasks(@NotNull RunConfiguration settings, Key taskProviderID); + public abstract List getBeforeRunTasks(@NotNull RunConfiguration settings, Key taskProviderId); @NotNull - public abstract List getBeforeRunTasks(Key taskProviderID); + public abstract List getBeforeRunTasks(Key taskProviderId); public abstract RunnerAndConfigurationSettings findConfigurationByName(@Nullable String name); diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/CopyConfigurationAction.java b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/CopyConfigurationAction.java index dd134629f545..c5529a9dfb92 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/CopyConfigurationAction.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/CopyConfigurationAction.java @@ -68,9 +68,8 @@ public class CopyConfigurationAction extends RunConfigurationTreeAction { ((ConfigurationFactoryEx)factory).onConfigurationCopied(settings.getConfiguration()); } - if (RunDialog.editConfiguration(node.getProject(), copiedSettings, - ExecutionBundle.message("run.dashboard.edit.configuration.dialog.title"))) { - runManager.addConfiguration(copiedSettings, runManager.isConfigurationShared(settings), runManager.getBeforeRunTasks(settings.getConfiguration())); + if (RunDialog.editConfiguration(node.getProject(), copiedSettings, ExecutionBundle.message("run.dashboard.edit.configuration.dialog.title"))) { + runManager.addConfiguration(copiedSettings, runManager.isConfigurationShared(settings)); } } } diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java b/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java index 506639b0b95f..558d913b546b 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -126,7 +126,7 @@ public class ConfigurationSettingsEditorWrapper extends SettingsEditor() +private val SELECTED_ATTR = "selected" +private val METHOD = "method" +private val OPTION = "option" @State(name = "RunManager", defaultStateAsResource = true, storages = arrayOf(Storage(StoragePathMacros.WORKSPACE_FILE))) -abstract class RunManagerImpl(internal val project: Project, propertiesComponent: PropertiesComponent) : RunManagerEx(), PersistentStateComponent, NamedComponent, Disposable { +class RunManagerImpl(internal val project: Project) : RunManagerEx(), PersistentStateComponent, NamedComponent, Disposable { companion object { @JvmField val CONFIGURATION = "configuration" - protected val RECENT = "recent_temporary" + private val RECENT = "recent_temporary" @JvmField val NAME_ATTR = "name" - protected val SELECTED_ATTR = "selected" - private val METHOD = "method" - private val OPTION = "option" @JvmStatic fun getInstanceImpl(project: Project) = RunManager.getInstance(project) as RunManagerImpl @@ -93,33 +95,34 @@ abstract class RunManagerImpl(internal val project: Project, propertiesComponent } } - private val typeByName = LinkedHashMap() + private val lock = ReentrantReadWriteLock() - protected val templateConfigurationMap = ContainerUtil.newConcurrentMap() - private val myConfigurations = LinkedHashMap() // template configurations are not included here - protected val mySharedConfigurations: MutableMap = ConcurrentHashMap() + private val idToType = LinkedHashMap() + + private val templateIdToConfiguration = THashMap() + private val idToSettings = LinkedHashMap() // template configurations are not included here + private val sharedConfigurations: MutableMap = ConcurrentHashMap() // When readExternal not all configuration may be loaded, so we need to remember the selected configuration // so that when it is eventually loaded, we can mark is as a selected. private var myLoadedSelectedConfigurationUniqueName: String? = null - protected var mySelectedConfigurationId: String? = null + private var mySelectedConfigurationId: String? = null - private val myIconCache = TimedIconCache() - private var myTypes: Array by Delegates.notNull() - private val myConfig = RunManagerConfig(propertiesComponent) + private val iconCache = TimedIconCache() + private var types: Array by Delegates.notNull() + private val _config by lazy { RunManagerConfig(PropertiesComponent.getInstance(project)) } - private var myUnknownElements: List? = null @Suppress("DEPRECATION") private val myOrder = JDOMExternalizableStringList() - protected val myRecentlyUsedTemporaries = ArrayList() + private val myRecentlyUsedTemporaries = ArrayList() private var myOrdered = true - protected val myDispatcher = EventDispatcher.create(RunManagerListener::class.java)!! + private val myDispatcher = EventDispatcher.create(RunManagerListener::class.java)!! - protected val schemeManagerProvider = SchemeManagerIprProvider("configuration") + private val schemeManagerProvider = SchemeManagerIprProvider("configuration") - protected val schemeManager = SchemeManagerFactory.getInstance(project).create("workspace", - object : LazySchemeProcessor() { + private val schemeManager = SchemeManagerFactory.getInstance(project).create("workspace", + object : LazySchemeProcessor() { override fun createScheme(dataHolder: SchemeDataHolder, name: String, attributeProvider: Function, isBundled: Boolean): RunConfigurationScheme { val settings = RunnerAndConfigurationSettingsImpl(this@RunManagerImpl) val element = dataHolder.read() @@ -155,7 +158,7 @@ abstract class RunManagerImpl(internal val project: Project, propertiesComponent override fun rootsChanged(event: ModuleRootEvent) { val configuration = selectedConfiguration if (configuration != null) { - myIconCache.remove(configuration.uniqueID) + iconCache.remove(configuration.uniqueID) } } }) @@ -163,21 +166,14 @@ abstract class RunManagerImpl(internal val project: Project, propertiesComponent // separate method needed for tests fun initializeConfigurationTypes(factories: Array) { - factories.sortBy { it.displayName } - val types = factories.toMutableList() + types.sortBy { it.displayName } types.add(UnknownConfigurationType.INSTANCE) - myTypes = types.toTypedArray() - - for (type in factories) { - typeByName.put(type.id, type) + for (type in types) { + idToType.put(type.id, type) } - - val broken = UnknownConfigurationType.INSTANCE - typeByName.put(broken.id, broken) } - @Suppress("OverridingDeprecatedMember") override fun createConfiguration(name: String, factory: ConfigurationFactory): RunnerAndConfigurationSettings { val template = getConfigurationTemplate(factory) return createConfiguration(factory.createConfiguration(name, template.configuration), template) @@ -188,25 +184,25 @@ abstract class RunManagerImpl(internal val project: Project, propertiesComponent private fun createConfiguration(runConfiguration: RunConfiguration, template: RunnerAndConfigurationSettingsImpl): RunnerAndConfigurationSettings { val settings = RunnerAndConfigurationSettingsImpl(this, runConfiguration, false) settings.importRunnerAndConfigurationSettings(template) - if (!mySharedConfigurations.containsKey(settings.uniqueID)) { + if (!sharedConfigurations.containsKey(settings.uniqueID)) { shareConfiguration(settings, isConfigurationShared(template)) } return settings } override fun dispose() { - templateConfigurationMap.clear() + lock.write { templateIdToConfiguration.clear() } } - override fun getConfig() = myConfig + override fun getConfig() = _config - override fun getConfigurationFactories() = myTypes.clone() + override fun getConfigurationFactories() = idToType.values.toTypedArray() fun getConfigurationFactories(includeUnknown: Boolean): Array { if (!includeUnknown) { - return myTypes.filter { it !is UnknownConfigurationType }.toTypedArray() + return idToType.values.filter { it !is UnknownConfigurationType }.toTypedArray() } - return myTypes.clone() + return idToType.values.toTypedArray() } /** @@ -228,15 +224,7 @@ abstract class RunManagerImpl(internal val project: Project, propertiesComponent override fun getAllConfigurationsList(): List { val sortedConfigurations = sortedConfigurations - if (sortedConfigurations.isEmpty()) { - return emptyList() - } - - val result = ArrayList(sortedConfigurations.size) - for (settings in sortedConfigurations) { - result.add(settings.configuration) - } - return result + return if (sortedConfigurations.isEmpty()) emptyList() else sortedConfigurations.mapSmart { it.configuration } } @Suppress("OverridingDeprecatedMember") @@ -266,7 +254,7 @@ abstract class RunManagerImpl(internal val project: Project, propertiesComponent @Suppress("OverridingDeprecatedMember") override fun getConfigurations(type: ConfigurationType) = getConfigurationSettingsList(type).map { it.configuration }.toTypedArray() - fun getConfigurationSettings() = myConfigurations.values.toTypedArray() + fun getConfigurationSettings() = idToSettings.values.toTypedArray() override fun getStructure(type: ConfigurationType): Map> { val result = LinkedHashMap>() @@ -287,35 +275,35 @@ abstract class RunManagerImpl(internal val project: Project, propertiesComponent override fun getConfigurationTemplate(factory: ConfigurationFactory): RunnerAndConfigurationSettingsImpl { val key = "${factory.type.id}.${factory.name}" - var template = templateConfigurationMap.get(key) - if (template == null) { - template = RunnerAndConfigurationSettingsImpl(this, factory.createTemplateConfiguration(project, this), true) - template.isSingleton = factory.isConfigurationSingletonByDefault - (template.configuration as? UnknownRunConfiguration)?.let { - it.isDoNotStore = true + return lock.read { templateIdToConfiguration.get(key) } ?: lock.write { + templateIdToConfiguration.getOrPut(key) { + val template = RunnerAndConfigurationSettingsImpl(this, factory.createTemplateConfiguration(project, this), true) + template.isSingleton = factory.isConfigurationSingletonByDefault + (template.configuration as? UnknownRunConfiguration)?.let { + it.isDoNotStore = true + } + + schemeManager.addScheme(template) + + template } - - schemeManager.addScheme(template) - - templateConfigurationMap.put(key, template) } - return template } - override fun addConfiguration(settings: RunnerAndConfigurationSettings, shared: Boolean, tasks: List>, addEnabledTemplateTasksIfAbsent: Boolean) { + override fun addConfiguration(settings: RunnerAndConfigurationSettings, shared: Boolean, tasks: List>?, addEnabledTemplateTasksIfAbsent: Boolean) { val existingId = findExistingConfigurationId(settings) val newId = settings.uniqueID var existingSettings: RunnerAndConfigurationSettings? = null if (existingId != null) { - existingSettings = myConfigurations.remove(existingId) - mySharedConfigurations.remove(existingId) + existingSettings = idToSettings.remove(existingId) + sharedConfigurations.remove(existingId) } if (mySelectedConfigurationId != null && mySelectedConfigurationId == existingId) { setSelectedConfigurationId(newId) } - myConfigurations.put(newId, settings) + idToSettings.put(newId, settings) val configuration = settings.configuration if (existingId == null) { @@ -323,11 +311,14 @@ abstract class RunManagerImpl(internal val project: Project, propertiesComponent } checkRecentsLimit() - mySharedConfigurations.put(newId, shared) + sharedConfigurations.put(newId, shared) if (shared) { settings.isTemporary = false } - setBeforeRunTasks(configuration, tasks, addEnabledTemplateTasksIfAbsent) + + if (tasks != null) { + setBeforeRunTasks(configuration, tasks, addEnabledTemplateTasksIfAbsent) + } if (existingSettings === settings) { myDispatcher.multicaster.runConfigurationChanged(settings, existingId) @@ -365,7 +356,7 @@ abstract class RunManagerImpl(internal val project: Project, propertiesComponent trimUsagesListToLimit() val removed = SmartList() while (tempConfigurationsList.size > config.recentsLimit) { - val it = myConfigurations.values.iterator() + val it = idToSettings.values.iterator() while (it.hasNext()) { val configuration = it.next() if (configuration.isTemporary && !myRecentlyUsedTemporaries.contains(configuration.configuration)) { @@ -387,7 +378,7 @@ abstract class RunManagerImpl(internal val project: Project, propertiesComponent } private fun doSaveOrder(comparator: Comparator?) { - val sorted = myConfigurations.values.filter { it.type !is UnknownConfigurationType } + val sorted = idToSettings.values.filter { it.type !is UnknownConfigurationType } if (comparator != null) { sorted.sortedWith(comparator) } @@ -406,7 +397,7 @@ abstract class RunManagerImpl(internal val project: Project, propertiesComponent if (mySelectedConfigurationId == null && myLoadedSelectedConfigurationUniqueName != null) { setSelectedConfigurationId(myLoadedSelectedConfigurationUniqueName) } - return mySelectedConfigurationId?.let { myConfigurations.get(it) } + return mySelectedConfigurationId?.let { idToSettings.get(it) } } override fun setSelectedConfiguration(settings: RunnerAndConfigurationSettings?) { @@ -423,12 +414,12 @@ abstract class RunManagerImpl(internal val project: Project, propertiesComponent override fun getSortedConfigurations(): MutableCollection { if (myOrdered) { - return myConfigurations.values + return idToSettings.values } - val order = ArrayList>(myConfigurations.size) + val order = ArrayList>(idToSettings.size) val folderNames = SmartList() - for (each in myConfigurations.values) { + for (each in idToSettings.values) { order.add(Pair.create(each.uniqueID, each)) val folderName = each.folderName if (folderName != null && !folderNames.contains(folderName)) { @@ -436,7 +427,7 @@ abstract class RunManagerImpl(internal val project: Project, propertiesComponent } } folderNames.add(null) - myConfigurations.clear() + idToSettings.clear() if (myOrder.isEmpty()) { // IDEA-63663 Sort run configurations alphabetically if clean checkout @@ -479,11 +470,11 @@ abstract class RunManagerImpl(internal val project: Project, propertiesComponent for (each in order) { val setting = each.second - myConfigurations.put(setting.uniqueID, setting) + idToSettings.put(setting.uniqueID, setting) } myOrdered = true - return myConfigurations.values + return idToSettings.values } @Suppress("DEPRECATION") @@ -507,9 +498,9 @@ abstract class RunManagerImpl(internal val project: Project, propertiesComponent element.setAttribute(SELECTED_ATTR, it.uniqueID) } - if (myConfigurations.size > 1) { + if (idToSettings.size > 1) { var order: JDOMExternalizableStringList? = null - for (each in myConfigurations.values) { + for (each in idToSettings.values) { if (each.type is UnknownConfigurationType) { continue } @@ -537,20 +528,14 @@ abstract class RunManagerImpl(internal val project: Project, propertiesComponent element.addContent(recent) recentList.writeExternal(recent) } - - if (myUnknownElements != null) { - for (unloadedElement in myUnknownElements!!) { - element.addContent(unloadedElement.clone()) - } - } return element } fun writeContext(element: Element) { - val values = ArrayList(myConfigurations.values) + val values = ArrayList(idToSettings.values) for (configurationSettings in values) { if (configurationSettings.isTemporary) { - addConfigurationElement(element, configurationSettings, CONFIGURATION) + addConfigurationElement(element, configurationSettings) } } @@ -559,86 +544,55 @@ abstract class RunManagerImpl(internal val project: Project, propertiesComponent } } - fun addConfigurationElement(parentNode: Element, template: RunnerAndConfigurationSettings) { - addConfigurationElement(parentNode, template, CONFIGURATION) - } - - private fun addConfigurationElement(parentNode: Element, settings: RunnerAndConfigurationSettings, elementType: String) { - val configurationElement = Element(elementType) + fun addConfigurationElement(parentNode: Element, settings: RunnerAndConfigurationSettings) { + val configurationElement = Element(CONFIGURATION) parentNode.addContent(configurationElement) (settings as RunnerAndConfigurationSettingsImpl).writeExternal(configurationElement) - if (settings.configuration !is UnknownRunConfiguration) { - doWriteConfiguration(settings, configurationElement) + settings.configuration?.let { + writeBeforeRunTasks(it, settings.isTemplate, configurationElement) } } - internal fun doWriteConfiguration(settings: RunnerAndConfigurationSettings, configurationElement: Element) { - val tasks = ArrayList(getBeforeRunTasks(settings.configuration)) - val templateTasks = THashMap>, BeforeRunTask<*>>() - val beforeRunTasks: List>? - if (settings.isTemplate) { - beforeRunTasks = getHardcodedBeforeRunTasks(settings.configuration) - } - else { - beforeRunTasks = getConfigurationTemplate(settings.factory!!).configuration.beforeRunTasks ?: emptyList() - } - for (templateTask in beforeRunTasks) { - @Suppress("UNCHECKED_CAST") - templateTasks.put(templateTask.providerId as Key>?, templateTask) - if (templateTask.isEnabled) { - var found = false - for (realTask in tasks) { - if (realTask.providerId === templateTask.providerId) { - found = true - break - } - } - if (!found) { - val clone = templateTask.clone() - clone.isEnabled = false - tasks.add(0, clone) - } - } + internal fun writeBeforeRunTasks(configuration: RunConfiguration, isTemplate: Boolean, configurationElement: Element) { + if (configuration is UnknownRunConfiguration) { + return } - // we have to always write empty method element otherwise no way to indicate that - var methodsElement: Element? = if (settings.isTemplate) Element(METHOD) else null - var i = 0 - val size = tasks.size - while (i < size) { - val task = tasks.get(i) - var j = 0 - var templateTask: BeforeRunTask<*>? = null - for ((key, value) in templateTasks) { - if (key === task.providerId) { - templateTask = value - break - } - j++ - } - if (task == templateTask && i == j) { - // not necessary saving if the task is the same as template and on the same place - i++ - continue - } + val tasks = if (isTemplate) configuration.beforeRunTasks else getEffectiveBeforeRunTasks(configuration, ownIsOnlyEnabled = false, isDisableTemplateTasks = true) + if (tasks.isEmpty()) { + return + } + + val methodsElement = Element(METHOD) + for (task in tasks) { val child = Element(OPTION) child.setAttribute(NAME_ATTR, task.providerId.toString()) task.writeExternal(child) - - if (methodsElement == null) { - methodsElement = Element(METHOD) - } methodsElement.addContent(child) - i++ } - if (methodsElement != null) { - configurationElement.addContent(methodsElement) - } + configurationElement.addContent(methodsElement) } override fun loadState(parentNode: Element) { + clear(false) + + schemeManagerProvider.load(parentNode) { + var name = it.getAttributeValue("name") + if (name == "