001/* 002 * HA-JDBC: High-Availability JDBC 003 * Copyright (C) 2012 Paul Ferraro 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Lesser General Public License as published by 007 * the Free Software Foundation, either version 3 of the License, or 008 * (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018package net.sf.hajdbc.util.ref; 019 020import java.lang.ref.Reference; 021import java.util.Collection; 022import java.util.Iterator; 023import java.util.Map; 024import java.util.Set; 025 026/** 027 * A map that stores its values using a reference. 028 * @author Paul Ferraro 029 */ 030public class ReferenceMap<K, V> implements Map<K, V> 031{ 032 private final Map<K, Reference<V>> map; 033 final ReferenceFactory referenceFactory; 034 035 public ReferenceMap(Map<K, Reference<V>> map, ReferenceFactory referenceFactory) 036 { 037 this.map = map; 038 this.referenceFactory = referenceFactory; 039 } 040 041 @Override 042 public void clear() 043 { 044 this.map.clear(); 045 } 046 047 @Override 048 public boolean containsKey(Object key) 049 { 050 return this.map.containsKey(key); 051 } 052 053 @Override 054 public boolean containsValue(Object object) 055 { 056 for (Reference<V> reference: this.map.values()) 057 { 058 V value = reference.get(); 059 060 if ((value != null) && value.equals(object)) 061 { 062 return true; 063 } 064 } 065 return false; 066 } 067 068 @Override 069 public Set<Map.Entry<K, V>> entrySet() 070 { 071 final Set<Map.Entry<K, Reference<V>>> entrySet = this.map.entrySet(); 072 073 return new Set<Map.Entry<K, V>>() 074 { 075 @Override 076 public boolean add(Map.Entry<K, V> entry) 077 { 078 throw new UnsupportedOperationException(); 079 } 080 081 @Override 082 public boolean addAll(Collection<? extends Map.Entry<K, V>> entries) 083 { 084 throw new UnsupportedOperationException(); 085 } 086 087 @Override 088 public void clear() 089 { 090 entrySet.clear(); 091 } 092 093 @Override 094 public boolean contains(Object object) 095 { 096 return false; 097 } 098 099 @Override 100 public boolean containsAll(Collection<?> collection) 101 { 102 return false; 103 } 104 105 @Override 106 public boolean isEmpty() 107 { 108 return entrySet.isEmpty(); 109 } 110 111 @Override 112 public Iterator<Map.Entry<K, V>> iterator() 113 { 114 final Iterator<Map.Entry<K, Reference<V>>> entries = entrySet.iterator(); 115 116 return new Iterator<Map.Entry<K, V>>() 117 { 118 @Override 119 public boolean hasNext() 120 { 121 return entries.hasNext(); 122 } 123 124 @Override 125 public java.util.Map.Entry<K, V> next() 126 { 127 final Map.Entry<K, Reference<V>> entry = entries.next(); 128 129 return new Map.Entry<K, V>() 130 { 131 @Override 132 public K getKey() 133 { 134 return entry.getKey(); 135 } 136 137 @Override 138 public V getValue() 139 { 140 return entry.getValue().get(); 141 } 142 143 @Override 144 public V setValue(V value) 145 { 146 Reference<V> reference = entry.setValue(ReferenceMap.this.referenceFactory.createReference(value)); 147 148 return (reference != null) ? reference.get() : null; 149 } 150 }; 151 } 152 153 @Override 154 public void remove() 155 { 156 entries.remove(); 157 } 158 }; 159 } 160 161 @Override 162 public boolean remove(Object object) 163 { 164 return false; 165 } 166 167 @Override 168 public boolean removeAll(Collection<?> collection) 169 { 170 return false; 171 } 172 173 @Override 174 public boolean retainAll(Collection<?> collection) 175 { 176 return false; 177 } 178 179 @Override 180 public int size() 181 { 182 return entrySet.size(); 183 } 184 185 @Override 186 public Object[] toArray() 187 { 188 return null; 189 } 190 191 @Override 192 public <T> T[] toArray(T[] arg0) 193 { 194 return null; 195 } 196 }; 197 } 198 199 @Override 200 public V get(Object key) 201 { 202 Reference<V> reference = this.map.get(key); 203 204 return (reference != null) ? reference.get() : null; 205 } 206 207 @Override 208 public boolean isEmpty() 209 { 210 return this.map.isEmpty(); 211 } 212 213 @Override 214 public Set<K> keySet() 215 { 216 return this.map.keySet(); 217 } 218 219 @Override 220 public V put(K key, V value) 221 { 222 Reference<V> reference = this.map.put(key, this.referenceFactory.createReference(value)); 223 224 return (reference != null) ? reference.get() : null; 225 } 226 227 @Override 228 public void putAll(Map<? extends K, ? extends V> map) 229 { 230 for (Map.Entry<? extends K, ? extends V> entry: map.entrySet()) 231 { 232 this.put(entry.getKey(), entry.getValue()); 233 } 234 } 235 236 @Override 237 public V remove(Object key) 238 { 239 Reference<V> reference = this.map.remove(key); 240 241 return (reference != null) ? reference.get() : null; 242 } 243 244 @Override 245 public int size() 246 { 247 return this.map.size(); 248 } 249 250 @Override 251 public Collection<V> values() 252 { 253 final Collection<Reference<V>> references = this.map.values(); 254 255 return new Collection<V>() 256 { 257 @Override 258 public boolean add(V arg0) 259 { 260 throw new UnsupportedOperationException(); 261 } 262 263 @Override 264 public boolean addAll(Collection<? extends V> arg0) 265 { 266 throw new UnsupportedOperationException(); 267 } 268 269 @Override 270 public void clear() 271 { 272 references.clear(); 273 } 274 275 @Override 276 public boolean contains(Object object) 277 { 278 for (Reference<V> reference: references) 279 { 280 V value = reference.get(); 281 282 if ((value != null) && value.equals(object)) 283 { 284 return true; 285 } 286 } 287 288 return false; 289 } 290 291 @Override 292 public boolean containsAll(Collection<?> objects) 293 { 294 return false; 295 } 296 297 @Override 298 public boolean isEmpty() 299 { 300 return references.isEmpty(); 301 } 302 303 @Override 304 public Iterator<V> iterator() 305 { 306 final Iterator<Reference<V>> refs = references.iterator(); 307 308 return new Iterator<V>() 309 { 310 @Override 311 public boolean hasNext() 312 { 313 return refs.hasNext(); 314 } 315 316 @Override 317 public V next() 318 { 319 Reference<V> reference = refs.next(); 320 321 return (reference != null) ? reference.get() : null; 322 } 323 324 @Override 325 public void remove() 326 { 327 refs.remove(); 328 } 329 }; 330 } 331 332 @Override 333 public boolean remove(Object value) 334 { 335 return false; 336 } 337 338 @Override 339 public boolean removeAll(Collection<?> values) 340 { 341 return false; 342 } 343 344 @Override 345 public boolean retainAll(Collection<?> values) 346 { 347 return false; 348 } 349 350 @Override 351 public int size() 352 { 353 return references.size(); 354 } 355 356 @Override 357 public Object[] toArray() 358 { 359 return null; 360 } 361 362 @Override 363 public <T> T[] toArray(T[] arg0) 364 { 365 return null; 366 } 367 }; 368 } 369}