cleanup yellow code, add toString for easier debugging, javadoc
[idea/community.git] / platform / lang-impl / src / com / intellij / execution / configuration / EnvironmentVariablesData.java
1 /*
2  * Copyright 2000-2015 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package com.intellij.execution.configuration;
17
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;
24
25 import java.util.LinkedHashMap;
26 import java.util.Map;
27
28 /**
29  * Holds environment variables configuration:
30  * <ul>
31  * <li>list of user-defined environment variables</li>
32  * <li>boolean flag - whether to pass system environment</li>
33  * </ul>
34  * Instances of this class are immutable objects, so it can be safely passed across threads.
35  */
36 public class EnvironmentVariablesData {
37
38   public static final EnvironmentVariablesData DEFAULT = new EnvironmentVariablesData(ImmutableMap.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;
44
45   private final ImmutableMap<String, String> myEnvs;
46   private final boolean myPassParentEnvs;
47
48   private EnvironmentVariablesData(@NotNull Map<String, String> envs, boolean passParentEnvs) {
49     myEnvs = ImmutableMap.copyOf(envs);
50     myPassParentEnvs = passParentEnvs;
51   }
52
53   /**
54    * @return immutable Map instance containing user-defined environment variables (iteration order is reliable user-specified)
55    */
56   @NotNull
57   public Map<String, String> getEnvs() {
58     return myEnvs;
59   }
60
61   public boolean isPassParentEnvs() {
62     return myPassParentEnvs;
63   }
64
65   @Override
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);
71   }
72
73   @Override
74   public int hashCode() {
75     int result = myEnvs.hashCode();
76     result = 31 * result + (myPassParentEnvs ? 1 : 0);
77     return result;
78   }
79
80   @Override
81   public String toString() {
82     return "envs=" + myEnvs + ", passParentEnvs=" + myPassParentEnvs;
83   }
84
85   @NotNull
86   public static EnvironmentVariablesData readExternal(@NotNull Element element) {
87     Element envsElement = element.getChild(ENVS);
88     if (envsElement == null) {
89       return DEFAULT;
90     }
91     Map<String, String> envs = ImmutableMap.of();
92     String passParentEnvsStr = envsElement.getAttributeValue(PASS_PARENT_ENVS);
93     boolean passParentEnvs = passParentEnvsStr == null || Boolean.parseBoolean(passParentEnvsStr);
94     for (Element envElement : envsElement.getChildren(ENV)) {
95       String envName = envElement.getAttributeValue(NAME);
96       String envValue = envElement.getAttributeValue(VALUE);
97       if (envName != null && envValue != null) {
98         if (envs.isEmpty()) {
99           envs = ContainerUtil.newLinkedHashMap();
100         }
101         envs.put(envName, envValue);
102       }
103     }
104     return create(envs, passParentEnvs);
105   }
106
107   public void writeExternal(@NotNull Element parent) {
108     Element envsElement = new Element(ENVS);
109     if (!myPassParentEnvs) {
110       // Avoid writing pass-parent-envs="true" to minimize changes in xml comparing it to xml written by
111       // com.intellij.execution.configuration.EnvironmentVariablesComponent.writeExternal
112       envsElement.setAttribute(PASS_PARENT_ENVS, Boolean.FALSE.toString());
113     }
114     for (Map.Entry<String, String> entry : myEnvs.entrySet()) {
115       Element envElement = new Element(ENV);
116       envElement.setAttribute(NAME, entry.getKey());
117       envElement.setAttribute(VALUE, entry.getValue());
118       envsElement.addContent(envElement);
119     }
120     parent.addContent(envsElement);
121   }
122
123   public void configureCommandLine(@NotNull GeneralCommandLine commandLine, boolean consoleParentEnvs) {
124     if (myPassParentEnvs) {
125       commandLine.withParentEnvironmentType(consoleParentEnvs ? GeneralCommandLine.ParentEnvironmentType.CONSOLE
126                                                               : GeneralCommandLine.ParentEnvironmentType.SYSTEM);
127     }
128     else {
129       commandLine.withParentEnvironmentType(GeneralCommandLine.ParentEnvironmentType.NONE);
130     }
131     commandLine.withEnvironment(myEnvs);
132   }
133
134   /**
135    * @param envs Map instance containing user-defined environment variables
136    *             (iteration order should be reliable user-specified, like {@link LinkedHashMap} or {@link ImmutableMap})
137    * @param passParentEnvs true if system environment should be passed
138    */
139   @NotNull
140   public static EnvironmentVariablesData create(@NotNull Map<String, String> envs, boolean passParentEnvs) {
141     if (passParentEnvs && envs.isEmpty()) {
142       return DEFAULT;
143     }
144     return new EnvironmentVariablesData(envs, passParentEnvs);
145   }
146 }