Clover coverage report - PLT Utilities Test Coverage (plt-20120304-r5436)
Coverage timestamp: Sat Mar 3 2012 22:01:56 CST
file stats: LOC: 172   Methods: 15
NCLOC: 75   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
SwingWorker.java 0% 0% 0% 0%
coverage
 1    /*BEGIN_COPYRIGHT_BLOCK*
 2   
 3    PLT Utilities BSD License
 4   
 5    Copyright (c) 2007-2010 JavaPLT group at Rice University
 6    All rights reserved.
 7   
 8    Developed by: Java Programming Languages Team
 9    Rice University
 10    http://www.cs.rice.edu/~javaplt/
 11   
 12    Redistribution and use in source and binary forms, with or without modification, are permitted
 13    provided that the following conditions are met:
 14   
 15    - Redistributions of source code must retain the above copyright notice, this list of conditions
 16    and the following disclaimer.
 17    - Redistributions in binary form must reproduce the above copyright notice, this list of
 18    conditions and the following disclaimer in the documentation and/or other materials provided
 19    with the distribution.
 20    - Neither the name of the JavaPLT group, Rice University, nor the names of the library's
 21    contributors may be used to endorse or promote products derived from this software without
 22    specific prior written permission.
 23   
 24    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 25    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 26    FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND
 27    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 28    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 29    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 30    IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 31    OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 32   
 33    *END_COPYRIGHT_BLOCK*/
 34   
 35    package edu.rice.cs.plt.swing;
 36   
 37    import java.util.LinkedList;
 38    import java.util.List;
 39    import java.util.concurrent.BlockingQueue;
 40   
 41    import javax.swing.SwingUtilities;
 42   
 43    import edu.rice.cs.plt.lambda.Runnable1;
 44    import edu.rice.cs.plt.lambda.WrappedException;
 45    import edu.rice.cs.plt.concurrent.CompletionMonitor;
 46    import edu.rice.cs.plt.concurrent.IncrementalTaskController;
 47   
 48    /**
 49    * <p>A utility class providing the core functionality of {@code javax.swing.SwingWorker} (first available
 50    * in Java 6), in addition to supporting the IncrementalTaskController interface. Allows a task to be
 51    * separated into two parts: a working portion that calculates a value (or sequence of intermediate values)
 52    * in the background, and a GUI portion that executes in the Swing event thread when the working portion is
 53    * complete. Implementations should define {@link #doInBackground} and, optionally, {@link #process}
 54    * and {@link #done}. The {@code doInBackground()} implementation may call {@link #publish}
 55    * and {@link #authorizeContinue}; other protected methods should generally be ignored as implementation
 56    * details.</p>
 57    *
 58    * <p>Implementations should be able to migrate seamlessly to the Java 6 API version by simply changing
 59    * the parent class, as long as they stick to methods that are defined in both classes. This version doesn't
 60    * support PropertyChangeListeners, a progress property, the Runnable interface, a {@code getState()} method
 61    * (although {@code status()} provides similar information), or an {@code isCancelled()} method that can be
 62    * polled by {@code doInBackground()} ({@code isCancelled()} is defined, but its result is never
 63    * {@code true} before {@code doInBackground()} returns; implementations should instead handle cancellation
 64    * by checking for an interrupt). There is also (currently) no thread pooling &mdash;
 65    * each worker runs in a new thread. This version <em>adds</em> the methods provided by
 66    * IncrementalTaskController, as well as {@link #authorizeContinue}, which supports the implementation
 67    * of {@link #pause}.</p>
 68    */
 69    public abstract class SwingWorker<R, I> extends IncrementalTaskController<I, R> {
 70   
 71    private CompletionMonitor _continueMonitor;
 72    private Thread _workerThread;
 73   
 74  0 public SwingWorker() {
 75  0 super();
 76  0 _continueMonitor = new CompletionMonitor(false);
 77  0 _workerThread = new Thread("SwingWorker") {
 78  0 public void run() {
 79  0 started();
 80  0 try { finishedCleanly(doInBackground()); }
 81  0 catch (InterruptedException e) { stopped(); }
 82  0 catch (Exception e) { finishedWithTaskException(e); }
 83  0 catch (Throwable t) { finishedWithImplementationException(new WrappedException(t)); }
 84    }
 85    };
 86  0 finishListeners().add(new Runnable() {
 87  0 public void run() {
 88  0 SwingUtilities.invokeLater(new Runnable() {
 89  0 public void run() { done(); }
 90    });
 91    }
 92    });
 93    // Defined as a stand-alone class in order to simplify self-references.
 94    class IntermediateListener implements Runnable1<I> {
 95  0 public void run(I val) {
 96  0 intermediateListeners().remove(this); // don't respond again until the Swing task runs
 97  0 SwingUtilities.invokeLater(new Runnable() {
 98  0 public void run() {
 99  0 List<I> vals = new LinkedList<I>();
 100    // add listener before drain to ensure a concurrent write isn't missed
 101  0 intermediateListeners().add(IntermediateListener.this);
 102  0 intermediateQueue().drainTo(vals);
 103  0 process(vals);
 104    }
 105    });
 106    }
 107    }
 108  0 @SuppressWarnings("unchecked") // javac 6 bug (Eclipse and javac 5 are fine)
 109    Runnable1<I> listener = new IntermediateListener();
 110  0 intermediateListeners().add(listener);
 111    }
 112   
 113   
 114    /*=== Public SwingWorker interface. ===*/
 115   
 116  0 public final void execute() { start(); }
 117   
 118   
 119    /*=== Methods to be overridden by the subclass. ===*/
 120   
 121    /** Work to be performed in a worker thread. */
 122    protected abstract R doInBackground() throws Exception;
 123   
 124    /** Action to be performed in the event thread when intermediate results are available. */
 125  0 protected void process(List<I> chunks) {}
 126   
 127    /** Action to be performed in the event thread when work has completed. */
 128  0 protected void done() {}
 129   
 130   
 131    /*=== Methods that the subclass may call in doInBackground(). ===*/
 132   
 133    /** Called by {@link #doInBackground} when intermediate results are available. */
 134  0 protected final void publish(I... chunks) {
 135  0 BlockingQueue<I> queue = intermediateQueue();
 136  0 try {
 137  0 for (I val : chunks) { queue.put(val); }
 138    }
 139  0 catch (InterruptedException e) { throw new WrappedException(e); }
 140    }
 141   
 142    /**
 143    * <p>Called by {@link #doInBackground} to ensure that the task has not been paused or canceled.
 144    * If paused, this method blocks until the task is restarted. If canceled, throws an
 145    * InterruptedException.</p>
 146    *
 147    * <p>Tasks that wish to maintain migration compatibility with {@code javax.swing.SwingWorker} cannot
 148    * call this method or support pausing. Instead, they should simply respond to an interrupt when canceled
 149    * (checking, for example, via {@link Thread#interrupted}).</p>
 150    */
 151  0 protected void authorizeContinue() throws InterruptedException {
 152  0 if (Thread.interrupted()) { throw new InterruptedException(); }
 153  0 if (!_continueMonitor.isSignaled()) {
 154  0 paused();
 155  0 _continueMonitor.ensureSignaled();
 156  0 started();
 157    }
 158    }
 159   
 160   
 161    /*=== Implementation of IncrementalTaskController. ===*/
 162   
 163   
 164  0 protected final void doStart() {
 165  0 _continueMonitor.signal();
 166  0 _workerThread.start();
 167    }
 168  0 protected final void doPause() { _continueMonitor.reset(); }
 169  0 protected final void doResume() { _continueMonitor.signal(); }
 170  0 protected final void doStop() { _workerThread.interrupt(); }
 171   
 172    }