]> git.argeo.org Git - gpl/argeo-slc.git/blobdiff - runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/tasks/SystemCall.java
Revert to Equinox v3.4.2
[gpl/argeo-slc.git] / runtime / org.argeo.slc.core / src / main / java / org / argeo / slc / core / execution / tasks / SystemCall.java
index a14e550bf85eb39455fec181ff517e562c395641..4d7e5d05dbc8013d7b8d829787bec8cc0b7f3ded 100644 (file)
@@ -3,6 +3,8 @@ package org.argeo.slc.core.execution.tasks;
 import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.io.Writer;
 import java.util.HashMap;
 import java.util.List;
@@ -12,15 +14,18 @@ import org.apache.commons.exec.CommandLine;
 import org.apache.commons.exec.DefaultExecutor;
 import org.apache.commons.exec.ExecuteException;
 import org.apache.commons.exec.ExecuteResultHandler;
+import org.apache.commons.exec.ExecuteStreamHandler;
 import org.apache.commons.exec.ExecuteWatchdog;
 import org.apache.commons.exec.Executor;
 import org.apache.commons.exec.LogOutputStream;
 import org.apache.commons.exec.PumpStreamHandler;
 import org.apache.commons.exec.ShutdownHookProcessDestroyer;
+import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.slc.SlcException;
+import org.argeo.slc.UnsupportedException;
 import org.argeo.slc.core.structure.tree.TreeSPath;
 import org.argeo.slc.core.structure.tree.TreeSRelatedHelper;
 import org.argeo.slc.core.test.SimpleResultPart;
@@ -51,10 +56,17 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable,
        private Map<String, String> osCmds = new HashMap<String, String>();
        private Map<String, String> environmentVariables = new HashMap<String, String>();
 
+       private Boolean logCommand = false;
+       private Boolean redirectStreams = true;
+       private String osConsole = null;
+       private String generateScript = null;
+
        private Long watchdogTimeout = 24 * 60 * 60 * 1000l;
 
        private TestResult testResult;
 
+       // Internal use
+
        public SystemCall() {
 
        }
