1 package org
.argeo
.slc
.core
.execution
.tasks
;
4 import java
.util
.HashMap
;
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
;
22 /** Execute and OS system call. */
23 public class SystemCall
implements Runnable
{
24 private final Log log
= LogFactory
.getLog(getClass());
26 private String execDir
;
28 private String cmd
= null;
29 private List
<Object
> command
= null;
31 private Boolean synchronous
= true;
33 private String stdErrLogLevel
= "ERROR";
34 private String stdOutLogLevel
= "INFO";
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
>();
40 private Long watchdogTimeout
= 24 * 60 * 60 * 1000l;
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"));
50 // Execution directory
52 if (execDir
!= null) {
53 // Replace '/' by local file separator, for portability
54 execDir
.replace('/', File
.separatorChar
);
55 dir
= new File(execDir
).getCanonicalFile();
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
);
64 commandToUse
= command
;
65 String cmdToUse
= null;
66 if (osCmds
.containsKey(osName
))
67 cmdToUse
= osCmds
.get(osName
);
73 dir
= new File(getUsedDir(dir
));
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
);
84 }, new LogOutputStream() {
85 protected void processLine(String line
, int level
) {
86 log(stdErrLogLevel
, line
);
89 executor
.setStreamHandler(pumpStreamHandler
);
90 executor
.setProcessDestroyer(new ShutdownHookProcessDestroyer());
91 executor
.setWorkingDirectory(dir
);
92 final CommandLine commandLine
;
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 "
105 commandLine
= CommandLine
.parse(cmdToUse
);
106 } else if (commandToUse
!= null) {
107 if (log
.isTraceEnabled())
108 log
.trace("Execute '" + commandToUse
+ "' in "
110 if (commandToUse
.size() == 0)
111 throw new SlcException("Command line is empty.");
113 commandLine
= new CommandLine(commandToUse
.get(0).toString());
114 for (int i
= 1; i
< commandToUse
.size(); i
++)
115 commandLine
.addArgument(commandToUse
.get(i
).toString());
117 // all cases covered previously
118 throw new NotImplementedException();
122 Map
<String
, String
> environmentVariablesToUse
= environmentVariables
123 .size() > 0 ? environmentVariables
: null;
126 ExecuteResultHandler executeResultHandler
= new ExecuteResultHandler() {
128 public void onProcessComplete(int exitValue
) {
129 if (log
.isDebugEnabled())
130 log
.debug("Process " + commandLine
131 + " properly completed.");
134 public void onProcessFailed(ExecuteException e
) {
135 throw new SlcException("Process " + commandLine
142 int exitValue
= executor
.execute(commandLine
,
143 environmentVariablesToUse
);
144 executeResultHandler
.onProcessComplete(exitValue
);
145 } catch (ExecuteException e1
) {
146 executeResultHandler
.onProcessFailed(e1
);
149 executor
.execute(commandLine
, environmentVariablesToUse
,
150 executeResultHandler
);
151 } catch (Exception e
) {
152 throw new SlcException("Could not execute command " + cmd
, e
);
158 * Shortcut method returning the current exec dir if the specified one is
161 private String
getUsedDir(File dir
) {
163 return System
.getProperty("user.dir");
165 return dir
.getPath();
168 protected void log(String logLevel
, String line
) {
169 if ("ERROR".equals(logLevel
))
171 else if ("WARN".equals(logLevel
))
173 else if ("INFO".equals(logLevel
))
175 else if ("DEBUG".equals(logLevel
))
177 else if ("TRACE".equals(logLevel
))
180 throw new SlcException("Unknown log level " + logLevel
);
183 public void setCmd(String command
) {
187 public void setExecDir(String execdir
) {
188 this.execDir
= execdir
;
191 public void setStdErrLogLevel(String stdErrLogLevel
) {
192 this.stdErrLogLevel
= stdErrLogLevel
;
195 public void setStdOutLogLevel(String stdOutLogLevel
) {
196 this.stdOutLogLevel
= stdOutLogLevel
;
199 public void setSynchronous(Boolean synchronous
) {
200 this.synchronous
= synchronous
;
203 public void setCommand(List
<Object
> command
) {
204 this.command
= command
;
207 public void setOsCommands(Map
<String
, List
<Object
>> osCommands
) {
208 this.osCommands
= osCommands
;
211 public void setOsCmds(Map
<String
, String
> osCmds
) {
212 this.osCmds
= osCmds
;
215 public void setEnvironmentVariables(Map
<String
, String
> environmentVariables
) {
216 this.environmentVariables
= environmentVariables
;
219 public void setWatchdogTimeout(Long watchdogTimeout
) {
220 this.watchdogTimeout
= watchdogTimeout
;