Clover coverage report - PLT Utilities Test Coverage (plt-20120304-r5436)
Coverage timestamp: Sat Mar 3 2012 22:01:56 CST
file stats: LOC: 209   Methods: 44
NCLOC: 119   Classes: 9
 
 Source file Conditionals Statements Methods TOTAL
LogSink.java 50% 60.3% 52.3% 56.7%
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.util.Date;
 38    import java.util.LinkedList;
 39    import java.util.List;
 40    import java.io.Closeable;
 41    import java.io.Serializable;
 42    import edu.rice.cs.plt.tuple.Option;
 43    import edu.rice.cs.plt.tuple.Pair;
 44    import edu.rice.cs.plt.io.IOUtil;
 45    import edu.rice.cs.plt.iter.IterUtil;
 46   
 47    /**
 48    * <p>A destination for log messages. After front-end processing in a {@link Log}, which determines the calling
 49    * time, stack, etc., log messages are created and passed to a sink, which records them as desired. LogSinks
 50    * are often associated with system resources, and so care should be taken to close them when no longer needed.
 51    * {@link IOUtil#closeOnExit} allows LogSinks to be closed at program termination.</p>
 52    *
 53    * <p>LogSink implementations should be thread-safe: each {@code log} invocation should appear to have executed
 54    * atomically.</p>
 55    */
 56    public interface LogSink extends Closeable {
 57   
 58    public void log(StandardMessage m);
 59    public void logStart(StartMessage m);
 60    public void logEnd(EndMessage m);
 61    public void logError(ErrorMessage m);
 62    public void logStack(StackMessage m);
 63   
 64    public abstract class Message implements Serializable {
 65    private final ThreadSnapshot _thread;
 66    private final Option<String> _text;
 67   
 68  15 protected Message(ThreadSnapshot thread) { _thread = thread; _text = Option.none(); }
 69  3 protected Message(ThreadSnapshot thread, String text) { _thread = thread; _text = Option.some(text); }
 70  18 protected Message(Message copy) { _thread = copy._thread; _text = copy._text; }
 71   
 72    /** A ThreadSnapshot created at the initial log method invocation. */
 73  0 public ThreadSnapshot thread() { return _thread; }
 74    /** An optional, arbitrary text message to be logged. */
 75  0 public Option<String> text() { return _text; }
 76    /** The time at which the log method was invoked. */
 77  0 public Date time() { return _thread.snapshotTime(); }
 78    /** The location from which the log method was invoked, if available. */
 79  0 public Option<StackTraceElement> caller() { return Option.wrap(_thread.callingLocation()); }
 80    /** The stack from which the log method was invoked, with the caller on top. */
 81  0 public Iterable<StackTraceElement> stack() { return IterUtil.skipFirst(_thread.getStackTrace()); }
 82   
 83    public abstract void send(LogSink sink);
 84    public abstract <T> T apply(MessageVisitor<? extends T> visitor);
 85   
 86    /**
 87    * Convert the message to a form that is guaranteed to be serializable (e.g., invokes {@code toString()} on
 88    * objects of arbitrary type).
 89    */
 90    public abstract Message serializable();
 91   
 92   
 93    }
 94   
 95    public abstract class ValueMessage extends Message {
 96    private final Iterable<Pair<String, Object>> _values;
 97   
 98  9 protected ValueMessage(ThreadSnapshot thread, String[] names, Object[] vals) {
 99  9 super(thread);
 100  9 _values = makeValues(names, vals);
 101    }
 102  3 protected ValueMessage(ThreadSnapshot thread, String message, String[] names, Object[] vals) {
 103  3 super(thread, message);
 104  3 _values = makeValues(names, vals);
 105    }
 106    /** Copy the given message, with values converted to a serializable form */
 107  12 protected ValueMessage(ValueMessage copy) {
 108  12 super(copy);
 109  12 List<Pair<String, Object>> safeVals = new LinkedList<Pair<String, Object>>();
 110  12 for (Pair<String, Object> p : copy._values) {
 111  12 safeVals.add(Pair.make(p.first(), IOUtil.ensureSerializable(p.second())));
 112    }
 113  12 _values = safeVals;
 114    }
 115   
 116  12 private Iterable<Pair<String, Object>> makeValues(String[] names, Object[] vals) {
 117  12 if (names.length != vals.length) {
 118  0 throw new IllegalArgumentException("Lengths of names and values are inconsistent");
 119    }
 120  12 return IterUtil.zip(IterUtil.make(names), IterUtil.make(vals));
 121    }
 122   
 123    /** A list of name-value pairs to be logged. May be empty. */
 124  0 public Iterable<Pair<String, Object>> values() { return _values; }
 125   
 126    }
 127   
 128    /** A standard logging message, which may include a text message and name-value pairs. */
 129    public class StandardMessage extends ValueMessage {
 130  3 public StandardMessage(ThreadSnapshot thread, String[] names, Object[] vals) {
 131  3 super(thread, names, vals);
 132    }
 133  3 public StandardMessage(ThreadSnapshot thread, String message, String[] names, Object[] vals) {
 134  3 super(thread, message, names, vals);
 135    }
 136  6 protected StandardMessage(StandardMessage copy) { super(copy); }
 137  0 public void send(LogSink sink) { sink.log(this); }
 138  0 public <T> T apply(MessageVisitor<? extends T> visitor) { return visitor.forStandard(this); }
 139  6 public StandardMessage serializable() { return new StandardMessage(this); }
 140    }
 141   
 142    /**
 143    * A message signifying the beginning of a block of code. Should be matched by an EndMessage occurring
 144    * in the same thread.
 145    */
 146    public class StartMessage extends ValueMessage {
 147  3 public StartMessage(ThreadSnapshot thread, String[] names, Object[] vals) {
 148  3 super(thread, names, vals);
 149    }
 150  0 public StartMessage(ThreadSnapshot thread, String message, String[] names, Object[] vals) {
 151  0 super(thread, message, names, vals);
 152    }
 153  3 protected StartMessage(StartMessage copy) { super(copy); }
 154  0 public void send(LogSink sink) { sink.logStart(this); }
 155  0 public <T> T apply(MessageVisitor<? extends T> visitor) { return visitor.forStart(this); }
 156  3 public StartMessage serializable() { return new StartMessage(this); }
 157    }
 158   
 159    /** A message signifying the end of a block of code. Should match a previous StartMessage in the same thread. */
 160    public class EndMessage extends ValueMessage {
 161  3 public EndMessage(ThreadSnapshot thread, String[] names, Object[] vals) {
 162  3 super(thread, names, vals);
 163    }
 164  0 public EndMessage(ThreadSnapshot thread, String message, String[] names, Object[] vals) {
 165  0 super(thread, message, names, vals);
 166    }
 167  3 protected EndMessage(EndMessage copy) { super(copy); }
 168  0 public void send(LogSink sink) { sink.logEnd(this); }
 169  0 public <T> T apply(MessageVisitor<? extends T> visitor) { return visitor.forEnd(this); }
 170  3 public EndMessage serializable() { return new EndMessage(this); }
 171    }
 172   
 173    /**
 174    * A message logging the occurrence of some error (a Throwable). Serialization may fail if the
 175    * Throwable is not serializable.
 176    */
 177    public class ErrorMessage extends Message {
 178    private final Throwable _error;
 179  3 public ErrorMessage(ThreadSnapshot thread, Throwable error) { super(thread); _error = error; }
 180  0 public ErrorMessage(ThreadSnapshot thread, String text, Throwable error) { super(thread, text); _error = error; }
 181  3 public ErrorMessage(ErrorMessage copy) { super(copy); _error = IOUtil.ensureSerializable(copy._error); }
 182  0 public Throwable error() { return _error; }
 183  0 public void send(LogSink sink) { sink.logError(this); }
 184  0 public <T> T apply(MessageVisitor<? extends T> visitor) { return visitor.forError(this); }
 185  3 public ErrorMessage serializable() { return new ErrorMessage(this); }
 186    }
 187   
 188    /**
 189    * A message logging the thread's current stack trace. While all Messages have ThreadSnapshots and accompanying
 190    * stack traces, StackMessages explicitly request that the stack be recorded.
 191    */
 192    public class StackMessage extends Message {
 193  3 public StackMessage(ThreadSnapshot thread) { super(thread); }
 194  0 public StackMessage(ThreadSnapshot thread, String text) { super(thread, text); }
 195  3 public StackMessage(StackMessage copy) { super(copy); }
 196  0 public void send(LogSink sink) { sink.logStack(this); }
 197  0 public <T> T apply(MessageVisitor<? extends T> visitor) { return visitor.forStack(this); }
 198  3 public StackMessage serializable() { return new StackMessage(this); }
 199    }
 200   
 201    public interface MessageVisitor<T> {
 202    public T forStandard(StandardMessage m);
 203    public T forStart(StartMessage m);
 204    public T forEnd(EndMessage m);
 205    public T forError(ErrorMessage m);
 206    public T forStack(StackMessage m);
 207    }
 208   
 209    }