blob: ed47336f012a6a430fcec63689d8bc7b51cbd8ae (
plain) (
tree)
|
|
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 ( Exception 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 ( Exception e ) {
}
}
} );
stdout.start();
stderr.start();
// Wait for everything
process.waitFor();
try {
process.getErrorStream().close();
} catch ( Throwable t ) {
}
try {
process.getOutputStream().close();
} catch ( Throwable t ) {
}
stdout.join( 2000 );
stderr.join( 2000 );
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 );
}
|