]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/tasks/SystemCall.java
Compilation error with JDK 1.5
[gpl/argeo-slc.git] / runtime / org.argeo.slc.support.simple / src / main / java / org / argeo / slc / core / execution / tasks / SystemCall.java
1 package org.argeo.slc.core.execution.tasks;
2
3 import java.io.File;
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7
8 import org.apache.commons.exec.CommandLine;
9 import org.apache.commons.exec.DefaultExecutor;
10 import org.apache.commons.exec.ExecuteException;
11 import org.apache.commons.exec.ExecuteResultHandler;
12 import org.apache.commons.exec.ExecuteWatchdog;
13 import org.apache.commons.exec.Executor;
14 import org.apache.commons.exec.LogOutputStream;
15 import org.apache.commons.exec.PumpStreamHandler;
16 import org.apache.commons.exec.ShutdownHookProcessDestroyer;
17 import org.apache.commons.lang.NotImplementedException;
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20 import org.argeo.slc.SlcException;
21
22 /** Execute and OS system call. */
23 public class SystemCall implements Runnable {
24 private final Log log = LogFactory.getLog(getClass());
25
26 private String execDir;
27
28 private String cmd = null;
29 private List<Object> command = null;
30
31 private Boolean synchronous = true;
32
33 private String stdErrLogLevel = "ERROR";
34 private String stdOutLogLevel = "INFO";
35
36 private Map<String, List<Object>> osCommands = new HashMap<String, List<Object>>();
37 private Map<String, String> osCmds = new HashMap<String, String>();
38 private Map<String, String> environmentVariables = new HashMap<String, String>();
39
40 private Long watchdogTimeout = 24 * 60 * 60 * 1000l;
41
42 public void run() {
43 try {
44 if (log.isTraceEnabled()) {
45 log.debug("os.name=" + System.getProperty("os.name"));
46 log.debug("os.arch=" + System.getProperty("os.arch"));
47 log.debug("os.version=" + System.getProperty("os.version"));
48 }
49
50 // Execution directory
51 File dir = null;
52 if (execDir != null) {
53 // Replace '/' by local file separator, for portability
54 execDir.replace('/', File.separatorChar);
55 dir = new File(execDir).getCanonicalFile();
56 }
57
58 // Check if an OS specific command overrides
59 String osName = System.getProperty("os.name");
60 List<Object> commandToUse = null;
61 if (osCommands.containsKey(osName))
62 commandToUse = osCommands.get(osName);
63 else
64 commandToUse = command;
65 String cmdToUse = null;
66 if (osCmds.containsKey(osName))
67 cmdToUse = osCmds.get(osName);
68 else
69 cmdToUse = cmd;
70
71 // Prepare executor
72 if (dir == null)
73 dir = new File(getUsedDir(dir));
74 if (!dir.exists())
75 dir.mkdirs();
76
77 Executor executor = new DefaultExecutor();
78 executor.setWatchdog(new ExecuteWatchdog(watchdogTimeout));
79 PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(
80 new LogOutputStream() {
81 protected void processLine(String line, int level) {
82 log(stdOutLogLevel, line);
83 }
84 }, new LogOutputStream() {
85 protected void processLine(String line, int level) {
86 log(stdErrLogLevel, line);
87 }
88 }, null);
89 executor.setStreamHandler(pumpStreamHandler);
90 executor.setProcessDestroyer(new ShutdownHookProcessDestroyer());
91 executor.setWorkingDirectory(dir);
92 final CommandLine commandLine;
93
94 // Which command definition to use
95 if (commandToUse == null && cmdToUse == null)
96 throw new SlcException("Please specify a command.");
97 else if (commandToUse != null && cmdToUse != null)
98 throw new SlcException(
99 "Specify the command either as a line or as a list.");
100 else if (cmdToUse != null) {
101 if (log.isTraceEnabled())
102 log.trace("Execute '" + cmdToUse + "' in "
103 + getUsedDir(dir));
104
105 commandLine = CommandLine.parse(cmdToUse);
106 } else if (commandToUse != null) {
107 if (log.isTraceEnabled())
108 log.trace("Execute '" + commandToUse + "' in "
109 + getUsedDir(dir));
110 if (commandToUse.size() == 0)
111 throw new SlcException("Command line is empty.");
112
113 commandLine = new CommandLine(commandToUse.get(0).toString());
114 for (int i = 1; i < commandToUse.size(); i++)
115 commandLine.addArgument(commandToUse.get(i).toString());
116 } else {
117 // all cases covered previously
118 throw new NotImplementedException();
119 }
120
121 // Env variables
122 Map<String, String> environmentVariablesToUse = environmentVariables
123 .size() > 0 ? environmentVariables : null;
124
125 // Execute
126 ExecuteResultHandler executeResultHandler = new ExecuteResultHandler() {
127
128 public void onProcessComplete(int exitValue) {
129 if (log.isDebugEnabled())
130 log.debug("Process " + commandLine
131 + " properly completed.");
132 }
133
134 public void onProcessFailed(ExecuteException e) {
135 throw new SlcException("Process " + commandLine
136 + " failed.", e);
137 }
138 };
139
140 if (synchronous)
141 try {
142 int exitValue = executor.execute(commandLine,
143 environmentVariablesToUse);
144 executeResultHandler.onProcessComplete(exitValue);
145 } catch (ExecuteException e1) {
146 executeResultHandler.onProcessFailed(e1);
147 }
148 else
149 executor.execute(commandLine, environmentVariablesToUse,
150 executeResultHandler);
151 } catch (Exception e) {
152 throw new SlcException("Could not execute command " + cmd, e);
153 }
154
155 }
156
157 /**
158 * Shortcut method returning the current exec dir if the specified one is
159 * null.
160 */
161 private String getUsedDir(File dir) {
162 if (dir == null)
163 return System.getProperty("user.dir");
164 else
165 return dir.getPath();
166 }
167
168 protected void log(String logLevel, String line) {
169 if ("ERROR".equals(logLevel))
170 log.error(line);
171 else if ("WARN".equals(logLevel))
172 log.warn(line);
173 else if ("INFO".equals(logLevel))
174 log.info(line);
175 else if ("DEBUG".equals(logLevel))
176 log.debug(line);
177 else if ("TRACE".equals(logLevel))
178 log.trace(line);
179 else
180 throw new SlcException("Unknown log level " + logLevel);
181 }
182
183 public void setCmd(String command) {
184 this.cmd = command;
185 }
186
187 public void setExecDir(String execdir) {
188 this.execDir = execdir;
189 }
190
191 public void setStdErrLogLevel(String stdErrLogLevel) {
192 this.stdErrLogLevel = stdErrLogLevel;
193 }
194
195 public void setStdOutLogLevel(String stdOutLogLevel) {
196 this.stdOutLogLevel = stdOutLogLevel;
197 }
198
199 public void setSynchronous(Boolean synchronous) {
200 this.synchronous = synchronous;
201 }
202
203 public void setCommand(List<Object> command) {
204 this.command = command;
205 }
206
207 public void setOsCommands(Map<String, List<Object>> osCommands) {
208 this.osCommands = osCommands;
209 }
210
211 public void setOsCmds(Map<String, String> osCmds) {
212 this.osCmds = osCmds;
213 }
214
215 public void setEnvironmentVariables(Map<String, String> environmentVariables) {
216 this.environmentVariables = environmentVariables;
217 }
218
219 public void setWatchdogTimeout(Long watchdogTimeout) {
220 this.watchdogTimeout = watchdogTimeout;
221 }
222
223 }