001 /*
002 * WeakValueMap.java created on 31.10.2006
003 *
004 * To change this generated comment go to
005 * Window>Preferences>Java>Code Generation>Code and Comments
006 */
007 package org.codehaus.groovy.runtime;
008
009 import java.lang.ref.ReferenceQueue;
010 import java.lang.ref.SoftReference;
011 import java.util.ArrayList;
012 import java.util.Collection;
013 import java.util.Iterator;
014 import java.util.Set;
015 import java.util.WeakHashMap;
016
017 public class ReferenceMap extends WeakHashMap {
018
019 private static class HardReference extends SoftReference {
020 private Object value;
021 public HardReference(Object arg) {
022 super(null);
023 value = arg;
024 }
025 public Object get() {
026 return value;
027 }
028 }
029
030 private ReferenceQueue queue = new ReferenceQueue();
031
032 public ReferenceMap() {
033 super();
034 }
035
036 public boolean containsValue(Object value) {
037 throw new UnsupportedOperationException();
038 }
039
040 public Set entrySet() {
041 throw new UnsupportedOperationException();
042 }
043
044 public Object get(Object key) {
045 Object ret = super.get(key);
046 if (ret!=null) {
047 SoftReference weak = (SoftReference) ret;
048 ret = weak.get();
049 if (ret==null) remove(key);
050 }
051 return ret;
052 }
053
054 public Object put(Object key, Object value) {
055 removeDereferencedEntries();
056 if (value!=null) {
057 value = new SoftReference(value,queue);
058 }
059 return super.put(key, value);
060 }
061
062 public Object putStrong(Object key, Object value) {
063 removeDereferencedEntries();
064 if (value!=null) {
065 value = new HardReference(value);
066 }
067 return super.put(key, value);
068 }
069
070 public Collection values() {
071 removeDereferencedEntries();
072 Collection origColl = super.values();
073 ArrayList newColl = new ArrayList(origColl.size());
074 for (Iterator iter = origColl.iterator(); iter.hasNext();) {
075 SoftReference element = (SoftReference) iter.next();
076 if (element!=null) {
077 Object strong = element.get();
078 if (strong==null) continue;
079 newColl.add(strong);
080 } else {
081 newColl.add(null);
082 }
083 }
084 return newColl;
085 }
086
087 private void removeDereferencedEntries(){
088 SoftReference e;
089 while ( (e = (SoftReference) queue.poll()) != null) {
090 Object strong = e.get();
091 if (strong==null) continue;
092 remove(strong);
093 }
094 }
095 }