From 1ca026d6a3d975aeb526b0892c86720c6ddb1696 Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Sat, 4 Jul 2015 12:25:11 +0300 Subject: [PATCH] utility class to hold user-defined environment variables and boolean flag whether to pass system environment --- .../EnvironmentVariablesData.java | 129 ++++++++++++++++++ ...entVariablesTextFieldWithBrowseButton.java | 41 +++--- 2 files changed, 153 insertions(+), 17 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesData.java diff --git a/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesData.java b/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesData.java new file mode 100644 index 000000000000..1f4a7b9083ec --- /dev/null +++ b/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesData.java @@ -0,0 +1,129 @@ +/* + * Copyright 2000-2015 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.execution.configuration; + +import com.google.common.collect.ImmutableMap; +import com.intellij.util.containers.ContainerUtil; +import org.jdom.Element; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Holds environment variables configuration: + * + * Instances of this class are immutable objects, so it can be safely passed across threads. + */ +public class EnvironmentVariablesData { + + public static final EnvironmentVariablesData DEFAULT = new EnvironmentVariablesData(ImmutableMap.of(), true); + @NonNls private static final String ENVS = "envs"; + @NonNls private static final String PASS_PARENT_ENVS = "pass-parent-envs"; + @NonNls private static final String ENV = EnvironmentVariablesComponent.ENV; + @NonNls private static final String NAME = EnvironmentVariablesComponent.NAME; + @NonNls private static final String VALUE = EnvironmentVariablesComponent.VALUE; + + private final ImmutableMap myEnvs; + private final boolean myPassParentEnvs; + + private EnvironmentVariablesData(@NotNull Map envs, boolean passParentEnvs) { + myEnvs = ImmutableMap.copyOf(envs); + myPassParentEnvs = passParentEnvs; + } + + /** + * @return immutable Map instance containing user-defined environment variables (iteration order is reliable user-specified) + */ + @NotNull + public Map getEnvs() { + return myEnvs; + } + + public boolean isPassParentEnvs() { + return myPassParentEnvs; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + EnvironmentVariablesData data = (EnvironmentVariablesData)o; + return myPassParentEnvs == data.myPassParentEnvs && myEnvs.equals(data.myEnvs); + } + + @Override + public int hashCode() { + int result = myEnvs.hashCode(); + result = 31 * result + (myPassParentEnvs ? 1 : 0); + return result; + } + + @NotNull + public static EnvironmentVariablesData readExternal(@NotNull Element element) { + Element envsElement = element.getChild(ENVS); + if (envsElement == null) { + return DEFAULT; + } + Map envs = ImmutableMap.of(); + String passParentEnvsStr = element.getAttributeValue(PASS_PARENT_ENVS); + boolean passParentEnvs = passParentEnvsStr == null || Boolean.parseBoolean(passParentEnvsStr); + for (Element envElement : envsElement.getChildren(ENV)) { + String envName = envElement.getAttributeValue(NAME); + String envValue = envElement.getAttributeValue(VALUE); + if (envName != null && envValue != null) { + if (envs.isEmpty()) { + envs = ContainerUtil.newLinkedHashMap(); + } + envs.put(envName, envValue); + } + } + return create(envs, passParentEnvs); + } + + public void writeExternal(@NotNull Element parent) { + Element envsElement = new Element(ENVS); + if (!myPassParentEnvs) { + // Avoid writing pass-parent-envs="true" to minimize changes in xml comparing it to xml written by + // com.intellij.execution.configuration.EnvironmentVariablesComponent.writeExternal + envsElement.setAttribute(PASS_PARENT_ENVS, Boolean.FALSE.toString()); + } + for (Map.Entry entry : myEnvs.entrySet()) { + Element envElement = new Element(ENV); + envElement.setAttribute(NAME, entry.getKey()); + envElement.setAttribute(VALUE, entry.getValue()); + envsElement.addContent(envElement); + } + parent.addContent(envsElement); + } + + /** + * @param envs Map instance containing user-defined environment variables + * (iteration order should be reliable user-specified, like {@link LinkedHashMap} or {@link ImmutableMap}) + * @param passParentEnvs true if system environment should be passed + */ + @NotNull + public static EnvironmentVariablesData create(@NotNull Map envs, boolean passParentEnvs) { + if (passParentEnvs && envs.isEmpty()) { + return DEFAULT; + } + return new EnvironmentVariablesData(envs, passParentEnvs); + } +} diff --git a/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesTextFieldWithBrowseButton.java b/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesTextFieldWithBrowseButton.java index c5d443f5a039..bd68e978818a 100644 --- a/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesTextFieldWithBrowseButton.java +++ b/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesTextFieldWithBrowseButton.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -43,9 +43,7 @@ import java.util.List; public class EnvironmentVariablesTextFieldWithBrowseButton extends TextFieldWithBrowseButton implements UserActivityProviderComponent { - // immutable map instance with reliable user-specified iteration order - private Map myEnvs = Collections.emptyMap(); - private boolean myPassParentEnvs; + private EnvironmentVariablesData myData = EnvironmentVariablesData.DEFAULT; private final List myListeners = ContainerUtil.createLockFreeCopyOnWriteList(); public EnvironmentVariablesTextFieldWithBrowseButton() { @@ -60,21 +58,33 @@ public class EnvironmentVariablesTextFieldWithBrowseButton extends TextFieldWith } /** - * @return unmodifiable Map instance, use {@link #setEnvs(java.util.Map)} to update env vars + * @return unmodifiable Map instance */ @NotNull public Map getEnvs() { - return myEnvs; + return myData.getEnvs(); } /** - * @param envs Map instance with reliable user-specified iteration order, - * like {@link java.util.LinkedHashMap} or {@link com.google.common.collect.ImmutableMap} + * @param envs Map instance containing user-defined environment variables + * (iteration order should be reliable user-specified, like {@link LinkedHashMap} or {@link ImmutableMap}) */ public void setEnvs(@NotNull Map envs) { - myEnvs = ImmutableMap.copyOf(envs); - String envsStr = stringifyEnvs(myEnvs); - setText(envsStr); + setData(EnvironmentVariablesData.create(envs, myData.isPassParentEnvs())); + } + + @NotNull + public EnvironmentVariablesData getData() { + return myData; + } + + public void setData(@NotNull EnvironmentVariablesData data) { + EnvironmentVariablesData oldData = myData; + myData = data; + setText(stringifyEnvs(data.getEnvs())); + if (oldData.isPassParentEnvs() != data.isPassParentEnvs()) { + fireStateChanged(); + } } @NotNull @@ -93,14 +103,11 @@ public class EnvironmentVariablesTextFieldWithBrowseButton extends TextFieldWith } public boolean isPassParentEnvs() { - return myPassParentEnvs; + return myData.isPassParentEnvs(); } public void setPassParentEnvs(boolean passParentEnvs) { - if (myPassParentEnvs != passParentEnvs) { - myPassParentEnvs = passParentEnvs; - fireStateChanged(); - } + setData(EnvironmentVariablesData.create(myData.getEnvs(), passParentEnvs)); } @Override @@ -152,7 +159,7 @@ public class EnvironmentVariablesTextFieldWithBrowseButton extends TextFieldWith protected MyEnvironmentVariablesDialog() { super(EnvironmentVariablesTextFieldWithBrowseButton.this, true); myEnvVariablesTable = new EnvVariablesTable(); - myEnvVariablesTable.setValues(convertToVariables(myEnvs, false)); + myEnvVariablesTable.setValues(convertToVariables(myData.getEnvs(), false)); myUseDefaultCb.setSelected(isPassParentEnvs()); myWholePanel.add(myEnvVariablesTable.getComponent(), BorderLayout.CENTER);