KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javolution > util > LocalMap


1 package javolution.util;
2
3 import j2me.util.Collection;
4 import j2me.util.Map;
5 import j2me.util.Set;
6 import javolution.context.LocalContext;
7
8 /**
9  * <p> This class represents a map which can be temporarily modified
10  * without impacting other threads ({@link LocalContext locally}
11  * scoped changes).</p>
12  *
13  * <p> Operation on instances of this class are completely thread-safe.
14  * For example:
15  * public class XMLFormat {
16  * static LocalMap<Class, XMLFormat> CLASS_TO_FORMAT = new LocalMap<Class, XMLFormat>();
17  * public static void setFormat(Class forClass, XMLFormat that) {
18  * CLASS_TO_FORMAT.put(forClass, that); // No synchronization required.
19  * }
20  * public static XMLFormat getInstance(Class forClass) {
21  * return CLASS_TO_FORMAT.get(forClass); // No synchronization required.
22  * }
23  * }
24  * public void main(String[] args) {
25  * // Sets default (global settings).
26  * XMLFormat.setFormat(Foo.class, xFormat);
27  * XMLFormat.setFormat(Bar.class, yFormat);
28  * }
29  * ... // Another thread.
30  * LocalContext.enter();
31  * try { // Use of local context to avoid impacting other threads.
32  * XMLFormat.setFormat(Foo.class, zFormat);
33  * XMLFormat.getInstance(Foo.class); // Returns zFormat
34  * XMLFormat.getInstance(Bar.class); // Returns yFormat (inherited)
35  * } finally {
36  * LocalContext.exit();
37  * }
38  * getInstance(Foo.class); // Returns xFormat
39  * [/code]</p>
40  *
41  * <p> <b>Note:</b> Because key-value mappings are inherited, the semantic of
42  * {@link #remove} and {@link #clear} is slightly modified (associate
43  * <code>null</code> values instead of removing the entries).</p>
44  *
45  * @author <a HREF="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
46  * @version 3.7, January 27, 2005
47  */

