Clover coverage report - PLT Utilities Test Coverage (plt-20120304-r5436)
Coverage timestamp: Sat Mar 3 2012 22:01:56 CST
file stats: LOC: 128   Methods: 10
NCLOC: 44   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
ListenerSet.java 25% 33.3% 30% 31.2%
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.collect;
 36   
 37    import java.util.Set;
 38    import java.util.concurrent.CopyOnWriteArraySet;
 39   
 40    import edu.rice.cs.plt.lambda.LambdaUtil;
 41    import edu.rice.cs.plt.lambda.Runnable1;
 42   
 43    /**
 44    * A mutable set of listeners. Each listener is a {@link Runnable1} and receives an argument
 45    * of type {@code T}. In typical usage, a class supporting listeners has some number of
 46    * {@code ListenerSet<T>} fields and associated getters returning {@code ListenerSet<T>.Sink}s
 47    * (one for each different kind of event to be responded to). Clients use expressions like
 48    * {@code foo.listeners().add(...)} to add listeners; the listener class then calls
 49    * {@code _listeners.run(...)} when an event occurs.
 50    */
 51    public class ListenerSet<T> extends DelegatingSet<Runnable1<? super T>> implements Runnable1<T> {
 52   
 53    private final Sink _sink;
 54   
 55    /**
 56    * Create a ListenerSet backed by a {@link CopyOnWriteArraySet} (thread-safe and efficient for
 57    * frequent traversal, but slow when frequently mutated).
 58    */
 59  2 public ListenerSet() { this(new CopyOnWriteArraySet<Runnable1<? super T>>()); }
 60   
 61    /** Create a ListenerSet backed by the given set. */
 62  14 public ListenerSet(Set<Runnable1<? super T>> delegate) {
 63  14 super(delegate);
 64  14 _sink = new Sink();
 65    }
 66   
 67    /**
 68    * Pass the given value to each of the listeners in turn. Execution order is determined by
 69    * the backing set. If an exception occurs in a listener, that exception is set aside until
 70    * all listeners can be run. Upon completion, the first exception to occur (if any) is thrown.
 71    */
 72  19 public void run(T arg) {
 73  19 RuntimeException exception = null;
 74  19 for (Runnable1<? super T> l : _delegate) {
 75  0 try { l.run(arg); }
 76    catch (RuntimeException e) {
 77  0 if (exception == null) { exception = e; }
 78    }
 79    }
 80  0 if (exception != null) { throw exception; }
 81    }
 82   
 83    /**
 84    * Get a write-only sink view of the set. Clients should generally use this interface to register
 85    * listeners.
 86    */
 87  0 public Sink sink() { return _sink; }
 88   
 89   
 90    /**
 91    * A write-only view of the set. This interface ensures that clients act independently &mdash;
 92    * a client with only a reference to a certain listener cannot view, remove, or run other listeners.
 93    */
 94    public class Sink {
 95   
 96    /** Add the given listener to the set. */
 97  0 public boolean add(Runnable1<? super T> listener) {
 98  0 return _delegate.add(listener);
 99    }
 100   
 101    /** Add the given listener to the set, wrapped with {@link LambdaUtil#promote(Runnable)}. */
 102  0 public boolean add(Runnable listener) {
 103  0 return _delegate.add(LambdaUtil.promote(listener));
 104    }
 105   
 106    /** Add the given listeners to the set. */
 107  0 public boolean addAll(Iterable<Runnable1<? super T>> addList) {
 108  0 return CollectUtil.addAll(_delegate, addList);
 109    }
 110   
 111    /** Remove the given listener from the set. */
 112  0 public boolean remove(Runnable1<? super T> listener) {
 113  0 return _delegate.remove(listener);
 114    }
 115   
 116    /** Remove all of the given listeners from the set. */
 117  0 public boolean removeAll(Iterable<Runnable1<? super T>> removeList) {
 118  0 return CollectUtil.removeAll(_delegate, removeList);
 119    }
 120   
 121    }
 122   
 123    /** Call the constructor (allows {@code T} to be inferred). */
 124  0 public static <T> ListenerSet<T> make(Set<Runnable1<? super T>> delegate) {
 125  0 return new ListenerSet<T>(delegate);
 126    }
 127   
 128    }