diff options
Diffstat (limited to 'api/src/main/java/org/openslx/taskmanager/api/SystemCommandTask.java')
-rw-r--r-- | api/src/main/java/org/openslx/taskmanager/api/SystemCommandTask.java | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/api/src/main/java/org/openslx/taskmanager/api/SystemCommandTask.java b/api/src/main/java/org/openslx/taskmanager/api/SystemCommandTask.java new file mode 100644 index 0000000..ea71ea5 --- /dev/null +++ b/api/src/main/java/org/openslx/taskmanager/api/SystemCommandTask.java @@ -0,0 +1,169 @@ +package org.openslx.taskmanager.api; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + +import org.apache.log4j.Logger; + +public abstract class SystemCommandTask extends AbstractTask +{ + + private static final Logger log = Logger.getLogger( SystemCommandTask.class ); + + private String[] command = null; + + private Process process = null; + + + @Override + protected final boolean execute() + { + command = initCommandLine(); + if ( command == null || command.length == 0 ) { + return processEnded( -1 ); + } + + ProcessBuilder pb = new ProcessBuilder( command ); + pb.directory( new File( "/" ) ); + + try { + + // Create process + process = pb.start(); + final Process p = process; + processStarted(); + p.getOutputStream(); + + // Read its stdout + Thread stdout = new Thread( new Runnable() { + @Override + public void run() + { + try { + BufferedReader reader = new BufferedReader( new InputStreamReader( p.getInputStream() ) ); + String line; + while ( ( line = reader.readLine() ) != null ) { + synchronized ( p ) { + processStdOut( line ); + } + } + } catch ( IOException e ) { + } + } + } ); + // Read its stderr + Thread stderr = new Thread( new Runnable() { + @Override + public void run() + { + try { + BufferedReader reader = new BufferedReader( new InputStreamReader( p.getErrorStream() ) ); + String line; + while ( ( line = reader.readLine() ) != null ) { + synchronized ( p ) { + processStdErr( line ); + } + } + } catch ( IOException e ) { + } + } + } ); + + stdout.start(); + stderr.start(); + + // Wait for everything + stdout.join(); + stderr.join(); + process.waitFor(); + + return processEnded( process.exitValue() ); + + } catch ( IOException e ) { + log.warn( "Process of task " + getId() + " died." ); + processStdErr( e.toString() ); + return processEnded( -2 ); + } catch ( InterruptedException e ) { + Thread.currentThread().interrupt(); + return false; + } catch ( Exception e ) { + log.warn( "Unexpected exception when executing " + getId() + ": " + e.toString() ); + processStdErr( e.toString() ); + return processEnded( -3 ); + } finally { + if ( process != null ) + process.destroy(); + } + } + + /** + * Write data to the process's stdin. + * + * @param data stuff to write + * @return success or failure mapped to a boolean in a really complicated way + */ + protected final boolean toStdIn(byte[] data) + { + try { + process.getOutputStream().write( data ); + } catch ( IOException e ) { + e.printStackTrace(); + return false; + } + return true; + } + + /** + * Write text to the process's stdin. + * + * @param text stuff to write + * @return success or failure mapped to a boolean in a really complicated way + */ + protected final boolean toStdIn(String text) + { + return toStdIn( text.getBytes( StandardCharsets.UTF_8 ) ); + } + + /** + * Called to get the command line. Each argument should be a separate array + * element. Returning null means the task should not run (as the arguments + * were probably faulty). + * + * @return List of arguments. First element is the command itself. + */ + protected abstract String[] initCommandLine(); + + /** + * Called when the process has been successfully started. + */ + protected void processStarted() + { + } + + /** + * Called when the process has finished running + * + * @param exitCode the process' exit code + * @return + */ + protected abstract boolean processEnded( int exitCode ); + + /** + * Called when a line has been read from the process' stdout. + * + * @param line The line read from the process, without any newline characters + */ + protected abstract void processStdOut( String line ); + + /** + * Called when a line has been read from the process' stderr. + * Trailing newline is removed. + * + * @param line The line read from the process, without any newline characters + */ + protected abstract void processStdErr( String line ); + +} |