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 }