Ignore:
Timestamp:
2017-04-21T20:00:54+12:00 (7 years ago)
Author:
ak19
Message:

Further changes to SafeProcess to turn some interfaces to abstract classes. Corresponding changes to GS2PerlConstructor which makes use of this.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone3/src/java/org/greenstone/util/SafeProcess.java

    r31620 r31631  
    2020
    2121public class SafeProcess {
     22   
     23    public static final int STDERR = 0;
     24    public static final int STDOUT = 1;
     25    public static final int STDIN = 2;   
    2226
    2327    static Logger logger = Logger.getLogger(org.greenstone.util.SafeProcess.class.getName());
     
    204208    }
    205209
    206     // Runs a process with default stream processing
     210    // Runs a process with default stream processing. Returns the exitValue
    207211    public int runProcess() {
    208212    return runProcess(null, null, null); // use default processing of all 3 of the process' iostreams
     
    210214
    211215    // Run a process with custom stream processing (any custom handlers passed in that are null
    212     // will use the default stream processing)
     216    // will use the default stream processing).
     217    // Returns the exitValue from running the Process
    213218    public int runProcess(CustomProcessHandler procInHandler,
    214219               CustomProcessHandler procOutHandler,
     
    239244        if(procErrHandler == null) {
    240245        errorGobbler // ReaderFromProcessOutputStream
    241             = new SafeProcess.InputStreamGobbler(prcs.getErrorStream(), splitStdErrorNewLines);     
     246            = new SafeProcess.InputStreamGobbler(prcs.getErrorStream(), splitStdErrorNewLines);
    242247        } else {
    243248        errorGobbler
     
    414419
    415420
    416 //******************** Inner class interface definitions ********************//
     421//******************** Inner class and interface definitions ********************//
    417422// Static inner classes can be instantiated without having to instantiate an object of the outer class first
    418423
     
    423428public static interface ExceptionHandler {
    424429
    425     // SHOULD I DECLARE THIS SYNCHRONIZED?
    426     // It ends up being thread safe for the particular instance I'm using it for, but that doesn't
    427     // make it future proof...
    428     public void gotException(Exception e);
     430    // when implementing ExceptionHandler.gotException(), if it manipulates anything that's
     431    // not threadsafe, declare gotException() as a synchronized method to ensure thread safety
     432    public void gotException(Exception e); // can't declare as synchronized in interface method declaration
    429433}
    430434
    431435// Write your own run() body for any StreamGobbler. You need to create an instance of a class
    432 // implementing CustomProcessHandler for EACH IOSTREAM of the process that you want to handle.
     436// extending CustomProcessHandler for EACH IOSTREAM of the process that you want to handle.
    433437// Do not create a single CustomProcessHandler instance and reuse it for all three streams,
    434438// i.e. don't call SafeProcess' runProcess(x, x, x); It should be runProcess(x, y, z).
    435439// Make sure your implementation is threadsafe if you're sharing immutable objects between the threaded streams
    436440// example implementation is in the GS2PerlConstructor.SynchronizedProcessHandler class.
    437 public static interface CustomProcessHandler {
    438     public void run(Closeable stream); //InputStream or OutputStream
     441// CustomProcessHandler is made an abstract class instead of an interface to force classes that want
     442// to use a CustomProcessHandler to create a separate class that extends CustomProcessHandler, rather than
     443// that the classes that wish to use it "implementing" the CustomProcessHandler interface itself: the
     444// CustomProcessHandler.run() method may then be called in the major thread from which the Process is being
     445// executed, rather than from the individual threads that deal with each iostream of the Process.
     446public static abstract class CustomProcessHandler {
     447
     448    protected final int source;
     449
     450    protected CustomProcessHandler(int src) {
     451    this.source = src; // STDERR or STDOUT or STDIN
     452    }
     453   
     454    public abstract void run(Closeable stream); //InputStream or OutputStream
    439455}
    440456
    441 // When using the default stream processing to read from a process' stdout or stderr stream,
    442 // you can create a LineByLineHandler for the process' err and out streams
     457// When using the default stream processing to read from a process' stdout or stderr stream, you can
     458// create a class extending LineByLineHandler for the process' err stream and one for its output stream
    443459// to do something on a line by line basis, such as sending the line to a log
    444 public static interface LineByLineHandler {
    445     public void gotLine(String line);
    446     public void gotException(Exception e); // for when an exception occurs instead of getting a line
     460public static abstract class LineByLineHandler {
     461    protected final int source;
     462
     463    protected LineByLineHandler(int src) {
     464    this.source = src; // STDERR or STDOUT
     465    }
     466
     467    public abstract void gotLine(String line); // first non-null line
     468    public abstract void gotException(Exception e); // for when an exception occurs instead of getting a line
    447469}
    448470
Note: See TracChangeset for help on using the changeset viewer.