WorkspaceRunManager

(cherry picked from commit dac0b91a7c98771569e777e32d5e83941de0677b)
This commit is contained in:
Vladimir Krivosheev
2017-04-10 18:19:52 +02:00
parent 49558d8935
commit 887cf7940d
14 changed files with 263 additions and 195 deletions
@@ -246,12 +246,17 @@ public class ApplicationConfiguration extends ModuleBasedConfiguration<JavaRunCo
}
@Override
public void writeExternal(final Element element) {
public void writeExternal(@NotNull Element element) {
super.writeExternal(element);
JavaRunConfigurationExtensionManager.getInstance().writeExternal(this, element);
DefaultJDOMExternalizer.writeExternal(this, element);
writeModule(element);
EnvironmentVariablesComponent.writeExternal(element, getEnvs());
Map<String, String> envs = getEnvs();
if (!envs.isEmpty()) {
EnvironmentVariablesComponent.writeExternal(element, envs);
}
}
public static class JavaApplicationCommandLineState<T extends ApplicationConfiguration> extends BaseJavaApplicationCommandLineState<T> {
@@ -625,7 +625,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
}
// if another new scheme uses old name of this scheme, we must not delete it (as part of rename operation)
val renamed = externalInfo != null && fileNameWithoutExtension !== currentFileNameWithoutExtension && nameGenerator.isUnique(currentFileNameWithoutExtension)
val renamed = externalInfo != null && fileNameWithoutExtension !== currentFileNameWithoutExtension && currentFileNameWithoutExtension != null && nameGenerator.isUnique(currentFileNameWithoutExtension)
if (providerPath == null) {
if (useVfs) {
var file: VirtualFile? = null
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 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.
@@ -213,7 +213,7 @@ public abstract class RunManager {
* @param isShared true if the configuration is marked as shared (stored in the versioned part of the project files), false if it's local
* (stored in the workspace file).
*/
public abstract void addConfiguration(final RunnerAndConfigurationSettings settings, final boolean isShared);
public abstract void addConfiguration(@NotNull RunnerAndConfigurationSettings settings, boolean isShared);
/**
* Marks the specified run configuration as recently used (the temporary run configurations are deleted in LRU order).
@@ -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.
@@ -59,8 +59,7 @@ public abstract class RunConfigurationExtensionBase<T extends RunConfigurationBa
* @param runConfiguration the run configuration being serialized.
* @param element the element into which the settings should be persisted,
*/
protected void writeExternal(@NotNull final T runConfiguration,
@NotNull final Element element) throws WriteExternalException {
protected void writeExternal(@NotNull T runConfiguration, @NotNull Element element) {
throw new WriteExternalException();
}
@@ -13,16 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.execution.configurations;
package com.intellij.execution.configurations
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.runners.ProgramRunner
public interface ConfigurationInfoProvider {
ProgramRunner getRunner();
interface ConfigurationInfoProvider {
val runner: ProgramRunner<*>
RunConfiguration getConfiguration();
val configuration: RunConfiguration
RunnerSettings getRunnerSettings();
val runnerSettings: RunnerSettings
ConfigurationPerRunnerSettings getConfigurationSettings();
val configurationSettings: ConfigurationPerRunnerSettings
}
@@ -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.
@@ -71,8 +71,10 @@ public abstract class ModuleBasedConfiguration<ConfigurationModule extends RunCo
myModule.readExternal(element);
}
protected void writeModule(final Element element) {
myModule.writeExternal(element);
protected void writeModule(@NotNull Element element) {
if (myModule.getModule() != null) {
myModule.writeExternal(element);
}
}
public Collection<Module> getAllModules() {
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.execution.configurations;
import com.intellij.execution.ExecutionException;
@@ -30,7 +29,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -126,22 +124,18 @@ public class UnknownRunConfiguration implements RunConfiguration, WithoutOwnBefo
@Override
public void readExternal(final Element element) throws InvalidDataException {
myStoredElement = (Element) element.clone();
myStoredElement = element.clone();
}
@Override
public void writeExternal(final Element element) throws WriteExternalException {
if (myStoredElement != null) {
final List attributeList = myStoredElement.getAttributes();
for (Object anAttributeList : attributeList) {
final Attribute a = (Attribute) anAttributeList;
for (Attribute a : myStoredElement.getAttributes()) {
element.setAttribute(a.getName(), a.getValue());
}
final List list = myStoredElement.getChildren();
for (Object child : list) {
final Element c = (Element) child;
element.addContent((Element) c.clone());
for (Element child : myStoredElement.getChildren()) {
element.addContent(child.clone());
}
}
}
@@ -153,7 +147,7 @@ public class UnknownRunConfiguration implements RunConfiguration, WithoutOwnBefo
myPanel = new JPanel();
myPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 50, 0));
myPanel.add(new JLabel("This configuration cannot be edited", JLabel.CENTER));
myPanel.add(new JLabel("This configuration cannot be edited", SwingConstants.CENTER));
}
@Override
@@ -62,11 +62,11 @@ import java.util.concurrent.ConcurrentSkipListMap;
public abstract class RunManagerImpl extends RunManagerEx implements PersistentStateComponent<Element>, NamedComponent, Disposable {
protected static final Logger LOG = Logger.getInstance(RunManagerImpl.class);
private final Project myProject;
final Project myProject;
private final Map<String, ConfigurationType> myTypesByName = new LinkedHashMap<>();
private final Map<String, RunnerAndConfigurationSettings> myTemplateConfigurationsMap = new ConcurrentSkipListMap<>();
protected final Map<String, RunnerAndConfigurationSettings> myTemplateConfigurationsMap = new ConcurrentSkipListMap<>();
private final Map<String, RunnerAndConfigurationSettings> myConfigurations =
new LinkedHashMap<>(); // template configurations are not included here
private final Map<String, Boolean> mySharedConfigurations = new ConcurrentHashMap<>();
@@ -116,6 +116,10 @@ public abstract class RunManagerImpl extends RunManagerEx implements PersistentS
});
}
public static RunManagerImpl getInstanceImpl(@NotNull Project project) {
return (RunManagerImpl)RunManager.getInstance(project);
}
// separate method needed for tests
public final void initializeConfigurationTypes(@NotNull final ConfigurationType[] factories) {
Arrays.sort(factories, Comparator.comparing(ConfigurationType::getDisplayName));
@@ -326,15 +330,14 @@ public abstract class RunManagerImpl extends RunManagerEx implements PersistentS
if (template.getConfiguration() instanceof UnknownRunConfiguration) {
((UnknownRunConfiguration)template.getConfiguration()).setDoNotStore(true);
}
myTemplateConfigurationsMap.put(factory.getType().getId() + "." + factory.getName(), template);
}
return template;
}
@Override
public void addConfiguration(RunnerAndConfigurationSettings settings,
boolean shared,
List<BeforeRunTask> tasks, boolean addEnabledTemplateTasksIfAbsent) {
public void addConfiguration(RunnerAndConfigurationSettings settings, boolean shared, List<BeforeRunTask> tasks, boolean addEnabledTemplateTasksIfAbsent) {
String existingId = findExistingConfigurationId(settings);
String newId = settings.getUniqueID();
RunnerAndConfigurationSettings existingSettings = null;
@@ -365,10 +368,14 @@ public abstract class RunManagerImpl extends RunManagerEx implements PersistentS
myDispatcher.getMulticaster().runConfigurationChanged(settings, existingId);
}
else {
myDispatcher.getMulticaster().runConfigurationAdded(settings);
runConfigurationAdded(settings);
}
}
protected void runConfigurationAdded(@NotNull RunnerAndConfigurationSettings settings) {
myDispatcher.getMulticaster().runConfigurationAdded(settings);
}
@Override
public void refreshUsagesList(RunProfile profile) {
if (!(profile instanceof RunConfiguration)) return;
@@ -568,35 +575,21 @@ public abstract class RunManagerImpl extends RunManagerEx implements PersistentS
@Nullable
public Element getState(@NotNull Element parentNode) {
// writes temporary configurations here
writeContext(parentNode);
if (myConfigurations.size() > 1) {
JDOMExternalizableStringList order = null;
for (RunnerAndConfigurationSettings each : myConfigurations.values()) {
if (each.getType() instanceof UnknownConfigurationType) {
continue;
}
for (RunnerAndConfigurationSettings configuration : myTemplateConfigurationsMap.values()) {
if (configuration.getConfiguration() instanceof UnknownRunConfiguration &&
((UnknownRunConfiguration)configuration.getConfiguration()).isDoNotStore()) {
continue;
if (order == null) {
order = new JDOMExternalizableStringList();
}
order.add(each.getUniqueID());
}
addConfigurationElement(parentNode, configuration);
}
for (RunnerAndConfigurationSettings configuration : getStableConfigurations(false)) {
addConfigurationElement(parentNode, configuration);
}
JDOMExternalizableStringList order = null;
for (RunnerAndConfigurationSettings each : myConfigurations.values()) {
if (each.getType() instanceof UnknownConfigurationType) {
continue;
if (order != null) {
order.writeExternal(parentNode);
}
if (order == null) {
order = new JDOMExternalizableStringList();
}
order.add(each.getUniqueID());
}
if (order != null) {
order.writeExternal(parentNode);
}
final JDOMExternalizableStringList recentList = new JDOMExternalizableStringList();
@@ -624,10 +617,17 @@ public abstract class RunManagerImpl extends RunManagerEx implements PersistentS
return parentNode;
}
public void writeContext(@NotNull Element parentNode) {
public void writeContext(@NotNull Element element) {
Collection<RunnerAndConfigurationSettings> values = new ArrayList<>(myConfigurations.values());
for (RunnerAndConfigurationSettings configurationSettings : values) {
if (configurationSettings.isTemporary()) {
addConfigurationElement(element, configurationSettings, CONFIGURATION);
}
}
RunnerAndConfigurationSettings selected = getSelectedConfiguration();
if (selected != null) {
parentNode.setAttribute(SELECTED_ATTR, selected.getUniqueID());
element.setAttribute(SELECTED_ATTR, selected.getUniqueID());
}
}
@@ -671,7 +671,7 @@ public abstract class RunManagerImpl extends RunManagerEx implements PersistentS
}
}
Element methodsElement = new Element(METHOD);
Element methodsElement = null;
for (int i = 0, size = tasks.size(); i < size; i++) {
BeforeRunTask task = tasks.get(i);
int j = 0;
@@ -690,9 +690,16 @@ public abstract class RunManagerImpl extends RunManagerEx implements PersistentS
Element child = new Element(OPTION);
child.setAttribute(NAME_ATTR, task.getProviderId().toString());
task.writeExternal(child);
if (methodsElement == null) {
methodsElement = new Element(METHOD);
}
methodsElement.addContent(child);
}
configurationElement.addContent(methodsElement);
if (methodsElement != null) {
configurationElement.addContent(methodsElement);
}
}
@Override
@@ -844,7 +851,7 @@ public abstract class RunManagerImpl extends RunManagerEx implements PersistentS
else {
addConfiguration(settings, isShared, tasks, true);
if (Boolean.parseBoolean(element.getAttributeValue(SELECTED_ATTR))) {
//to support old style
// to support old style
setSelectedConfiguration(settings);
}
}
@@ -1237,14 +1244,10 @@ public abstract class RunManagerImpl extends RunManagerEx implements PersistentS
}
@Override
public void addConfiguration(final RunnerAndConfigurationSettings settings, final boolean isShared) {
public void addConfiguration(@NotNull RunnerAndConfigurationSettings settings, boolean isShared) {
addConfiguration(settings, isShared, getTemplateBeforeRunTasks(settings.getConfiguration()), false);
}
public static RunManagerImpl getInstanceImpl(final Project project) {
return (RunManagerImpl)RunManager.getInstance(project);
}
void removeNotExistingSharedConfigurations(@NotNull Set<String> existing) {
List<RunnerAndConfigurationSettings> removed = null;
for (Iterator<Map.Entry<String, RunnerAndConfigurationSettings>> it = myConfigurations.entrySet().iterator(); it.hasNext(); ) {
@@ -25,6 +25,7 @@ import com.intellij.openapi.components.PathMacroManager
import com.intellij.openapi.components.PersistentStateComponent
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.extensions.ExtensionException
import com.intellij.openapi.options.SchemeState
import com.intellij.openapi.util.*
import com.intellij.openapi.util.text.StringUtil
import com.intellij.util.SmartList
@@ -39,7 +40,6 @@ private val RUNNER_ID = "RunnerId"
private val CONFIGURATION_TYPE_ATTRIBUTE = "type"
private val FACTORY_NAME_ATTRIBUTE = "factoryName"
private val FOLDER_NAME = "folderName"
internal val TEMPLATE_FLAG_ATTRIBUTE = "default"
val NAME_ATTR = "name"
val DUMMY_ELEMENT_NAME = "dummy"
private val TEMPORARY_ATTRIBUTE = "temporary"
@@ -52,26 +52,29 @@ class RunnerAndConfigurationSettingsImpl : Cloneable, RunnerAndConfigurationSett
companion object {
@JvmField
val SINGLETON = "singleton"
@JvmField
internal val TEMPLATE_FLAG_ATTRIBUTE = "default"
}
private val manager: RunManagerImpl
private var myConfiguration: RunConfiguration? = null
private var myIsTemplate: Boolean = false
private var configuration: RunConfiguration? = null
private var isTemplate: Boolean = false
private val myRunnerSettings = object : RunnerItem<RunnerSettings>("RunnerSettings") {
private val runnerSettings = object : RunnerItem<RunnerSettings>("RunnerSettings") {
override fun createSettings(runner: ProgramRunner<*>) = runner.createConfigurationData(InfoProvider(runner))
}
private val myConfigurationPerRunnerSettings = object : RunnerItem<ConfigurationPerRunnerSettings>("ConfigurationWrapper") {
override fun createSettings(runner: ProgramRunner<*>) = myConfiguration!!.createRunnerSettings(InfoProvider(runner))
private val configurationPerRunnerSettings = object : RunnerItem<ConfigurationPerRunnerSettings>("ConfigurationWrapper") {
override fun createSettings(runner: ProgramRunner<*>) = configuration!!.createRunnerSettings(InfoProvider(runner))
}
private var myTemporary: Boolean = false
private var myEditBeforeRun: Boolean = false
private var myActivateToolWindowBeforeRun = true
private var mySingleton: Boolean = false
private var myWasSingletonSpecifiedExplicitly: Boolean = false
private var myFolderName: String? = null
private var isTemporary: Boolean = false
private var isEditBeforeRun: Boolean = false
private var isActivateToolWindowBeforeRun = true
private var singleton: Boolean = false
private var wasSingletonSpecifiedExplicitly: Boolean = false
private var folderName: String? = null
constructor(manager: RunManagerImpl) {
this.manager = manager
@@ -79,93 +82,99 @@ class RunnerAndConfigurationSettingsImpl : Cloneable, RunnerAndConfigurationSett
constructor(manager: RunManagerImpl, configuration: RunConfiguration, isTemplate: Boolean) {
this.manager = manager
myConfiguration = configuration
myIsTemplate = isTemplate
this.configuration = configuration
this.isTemplate = isTemplate
}
override fun getFactory() = myConfiguration?.factory
override fun getFactory() = configuration?.factory
override fun isTemplate() = myIsTemplate
override fun isTemplate() = isTemplate
override fun isTemporary() = myTemporary
override fun isTemporary() = isTemporary
override fun setTemporary(temporary: Boolean) {
myTemporary = temporary
isTemporary = temporary
}
override fun getConfiguration(): RunConfiguration = myConfiguration!!
override fun getConfiguration(): RunConfiguration = configuration!!
override fun createFactory() = Factory<RunnerAndConfigurationSettings> {
val configuration = myConfiguration!!
val configuration = configuration!!
RunnerAndConfigurationSettingsImpl(manager, configuration.factory.createConfiguration(ExecutionBundle.message("default.run.configuration.name"), configuration), false)
}
override fun setName(name: String) {
myConfiguration!!.name = name
configuration!!.name = name
}
override fun getName() = myConfiguration!!.name
override fun getName(): String {
val configuration = configuration!!
if (isTemplate) {
return "<template> of ${configuration.factory.name}"
}
return configuration.name
}
override fun getUniqueID(): String {
val configuration = myConfiguration!!
val configuration = configuration!!
return "${configuration.type.displayName}.${configuration.name}${(configuration as? UnknownRunConfiguration)?.uniqueID ?: ""}"
}
override fun setEditBeforeRun(b: Boolean) {
myEditBeforeRun = b
isEditBeforeRun = b
}
override fun isEditBeforeRun() = myEditBeforeRun
override fun isEditBeforeRun() = isEditBeforeRun
override fun setActivateToolWindowBeforeRun(activate: Boolean) {
myActivateToolWindowBeforeRun = activate
isActivateToolWindowBeforeRun = activate
}
override fun isActivateToolWindowBeforeRun() = myActivateToolWindowBeforeRun
override fun isActivateToolWindowBeforeRun() = isActivateToolWindowBeforeRun
override fun setSingleton(singleton: Boolean) {
mySingleton = singleton
this.singleton = singleton
}
override fun isSingleton() = mySingleton
override fun isSingleton() = singleton
override fun setFolderName(folderName: String?) {
myFolderName = folderName
this.folderName = folderName
}
override fun getFolderName() = myFolderName
override fun getFolderName() = folderName
private fun getFactory(element: Element): ConfigurationFactory? {
val typeName = element.getAttributeValue(CONFIGURATION_TYPE_ATTRIBUTE)
val factoryName = element.getAttributeValue(FACTORY_NAME_ATTRIBUTE)
return manager.getFactory(typeName, factoryName, !myIsTemplate)
return manager.getFactory(typeName, factoryName, !isTemplate)
}
fun readExternal(element: Element) {
myIsTemplate = java.lang.Boolean.parseBoolean(element.getAttributeValue(TEMPLATE_FLAG_ATTRIBUTE))
myTemporary = java.lang.Boolean.parseBoolean(element.getAttributeValue(TEMPORARY_ATTRIBUTE)) || TEMP_CONFIGURATION == element.name
myEditBeforeRun = java.lang.Boolean.parseBoolean(element.getAttributeValue(EDIT_BEFORE_RUN))
isTemplate = java.lang.Boolean.parseBoolean(element.getAttributeValue(TEMPLATE_FLAG_ATTRIBUTE))
isTemporary = java.lang.Boolean.parseBoolean(element.getAttributeValue(TEMPORARY_ATTRIBUTE)) || TEMP_CONFIGURATION == element.name
isEditBeforeRun = java.lang.Boolean.parseBoolean(element.getAttributeValue(EDIT_BEFORE_RUN))
val value = element.getAttributeValue(ACTIVATE_TOOLWINDOW_BEFORE_RUN)
myActivateToolWindowBeforeRun = value == null || java.lang.Boolean.parseBoolean(value)
myFolderName = element.getAttributeValue(FOLDER_NAME)
isActivateToolWindowBeforeRun = value == null || java.lang.Boolean.parseBoolean(value)
folderName = element.getAttributeValue(FOLDER_NAME)
val factory = getFactory(element) ?: return
myWasSingletonSpecifiedExplicitly = false
if (myIsTemplate) {
mySingleton = factory.isConfigurationSingletonByDefault
wasSingletonSpecifiedExplicitly = false
if (isTemplate) {
singleton = factory.isConfigurationSingletonByDefault
}
else {
val singletonStr = element.getAttributeValue(SINGLETON)
if (StringUtil.isEmpty(singletonStr)) {
mySingleton = factory.isConfigurationSingletonByDefault
singleton = factory.isConfigurationSingletonByDefault
}
else {
myWasSingletonSpecifiedExplicitly = true
mySingleton = java.lang.Boolean.parseBoolean(singletonStr)
wasSingletonSpecifiedExplicitly = true
singleton = java.lang.Boolean.parseBoolean(singletonStr)
}
}
myConfiguration = if (myIsTemplate) {
val configuration = if (isTemplate) {
manager.getConfigurationTemplate(factory).configuration
}
else {
@@ -174,29 +183,31 @@ class RunnerAndConfigurationSettingsImpl : Cloneable, RunnerAndConfigurationSett
manager.doCreateConfiguration(element.getAttributeValue(NAME_ATTR), factory, false)
}
PathMacroManager.getInstance(myConfiguration!!.project).expandPaths(element)
if (myConfiguration is ModuleBasedConfiguration<*>) {
(myConfiguration as ModuleBasedConfiguration<*>).configurationModule.module?.let {
this.configuration = configuration
PathMacroManager.getInstance(configuration.project).expandPaths(element)
if (configuration is ModuleBasedConfiguration<*>) {
configuration.configurationModule.module?.let {
PathMacroManager.getInstance(it).expandPaths(element)
}
}
if (myConfiguration is PersistentStateComponent<*>) {
(myConfiguration as PersistentStateComponent<*>).deserializeAndLoadState(element)
if (configuration is PersistentStateComponent<*>) {
configuration.deserializeAndLoadState(element)
}
else {
myConfiguration!!.readExternal(element)
configuration.readExternal(element)
}
myRunnerSettings.loadState(element)
myConfigurationPerRunnerSettings.loadState(element)
runnerSettings.loadState(element)
configurationPerRunnerSettings.loadState(element)
}
fun writeExternal(element: Element) {
val configuration = myConfiguration
val configuration = configuration
val factory = configuration!!.factory
if (configuration !is UnknownRunConfiguration) {
if (myIsTemplate) {
if (isTemplate) {
element.setAttribute(TEMPLATE_FLAG_ATTRIBUTE, "true")
}
else {
@@ -205,8 +216,8 @@ class RunnerAndConfigurationSettingsImpl : Cloneable, RunnerAndConfigurationSett
element.setAttribute(CONFIGURATION_TYPE_ATTRIBUTE, factory.type.id)
element.setAttribute(FACTORY_NAME_ATTRIBUTE, factory.name)
if (myFolderName != null) {
element.setAttribute(FOLDER_NAME, myFolderName!!)
if (folderName != null) {
element.setAttribute(FOLDER_NAME, folderName!!)
}
if (isEditBeforeRun) {
@@ -215,25 +226,29 @@ class RunnerAndConfigurationSettingsImpl : Cloneable, RunnerAndConfigurationSett
if (!isActivateToolWindowBeforeRun) {
element.setAttribute(ACTIVATE_TOOLWINDOW_BEFORE_RUN, "false")
}
if (myWasSingletonSpecifiedExplicitly || mySingleton != factory.isConfigurationSingletonByDefault) {
element.setAttribute(SINGLETON, mySingleton.toString())
if (wasSingletonSpecifiedExplicitly || singleton != factory.isConfigurationSingletonByDefault) {
element.setAttribute(SINGLETON, singleton.toString())
}
if (myTemporary) {
if (isTemporary) {
element.setAttribute(TEMPORARY_ATTRIBUTE, "true")
}
}
serializeConfigurationInto(configuration, element)
if (configuration !is UnknownRunConfiguration) {
runnerSettings.getState(element)
configurationPerRunnerSettings.getState(element)
}
}
private fun serializeConfigurationInto(configuration: RunConfiguration, element: Element) {
if (configuration is PersistentStateComponent<*>) {
configuration.state!!.serializeInto<Any>(element)
configuration.state!!.serializeInto(element)
}
else {
configuration.writeExternal(element)
}
if (configuration !is UnknownRunConfiguration) {
myRunnerSettings.getState(element)
myConfigurationPerRunnerSettings.getState(element)
}
}
override fun writeScheme(): Element {
@@ -248,19 +263,19 @@ class RunnerAndConfigurationSettingsImpl : Cloneable, RunnerAndConfigurationSett
}
override fun checkSettings(executor: Executor?) {
val configuration = myConfiguration!!
val configuration = configuration!!
configuration.checkConfiguration()
if (configuration !is RunConfigurationBase) {
return
}
val runners = THashSet<ProgramRunner<*>>()
runners.addAll(myRunnerSettings.settings.keys)
runners.addAll(myConfigurationPerRunnerSettings.settings.keys)
runners.addAll(runnerSettings.settings.keys)
runners.addAll(configurationPerRunnerSettings.settings.keys)
for (runner in runners) {
if (executor == null || runner.canRun(executor.id, configuration)) {
configuration.checkRunnerSettings(runner, myRunnerSettings.settings[runner],
myConfigurationPerRunnerSettings.settings[runner])
configuration.checkRunnerSettings(runner, runnerSettings.settings[runner],
configurationPerRunnerSettings.settings[runner])
}
}
if (executor != null) {
@@ -269,25 +284,25 @@ class RunnerAndConfigurationSettingsImpl : Cloneable, RunnerAndConfigurationSett
}
override fun canRunOn(target: ExecutionTarget): Boolean {
val configuration = myConfiguration
val configuration = configuration
return if (configuration is TargetAwareRunProfile) configuration.canRunOn(target) else true
}
override fun getRunnerSettings(runner: ProgramRunner<*>) = myRunnerSettings.getOrCreateSettings(runner)
override fun getRunnerSettings(runner: ProgramRunner<*>) = runnerSettings.getOrCreateSettings(runner)
override fun getConfigurationSettings(runner: ProgramRunner<*>) = myConfigurationPerRunnerSettings.getOrCreateSettings(runner)
override fun getConfigurationSettings(runner: ProgramRunner<*>) = configurationPerRunnerSettings.getOrCreateSettings(runner)
override fun getType() = myConfiguration?.type
override fun getType() = configuration?.type
public override fun clone(): RunnerAndConfigurationSettings {
val copy = RunnerAndConfigurationSettingsImpl(manager, myConfiguration!!.clone(), false)
val copy = RunnerAndConfigurationSettingsImpl(manager, configuration!!.clone(), false)
copy.importRunnerAndConfigurationSettings(this)
return copy
}
fun importRunnerAndConfigurationSettings(template: RunnerAndConfigurationSettingsImpl) {
importFromTemplate(template.myRunnerSettings, myRunnerSettings)
importFromTemplate(template.myConfigurationPerRunnerSettings, myConfigurationPerRunnerSettings)
importFromTemplate(template.runnerSettings, runnerSettings)
importFromTemplate(template.configurationPerRunnerSettings, configurationPerRunnerSettings)
isSingleton = template.isSingleton
isEditBeforeRun = template.isEditBeforeRun
@@ -326,14 +341,36 @@ class RunnerAndConfigurationSettingsImpl : Cloneable, RunnerAndConfigurationSett
return "${if (type == null) "" else "${type.displayName}: "}${if (isTemplate) "<template>" else name}"
}
private inner class InfoProvider(private val runner: ProgramRunner<*>) : ConfigurationInfoProvider {
override fun getRunner() = runner
private inner class InfoProvider(override val runner: ProgramRunner<*>) : ConfigurationInfoProvider {
override val configuration: RunConfiguration
get() = RunnerAndConfigurationSettingsImpl@this.configuration
override fun getConfiguration() = myConfiguration
override val runnerSettings: RunnerSettings
get() = this@RunnerAndConfigurationSettingsImpl.getRunnerSettings(runner)
override fun getRunnerSettings() = this@RunnerAndConfigurationSettingsImpl.getRunnerSettings(runner)
override val configurationSettings: ConfigurationPerRunnerSettings
get() = this@RunnerAndConfigurationSettingsImpl.getConfigurationSettings(runner)
}
override fun getConfigurationSettings() = this@RunnerAndConfigurationSettingsImpl.getConfigurationSettings(runner)
override fun getSchemeState(): SchemeState? {
val configuration = configuration
if (configuration is UnknownRunConfiguration) {
return if (configuration.isDoNotStore) SchemeState.NON_PERSISTENT else SchemeState.UNCHANGED
}
if (isTemplate && configuration != null) {
val templateConfiguration = configuration.factory.createTemplateConfiguration(manager.myProject, manager)
val templateState = Element("state")
serializeConfigurationInto(templateConfiguration, templateState)
val state = Element("state")
serializeConfigurationInto(configuration, state)
if (JDOMUtil.areElementsEqual(state, templateState)) {
return SchemeState.NON_PERSISTENT
}
}
return null
}
private abstract inner class RunnerItem<T>(private val childTagName: String) {
@@ -372,7 +409,7 @@ class RunnerAndConfigurationSettingsImpl : Cloneable, RunnerAndConfigurationSett
else {
LOG.error("More than one runner found for ID: $runnerId")
for (executor in ExecutorRegistry.getInstance().registeredExecutors) {
runnersById.firstOrNull { it.canRun(executor.id, myConfiguration!!) }?.let {
runnersById.firstOrNull { it.canRun(executor.id, configuration!!) }?.let {
return it
}
}
@@ -383,7 +420,7 @@ class RunnerAndConfigurationSettingsImpl : Cloneable, RunnerAndConfigurationSett
fun getState(element: Element) {
val runnerSettings = SmartList<Element>()
for (runner in settings.keys) {
val settings = this.settings[runner]
val settings = this.settings.get(runner)
val wasLoaded = loadedIds.contains(runner.runnerId)
if (settings == null && !wasLoaded) {
continue
@@ -441,7 +478,7 @@ class RunnerAndConfigurationSettingsImpl : Cloneable, RunnerAndConfigurationSett
settings.put(runner, result)
}
catch (ignored: AbstractMethodError) {
LOG.error("Update failed for: ${myConfiguration!!.type.displayName}, runner: ${runner.runnerId}", ExtensionException(runner.javaClass))
LOG.error("Update failed for: ${configuration!!.type.displayName}, runner: ${runner.runnerId}", ExtensionException(runner.javaClass))
}
}
@@ -16,6 +16,9 @@
package com.intellij.execution.impl
import com.intellij.configurationStore.*
import com.intellij.execution.RunnerAndConfigurationSettings
import com.intellij.execution.configurations.ConfigurationFactory
import com.intellij.execution.configurations.UnknownRunConfiguration
import com.intellij.ide.util.PropertiesComponent
import com.intellij.openapi.options.Scheme
import com.intellij.openapi.options.SchemeManagerFactory
@@ -23,6 +26,7 @@ import com.intellij.openapi.options.SchemeState
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.InvalidDataException
import org.jdom.Element
import java.util.*
import java.util.function.Function
internal class WorkspaceRunManager(project: Project, propertiesComponent: PropertiesComponent) : RunManagerImpl(project, propertiesComponent) {
@@ -40,7 +44,7 @@ internal class WorkspaceRunManager(project: Project, propertiesComponent: Proper
LOG.error(e)
}
val factory = settings.factory ?: return UnknownRunConfigurationScheme(name, dataHolder)
val factory = settings.factory ?: return UnknownRunConfigurationScheme(name)
doLoadConfiguration(element, false, settings, factory)
return settings
}
@@ -77,33 +81,59 @@ internal class WorkspaceRunManager(project: Project, propertiesComponent: Proper
}
schemeManager.reload()
// val children = parentNode.getChildren(CONFIGURATION)
// val sortedElements = children.toTypedArray()
// // ensure templates are loaded first
// Arrays.sort(sortedElements) { a, b ->
// val aDefault = java.lang.Boolean.valueOf(a.getAttributeValue("default", "false"))!!
// val bDefault = java.lang.Boolean.valueOf(b.getAttributeValue("default", "false"))!!
// if (aDefault == bDefault) 0 else if (aDefault) -1 else 1
// }
super.loadState(parentNode)
}
override fun writeContext(parentNode: Element) {
override fun getState(): Element {
val element = Element("state")
schemeManager.save()
schemeManagerProvider.writeState(parentNode)
// template rc in the end
schemeManagerProvider.writeState(element, Comparator { n1, n2 ->
val w1 = if (n1.startsWith("<template> of ")) 1 else 0
val w2 = if (n2.startsWith("<template> of ")) 1 else 0
if (w1 != w2) {
w1 - w2
}
else {
n1.compareTo(n2)
}
})
super.getState(element)
return element
}
override fun getState(): Element {
val parentNode = Element("state")
super.getState(parentNode)
return parentNode
override fun runConfigurationAdded(settings: RunnerAndConfigurationSettings) {
if (settings.isTemporary) {
schemeManager.addScheme(settings as RunConfigurationScheme)
}
super.runConfigurationAdded(settings)
}
override fun getConfigurationTemplate(factory: ConfigurationFactory): RunnerAndConfigurationSettings {
val key = "${factory.type.id}.${factory.name}"
var template = myTemplateConfigurationsMap.get(key)
if (template == null) {
template = RunnerAndConfigurationSettingsImpl(this, factory.createTemplateConfiguration(myProject, this), true)
template.isSingleton = factory.isConfigurationSingletonByDefault
(template.configuration as? UnknownRunConfiguration)?.let {
it.isDoNotStore = true
}
schemeManager.addScheme(template)
myTemplateConfigurationsMap.put(key, template)
}
return template
}
}
interface RunConfigurationScheme : Scheme
private class UnknownRunConfigurationScheme(private val name: String, private val dataHolder: SchemeDataHolder<RunConfigurationScheme>) : RunConfigurationScheme, SerializableScheme {
private class UnknownRunConfigurationScheme(private val name: String) : RunConfigurationScheme, SerializableScheme {
override fun getSchemeState() = SchemeState.UNCHANGED
override fun writeScheme() = throw AssertionError("Must be not called")
@@ -16,13 +16,16 @@
package com.intellij.configurationStore
import com.intellij.openapi.components.RoamingType
import com.intellij.openapi.util.io.FileUtil
import com.intellij.util.ArrayUtil
import com.intellij.util.PathUtilRt
import com.intellij.util.containers.ContainerUtil
import com.intellij.util.loadElement
import com.intellij.util.text.UniqueNameGenerator
import com.intellij.util.toByteArray
import org.jdom.Element
import java.io.InputStream
import java.util.*
class SchemeManagerIprProvider(private val subStateTagName: String) : StreamProvider {
private val nameToData = ContainerUtil.newConcurrentMap<String, ByteArray>()
@@ -61,6 +64,7 @@ class SchemeManagerIprProvider(private val subStateTagName: String) : StreamProv
return
}
val nameGenerator = UniqueNameGenerator()
for (child in state.getChildren(subStateTagName)) {
var name = nameGetter?.invoke(child) ?: child.getAttributeValue("name")
if (name == null) {
@@ -75,13 +79,18 @@ class SchemeManagerIprProvider(private val subStateTagName: String) : StreamProv
continue
}
nameToData.put("$name.xml", child.toByteArray())
nameToData.put(nameGenerator.generateUniqueName(FileUtil.sanitizeFileName("$name.xml", false)), child.toByteArray())
}
}
fun writeState(state: Element) {
fun writeState(state: Element, comparator: Comparator<String>? = null) {
val names = nameToData.keys.toTypedArray()
names.sort()
if (comparator == null) {
names.sort()
}
else {
names.sortWith(comparator)
}
for (name in names) {
nameToData.get(name)?.let { state.addContent(loadElement(it.inputStream())) }
}
@@ -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.
@@ -1193,12 +1193,7 @@ public class FileUtil extends FileUtilRt {
public static String sanitizeFileName(@NotNull String name) {
return sanitizeFileName(name, true);
}
/** @deprecated use {@link #sanitizeFileName(String, boolean)} (to be removed in IDEA 17) */
public static String sanitizeName(@NotNull String name) {
return sanitizeFileName(name, false);
}
@NotNull
public static String sanitizeFileName(@NotNull String name, boolean strict) {
StringBuilder result = null;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 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.
@@ -17,7 +17,7 @@ package com.intellij.util.text;
import com.intellij.openapi.util.Condition;
import com.intellij.util.Function;
import com.intellij.util.containers.HashSet;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -28,7 +28,7 @@ import java.util.Set;
* @author peter
*/
public class UniqueNameGenerator implements Condition<String> {
private final Set<String> myExistingNames = new HashSet<String>();
private final Set<String> myExistingNames = new THashSet<String>();
public <T> UniqueNameGenerator(@NotNull Collection<T> elements, @Nullable Function<T, String> namer) {
for (final T t : elements) {
@@ -44,7 +44,7 @@ public class UniqueNameGenerator implements Condition<String> {
return isUnique(candidate);
}
public final boolean isUnique(String candidate) {
public final boolean isUnique(@NotNull String candidate) {
return !myExistingNames.contains(candidate);
}
@@ -105,7 +105,7 @@ public class UniqueNameGenerator implements Condition<String> {
return result;
}
public void addExistingName(String result) {
public void addExistingName(@NotNull String result) {
myExistingNames.add(result);
}
@@ -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.
@@ -35,7 +35,6 @@ import com.intellij.openapi.components.BaseComponent;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.extensions.AreaInstance;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.pom.Navigatable;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.lw.LwComponent;
@@ -127,11 +126,6 @@ public class SnapShooterConfigurationExtension extends RunConfigurationExtension
public void readExternal(@NotNull RunConfigurationBase runConfiguration, @NotNull Element element) throws InvalidDataException {
}
@Override
public void writeExternal(@NotNull RunConfigurationBase runConfiguration, @NotNull Element element) throws WriteExternalException {
throw new WriteExternalException();
}
@Override
public void extendCreatedConfiguration(@NotNull RunConfigurationBase runJavaConfiguration, @NotNull Location location) {
}