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 }