Changeset 31631


Ignore:
Timestamp:
04/21/17 20:00:54 (4 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.

Location:
main/trunk/greenstone3/src/java/org/greenstone
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/build/GS2PerlConstructor.java

    r31602 r31631  
    485485        // handle each incoming line from stdout and stderr streams, and any exceptions that occur then
    486486        SafeProcess.CustomProcessHandler processOutHandler
    487         = new SynchronizedProcessHandler(bw, SynchronizedProcessHandler.STDOUT);
     487        = new SynchronizedProcessHandler(bw, SafeProcess.STDOUT);
    488488        SafeProcess.CustomProcessHandler processErrHandler
    489         = new SynchronizedProcessHandler(bw, SynchronizedProcessHandler.STDERR);
     489        = new SynchronizedProcessHandler(bw, SafeProcess.STDERR);
    490490       
    491491        // GS2PerlConstructor will do further handling of exceptions that may occur during the perl
     
    700700    // exceptions when reading from our perl process' stderr and stdout streams are handled by
    701701    // SynchronizedProcessHandler.gotException() below, since they happen in separate threads
    702     // from this one (the ine from which the perl process is run).
     702    // from this one (the one from which the perl process is run).
    703703    public synchronized void gotException(Exception e) {
    704704
     
    719719    // we do that here too, to continue original behaviour. These calls are also synchronized to make their
    720720    // use of the EventListeners threadsafe.
    721     protected class SynchronizedProcessHandler implements SafeProcess.CustomProcessHandler
     721    protected class SynchronizedProcessHandler extends SafeProcess.CustomProcessHandler
    722722    {
    723     public static final int STDERR = 0;
    724     public static final int STDOUT = 1;
    725 
    726     private final int source;
    727723    private final BufferedWriter bwHandle; // needs to be final to synchronize on the object
    728724       
    729 
    730725    public SynchronizedProcessHandler(BufferedWriter bw, int src) {
     726        super(src); // will set this.source to STDERR or STDOUT
    731727        this.bwHandle = bw; // caller will close bw, since many more than one
    732728                            // SynchronizedProcessHandlers are using it
    733         this.source = src; // STDERR or STDOUT
    734729    }
    735730
     
    751746
    752747
    753             //if(this.source == STDERR) {
     748            //if(this.source == SafeProcess.STDERR) {
    754749            ///System.err.println("ERROR: " + line);
    755750            //} else {
     
    767762            }
    768763            } catch(IOException ioe) {
    769             String msg = (source == STDERR) ? "stderr" : "stdout";
     764            String msg = (this.source == SafeProcess.STDERR) ? "stderr" : "stdout";
    770765            msg = "Exception when writing out a line read from perl process' " + msg + " stream.";
    771766            GS2PerlConstructor.logger.error(msg, ioe);
     
    780775        } catch (IOException ioe) { // problem with reading in from process with BufferedReader br
    781776
    782         String msg = (source == STDERR) ? "stderr" : "stdout";
     777        String msg = (this.source == SafeProcess.STDERR) ? "stderr" : "stdout";
    783778        msg = "Got exception when processing the perl process' " + msg + " stream.";
    784779        GS2PerlConstructor.logger.error(msg, ioe);
     
    821816        // http://stackoverflow.com/questions/14211629/java-util-logger-write-synchronization
    822817       
    823         String msg = (source == STDERR) ? "stderr" : "stdout";
     818        String msg = (this.source == SafeProcess.STDERR) ? "stderr" : "stdout";
    824819        msg = "IOException when writing out a line read from perl process' " + msg + " stream.";
    825820        msg += "\nGot line: " + line + "\n";
  • 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.