48 public final class LocalMap/*<K,V>*/implements Map/*<K,V>*/{
49
50     /**
51      * Holds the fast map reference (shared map).
52      */

53     private final LocalContext.Reference _mapRef
54         = new LocalContext.Reference(new FastMap().setShared(true));
55
56     /**
57      * Default constructor.
58      */

59     public LocalMap() {
60     }
61
62     /**
63      * Sets the key comparator for this local map.
64      *
65      * @param keyComparator the key comparator.
66      * @return <code>this</code>
67      */

68     public LocalMap /*<K,V>*/setKeyComparator(FastComparator/*<? super K>*/ keyComparator) {
69         localMap().setKeyComparator(keyComparator);
70         return this;
71     }
72
73     /**
74      * Sets the value comparator for this local map.
75      *
76      * @param valueComparator the value comparator.
77      * @return <code>this</code>
78      */

79     public LocalMap/*<K,V>*/setValueComparator(FastComparator/*<? super V>*/ valueComparator) {
80         localMap().setValueComparator(valueComparator);
81         return this;
82     }
83
84     /**
85      * Sets the default value for the specified key (typically done at
86      * initialization).
87      *
88      * @param key the key with which the specified value is to be associated.
89      * @param defaultValue the default value to be associated with the
90      * specified key.
91      * @return the previous default value associated with specified key, or
92      * <code>null</code> if there was no mapping for key. A
93      * <code>null</code> return can also indicate that the map
94      * previously associated <code>null</code> with the specified key.
95      * @throws NullPointerException if the key is <code>null</code>.
96      */

97     public Object JavaDoc/*{V}*/putDefault(Object JavaDoc/*{K}*/key, Object JavaDoc/*{V}*/defaultValue) {
98         return (Object JavaDoc/*{V}*/) ((FastMap) _mapRef.getDefault()).put(key,
99                 defaultValue);
100     }
101     /**
102      * Returns the number of key-value mappings in this map.
103      *
104      * @return this map's size.
105      */

106     public int size() {
107         return ((FastMap) _mapRef.get()).size();
108     }
109
110     /**
111      * Indicates if this map contains no key-value mappings.
112      *
113      * @return <code>true</code> if this map contains no key-value mappings;
114      * <code>false</code> otherwise.
115      */

116     public boolean isEmpty() {
117         return ((FastMap) _mapRef.get()).isEmpty();
118     }
119
120     /**
121      * Indicates if this map contains a mapping for the specified key.
122      *
123      * @param key the key whose presence in this map is to be tested.
124      * @return <code>true</code> if this map contains a mapping for the
125      * specified key; <code>false</code> otherwise.
126      * @throws NullPointerException if the key is <code>null</code>.
127      */

128     public boolean containsKey(Object JavaDoc key) {
129         return ((FastMap) _mapRef.get()).containsKey(key);
130     }
131
132     /**
133      * Indicates if this map associates one or more keys to the
134      * specified value.
135      *
136      * @param value the value whose presence in this map is to be tested.
137      * @return <code>true</code> if this map maps one or more keys to the
138      * specified value.
139      * @throws NullPointerException if the key is <code>null</code>.
140      */

141     public boolean containsValue(Object JavaDoc value) {
142         return ((FastMap) _mapRef.get()).containsValue(value);
143     }
144
145     /**
146      * Returns the value to which this map associates the specified key.
147      *
148      * @param key the key whose associated value is to be returned.
149      * @return the value to which this map maps the specified key, or
150      * <code>null</code> if there is no mapping for the key.
151      * @throws NullPointerException if key is <code>null</code>.
152      */

153     public Object JavaDoc/*{V}*/get(Object JavaDoc key) {
154         return (Object JavaDoc/*{V}*/) ((FastMap) _mapRef.get()).get(key);
155     }
156
157     /**
158      * Associates the specified value with the specified key in this map.
159      *
160      * @param key the key with which the specified value is to be associated.
161      * @param value the value to be associated with the specified key.
162      * @return the previous value associated with specified key, or
163      * <code>null</code> if there was no mapping for key. A
164      * <code>null</code> return can also indicate that the map
165      * previously associated <code>null</code> with the specified key.
166      * @throws NullPointerException if the key is <code>null</code>.
167      */

168     public Object JavaDoc/*{V}*/put(Object JavaDoc/*{K}*/key, Object JavaDoc/*{V}*/value) {
169         return (Object JavaDoc/*{V}*/) localMap().put(key, value);
170     }
171
172     /**
173      * Copies all of the mappings from the specified map to this map.
174      *
175      * @param map the mappings to be stored in this map.
176      * @throws NullPointerException the specified map is <code>null</code>,
177      * or the specified map contains <code>null</code> keys.
178      */

179     public void putAll(Map/*<? extends K, ? extends V>*/map) {
180         localMap().putAll(map);
181     }
182
183     /**
184      * Removes the mapping for this key from this map if present
185      * (sets the local value to <code>null</code>).
186      *
187      * @param key the key whose value is set to <code>null</code>
188      * @return <code>put(key, null)</code>
189      * @throws NullPointerException if the key is <code>null</code>.
190      */

191     public Object JavaDoc/*{V}*/remove(Object JavaDoc key) {
192         return put((Object JavaDoc/*{K}*/)key, null);
193     }
194
195     /**
196      * Removes all mappings from this map (sets the local values to
197      * <code>null</code>).
198      */

199     public void clear() {
200         FastMap localMap = localMap();
201         for (FastMap.Entry e = localMap.head(), end = localMap.tail(); (e = (FastMap.Entry) e.getNext()) != end;) {
202             e.setValue(null);
203         }
204     }
205
206     /**
207      * Returns a {@link FastCollection} view of the keys contained in this map.
208      *
209      * @return a set view of the keys contained in this map
210      * (instance of {@link FastCollection}).
211      */

212     public Set/*<K>*/keySet() {
213         return localMap().keySet();
214     }
215
216     /**
217      * Returns a {@link FastCollection} view of the values contained in this
218      * map.
219      *
220      * @return a collection view of the values contained in this map
221      * (instance of {@link FastCollection}).
222      */

223     public Collection/*<V>*/values() {
224         return localMap().values();
225     }
226
227     /**
228      * Returns a {@link FastCollection} view of the mappings contained in this
229      * map.
230      *
231      * @return a collection view of the mappings contained in this map
232      * (instance of {@link FastCollection}).
233      */

234     public Set/*<Map.Entry<K,V>>*/entrySet() {
235         return localMap().entrySet();
236     }
237
238     /**
239      * Returns the local map or creates one on the stack and populates
240      * it from inherited settings.
241      *
242      * @return a shared fast map belonging to the current local context.
243      */

244     private FastMap/*<K,V>*/localMap() {
245         FastMap localMap = (FastMap) _mapRef.getLocal();
246         return (localMap != null) ? localMap : newLocalMap();
247     }
248
249     private FastMap newLocalMap() {
250         FastMap parentMap = (FastMap) _mapRef.get();
251         FastMap localMap = FastMap.newInstance();
252         localMap.setShared(true);
253         localMap.setKeyComparator(parentMap.getKeyComparator());
254         localMap.setValueComparator(parentMap.getValueComparator());
255         localMap.putAll(parentMap);
256         _mapRef.set(localMap);
257         return localMap;
258     }
259 }
Popular Tags