Clover coverage report - PLT Utilities Test Coverage (plt-20120304-r5436)
Coverage timestamp: Sat Mar 3 2012 22:01:56 CST
file stats: LOC: 219   Methods: 31
NCLOC: 108   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
FilteredLogSink.java 0% 26.7% 35.5% 26.1%
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.IOException;
 38    import java.util.HashSet;
 39    import java.util.Set;
 40   
 41    import edu.rice.cs.plt.lambda.LambdaUtil;
 42    import edu.rice.cs.plt.lambda.Predicate;
 43    import edu.rice.cs.plt.text.TextUtil;
 44    import edu.rice.cs.plt.tuple.Option;
 45   
 46    /**
 47    * A LogSink that discards any messages that are not accepted by a given predicate. Messages that match
 48    * are passed on to another LogSink. For convenience, a variety of Message predicate constructors are
 49    * defined in the class; these can be composed with the methods in LambdaUtil.
 50    * @see edu.rice.cs.plt.lambda.LambdaUtil#and(Predicate, Predicate)
 51    * @see edu.rice.cs.plt.lambda.LambdaUtil#or(Predicate, Predicate)
 52    * @see edu.rice.cs.plt.lambda.LambdaUtil#negate(Predicate)
 53    */
 54    public class FilteredLogSink implements LogSink {
 55   
 56    private final LogSink _delegate;
 57    private final Predicate<? super Message> _pred;
 58   
 59  9 public FilteredLogSink(LogSink delegate, Predicate<? super Message> pred) {
 60  9 _delegate = delegate;
 61  9 _pred = pred;
 62    }
 63   
 64  0 public void close() throws IOException { _delegate.close(); }
 65   
 66  0 public void log(StandardMessage m) {
 67  0 if (_pred.contains(m)) { _delegate.log(m); }
 68    }
 69   
 70  0 public void logEnd(EndMessage m) {
 71  0 if (_pred.contains(m)) { _delegate.logEnd(m); }
 72    }
 73   
 74  0 public void logError(ErrorMessage m) {
 75  0 if (_pred.contains(m)) { _delegate.logError(m); }
 76    }
 77   
 78  0 public void logStack(StackMessage m) {
 79  0 if (_pred.contains(m)) { _delegate.logStack(m); }
 80    }
 81   
 82  0 public void logStart(StartMessage m) {
 83  0 if (_pred.contains(m)) { _delegate.logStart(m); }
 84    }
 85   
 86    /** Create a LogSink filtered by a {@link #locationWhiteListPredicate}. */
 87  5 public static FilteredLogSink byLocationWhiteList(LogSink delegate, final String... prefixes) {
 88  5 return new FilteredLogSink(delegate, locationWhiteListPredicate(prefixes));
 89    }
 90   
 91    /** Create a LogSink filtered by a {@link #locationBlackListPredicate}. */
 92  2 public static FilteredLogSink byLocationBlackList(LogSink delegate, final String... prefixes) {
 93  2 return new FilteredLogSink(delegate, locationBlackListPredicate(prefixes));
 94    }
 95   
 96    /** Create a LogSink filtered by a {@link #locationPredicate}. */
 97  0 public static FilteredLogSink byLocation(LogSink delegate, final Predicate<? super String> pred) {
 98  0 return new FilteredLogSink(delegate, locationPredicate(pred));
 99    }
 100   
 101    /** Create a LogSink filtered by a {@link #stackDepthPredicate}. */
 102  0 public static FilteredLogSink byStackDepth(LogSink delegate, int maxDepth) {
 103  0 return new FilteredLogSink(delegate, stackDepthPredicate(maxDepth));
 104    }
 105   
 106    /** Create a LogSink filtered by a {@link #threadWhiteListPredicate}. */
 107  0 public static FilteredLogSink byThreadWhiteList(LogSink delegate, Thread... threads) {
 108  0 return new FilteredLogSink(delegate, threadWhiteListPredicate(threads));
 109    }
 110   
 111    /** Create a LogSink filtered by a {@link #threadWhiteListPredicate}. */
 112  1 public static FilteredLogSink byThreadWhiteList(LogSink delegate, String... nameParts) {
 113  1 return new FilteredLogSink(delegate, threadWhiteListPredicate(nameParts));
 114    }
 115   
 116    /** Create a LogSink filtered by a {@link #threadBlackListPredicate}. */
 117  0 public static FilteredLogSink byThreadBlackList(LogSink delegate, Thread... threads) {
 118  0 return new FilteredLogSink(delegate, threadBlackListPredicate(threads));
 119    }
 120   
 121    /** Create a LogSink filtered by a {@link #threadBlackListPredicate}. */
 122  1 public static FilteredLogSink byThreadBlackList(LogSink delegate, String... nameParts) {
 123  1 return new FilteredLogSink(delegate, threadBlackListPredicate(nameParts));
 124    }
 125   
 126    /** Create a LogSink filtered by a {@link #threadPredicate}. */
 127  0 public static FilteredLogSink byThread(LogSink delegate, Predicate<? super ThreadSnapshot> pred) {
 128  0 return new FilteredLogSink(delegate, threadPredicate(pred));
 129    }
 130   
 131    /**
 132    * Produce a predicate that accepts only caller locations starting with the given prefixes. A prefix
 133    * {@code p} matches a caller location {@code loc} iff
 134    * {@code (loc.getClassName() + "." + loc.getMethodName()).startsWith(p)}. If no caller information
 135    * is available, the empty string is used.
 136    */
 137  7 public static Predicate<Message> locationWhiteListPredicate(final String... prefixes) {
 138  7 return locationPredicate(new Predicate<String>() {
 139  0 public boolean contains(String s) { return TextUtil.startsWithAny(s, prefixes); }
 140    });
 141    }
 142   
 143    /**
 144    * Produce a predicate that rejects any caller locations starting with the given prefixes. A prefix
 145    * {@code p} matches a caller location {@code loc} iff
 146    * {@code (loc.getClassName() + "." + loc.getMethodName()).startsWith(p)}. If no caller information
 147    * is available, the empty string is used.
 148    */
 149  2 public static Predicate<Message> locationBlackListPredicate(final String... prefixes) {
 150  2 return LambdaUtil.negate(locationWhiteListPredicate(prefixes));
 151    }
 152   
 153    /**
 154    * Produce a predicate that accepts messages iff their caller location is accepted by {@code pred}.
 155    * The caller location string is defined for a location {@code loc} as
 156    * {@code loc.getClassName() + "." + loc.getMethodName()}. If no caller information is available,
 157    * the empty string is used.
 158    */
 159  7 public static Predicate<Message> locationPredicate(final Predicate<? super String> pred) {
 160  7 return new Predicate<Message>() {
 161  0 public boolean contains(Message m) {
 162  0 Option<StackTraceElement> locOpt = m.caller();
 163  0 if (locOpt.isSome()) {
 164  0 StackTraceElement loc = locOpt.unwrap();
 165  0 return pred.contains(loc.getClassName() + "." + loc.getMethodName());
 166    }
 167  0 else { return pred.contains(""); }
 168    }
 169    };
 170    }
 171   
 172    /** Produce a predicate that only accepts message with stack traces of at most the given depth. */
 173  0 public static Predicate<Message> stackDepthPredicate(final int maxDepth) {
 174  0 return new Predicate<Message>() {
 175  0 public boolean contains(Message m) { return m.thread().getStackTrace().size() <= maxDepth; }
 176    };
 177    }
 178   
 179    /** Produce a predicate that only accepts messages logged from the given thread. */
 180  0 public static Predicate<Message> threadWhiteListPredicate(Thread... threads) {
 181  0 final Set<Long> ids = new HashSet<Long>();
 182  0 for (Thread t : threads) { ids.add(t.getId()); }
 183  0 threads = null; // no need to hold on to a reference
 184  0 return threadPredicate(new Predicate<ThreadSnapshot>() {
 185  0 public boolean contains(ThreadSnapshot t) { return ids.contains(t.getId()); }
 186    });
 187    }
 188   
 189    /**
 190    * Produce a predicate that only accepts messages logged from threads matching the given names.
 191    * A thread matches a name part {@code s} iff its name contains {@code s}.
 192    */
 193  2 public static Predicate<Message> threadWhiteListPredicate(final String... nameParts) {
 194  2 return threadPredicate(new Predicate<ThreadSnapshot>() {
 195  0 public boolean contains(ThreadSnapshot t) { return TextUtil.containsAny(t.getName(), nameParts); }
 196    });
 197    }
 198   
 199    /** Produce a predicate that only accepts messages logged from the given thread. */
 200  0 public static Predicate<Message> threadBlackListPredicate(Thread... threads) {
 201  0 return LambdaUtil.negate(threadWhiteListPredicate(threads));
 202    }
 203   
 204    /**
 205    * Produce a predicate that only accepts messages logged from threads matching the given names.
 206    * A thread matches a name part {@code s} iff its name contains {@code s}.
 207    */
 208  1 public static Predicate<Message> threadBlackListPredicate(String... nameParts) {
 209  1 return LambdaUtil.negate(threadWhiteListPredicate(nameParts));
 210    }
 211   
 212    /** Produce a predicate that accepts messages iff their associated ThreadSnapshot is accepted by {@code pred}. */
 213  2 public static Predicate<Message> threadPredicate(final Predicate<? super ThreadSnapshot> pred) {
 214  2 return new Predicate<Message>() {
 215  0 public boolean contains(Message m) { return pred.contains(m.thread()); }
 216    };
 217    }
 218   
 219    }