KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > portal > generic > KeyLinkMap


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2001-2004 Caucho Technology, Inc. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution, if
19  * any, must include the following acknowlegement:
20  * "This product includes software developed by the
21  * Caucho Technology (http://www.caucho.com/)."
22  * Alternately, this acknowlegement may appear in the software itself,
23  * if and wherever such third-party acknowlegements normally appear.
24  *
25  * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
26  * endorse or promote products derived from this software without prior
27  * written permission. For written permission, please contact
28  * info@caucho.com.
29  *
30  * 5. Products derived from this software may not be called "Resin"
31  * nor may "Resin" appear in their names without prior written
32  * permission of Caucho Technology.
33  *
34  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
35  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
36  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37  * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
38  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
39  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
40  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
42  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
43  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
44  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45  *
46  * @author Sam
47  */

48
49 package com.caucho.portal.generic;
50
51 import java.util.AbstractSet JavaDoc;
52 import java.util.Collection JavaDoc;
53 import java.util.HashMap JavaDoc;
54 import java.util.Iterator JavaDoc;
55 import java.util.Map JavaDoc;
56 import java.util.Set JavaDoc;
57 import java.util.logging.Logger JavaDoc;
58
59 /**
60  * A Map that wraps another map and uses different keys in the wrapped
61  * map than the keys that are exposed.
62  *
63  * The constructor is passed the map to be wrapped, and a keyLinkMap
64  * that maps keys as they are used by users of the map to different keys that
65  * are really used in the wrapped map. If a key is used that is not int the
66  * keyLinkMap, the key is used unchanged in the wrapped map.
67  */

68 public class KeyLinkMap<K, V> implements Map JavaDoc<K, V>
69 {
70   static protected final Logger JavaDoc log =
71     Logger.getLogger(KeyLinkMap.class.getName());
72
73   private Map JavaDoc<K, K> _keyLinkMap;
74   private Map JavaDoc<K, K> _keyLinkReverseMap;
75   private Map JavaDoc<K, V> _map;
76
77   private KeySet _keySet;
78   private EntrySet _entrySet;
79
80   public static <K> Map JavaDoc<K, K> getReverseKeyLinkMap(Map JavaDoc<K, K> keyLinkMap)
81   {
82     Map JavaDoc<K, K> keyLinkReverseMap = new HashMap JavaDoc<K, K>();
83     Iterator JavaDoc<Map.Entry JavaDoc<K, K>> iter = keyLinkMap.entrySet().iterator();
84
85     while (iter.hasNext()) {
86       Map.Entry JavaDoc<K, K> entry = iter.next();
87
88       keyLinkReverseMap.put(entry.getValue(), entry.getKey());
89     }
90
91     return keyLinkReverseMap;
92   }
93
94   public KeyLinkMap( Map JavaDoc<K, V> map,
95                      Map JavaDoc<K, K> keyLinkMap,
96                      Map JavaDoc<K, K> keyLinkReverseMap )
97   {
98     _map = map;
99     _keyLinkMap = keyLinkMap;
100     _keyLinkReverseMap = keyLinkReverseMap;
101   }
102
103   
104   public int size()
105   {
106     return _map.size();
107   }
108
109   public boolean isEmpty()
110   {
111     return _map.isEmpty();
112   }
113
114   private K getMapKey(K key)
115   {
116     K mapKey = key;
117
118     if (_keyLinkMap != null) {
119       mapKey = _keyLinkMap.get(key);
120       if (mapKey == null)
121         mapKey = key;
122     }
123
124     return mapKey;
125   }
126
127   private K getReverseMapKey(K key)
128   {
129     if (_keyLinkReverseMap == null)
130       return key;
131
132     K mapKey = key;
133
134     mapKey = _keyLinkReverseMap.get(key);
135
136     if (mapKey == null)
137       mapKey = key;
138
139     return mapKey;
140   }
141
142   public boolean containsKey(Object JavaDoc key)
143   {
144     return _map.containsKey(getMapKey( (K) key ));
145   }
146
147   public V get(Object JavaDoc key)
148   {
149     return _map.get(getMapKey( (K) key ));
150   }
151
152   public Set JavaDoc<K> keySet()
153   {
154     return _keySet == null ? (_keySet = new KeySet()) : _keySet;
155   }
156
157   public Set JavaDoc<Map.Entry JavaDoc<K, V>> entrySet()
158   {
159     return _entrySet == null ? (_entrySet = new EntrySet()) : _entrySet;
160   }
161
162   public boolean containsValue(Object JavaDoc v)
163   {
164     return _map.containsValue(v);
165   }
166
167   public Collection JavaDoc<V> values()
168   {
169     return _map.values();
170   }
171
172   public V put(K key, V value)
173   {
174     return _map.put(getMapKey(key), value);
175   }
176
177   public void putAll(Map JavaDoc<? extends K, ? extends V> srcMap)
178   {
179     Iterator JavaDoc<? extends Entry<? extends K, ? extends V>> iter
180       = srcMap.entrySet().iterator();
181
182     while (iter.hasNext()) {
183       Map.Entry JavaDoc<? extends K, ? extends V> entry = iter.next();
184       put(entry.getKey(), entry.getValue());
185     }
186   }
187
188   public V remove(Object JavaDoc key)
189   {
190     return _map.remove(getMapKey( (K) key ));
191   }
192
193   public void clear()
194   {
195     _map.clear();
196   }
197
198   private Iterator JavaDoc<K> newKeyIterator()
199   {
200     if (_keyLinkMap == null)
201       return _map.keySet().iterator();
202     else
203       return new KeyIterator();
204
205   }
206
207   private Iterator JavaDoc<Map.Entry JavaDoc<K, V>> newEntryIterator()
208   {
209     if (_keyLinkMap == null)
210       return _map.entrySet().iterator();
211     else
212       return new EntryIterator();
213   }
214
215   private class KeySet extends AbstractSet JavaDoc<K> {
216     public Iterator JavaDoc<K> iterator()
217     {
218       return newKeyIterator();
219     }
220
221     public int size()
222     {
223       return KeyLinkMap.this.size();
224     }
225
226     public boolean contains(Object JavaDoc o)
227     {
228       return KeyLinkMap.this.containsKey(o);
229     }
230
231     public boolean remove(Object JavaDoc o)
232     {
233       return KeyLinkMap.this.remove(o) != null;
234     }
235
236     public void clear()
237     {
238       KeyLinkMap.this.clear();
239     }
240   }
241
242   private class EntrySet extends AbstractSet JavaDoc<Map.Entry JavaDoc<K,V>>
243   {
244     public Iterator JavaDoc<Map.Entry JavaDoc<K,V>> iterator()
245     {
246       return newEntryIterator();
247     }
248
249     public boolean contains(Object JavaDoc o)
250     {
251       if (!(o instanceof Map.Entry JavaDoc))
252         return false;
253
254       Map.Entry JavaDoc<K,V> other = (Map.Entry JavaDoc<K,V>) o;
255
256       V value = KeyLinkMap.this.get(other.getKey());
257
258       if (value == null)
259         return other.getValue() == null;
260       else
261         return value.equals(other.getValue());
262     }
263
264     public boolean remove(Object JavaDoc o)
265     {
266       return KeyLinkMap.this.remove(o) != null;
267     }
268
269     public int size()
270     {
271       return KeyLinkMap.this.size();
272     }
273
274     public void clear()
275     {
276       KeyLinkMap.this.clear();
277     }
278   }
279
280   private class KeyIterator implements Iterator JavaDoc<K>
281   {
282     private Iterator JavaDoc<K> _iterator;
283
284     KeyIterator()
285     {
286       _iterator = _map.keySet().iterator();
287     }
288
289     public boolean hasNext()
290     {
291       return _iterator.hasNext();
292     }
293
294     public K next()
295     {
296       K next = _iterator.next();
297       K mapKey = KeyLinkMap.this.getReverseMapKey(next);
298
299       return mapKey;
300     }
301
302     public void remove()
303     {
304       _iterator.remove();
305     }
306   }
307
308   private class EntryIterator implements Iterator JavaDoc<Map.Entry JavaDoc<K, V>>
309   {
310     private Iterator JavaDoc<Map.Entry JavaDoc<K, V>> _iterator;
311
312     EntryIterator()
313     {
314       _iterator = _map.entrySet().iterator();
315     }
316
317     public boolean hasNext()
318     {
319       return _iterator.hasNext();
320     }
321
322     public Map.Entry JavaDoc<K, V> next()
323     {
324       Map.Entry JavaDoc<K, V> nextEntry = _iterator.next();
325       K nextKey = nextEntry.getKey();
326
327       K mapKey = KeyLinkMap.this.getReverseMapKey(nextEntry.getKey());
328
329       if (mapKey == nextKey)
330         return nextEntry;
331       else
332         return new MapEntry<K, V>(mapKey, nextEntry.getValue());
333     }
334
335     public void remove()
336     {
337       _iterator.remove();
338     }
339   }
340
341   private class MapEntry<K, V> implements Map.Entry JavaDoc<K, V>
342   {
343     private K _key;
344     private V _value;
345
346     MapEntry(K key, V value)
347     {
348       _key = key;
349       _value = value;
350     }
351
352     public K getKey()
353     {
354       return _key;
355     }
356
357     public K setKey(K key)
358     {
359       K oldKey = _key;
360       _key = key;
361       return oldKey;
362     }
363
364     public V getValue()
365     {
366       return _value;
367     }
368
369     public V setValue(V value)
370     {
371       V oldValue = _value;
372       _value = value;
373       return oldValue;
374     }
375
376     public boolean equals(Object JavaDoc o)
377     {
378       if (!(o instanceof Map.Entry JavaDoc))
379         return false;
380
381       Map.Entry JavaDoc<K, V> other = (Map.Entry JavaDoc<K, V>) o;
382
383       return
384         (getKey() == null
385          ? other.getKey() == null
386          : getKey().equals(other.getKey()))
387         &&
388         (getValue() == null
389          ? other.getValue() == null
390          : getValue().equals(other.getValue()));
391     }
392
393     public int hashCode()
394     {
395       return
396         (getKey() == null ? 0 : getKey().hashCode()) ^
397         (getValue() == null ? 0 : getValue().hashCode());
398     }
399   }
400 }
401
402
Popular Tags