001: /********************************************************************************
002: * CruiseControl, a Continuous Integration Toolkit
003: * Copyright (c) 2001-2003, ThoughtWorks, Inc.
004: * 200 E. Randolph, 25th Floor
005: * Chicago, IL 60601 USA
006: * All rights reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: *
012: * + Redistributions of source code must retain the above copyright
013: * notice, this list of conditions and the following disclaimer.
014: *
015: * + Redistributions in binary form must reproduce the above
016: * copyright notice, this list of conditions and the following
017: * disclaimer in the documentation and/or other materials provided
018: * with the distribution.
019: *
020: * + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
021: * names of its contributors may be used to endorse or promote
022: * products derived from this software without specific prior
023: * written permission.
024: *
025: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
026: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
027: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
028: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
029: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
030: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
031: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
032: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
033: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
034: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
035: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
036: ********************************************************************************/package net.sourceforge.cruisecontrol.util;
037:
038: import java.io.BufferedReader;
039: import java.io.InputStreamReader;
040: import java.util.ArrayList;
041: import java.util.Enumeration;
042: import java.util.List;
043: import java.util.Properties;
044:
045: import org.apache.log4j.Logger;
046:
047: /**
048: * A simple utility class for obtaining and parsing system environment
049: * variables. It has been tested on Windows 2000, Windows XP, Solaris, and
050: * HP-UX, though it should work with any Win32 (95+) or Unix based palatform.
051: *
052: * @author <a href="mailto:rjmpsmith@hotmail.com">Robert J. Smith </a>
053: */
054: public class OSEnvironment {
055:
056: private static final Logger LOG = Logger
057: .getLogger(OSEnvironment.class);
058:
059: /**
060: * Internal representation of the system environment
061: */
062: private Properties variables = new Properties();
063:
064: /**
065: * Constructor
066: *
067: * Creates an instance of OSEnvironment, queries the OS to discover it's
068: * environment variables and makes them available through the getter methods
069: */
070: public OSEnvironment() {
071: parse();
072: }
073:
074: /**
075: * Parses the OS environment and makes the environment variables available
076: * through the getter methods
077: */
078: private void parse() {
079:
080: String command;
081:
082: // Detemine the correct command to run based on OS name
083: String os = System.getProperty("os.name").toLowerCase();
084: if (isWindows9x(os)) {
085: command = "command.com /c set";
086: } else if ((os.indexOf("nt") > -1)
087: || (os.indexOf("windows") > -1)
088: || (os.indexOf("os/2") > -1)) {
089: command = "cmd.exe /c set";
090: } else {
091: // should work for just about any Unix variant
092: command = "env";
093: }
094:
095: // Get our environment
096: try {
097: Process p = Runtime.getRuntime().exec(command);
098: p.getOutputStream().close();
099:
100: // Capture the output of the command
101: BufferedReader stdoutStream = new BufferedReader(
102: new InputStreamReader(p.getInputStream()));
103: BufferedReader stderrStream = new BufferedReader(
104: new InputStreamReader(p.getErrorStream()));
105:
106: // Parse the output
107: String line;
108: String key = null;
109: while ((line = stdoutStream.readLine()) != null) {
110: int idx = line.indexOf('=');
111: String value;
112: if (idx == -1) {
113: if (key == null) {
114: continue;
115: }
116: // potential multi-line property. Let's rebuild it
117: value = variables.getProperty(key);
118: value += "\n" + line;
119: } else {
120: key = line.substring(0, idx);
121: value = line.substring(idx + 1);
122: }
123: variables.setProperty(key, value);
124: }
125:
126: // Close down our streams
127: stdoutStream.close();
128: stderrStream.close();
129:
130: } catch (Exception e) {
131: LOG.error("Failed to parse the OS environment.", e);
132: }
133: }
134:
135: private boolean isWindows9x(String os) {
136: return os.indexOf("windows 9") > -1;
137: }
138:
139: /**
140: * Gets the value of an environment variable. The variable name is case
141: * sensitive.
142: *
143: * @param variable
144: * The variable for which you wish the value
145: *
146: * @return The value of the variable, or <code>null</code> if not found
147: *
148: * @see #getVariable(String variable, String defaultValue)
149: */
150: public String getVariable(String variable) {
151: return variables.getProperty(variable);
152: }
153:
154: /**
155: * Gets the value of an environment variable. The variable name is case
156: * sensitive.
157: *
158: * @param variable
159: * the variable for which you wish the value
160: *
161: * @param defaultValue
162: * The value to return if the variable is not set in the
163: * environment.
164: *
165: * @return The value of the variable. If the variable is not found, the
166: * defaultValue is returned.
167: */
168: public String getVariable(String variable, String defaultValue) {
169: return variables.getProperty(variable, defaultValue);
170: }
171:
172: /**
173: * Gets the value of an environment variable. The variable name is NOT case
174: * sensitive. If more than one variable matches the pattern provided, the
175: * result is unpredictable. You are greatly encouraged to use
176: * <code>getVariable()</code> instead.
177: *
178: * @param variable
179: * the variable for which you wish the value
180: *
181: * @see #getVariable(String variable)
182: * @see #getVariable(String variable, String defaultValue)
183: */
184: public String getVariableIgnoreCase(String variable) {
185: Enumeration keys = variables.keys();
186: while (keys.hasMoreElements()) {
187: String key = (String) keys.nextElement();
188: if (key.equalsIgnoreCase(variable)) {
189: return variables.getProperty(key);
190: }
191: }
192: return null;
193: }
194:
195: /**
196: * Adds a variable to this representation of the environment. If the
197: * variable already existed, the value will be replaced.
198: *
199: * @param variable
200: * the variable to set
201: * @param value
202: * the value of the variable
203: */
204: public void add(String variable, String value) {
205: variables.setProperty(variable, value);
206: }
207:
208: /**
209: * Returns all environment variables which were set at the time the class
210: * was instantiated, as well as any which have been added programatically.
211: *
212: * @return a <code>List</code> of all environment variables. The
213: * <code>List</code> is made up of <code>String</code>s of the
214: * form "variable=value".
215: *
216: * @see #toArray()
217: */
218: public List getEnvironment() {
219: List env = new ArrayList();
220: Enumeration keys = variables.keys();
221: while (keys.hasMoreElements()) {
222: String key = (String) keys.nextElement();
223: env.add(key + "=" + variables.getProperty(key));
224: }
225: return env;
226: }
227:
228: /**
229: * Returns all environment variables which were set at the time the class
230: * was instantiated, as well as any which have been added programatically.
231: *
232: * @return a <code>String[]</code> containing all environment variables.
233: * The <code>String</code>s are of the form "variable=value".
234: * This is the format expected by
235: * <code>java.lang.Runtime.exec()</code>.
236: *
237: * @see java.lang.Runtime
238: */
239: public String[] toArray() {
240: List list = getEnvironment();
241: return (String[]) list.toArray(new String[list.size()]);
242: }
243:
244: /**
245: * Returns a <code>String<code> representation of the
246: * environment.
247: *
248: * @return A <code>String<code> representation of the environment
249: */
250: public String toString() {
251: return variables.toString();
252: }
253: }
|