View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.exec.environment;
19  
20  import java.io.BufferedReader;
21  import java.io.IOException;
22  import java.util.Comparator;
23  import java.util.HashMap;
24  import java.util.Map;
25  import java.util.TreeMap;
26  
27  import org.apache.commons.exec.CommandLine;
28  import org.apache.commons.exec.OS;
29  
30  /**
31   * Helper class to determine the environment variable
32   * for the OS. Depending on the JDK the environment
33   * variables can be either retrieved directly from the
34   * JVM or requires starting a process to get them running
35   * an OS command line.
36   *
37   * @version $Id: DefaultProcessingEnvironment.java 1557385 2014-01-11 13:19:33Z sebb $
38   */
39  public class DefaultProcessingEnvironment {
40  
41      /** the line separator of the system */
42  //    private static final String LINE_SEPARATOR = System.getProperty("line.separator");
43  
44      /** the environment variables of the process */
45      protected Map<String, String> procEnvironment;
46  
47      /**
48       * Find the list of environment variables for this process.
49       *
50       * @return a map containing the environment variables
51       * @throws IOException obtaining the environment variables failed
52       */
53      public synchronized Map<String, String> getProcEnvironment() throws IOException {
54  
55          if (procEnvironment == null) {
56              procEnvironment = this.createProcEnvironment();
57          }
58  
59          // create a copy of the map just in case that
60          // anyone is going to modifiy it, e.g. removing
61          // or setting an evironment variable
62          final Map<String, String> copy = createEnvironmentMap();
63          copy.putAll(procEnvironment);
64          return copy;
65      }
66  
67      /**
68       * Find the list of environment variables for this process.
69       *
70       * @return a amp containing the environment variables
71       * @throws IOException the operation failed
72       */
73      protected Map<String, String> createProcEnvironment() throws IOException {
74          if (procEnvironment == null) {
75              final Map<String, String> env = System.getenv();
76              procEnvironment = createEnvironmentMap();
77              procEnvironment.putAll(env);
78          }
79  
80  // No longer needed
81  //        if (procEnvironment == null) {
82  //            procEnvironment = createEnvironmentMap();
83  //            final BufferedReader in = runProcEnvCommand();
84  //
85  //            String var = null;
86  //            String line;
87  //            while ((line = in.readLine()) != null) {
88  //                if (line.indexOf('=') == -1) {
89  //                    // Chunk part of previous env var (UNIX env vars can
90  //                    // contain embedded new lines).
91  //                    if (var == null) {
92  //                        var = LINE_SEPARATOR + line;
93  //                    } else {
94  //                        var += LINE_SEPARATOR + line;
95  //                    }
96  //                } else {
97  //                    // New env var...append the previous one if we have it.
98  //                    if (var != null) {
99  //                        EnvironmentUtils.addVariableToEnvironment(procEnvironment, var);
100 //                    }
101 //                    var = line;
102 //                }
103 //            }
104 //            // Since we "look ahead" before adding, there's one last env var.
105 //            if (var != null) {
106 //                EnvironmentUtils.addVariableToEnvironment(procEnvironment, var);
107 //            }
108 //        }
109         return procEnvironment;
110     }
111 
112     /**
113      * Start a process to list the environment variables.
114      *
115      * @return a reader containing the output of the process
116      * @throws IOException starting the process failed
117      * @deprecated No longer needed
118      */
119     @Deprecated
120     protected BufferedReader runProcEnvCommand() throws IOException {
121 //        final ByteArrayOutputStream out = new ByteArrayOutputStream();
122 //        final Executor exe = new DefaultExecutor();
123 //        exe.setStreamHandler(new PumpStreamHandler(out));
124 //        // ignore the exit value - Just try to use what we got
125 //        exe.execute(getProcEnvCommand());
126 //        return new BufferedReader(new StringReader(toString(out)));
127         return null;
128     }
129 
130     /**
131      * Determine the OS specific command line to get a list of environment
132      * variables.
133      *
134      * @return the command line
135      * @deprecated No longer needed
136      */
137     @Deprecated
138     protected CommandLine getProcEnvCommand() {
139 //        String executable;
140 //        String[] arguments = null;
141 //        if (OS.isFamilyOS2()) {
142 //            // OS/2 - use same mechanism as Windows 2000
143 //            executable = "cmd";
144 //
145 //            arguments = new String[] {"/c", "set"};
146 //        } else if (OS.isFamilyWindows()) {
147 //            // Determine if we're running under XP/2000/NT or 98/95
148 //            if (OS.isFamilyWin9x()) {
149 //                executable = "command.com";
150 //                // Windows 98/95
151 //            } else {
152 //                executable = "cmd";
153 //                // Windows XP/2000/NT/2003
154 //            }
155 //            arguments = new String[] {"/c", "set"};
156 //        } else if (OS.isFamilyZOS() || OS.isFamilyUnix()) {
157 //            // On most systems one could use: /bin/sh -c env
158 //
159 //            // Some systems have /bin/env, others /usr/bin/env, just try
160 //            if (new File("/bin/env").canRead()) {
161 //                executable = "/bin/env";
162 //            } else if (new File("/usr/bin/env").canRead()) {
163 //                executable = "/usr/bin/env";
164 //            } else {
165 //                // rely on PATH
166 //                executable = "env";
167 //            }
168 //        } else if (OS.isFamilyNetware() || OS.isFamilyOS400()) {
169 //            // rely on PATH
170 //            executable = "env";
171 //        } else {
172 //            // MAC OS 9 and previous
173 //            // TODO: I have no idea how to get it, someone must fix it
174 //            executable = null;
175 //        }
176         CommandLine commandLine = null;
177 //        if (executable != null) {
178 //            commandLine = new CommandLine(executable);
179 //            commandLine.addArguments(arguments);
180 //        }
181         return commandLine;
182     }
183 
184 //    /**
185 //     * ByteArrayOutputStream#toString doesn't seem to work reliably on OS/390,
186 //     * at least not the way we use it in the execution context.
187 //     *
188 //     * @param bos
189 //     *            the output stream that one wants to read
190 //     * @return the output stream as a string, read with special encodings in the
191 //     *         case of z/os and os/400
192 //     */
193 //    private String toString(final ByteArrayOutputStream bos) {
194 //        if (OS.isFamilyZOS()) {
195 //            try {
196 //                return bos.toString("Cp1047");
197 //            } catch (final java.io.UnsupportedEncodingException e) {
198 //                // noop default encoding used
199 //            }
200 //        } else if (OS.isFamilyOS400()) {
201 //            try {
202 //                return bos.toString("Cp500");
203 //            } catch (final java.io.UnsupportedEncodingException e) {
204 //                // noop default encoding used
205 //            }
206 //        }
207 //        return bos.toString();
208 //    }
209 
210     /**
211      * Creates a map that obeys the casing rules of the current platform for key
212      * lookup. E.g. on a Windows platform, the map keys will be
213      * case-insensitive.
214      *
215      * @return The map for storage of environment variables, never
216      *         <code>null</code>.
217      */
218     private Map<String, String> createEnvironmentMap() {
219         if (OS.isFamilyWindows()) {
220             return new TreeMap<String, String>(new Comparator<String>() {
221                 public int compare(final String key0, final String key1) {
222                     return key0.compareToIgnoreCase(key1);
223                 }
224             });
225         }
226         return new HashMap<String, String>();
227     }
228 
229 }