1 48 49 package com.caucho.portal.generic; 50 51 import java.util.AbstractSet ; 52 import java.util.Collection ; 53 import java.util.HashMap ; 54 import java.util.Iterator ; 55 import java.util.Map ; 56 import java.util.Set ; 57 import java.util.logging.Logger ; 58 59 68 public class KeyLinkMap<K, V> implements Map <K, V> 69 { 70 static protected final Logger log = 71 Logger.getLogger(KeyLinkMap.class.getName()); 72 73 private Map <K, K> _keyLinkMap; 74 private Map <K, K> _keyLinkReverseMap; 75 private Map <K, V> _map; 76 77 private KeySet _keySet; 78 private EntrySet _entrySet; 79 80 public static <K> Map <K, K> getReverseKeyLinkMap(Map <K, K> keyLinkMap) 81 { 82 Map <K, K> keyLinkReverseMap = new HashMap <K, K>(); 83 Iterator <Map.Entry <K, K>> iter = keyLinkMap.entrySet().iterator(); 84 85 while (iter.hasNext()) { 86 Map.Entry <K, K> entry = iter.next(); 87 88 keyLinkReverseMap.put(entry.getValue(), entry.getKey()); 89 } 90 91 return keyLinkReverseMap; 92 } 93 94 public KeyLinkMap( Map <K, V> map, 95 Map <K, K> keyLinkMap, 96 Map <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 key) 143 { 144 return _map.containsKey(getMapKey( (K) key )); 145 } 146 147 public V get(Object key) 148 { 149 return _map.get(getMapKey( (K) key )); 150 } 151 152 public Set <K> keySet() 153 { 154 return _keySet == null ? (_keySet = new KeySet()) : _keySet; 155 } 156 157 public Set <Map.Entry <K, V>> entrySet() 158 { 159 return _entrySet == null ? (_entrySet = new EntrySet()) : _entrySet; 160 } 161 162 public boolean containsValue(Object v) 163 { 164 return _map.containsValue(v); 165 } 166 167 public Collection <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 <? extends K, ? extends V> srcMap) 178 { 179 Iterator <? extends Entry<? extends K, ? extends V>> iter 180 = srcMap.entrySet().iterator(); 181 182 while (iter.hasNext()) { 183 Map.Entry <? extends K, ? extends V> entry = iter.next(); 184 put(entry.getKey(), entry.getValue()); 185 } 186 } 187 188 public V remove(Object key) 189 { 190 return _map.remove(getMapKey( (K) key )); 191 } 192 193 public void clear() 194 { 195 _map.clear(); 196 } 197 198 private Iterator <K> newKeyIterator() 199 { 200 if (_keyLinkMap == null) 201 return _map.keySet().iterator(); 202 else 203 return new KeyIterator(); 204 205 } 206 207 private Iterator <Map.Entry <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 <K> { 216 public Iterator <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 o) 227 { 228 return KeyLinkMap.this.containsKey(o); 229 } 230 231 public boolean remove(Object 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 <Map.Entry <K,V>> 243 { 244 public Iterator <Map.Entry <K,V>> iterator() 245 { 246 return newEntryIterator(); 247 } 248 249 public boolean contains(Object o) 250 { 251 if (!(o instanceof Map.Entry )) 252 return false; 253 254 Map.Entry <K,V> other = (Map.Entry <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 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 <K> 281 { 282 private Iterator <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 <Map.Entry <K, V>> 309 { 310 private Iterator <Map.Entry <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 <K, V> next() 323 { 324 Map.Entry <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 <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 o) 377 { 378 if (!(o instanceof Map.Entry )) 379 return false; 380 381 Map.Entry <K, V> other = (Map.Entry <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 |