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    }