summaryrefslogtreecommitdiffstats
path: root/api/src/main/java/org/openslx/taskmanager/api/SystemCommandTask.java
diff options
context:
space:
mode:
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.java169
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 );
+
+}