@@ -65,7 +77,6 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable,
        }
 
        public void run() {
-               // Log writers
                final Writer stdOutWriter;
                final Writer stdErrWriter;
                if (stdOutFile != null) {
@@ -89,112 +100,37 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable,
                        }
 
                        // Execution directory
-                       File dir = null;
-                       if (execDir != null) {
-                               // Replace '/' by local file separator, for portability
-                               execDir.replace('/', File.separatorChar);
-                               dir = new File(execDir).getCanonicalFile();
-                       }
-
-                       // Check if an OS specific command overrides
-                       String osName = System.getProperty("os.name");
-                       List<Object> commandToUse = null;
-                       if (osCommands.containsKey(osName))
-                               commandToUse = osCommands.get(osName);
-                       else
-                               commandToUse = command;
-                       String cmdToUse = null;
-                       if (osCmds.containsKey(osName))
-                               cmdToUse = osCmds.get(osName);
-                       else
-                               cmdToUse = cmd;
-
-                       // Prepare executor
-                       if (dir == null)
-                               dir = new File(getUsedDir(dir));
+                       File dir = new File(getExecDirToUse());
                        if (!dir.exists())
                                dir.mkdirs();
 
+                       // Watchdog to check for lost processes
                        Executor executor = new DefaultExecutor();
                        executor.setWatchdog(new ExecuteWatchdog(watchdogTimeout));
 
-                       PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(
-                                       new LogOutputStream() {
-                                               protected void processLine(String line, int level) {
-                                                       log(stdOutLogLevel, line);
-                                                       if (stdOutWriter != null)
-                                                               appendLineToFile(stdOutWriter, line);
-                                               }
-                                       }, new LogOutputStream() {
-                                               protected void processLine(String line, int level) {
-                                                       log(stdErrLogLevel, line);
-                                                       if (stdErrWriter != null)
-                                                               appendLineToFile(stdErrWriter, line);
-                                               }
-                                       }, null);
-                       executor.setStreamHandler(pumpStreamHandler);
+                       if (redirectStreams) {
+                               // Redirect standard streams
+                               executor.setStreamHandler(createExecuteStreamHandler(
+                                               stdOutWriter, stdErrWriter));
+                       } else {
+                               // Dummy stream handler (otherwise pump is used)
+                               executor.setStreamHandler(new DummyexecuteStreamHandler());
+                       }
+
                        executor.setProcessDestroyer(new ShutdownHookProcessDestroyer());
                        executor.setWorkingDirectory(dir);
-                       final CommandLine commandLine;
-
-                       // Which command definition to use
-                       if (commandToUse == null && cmdToUse == null)
-                               throw new SlcException("Please specify a command.");
-                       else if (commandToUse != null && cmdToUse != null)
-                               throw new SlcException(
-                                               "Specify the command either as a line or as a list.");
-                       else if (cmdToUse != null) {
-                               if (log.isTraceEnabled())
-                                       log.trace("Execute '" + cmdToUse + "' in "
-                                                       + getUsedDir(dir));
 
-                               commandLine = CommandLine.parse(cmdToUse);
-                       } else if (commandToUse != null) {
-                               if (log.isTraceEnabled())
-                                       log.trace("Execute '" + commandToUse + "' in "
-                                                       + getUsedDir(dir));
-                               if (commandToUse.size() == 0)
-                                       throw new SlcException("Command line is empty.");
-
-                               commandLine = new CommandLine(commandToUse.get(0).toString());
-                               for (int i = 1; i < commandToUse.size(); i++)
-                                       commandLine.addArgument(commandToUse.get(i).toString());
-                       } else {
-                               // all cases covered previously
-                               throw new UnsupportedOperationException();
-                       }
+                       // Command line to use
+                       final CommandLine commandLine = createCommandLine();
+                       if (logCommand)
+                               log.info("Execute command:\n" + commandLine + "\n");
 
                        // Env variables
                        Map<String, String> environmentVariablesToUse = environmentVariables
                                        .size() > 0 ? environmentVariables : null;
 
                        // Execute
-                       ExecuteResultHandler executeResultHandler = new ExecuteResultHandler() {
-
-                               public void onProcessComplete(int exitValue) {
-                                       if (log.isDebugEnabled())
-                                               log.debug("Process " + commandLine
-                                                               + " properly completed.");
-                                       if (testResult != null) {
-                                               forwardPath(testResult, null);
-                                               testResult.addResultPart(new SimpleResultPart(
-                                                               TestStatus.PASSED, "Process " + commandLine
-                                                                               + " properly completed."));
-                                       }
-                               }
-
-                               public void onProcessFailed(ExecuteException e) {
-                                       if (testResult != null) {
-                                               forwardPath(testResult, null);
-                                               testResult.addResultPart(new SimpleResultPart(
-                                                               TestStatus.ERROR, "Process " + commandLine
-                                                                               + " failed.", e));
-                                       } else {
-                                               throw new SlcException("Process " + commandLine
-                                                               + " failed.", e);
-                                       }
-                               }
-                       };
+                       ExecuteResultHandler executeResultHandler = createExecuteResultHandler(commandLine);
 
                        if (synchronous)
                                try {
@@ -216,15 +152,139 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable,
 
        }
 
+       /** Can be overridden by specific command wrapper */
+       protected CommandLine createCommandLine() {
+               // Check if an OS specific command overrides
+               String osName = System.getProperty("os.name");
+               List<Object> commandToUse = null;
+               if (osCommands.containsKey(osName))
+                       commandToUse = osCommands.get(osName);
+               else
+                       commandToUse = command;
+               String cmdToUse = null;
+               if (osCmds.containsKey(osName))
+                       cmdToUse = osCmds.get(osName);
+               else
+                       cmdToUse = cmd;
+
+               CommandLine commandLine = null;
+
+               // Which command definition to use
+               if (commandToUse == null && cmdToUse == null)
+                       throw new SlcException("Please specify a command.");
+               else if (commandToUse != null && cmdToUse != null)
+                       throw new SlcException(
+                                       "Specify the command either as a line or as a list.");
+               else if (cmdToUse != null) {
+                       commandLine = CommandLine.parse(cmdToUse);
+               } else if (commandToUse != null) {
+                       if (commandToUse.size() == 0)
+                               throw new SlcException("Command line is empty.");
+
+                       commandLine = new CommandLine(commandToUse.get(0).toString());
+
+                       for (int i = 1; i < commandToUse.size(); i++) {
+                               if (log.isTraceEnabled())
+                                       log.debug(commandToUse.get(i));
+                               commandLine.addArgument(commandToUse.get(i).toString());
+                       }
+               } else {
+                       // all cases covered previously
+                       throw new UnsupportedException();
+               }
+
+               if (generateScript != null) {
+                       File scriptFile = new File(getExecDirToUse() + File.separator
+                                       + generateScript);
+                       try {
+                               FileUtils.writeStringToFile(scriptFile,
+                                               (osConsole != null ? osConsole + " " : "")
+                                                               + commandLine.toString());
+                       } catch (IOException e) {
+                               throw new SlcException("Could not generate script "
+                                               + scriptFile, e);
+                       }
+                       commandLine = new CommandLine(scriptFile);
+               } else {
+                       if (osConsole != null)
+                               commandLine = CommandLine.parse(osConsole + " "
+                                               + commandLine.toString());
+               }
+
+               return commandLine;
+       }
+
+       protected ExecuteStreamHandler createExecuteStreamHandler(
+                       final Writer stdOutWriter, final Writer stdErrWriter) {
+               // Log writers
+
+               PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(
+                               new LogOutputStream() {
+                                       protected void processLine(String line, int level) {
+                                               log(stdOutLogLevel, line);
+                                               if (stdOutWriter != null)
+                                                       appendLineToFile(stdOutWriter, line);
+                                       }
+                               }, new LogOutputStream() {
+                                       protected void processLine(String line, int level) {
+                                               log(stdErrLogLevel, line);
+                                               if (stdErrWriter != null)
+                                                       appendLineToFile(stdErrWriter, line);
+                                       }
+                               }, null);
+               return pumpStreamHandler;
+       }
+
+       protected ExecuteResultHandler createExecuteResultHandler(
+                       final CommandLine commandLine) {
+               return new ExecuteResultHandler() {
+
+                       public void onProcessComplete(int exitValue) {
+                               if (log.isDebugEnabled())
+                                       log
+                                                       .debug("Process " + commandLine
+                                                                       + " properly completed.");
+                               if (testResult != null) {
+                                       forwardPath(testResult, null);
+                                       testResult.addResultPart(new SimpleResultPart(
+                                                       TestStatus.PASSED, "Process " + commandLine
+                                                                       + " properly completed."));
+                               }
+                       }
+
+                       public void onProcessFailed(ExecuteException e) {
+                               if (testResult != null) {
+                                       forwardPath(testResult, null);
+                                       testResult.addResultPart(new SimpleResultPart(
+                                                       TestStatus.ERROR, "Process " + commandLine
+                                                                       + " failed.", e));
+                               } else {
+                                       throw new SlcException("Process " + commandLine
+                                                       + " failed.", e);
+                               }
+                       }
+               };
+       }
+
        /**
-        * Shortcut method returning the current exec dir if the specified one is
-        * null.
+        * Shortcut method getting the execDir to use
         */
-       private String getUsedDir(File dir) {
-               if (dir == null)
-                       return System.getProperty("user.dir");
-               else
-                       return dir.getPath();
+       protected String getExecDirToUse() {
+               try {
+                       File dir = null;
+                       if (execDir != null) {
+                               // Replace '/' by local file separator, for portability
+                               execDir.replace('/', File.separatorChar);
+                               dir = new File(execDir).getCanonicalFile();
+                       }
+
+                       if (dir == null)
+                               return System.getProperty("user.dir");
+                       else
+                               return dir.getPath();
+               } catch (Exception e) {
+                       throw new SlcException("Cannot find exec dir", e);
+               }
        }
 
        protected void log(String logLevel, String line) {
@@ -314,4 +374,39 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable,
                this.testResult = testResult;
        }
 
+       public void setLogCommand(Boolean logCommand) {
+               this.logCommand = logCommand;
+       }
+
+       public void setRedirectStreams(Boolean redirectStreams) {
+               this.redirectStreams = redirectStreams;
+       }
+
+       public void setOsConsole(String osConsole) {
+               this.osConsole = osConsole;
+       }
+
+       public void setGenerateScript(String generateScript) {
+               this.generateScript = generateScript;
+       }
+
+       private class DummyexecuteStreamHandler implements ExecuteStreamHandler {
+
+               public void setProcessErrorStream(InputStream is) throws IOException {
+               }
+
+               public void setProcessInputStream(OutputStream os) throws IOException {
+               }
+
+               public void setProcessOutputStream(InputStream is) throws IOException {
+               }
+
+               public void start() throws IOException {
+               }
+
+               public void stop() {
+               }
+
+       }
+
 }