1
2
3
4
5
6
7 package org.codehaus.groovy.runtime;
8
9 import java.lang.ref.ReferenceQueue;
10 import java.lang.ref.SoftReference;
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.Iterator;
14 import java.util.Set;
15 import java.util.WeakHashMap;
16
17 public class ReferenceMap extends WeakHashMap {
18
19 private static class HardReference extends SoftReference {
20 private Object value;
21 public HardReference(Object arg) {
22 super(null);
23 value = arg;
24 }
25 public Object get() {
26 return value;
27 }
28 }
29
30 private ReferenceQueue queue = new ReferenceQueue();
31
32 public ReferenceMap() {
33 super();
34 }
35
36 public boolean containsValue(Object value) {
37 throw new UnsupportedOperationException();
38 }
39
40 public Set entrySet() {
41 throw new UnsupportedOperationException();
42 }
43
44 public Object get(Object key) {
45 Object ret = super.get(key);
46 if (ret!=null) {
47 SoftReference weak = (SoftReference) ret;
48 ret = weak.get();
49 if (ret==null) remove(key);
50 }
51 return ret;
52 }
53
54 public Object put(Object key, Object value) {
55 removeDereferencedEntries();
56 if (value!=null) {
57 value = new SoftReference(value,queue);
58 }
59 return super.put(key, value);
60 }
61
62 public Object putStrong(Object key, Object value) {
63 removeDereferencedEntries();
64 if (value!=null) {
65 value = new HardReference(value);
66 }
67 return super.put(key, value);
68 }
69
70 public Collection values() {
71 removeDereferencedEntries();
72 Collection origColl = super.values();
73 ArrayList newColl = new ArrayList(origColl.size());
74 for (Iterator iter = origColl.iterator(); iter.hasNext();) {
75 SoftReference element = (SoftReference) iter.next();
76 if (element!=null) {
77 Object strong = element.get();
78 if (strong==null) continue;
79 newColl.add(strong);
80 } else {
81 newColl.add(null);
82 }
83 }
84 return newColl;
85 }
86
87 private void removeDereferencedEntries(){
88 SoftReference e;
89 while ( (e = (SoftReference) queue.poll()) != null) {
90 Object strong = e.get();
91 if (strong==null) continue;
92 remove(strong);
93 }
94 }
95 }