KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > dynaop > util > Cache


1 package dynaop.util;
2
3 import java.lang.ref.Reference JavaDoc;
4 import java.lang.ref.ReferenceQueue JavaDoc;
5 import java.lang.ref.SoftReference JavaDoc;
6 import java.lang.ref.WeakReference JavaDoc;
7 import java.util.Collections JavaDoc;
8 import java.util.HashMap JavaDoc;
9 import java.util.Map JavaDoc;
10 import java.util.WeakHashMap JavaDoc;
11
12 /**
13  * Cache with weak keys and soft values.
14  *
15  * @author Bob Lee (crazybob@crazybob.org)
16  */

17 public abstract class Cache {
18
19     static Object JavaDoc NULL_VALUE = new Object JavaDoc();
20     
21     Map JavaDoc map;
22     ReferenceQueue JavaDoc queue = new ReferenceQueue JavaDoc();
23     
24     /**
25      * Creates cache.
26      *
27      * @param weakKeys Use weak references for keys.
28      */

29     public Cache(boolean weakKeys) {
30         this.map = (weakKeys) ?
31             (Map JavaDoc) new WeakHashMap JavaDoc() : new HashMap JavaDoc();
32         this.map = Collections.synchronizedMap(this.map);
33     }
34     
35     /**
36      * Defaults to weak keys.
37      */

38     public Cache() {
39         this(true);
40     }
41     
42     /**
43      * Creates value for key. Called by getter if
44      * value isn't cached.
45      */

46     protected abstract Object JavaDoc create(Object JavaDoc key);
47     
48     /**
49      * Gets value for key. Creates if necessary.
50      */

51     public Object JavaDoc get(Object JavaDoc key) {
52         Object JavaDoc value = internalGet(key);
53         if (value == null) {
54             value = create(key);
55             if (value == null)
56                 value = NULL_VALUE;
57             this.map.put(key,
58                 new ValueReference(key, value));
59         }
60         return (value == NULL_VALUE) ? null : value;
61     }
62     
63     void cleanUp() {
64         Reference JavaDoc reference;
65         while ((reference = this.queue.poll()) != null)
66             map.remove(
67                 ((ValueReference) reference).getKey());
68     }
69     
70     Object JavaDoc internalGet(Object JavaDoc key) {
71         cleanUp();
72         Reference JavaDoc reference = (Reference JavaDoc) map.get(key);
73         return (reference == null) ?
74             null : reference.get();
75     }
76     
77     class ValueReference extends SoftReference JavaDoc {
78         
79         WeakReference JavaDoc keyReference;
80         
81         ValueReference(Object JavaDoc key, Object JavaDoc value) {
82             super(value, queue);
83             this.keyReference = new WeakReference JavaDoc(key);
84         }
85         
86         Object JavaDoc getKey() {
87             return this.keyReference.get();
88         }
89     }
90 }
91
Popular Tags