Clover coverage report -
Coverage timestamp: Thu Jul 5 2007 20:02:32 EDT
file stats: LOC: 403   Methods: 43
NCLOC: 325   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
CachedMapImpl.java 55.2% 84.3% 88.4% 77.3%
coverage coverage
 1    /*
 2    * JBoss, the OpenSource J2EE webOS
 3    *
 4    * Distributable under LGPL license.
 5    * See terms of license at gnu.org.
 6    */
 7    package org.jboss.cache.pojo.collection;
 8   
 9    import static org.jboss.cache.pojo.impl.InternalConstant.POJOCACHE_OPERATION;
 10   
 11    import java.io.Serializable;
 12    import java.util.AbstractCollection;
 13    import java.util.AbstractSet;
 14    import java.util.ArrayList;
 15    import java.util.Collection;
 16    import java.util.Collections;
 17    import java.util.Iterator;
 18    import java.util.Map;
 19    import java.util.Set;
 20   
 21    import org.jboss.aop.Advised;
 22    import org.jboss.cache.Cache;
 23    import org.jboss.cache.CacheSPI;
 24    import org.jboss.cache.Fqn;
 25    import org.jboss.cache.Node;
 26    import org.jboss.cache.pojo.PojoCacheException;
 27    import org.jboss.cache.pojo.annotation.Reentrant;
 28    import org.jboss.cache.pojo.impl.PojoCacheImpl;
 29    import org.jboss.cache.pojo.interceptors.dynamic.AbstractCollectionInterceptor;
 30    import org.jboss.cache.pojo.util.CacheApiUtil;
 31    import org.jboss.cache.pojo.util.Null;
 32   
 33    /**
 34    * Map that uses cache as a backend store.
 35    *
 36    * @author Ben Wang
 37    * @author Scott Marlow
 38    */
 39    @Reentrant
 40    public class CachedMapImpl implements Map
 41    {
 42    private PojoCacheImpl pojoCache;
 43    private Cache<Object, Object> cache;
 44    private AbstractCollectionInterceptor interceptor;
 45   
 46  110 public CachedMapImpl(PojoCacheImpl pCache, AbstractCollectionInterceptor interceptor)
 47    {
 48  110 this.pojoCache = pCache;
 49  110 this.cache = pojoCache.getCache();
 50  110 this.interceptor = interceptor;
 51    }
 52   
 53  517 private static Fqn constructFqn(Fqn baseFqn, Object relative)
 54    {
 55  517 if (!(relative instanceof Serializable) && !(relative instanceof Advised))
 56    {
 57  2 throw new PojoCacheException("Non-serializable for " + relative.getClass().getName());
 58    }
 59   
 60  515 return new Fqn(baseFqn, relative);
 61    }
 62   
 63  809 private Fqn getFqn()
 64    {
 65  809 return interceptor.getFqn();
 66    }
 67   
 68  248 private Object attach(Object key, Object value)
 69    {
 70  248 Fqn fqn = constructFqn(getFqn(), Null.toNullKeyObject(key));
 71  246 Object o = pojoCache.attach(fqn, Null.toNullObject(value));
 72  246 pojoCache.getCache().put(fqn, POJOCACHE_OPERATION, "PUT");
 73   
 74  246 return o;
 75    }
 76   
 77  57 private Object detach(Object key)
 78    {
 79  57 Fqn fqn = constructFqn(getFqn(), Null.toNullKeyObject(key));
 80  57 pojoCache.getCache().put(fqn, POJOCACHE_OPERATION, "REMOVE");
 81   
 82  57 return pojoCache.detach(fqn);
 83    }
 84   
 85    // implementation of the java.util.Map interface
 86   
 87  292 private Set<Node> getNodeChildren()
 88    {
 89  292 return CacheApiUtil.getNodeChildren(cache, getFqn());
 90    }
 91   
 92  159 public Object get(Object key)
 93    {
 94  159 return Null.toNullValue(pojoCache.getObject(constructFqn(getFqn(), Null.toNullKeyObject(key))));
 95    }
 96   
 97  248 public Object put(Object key, Object value)
 98    {
 99  248 return attach(key, value);
 100    }
 101   
 102  2 public void putAll(Map map)
 103    {
 104  2 for (Iterator i = map.entrySet().iterator(); i.hasNext();)
 105    {
 106  4 Map.Entry entry = (Map.Entry) i.next();
 107  4 put(entry.getKey(), entry.getValue());
 108    }
 109    }
 110   
 111  57 public Object remove(Object key)
 112    {
 113  57 return detach(key);
 114    }
 115   
 116  4 public void clear()
 117    {
 118    // Need to clone first to avoid CME
 119  4 ArrayList list = new ArrayList(keySet());
 120  4 for (int i = 0; i < list.size(); i++)
 121    {
 122  11 remove(list.get(i));
 123    }
 124    }
 125   
 126  128 public int size()
 127    {
 128  128 Set<Node> children = getNodeChildren();
 129  128 return children == null ? 0 : children.size();
 130    }
 131   
 132  2 public boolean isEmpty()
 133    {
 134  2 return size() == 0;
 135    }
 136   
 137  23 public boolean containsKey(Object object)
 138    {
 139  23 Set<Node> children = getNodeChildren();
 140  0 if (children == null) return false;
 141  23 for (Object n : children)
 142    {
 143  15 if (((Node) n).getFqn().getLastElement().equals(Null.toNullKeyObject(object))) return true;
 144    }
 145   
 146  8 return false;
 147    }
 148   
 149  9 public boolean containsValue(Object object)
 150    {
 151  9 return values().contains(Null.toNullObject(object));
 152    }
 153   
 154  39 public Set entrySet()
 155    {
 156  39 final CachedMapImpl map = this;
 157   
 158  39 return new AbstractSet()
 159    {
 160   
 161  2 public int size()
 162    {
 163  2 Set<Node> children = getNodeChildren();
 164  2 return children == null ? 0 : children.size();
 165    }
 166   
 167  37 public Iterator iterator()
 168    {
 169  37 Set<Node> children = getNodeChildren();
 170  37 final Iterator i =
 171  37 children == null
 172    ? Collections.EMPTY_LIST.iterator()
 173    : children.iterator();
 174  37 return new Iterator()
 175    {
 176    Object lastKey; // for remove
 177   
 178  75 public boolean hasNext()
 179    {
 180  75 return i.hasNext();
 181    }
 182   
 183  53 public Object next()
 184    {
 185  53 return new Entry(lastKey = ((Node) i.next()).getFqn().getLastElement());
 186    }
 187   
 188  0 public void remove()
 189    {
 190  0 map.remove(lastKey);
 191    }
 192    };
 193    }
 194    };
 195    }
 196   
 197  16 public Collection values()
 198    {
 199  16 final CachedMapImpl map = this;
 200   
 201  16 return new AbstractCollection()
 202    {
 203   
 204  10 public int size()
 205    {
 206  10 Set<Node> children = getNodeChildren();
 207  10 return children == null ? 0 : children.size();
 208    }
 209   
 210  2 public void clear()
 211    {
 212  2 map.clear();
 213    }
 214   
 215  29 public Iterator iterator()
 216    {
 217  29 Set<Node> children = getNodeChildren();
 218  29 final Iterator i =
 219  29 children == null
 220    ? Collections.EMPTY_LIST.iterator()
 221    : children.iterator();
 222   
 223  29 return new Iterator()
 224    {
 225    Object lastKey; // for remove
 226   
 227  78 public boolean hasNext()
 228    {
 229  78 return i.hasNext();
 230    }
 231   
 232  70 public Object next()
 233    {
 234  70 Fqn f = ((Node) i.next()).getFqn();
 235  70 lastKey = f.getLastElement();
 236  70 return Null.toNullValue(pojoCache.getObject(f));
 237    }
 238   
 239  6 public void remove()
 240    {
 241  6 Object key = lastKey;
 242  6 if (key != null) // convert from internal Null form to actual null if needed
 243  6 key = Null.toNullKeyValue(key);
 244  6 map.remove(key);
 245    }
 246    };
 247    }
 248    };
 249    }
 250   
 251  55 public Set keySet()
 252    {
 253  55 final CachedMapImpl map = this;
 254   
 255  55 return new AbstractSet()
 256    {
 257   
 258  10 public int size()
 259    {
 260  10 Set<Node> children = getNodeChildren();
 261  10 return children == null ? 0 : children.size();
 262    }
 263   
 264  53 public Iterator iterator()
 265    {
 266  53 Set<Node> children = getNodeChildren();
 267  53 final Iterator i =
 268  53 children == null
 269    ? Collections.EMPTY_LIST.iterator()
 270    : children.iterator();
 271   
 272  53 return new Iterator()
 273    {
 274    Object lastKey; // for remove
 275   
 276  195 public boolean hasNext()
 277    {
 278  195 return i.hasNext();
 279    }
 280   
 281  102 public Object next()
 282    {
 283  102 lastKey = ((Node) i.next()).getFqn().getLastElement();
 284  102 return Null.toNullKeyValue(lastKey);
 285   
 286    }
 287   
 288  2 public void remove()
 289    {
 290  2 Object key = lastKey;
 291  2 if (key != null) // convert from internal Null form to actual null if needed
 292  2 key = Null.toNullKeyValue(key);
 293  2 map.remove(key);
 294    }
 295    };
 296   
 297    }
 298    };
 299    }
 300   
 301  0 public int hashCode()
 302    {
 303  0 int result = 0;
 304  0 for (Iterator i = entrySet().iterator(); i.hasNext();)
 305    {
 306  0 result += i.next().hashCode();
 307    }
 308  0 return result;
 309    }
 310   
 311  30 public boolean equals(Object object)
 312    {
 313  30 if (object == this)
 314  0 return true;
 315  30 if (object == null || !(object instanceof Map))
 316  0 return false;
 317  30 Map map = (Map) object;
 318  30 if (size() != map.size())
 319  0 return false;
 320  30 for (Iterator i = entrySet().iterator(); i.hasNext();)
 321    {
 322  40 Entry entry = (Entry) i.next();
 323  40 Object value = entry.getValue();
 324  40 Object key = entry.getKey();
 325  40 if (value == null)
 326    {
 327  3 if (!(map.get(key) == null && map.containsKey(key)))
 328    {
 329  0 return false;
 330    }
 331    } else
 332    {
 333  37 if (!value.equals(map.get(key)))
 334  5 return false;
 335    }
 336    }
 337  25 return true;
 338    }
 339   
 340  29 public String toString()
 341    {
 342  29 StringBuffer buf = new StringBuffer();
 343  29 Set set = keySet();
 344  29 for (Iterator it = set.iterator(); it.hasNext();)
 345    {
 346  56 Object key = it.next();
 347  56 buf.append("[").append(key).append(", ").append(get(key)).append("]");
 348  27 if (it.hasNext()) buf.append(", ");
 349    }
 350   
 351  29 return buf.toString();
 352    }
 353   
 354    class Entry implements Map.Entry
 355    {
 356   
 357    Object key;
 358   
 359  53 public Entry(Object key)
 360    {
 361  53 this.key = key;
 362    }
 363   
 364  48 public Object getKey()
 365    {
 366  48 return Null.toNullValue(key);
 367    }
 368   
 369  53 public Object getValue()
 370    {
 371  53 return Null.toNullValue(pojoCache.getObject(constructFqn(getFqn(), key)));
 372    }
 373   
 374  0 public Object setValue(Object value)
 375    {
 376  0 return attach(key, value);
 377    }
 378   
 379  0 public int hashCode()
 380    {
 381  0 Object value = getValue();
 382  0 return ((key == null) ? 0 : key.hashCode())
 383  0 ^ ((value == null) ? 0 : value.hashCode());
 384    }
 385   
 386  0 public boolean equals(Object obj)
 387    {
 388  0 if (!(obj instanceof Entry))
 389  0 return false;
 390  0 Entry entry = (Entry) obj;
 391  0 Object value = getValue();
 392  0 return (
 393  0 key == null
 394    ? entry.getKey() == null
 395    : key.equals(entry.getKey()))
 396  0 && (value == null
 397    ? entry.getValue() == null
 398    : value.equals(entry.getValue()));
 399    }
 400    }
 401   
 402   
 403    }