2 * Copyright 2000-2015 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.execution.configuration;
18 import com.google.common.collect.ImmutableMap;
19 import com.intellij.execution.configurations.GeneralCommandLine;
20 import com.intellij.util.containers.ContainerUtil;
21 import org.jdom.Element;
22 import org.jetbrains.annotations.NonNls;
23 import org.jetbrains.annotations.NotNull;
25 import java.util.LinkedHashMap;
29 * Holds environment variables configuration:
31 * <li>list of user-defined environment variables</li>
32 * <li>boolean flag - whether to pass system environment</li>
34 * Instances of this class are immutable objects, so it can be safely passed across threads.
36 public class EnvironmentVariablesData {
38 public static final EnvironmentVariablesData DEFAULT = new EnvironmentVariablesData(ImmutableMap.<String, String>of(), true);
39 @NonNls private static final String ENVS = "envs";
40 @NonNls private static final String PASS_PARENT_ENVS = "pass-parent-envs";
41 @NonNls private static final String ENV = EnvironmentVariablesComponent.ENV;
42 @NonNls private static final String NAME = EnvironmentVariablesComponent.NAME;
43 @NonNls private static final String VALUE = EnvironmentVariablesComponent.VALUE;
45 private final ImmutableMap<String, String> myEnvs;
46 private final boolean myPassParentEnvs;
48 private EnvironmentVariablesData(@NotNull Map<String, String> envs, boolean passParentEnvs) {
49 myEnvs = ImmutableMap.copyOf(envs);
50 myPassParentEnvs = passParentEnvs;
54 * @return immutable Map instance containing user-defined environment variables (iteration order is reliable user-specified)
57 public Map<String, String> getEnvs() {
61 public boolean isPassParentEnvs() {
62 return myPassParentEnvs;
66 public boolean equals(Object o) {
67 if (this == o) return true;
68 if (o == null || getClass() != o.getClass()) return false;
69 EnvironmentVariablesData data = (EnvironmentVariablesData)o;
70 return myPassParentEnvs == data.myPassParentEnvs && myEnvs.equals(data.myEnvs);
74 public int hashCode() {
75 int result = myEnvs.hashCode();
76 result = 31 * result + (myPassParentEnvs ? 1 : 0);
81 public static EnvironmentVariablesData readExternal(@NotNull Element element) {
82 Element envsElement = element.getChild(ENVS);
83 if (envsElement == null) {
86 Map<String, String> envs = ImmutableMap.of();
87 String passParentEnvsStr = envsElement.getAttributeValue(PASS_PARENT_ENVS);
88 boolean passParentEnvs = passParentEnvsStr == null || Boolean.parseBoolean(passParentEnvsStr);
89 for (Element envElement : envsElement.getChildren(ENV)) {
90 String envName = envElement.getAttributeValue(NAME);
91 String envValue = envElement.getAttributeValue(VALUE);
92 if (envName != null && envValue != null) {
94 envs = ContainerUtil.newLinkedHashMap();
96 envs.put(envName, envValue);
99 return create(envs, passParentEnvs);
102 public void writeExternal(@NotNull Element parent) {
103 Element envsElement = new Element(ENVS);
104 if (!myPassParentEnvs) {
105 // Avoid writing pass-parent-envs="true" to minimize changes in xml comparing it to xml written by
106 // com.intellij.execution.configuration.EnvironmentVariablesComponent.writeExternal
107 envsElement.setAttribute(PASS_PARENT_ENVS, Boolean.FALSE.toString());
109 for (Map.Entry<String, String> entry : myEnvs.entrySet()) {
110 Element envElement = new Element(ENV);
111 envElement.setAttribute(NAME, entry.getKey());
112 envElement.setAttribute(VALUE, entry.getValue());
113 envsElement.addContent(envElement);
115 parent.addContent(envsElement);
118 public void configureCommandLine(@NotNull GeneralCommandLine commandLine, boolean consoleParentEnvs) {
119 if (myPassParentEnvs) {
120 commandLine.withParentEnvironmentType(consoleParentEnvs ? GeneralCommandLine.ParentEnvironmentType.CONSOLE
121 : GeneralCommandLine.ParentEnvironmentType.SYSTEM);
124 commandLine.withParentEnvironmentType(GeneralCommandLine.ParentEnvironmentType.NONE);
126 commandLine.withEnvironment(myEnvs);
130 * @param envs Map instance containing user-defined environment variables
131 * (iteration order should be reliable user-specified, like {@link LinkedHashMap} or {@link ImmutableMap})
132 * @param passParentEnvs true if system environment should be passed
135 public static EnvironmentVariablesData create(@NotNull Map<String, String> envs, boolean passParentEnvs) {
136 if (passParentEnvs && envs.isEmpty()) {
139 return new EnvironmentVariablesData(envs, passParentEnvs);