    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    }