001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.commons.exec.environment;
019
020 import java.io.BufferedReader;
021 import java.io.IOException;
022 import java.util.HashMap;
023 import java.util.Iterator;
024 import java.util.Map;
025
026 import org.apache.commons.exec.CommandLine;
027
028 /**
029 * Helper class to determine the environment variable
030 * for VMS.
031 */
032 public class OpenVmsProcessingEnvironment extends DefaultProcessingEnvironment {
033
034 /**
035 * Find the list of environment variables for this process.
036 *
037 * @return a amp containing the environment variables
038 * @throws IOException the operation failed
039 */
040 protected Map createProcEnvironment() throws IOException {
041 if (procEnvironment == null) {
042 procEnvironment = new HashMap();
043
044 BufferedReader in = runProcEnvCommand();
045
046 procEnvironment = addVMSLogicals(procEnvironment, in);
047 return procEnvironment;
048 }
049
050 return procEnvironment;
051 }
052
053 /**
054 * Determine the OS specific command line to get a list of environment
055 * variables.
056 *
057 * @return the command line
058 */
059 protected CommandLine getProcEnvCommand() {
060 CommandLine commandLine = new CommandLine("show");
061 commandLine.addArgument("logical");
062 return commandLine;
063 }
064
065 /**
066 * This method is VMS specific and used by getProcEnvironment(). Parses VMS
067 * logicals from <code>in</code> and adds them to <code>environment</code>.
068 * <code>in</code> is expected to be the output of "SHOW LOGICAL". The
069 * method takes care of parsing the output correctly as well as making sure
070 * that a logical defined in multiple tables only gets added from the
071 * highest order table. Logicals with multiple equivalence names are mapped
072 * to a variable with multiple values separated by a comma (,).
073 *
074 * @param environment the current environment
075 * @param in the reader from the process to determine VMS env variables
076 * @return the updated environment
077 * @throws IOException operation failed
078 */
079 private Map addVMSLogicals(final Map environment,
080 final BufferedReader in) throws IOException {
081 String line;
082 HashMap logicals = new HashMap();
083 String logName = null, logValue = null, newLogName;
084 while ((line = in.readLine()) != null) {
085 // parse the VMS logicals into required format ("VAR=VAL[,VAL2]")
086 if (line.startsWith("\t=")) {
087 // further equivalence name of previous logical
088 if (logName != null) {
089 logValue += "," + line.substring(4, line.length() - 1);
090 }
091 } else if (line.startsWith(" \"")) {
092 // new logical?
093 if (logName != null) {
094 logicals.put(logName, logValue);
095 }
096 int eqIndex = line.indexOf('=');
097 newLogName = line.substring(3, eqIndex - 2);
098 if (logicals.containsKey(newLogName)) {
099 // already got this logical from a higher order table
100 logName = null;
101 } else {
102 logName = newLogName;
103 logValue = line.substring(eqIndex + 3, line.length() - 1);
104 }
105 }
106 }
107 // Since we "look ahead" before adding, there's one last env var.
108 if (logName != null) {
109 logicals.put(logName, logValue);
110 }
111
112 for (Iterator i = logicals.entrySet().iterator(); i.hasNext();) {
113 String logical = (String) ((Map.Entry) i.next()).getKey();
114 environment.put(logical, logicals.get(logical));
115 }
116 return environment;
117 }
118 }