    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
    019    package org.apache.commons.exec.launcher;
    020
    021    import java.io.File;
    022    import java.io.FileWriter;
    023    import java.io.IOException;
    024    import java.io.PrintWriter;
    025    import java.util.Iterator;
    026    import java.util.Map;
    027    import java.util.Map.Entry;
    028    import java.util.Set;
    029
    030    import org.apache.commons.exec.CommandLine;
    031    import org.apache.commons.exec.util.StringUtils;
    032
    033    /**
    034     * A command launcher for VMS that writes the command to a temporary DCL script
    035     * before launching commands. This is due to limitations of both the DCL
    036     * interpreter and the Java VM implementation.
    037     */
    038    public class VmsCommandLauncher extends Java13CommandLauncher {
    039
    040        /**
    041         * Launches the given command in a new process.
    042         */
    043        public Process exec(final CommandLine cmd, final Map env)
    044                throws IOException {
    045            CommandLine vmsCmd = new CommandLine(
    046                    createCommandFile(cmd, env).getPath()
    047            );
    048
    049            return super.exec(vmsCmd, env);
    050        }
    051
    052        /**
    053         * Launches the given command in a new process, in the given working
    054         * directory. Note that under Java 1.3.1, 1.4.0 and 1.4.1 on VMS this method
    055         * only works if <code>workingDir</code> is null or the logical
    056         * JAVA$FORK_SUPPORT_CHDIR needs to be set to TRUE.
    057         */
    058        public Process exec(final CommandLine cmd, final Map env,
    059                final File workingDir) throws IOException {
    060            CommandLine vmsCmd = new CommandLine(
    061                    createCommandFile(cmd, env).getPath()
    062            );
    063
    064            return super.exec(vmsCmd, env, workingDir);
    065        }
    066
    067        /** @see org.apache.commons.exec.launcher.CommandLauncher#isFailure(int) */
    068        public boolean isFailure( final int exitValue )
    069        {
    070            // even exit value signals failure
    071            return (exitValue % 2) == 0;
    072        }
    073
    074        /*
    075         * Writes the command into a temporary DCL script and returns the
    076         * corresponding File object. The script will be deleted on exit.
    077         */
    078        private File createCommandFile(final CommandLine cmd, final Map env)
    079                throws IOException {
    080            File script = File.createTempFile("EXEC", ".TMP");
    081            script.deleteOnExit();
    082            PrintWriter out = null;
    083            try {
    084                out = new PrintWriter(new FileWriter(script.getAbsolutePath(),true));
    085
    086                // add the environment as logicals to the DCL script
    087                if (env != null) {
    088                    Set entries = env.entrySet();
    089
    090                    for (Iterator iter = entries.iterator(); iter.hasNext();) {
    091                        Entry entry = (Entry) iter.next();
    092                        out.print("$ DEFINE/NOLOG ");
    093                        out.print(entry.getKey());
    094                        out.print(" \"");
    095                        out.print(entry.getValue());
    096                        out.println('\"');
    097                    }
    098                }
    099
    100                final String command = cmd.getExecutable();
    101                if (cmd.isFile()){// We assume it is it a script file
    102                    out.print("$ @");
    103                    // This is a bit crude, but seems to work
    104                    String parts[] = StringUtils.split(command,"/");
    105                    out.print(parts[0]); // device
    106                    out.print(":[");
    107                    out.print(parts[1]); // top level directory
    108                    final int lastPart = parts.length-1;
    109                    for(int i=2; i< lastPart; i++){
    110                        out.print(".");
    111                        out.print(parts[i]);
    112                    }
    113                    out.print("]");
    114                    out.print(parts[lastPart]);
    115                } else {
    116                    out.print("$ ");
    117                    out.print(command);
    118                }
    119                String[] args = cmd.getArguments();
    120                for (int i = 0; i < args.length; i++) {
    121                    out.println(" -");
    122                    out.print(args[i]);
    123                }
    124                out.println();
    125            } finally {
    126                if (out != null) {
    127                    out.close();
    128                }
    129            }
    130            return script;
    131        }
    132    }