Clover coverage report - PLT Utilities Test Coverage (plt-20120304-r5436)
Coverage timestamp: Sat Mar 3 2012 22:01:56 CST
file stats: LOC: 167   Methods: 19
NCLOC: 83   Classes: 3
 
 Source file Conditionals Statements Methods TOTAL
RMILogSink.java 75% 79.5% 94.7% 83.9%
coverage 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.debug;
 36   
 37    import java.io.Closeable;
 38    import java.io.IOException;
 39    import java.io.Serializable;
 40    import java.rmi.Remote;
 41    import java.rmi.RemoteException;
 42   
 43    import edu.rice.cs.plt.concurrent.ConcurrentUtil;
 44    import edu.rice.cs.plt.concurrent.JVMBuilder;
 45    import edu.rice.cs.plt.io.IOUtil;
 46    import edu.rice.cs.plt.lambda.LazyThunk;
 47    import edu.rice.cs.plt.lambda.Thunk;
 48    import edu.rice.cs.plt.lambda.WrappedException;
 49   
 50    /**
 51    * A log sink that passes messages to a separate JVM for recording or display. Clients provide a serializable
 52    * LogSink factory; when the first message is logged, a separate process is started and the factory object is
 53    * passed to it, allowing for the creation of an RMI-based LogSink server on the remote JVM. If any exception
 54    * occurs when the remote LogSink is started, it is thrown by the invoked {@code log} method.
 55    */
 56    public class RMILogSink implements LogSink, Closeable {
 57   
 58    private final Thunk<RemoteLogSink> _delegate;
 59    private volatile boolean _active;
 60   
 61    /**
 62    * Create a LogSink server in a new process using {@link JVMBuilder#DEFAULT}. {@code closeOnExit}
 63    * is {@code true}.
 64    * @param factory A serializable LogSink factory, to be invoked in the new process
 65    */
 66  3 public RMILogSink(final Thunk<? extends LogSink> factory) { this(factory, JVMBuilder.DEFAULT, true); }
 67   
 68    /**
 69    * Create a LogSink server in a new process using {@link JVMBuilder#DEFAULT}.
 70    * @param factory A serializable LogSink factory, to be invoked in the new process
 71    * @param closeOnExit Whether this sink should be registered to be closed on system exit.
 72    */
 73  2 public RMILogSink(final Thunk<? extends LogSink> factory, boolean closeOnExit) {
 74  2 this(factory, JVMBuilder.DEFAULT, closeOnExit);
 75    }
 76   
 77   
 78    /**
 79    * Create a LogSink server in a new process using {@link JVMBuilder#DEFAULT}. {@code closeOnExit} is
 80    * {@code true}.
 81    * @param factory A serializable LogSink factory, to be invoked in the new process
 82    * @param jvm A factory for producing the remote JVM. The class path must include the factory's class,
 83    * RMILogSink, ConcurrentUtil, and their dependencies.
 84    */
 85  0 public RMILogSink(final Thunk<? extends LogSink> factory, JVMBuilder jvm) {
 86  0 this(factory, jvm, true);
 87    }
 88   
 89    /**
 90    * Create a LogSink server in a new process using {@link JVMBuilder#DEFAULT}.
 91    * @param factory A serializable LogSink factory, to be invoked in the new process
 92    * @param jvm A factory for producing the remote JVM. The class path must include the factory's class,
 93    * RMILogSink, ConcurrentUtil, and their dependencies.
 94    * @param closeOnExit Whether this sink should be registered to be closed on system exit.
 95    */
 96  5 public RMILogSink(final Thunk<? extends LogSink> factory, final JVMBuilder jvm, boolean closeOnExit) {
 97  5 _delegate = LazyThunk.make(new Thunk<RemoteLogSink>() {
 98  3 public RemoteLogSink value() {
 99  3 try {
 100  3 RemoteLogSink result = (RemoteLogSink) ConcurrentUtil.exportInProcess(new ServerFactory(factory), jvm);
 101  3 _active = true;
 102  3 return result;
 103    }
 104  0 catch (Exception e) { throw new WrappedException(e); }
 105    }
 106    });
 107  5 _active = false;
 108  3 if (closeOnExit) { IOUtil.closeOnExit(this); }
 109    }
 110   
 111    /** Quit the remote process. */
 112  1 public void close() throws IOException {
 113  0 if (_active) { _delegate.value().close(); _active = false; }
 114    }
 115   
 116  6 public void log(StandardMessage m) {
 117  6 try { _delegate.value().log(m.serializable()); }
 118  0 catch (RemoteException e) { throw new WrappedException(e); }
 119    }
 120   
 121  3 public void logStart(StartMessage m) {
 122  3 try { _delegate.value().logStart(m.serializable()); }
 123  0 catch (RemoteException e) { throw new WrappedException(e); }
 124    }
 125   
 126  3 public void logEnd(EndMessage m) {
 127  3 try { _delegate.value().logEnd(m.serializable()); }
 128  0 catch (RemoteException e) { throw new WrappedException(e); }
 129    }
 130   
 131  3 public void logError(ErrorMessage m) {
 132  3 try { _delegate.value().logError(m.serializable()); }
 133  0 catch (RemoteException e) { throw new WrappedException(e); }
 134    }
 135   
 136  3 public void logStack(StackMessage m) {
 137  3 try { _delegate.value().logStack(m.serializable()); }
 138  0 catch (RemoteException e) { throw new WrappedException(e); }
 139    }
 140   
 141    private static interface RemoteLogSink extends Remote {
 142    public void log(StandardMessage m) throws RemoteException;
 143    public void logStart(StartMessage m) throws RemoteException;
 144    public void logEnd(EndMessage m) throws RemoteException;
 145    public void logError(ErrorMessage m) throws RemoteException;
 146    public void logStack(StackMessage m) throws RemoteException;
 147    public void close() throws IOException;
 148    }
 149   
 150    private static class ServerFactory implements Thunk<RemoteLogSink>, Serializable {
 151    private final Thunk<? extends LogSink> _sinkFactory;
 152  3 public ServerFactory(Thunk<? extends LogSink> sinkFactory) { _sinkFactory = sinkFactory; }
 153  3 public RemoteLogSink value() {
 154    // Code to execute in the remote JVM
 155  3 final LogSink sink = _sinkFactory.value();
 156  3 return new RemoteLogSink() {
 157  3 public void close() throws IOException { System.exit(0); }
 158  6 public void log(StandardMessage m) { sink.log(m); }
 159  3 public void logStart(StartMessage m) { sink.logStart(m); }
 160  3 public void logEnd(EndMessage m) { sink.logEnd(m); }
 161  3 public void logError(ErrorMessage m) { sink.logError(m); }
 162  3 public void logStack(StackMessage m) { sink.logStack(m); }
 163    };
 164    }
 165    }
 166   
 167    }