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 global symbols for 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("$ ");
093 out.print(entry.getKey());
094 out.print(" == "); // define as global symbol
095 out.println('\"');
096 String value = (String) entry.getValue();
097 // Any embedded " values need to be doubled
098 if (value.indexOf('\"') > 0){
099 StringBuffer sb = new StringBuffer();
100 for (int i = 0; i < value.length(); i++) {
101 char c = value.charAt(i);
102 if (c == '\"') {
103 sb.append('\"');
104 }
105 sb.append(c);
106 }
107 value=sb.toString();
108 }
109 out.print(value);
110 out.println('\"');
111 }
112 }
113
114 final String command = cmd.getExecutable();
115 if (cmd.isFile()){// We assume it is it a script file
116 out.print("$ @");
117 // This is a bit crude, but seems to work
118 String parts[] = StringUtils.split(command,"/");
119 out.print(parts[0]); // device
120 out.print(":[");
121 out.print(parts[1]); // top level directory
122 final int lastPart = parts.length-1;
123 for(int i=2; i< lastPart; i++){
124 out.print(".");
125 out.print(parts[i]);
126 }
127 out.print("]");
128 out.print(parts[lastPart]);
129 } else {
130 out.print("$ ");
131 out.print(command);
132 }
133 String[] args = cmd.getArguments();
134 for (int i = 0; i < args.length; i++) {
135 out.println(" -");
136 out.print(args[i]);
137 }
138 out.println();
139 } finally {
140 if (out != null) {
141 out.close();
142 }
143 }
144 return script;
145 }
146 }