package ctbrec.event; import lombok.extern.slf4j.Slf4j; import java.util.Arrays; import ctbrec.OS; import ctbrec.event.EventHandlerConfiguration.ActionConfiguration; import ctbrec.io.StreamRedirector; @Slf4j public class ExecuteProgram extends Action { private String executable; public ExecuteProgram() { name = "execute program"; } public ExecuteProgram(String executable) { this(); this.executable = executable; } @Override public void accept(Event evt) { Runtime rt = Runtime.getRuntime(); Process process = null; try { String[] args = evt.getExecutionParams(); String[] cmd = new String[args.length+1]; cmd[0] = executable; System.arraycopy(args, 0, cmd, 1, args.length); log.debug("Executing {}", Arrays.toString(cmd)); process = rt.exec(cmd, OS.getEnvironment()); // create threads, which read stdout and stderr of the player process. these are needed, // because otherwise the internal buffer for these streams fill up and block the process Thread std = new Thread(new StreamRedirector(process.getInputStream(), System.out)); std.setName("Player stdout pipe"); std.setDaemon(true); std.start(); Thread err = new Thread(new StreamRedirector(process.getErrorStream(), System.err)); err.setName("Player stderr pipe"); err.setDaemon(true); err.start(); process.waitFor(); log.debug("Executing {} finished", executable); } catch (Exception e) { log.error("Error while executing {}", executable, e); } } @Override public void configure(ActionConfiguration config) { executable = (String) config.getConfiguration().get("file"); } @Override public String toString() { return "execute " + executable; } }