Clover coverage report - PLT Utilities Test Coverage (plt-20120304-r5436)
Coverage timestamp: Sat Mar 3 2012 22:01:56 CST
file stats: LOC: 203   Methods: 32
NCLOC: 107   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
AbstractKeyBasedMap.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.collect;
 36   
 37    import java.util.Map;
 38    import java.util.Collection;
 39    import java.util.Set;
 40    import java.util.Iterator;
 41    import edu.rice.cs.plt.iter.IterUtil;
 42    import edu.rice.cs.plt.iter.MappedIterator;
 43    import edu.rice.cs.plt.lambda.Lambda;
 44   
 45    /**
 46    * An abstract parent class for {@code Map} implementations that defines its operations in terms
 47    * of the key-based methods {@code get()} and {@code keySet()}. This is an alternative to
 48    * {@link java.util.AbstractMap}, which defines its operations in terms of {@code entrySet()} (which is
 49    * generally more difficult to implement, while its use as a basic operation leads to inefficient behavior).
 50    * Subclasses must implement {@link #get} and {@link #keySet}; to support mutation, they must also
 51    * implement {@link #put}, {@link #remove}, and {@link #clear}.
 52    */
 53    public abstract class AbstractKeyBasedMap<K, V> implements LambdaMap<K, V> {
 54   
 55    public abstract V get(Object key);
 56    public abstract PredicateSet<K> keySet();
 57   
 58    /** Returns {@code get(key)}. */
 59  0 public V value(K key) { return get(key); }
 60    /** Returns {@code keySet().size()}. */
 61  0 public int size() { return keySet().size(); }
 62    /** Returns {@code keySet().isEmpty()}. */
 63  0 public boolean isEmpty() { return keySet().isEmpty(); }
 64    /** Returns {@code keySet().contains(key)}. */
 65  0 public boolean containsKey(Object key) { return keySet().contains(key); }
 66   
 67    /** Returns {@code IterUtil.contains(IterUtil.map(keySet(), this), val)}. */
 68  0 public boolean containsValue(Object val) {
 69  0 return IterUtil.contains(IterUtil.map(keySet(), this), val);
 70    }
 71   
 72    /** Return a collection backed by {@code IterUtil.map(keySet(), this)}. */
 73  0 public Collection<V> values() {
 74  0 return new IterableCollection<V>(IterUtil.map(keySet(), this));
 75    }
 76   
 77    /** Returns an instance of {@link EntrySet}. */
 78  0 public Set<Entry<K, V>> entrySet() {
 79  0 return new EntrySet();
 80    }
 81   
 82    /** Throws an {@link UnsupportedOperationException}. */
 83  0 public V put(K key, V val) { throw new UnsupportedOperationException(); }
 84    /** Throws an {@link UnsupportedOperationException}. */
 85  0 public V remove(Object key) { throw new UnsupportedOperationException(); }
 86    /** Throws an {@link UnsupportedOperationException}. */
 87  0 public void clear() { throw new UnsupportedOperationException(); }
 88   
 89    /** Invokes {@link #put} for each element of the given map's entry set. */
 90  0 public void putAll(Map<? extends K, ? extends V> elts) {
 91  0 for (Entry<? extends K, ? extends V> entry : elts.entrySet()) {
 92  0 put(entry.getKey(), entry.getValue());
 93    }
 94    }
 95   
 96  0 public String toString() { return IterUtil.toString(entrySet(), "{", ", ", "}"); }
 97   
 98  0 public boolean equals(Object o) {
 99  0 if (this == o) { return true; }
 100  0 else if (!(o instanceof Map<?, ?>)) { return false; }
 101  0 else { return entrySet().equals(((Map<?, ?>) o).entrySet()); }
 102    }
 103   
 104  0 public int hashCode() { return entrySet().hashCode(); }
 105   
 106   
 107    /** An entry set defined in terms of the enclosing map's other methods. */
 108    protected class EntrySet extends AbstractPredicateSet<Entry<K, V>> {
 109   
 110    /**
 111    * Test whether an entry is present by invoking {@code containsKey()} and
 112    * {@code get()}.
 113    */
 114  0 @Override public boolean contains(Object o) {
 115  0 if (o instanceof Entry<?, ?>) {
 116  0 Entry<?, ?> entry = (Entry<?, ?>) o;
 117  0 Object key = entry.getKey();
 118  0 if (containsKey(key)) {
 119  0 Object val = entry.getValue();
 120  0 Object mapVal = get(key);
 121  0 return (val == null) ? (mapVal == null) : val.equals(mapVal);
 122    }
 123    }
 124  0 return false;
 125    }
 126   
 127    /** Create an iterator based on {@link #mapEntryForKey}. */
 128  0 public Iterator<Entry<K, V>> iterator() {
 129  0 return MappedIterator.make(keySet().iterator(), new Lambda<K, Entry<K, V>>() {
 130  0 public Entry<K, V> value(K key) {
 131  0 return mapEntryForKey(AbstractKeyBasedMap.this, key);
 132    }
 133    });
 134    }
 135   
 136    /** Delegate to {@code keySet()}. */
 137  0 public boolean isInfinite() { return keySet().isInfinite(); }
 138    /** Delegate to {@code keySet()}. */
 139  0 public boolean hasFixedSize() { return keySet().hasFixedSize(); }
 140    /** False: can't guarantee that values won't change. */
 141  0 public boolean isStatic() { return false; }
 142   
 143    /** Delegate to the map's {@code isEmpty()} method. */
 144  0 @Override public boolean isEmpty() { return AbstractKeyBasedMap.this.isEmpty(); }
 145    /** Delegate to the map's {@code size()} method. */
 146  0 @Override public int size() { return AbstractKeyBasedMap.this.size(); }
 147    /** Delegate to {@code keySet()}. */
 148  0 @Override public int size(int bound) { return keySet().size(bound); }
 149   
 150    /** Delegate to the map's {@code put()} method. */
 151  0 @Override public boolean add(Entry<K, V> entry) {
 152  0 boolean present = contains(entry);
 153  0 AbstractKeyBasedMap.this.put(entry.getKey(), entry.getValue());
 154  0 return !present;
 155    }
 156   
 157    /** Delegate to the map's {@code remove()} method. */
 158  0 @Override public boolean remove(Object o) {
 159  0 if (o instanceof Entry<?, ?>) {
 160  0 Entry<?, ?> entry = (Entry<?, ?>) o;
 161  0 boolean present = containsKey(entry.getKey());
 162  0 AbstractKeyBasedMap.this.remove(entry.getKey());
 163  0 return present;
 164    }
 165  0 else { return false; }
 166    }
 167   
 168    /** Delegate to the map's {@code clear()} method. */
 169  0 @Override public void clear() {
 170  0 AbstractKeyBasedMap.this.clear();
 171    }
 172   
 173    }
 174   
 175    /**
 176    * Define a map entry in terms of a map's {@code get()} and {@code put()} methods.
 177    * For the result to be a valid entry in the given map, the map must contain the given key.
 178    */
 179  0 protected static <K, V> Entry<K, V> mapEntryForKey(final Map<K, V> map, final K key) {
 180  0 return new Entry<K, V>() {
 181  0 public K getKey() { return key; }
 182  0 public V getValue() { return map.get(key); }
 183  0 public V setValue(V value) { return map.put(key, value); }
 184  0 public boolean equals(Object o) {
 185  0 if (this == o) { return true; }
 186  0 else if (!(o instanceof Entry<?, ?>)) { return false; }
 187    else {
 188  0 Entry<?, ?> cast = (Entry<?, ?>) o;
 189  0 if (key == null ? cast.getKey() == null : key.equals(cast.getKey())) {
 190  0 V val = map.get(key);
 191  0 return val == null ? cast.getValue() == null : val.equals(cast.getValue());
 192    }
 193  0 else { return false; }
 194    }
 195    }
 196  0 public int hashCode() {
 197  0 V val = map.get(key);
 198  0 return (key == null ? 0 : key.hashCode()) ^ (val == null ? 0 : val.hashCode());
 199    }
 200    };
 201    }
 202   
 203    }