1 19 20 package org.openide.util; 21 22 import java.io.Serializable ; 23 import java.util.AbstractMap ; 24 import java.util.AbstractSet ; 25 import java.util.ArrayList ; 26 import java.util.Collection ; 27 import java.util.Enumeration ; 28 import java.util.HashMap ; 29 import java.util.HashSet ; 30 import java.util.Iterator ; 31 import java.util.LinkedList ; 32 import java.util.List ; 33 import java.util.Map ; 34 import java.util.NoSuchElementException ; 35 import java.util.RandomAccess ; 36 import java.util.Set ; 37 import java.util.logging.Level ; 38 import java.util.logging.Logger ; 39 40 49 public class NbCollections { 50 51 private NbCollections() {} 52 53 private static final Logger LOG = Logger.getLogger(NbCollections.class.getName()); 54 55 65 public static <E> Set <E> checkedSetByCopy(Set rawSet, Class <E> type, boolean strict) throws ClassCastException { 66 Set <E> s = new HashSet <E>(rawSet.size() * 4 / 3 + 1); 67 Iterator it = rawSet.iterator(); 68 while (it.hasNext()) { 69 Object e = it.next(); 70 try { 71 s.add(type.cast(e)); 72 } catch (ClassCastException x) { 73 if (strict) { 74 throw x; 75 } else { 76 LOG.log(Level.WARNING, "Element {0} not assignable to {1}", new Object [] {e, type}); 77 } 78 } 79 } 80 return s; 81 } 82 83 93 public static <E> List <E> checkedListByCopy(List rawList, Class <E> type, boolean strict) throws ClassCastException { 94 List <E> l = (rawList instanceof RandomAccess ) ? new ArrayList <E>(rawList.size()) : new LinkedList <E>(); 95 Iterator it = rawList.iterator(); 96 while (it.hasNext()) { 97 Object e = it.next(); 98 try { 99 l.add(type.cast(e)); 100 } catch (ClassCastException x) { 101 if (strict) { 102 throw x; 103 } else { 104 LOG.log(Level.WARNING, "Element {0} not assignable to {1}", new Object [] {e, type}); 105 } 106 } 107 } 108 return l; 109 } 110 111 122 public static <K,V> Map <K,V> checkedMapByCopy(Map rawMap, Class <K> keyType, Class <V> valueType, boolean strict) throws ClassCastException { 123 Map <K,V> m2 = new HashMap <K,V>(rawMap.size() * 4 / 3 + 1); 124 Iterator it = rawMap.entrySet().iterator(); 125 while (it.hasNext()) { 126 Map.Entry e = (Map.Entry ) it.next(); 127 try { 128 m2.put(keyType.cast(e.getKey()), valueType.cast(e.getValue())); 129 } catch (ClassCastException x) { 130 if (strict) { 131 throw x; 132 } else { 133 LOG.log(Level.WARNING, "Entry {0} not assignable to <{1},{2}>", new Object [] {e, keyType, valueType}); 134 } 135 } 136 } 137 return m2; 138 } 139 140 private static abstract class CheckedIterator<E> implements Iterator <E> { 141 142 private static final Object WAITING = new Object (); 143 144 private final Iterator it; 145 private Object next = WAITING; 146 147 public CheckedIterator(Iterator it) { 148 this.it = it; 149 } 150 151 protected abstract boolean accept(Object o); 152 153 public boolean hasNext() { 154 if (next != WAITING) { 155 return true; 156 } 157 while (it.hasNext()) { 158 next = it.next(); 159 if (accept(next)) { 160 return true; 161 } 162 } 163 next = WAITING; 164 return false; 165 } 166 167 public E next() { 168 if (next == WAITING && !hasNext()) { 169 throw new NoSuchElementException (); 170 } 171 assert next != WAITING; 172 @SuppressWarnings ("unchecked") E x = (E) next; 174 next = WAITING; 175 return x; 176 } 177 178 public void remove() { 179 it.remove(); 180 } 181 182 } 183 184 193 public static <E> Iterator <E> checkedIteratorByFilter(Iterator rawIterator, final Class <E> type, final boolean strict) { 194 return new CheckedIterator<E>(rawIterator) { 195 protected boolean accept(Object o) { 196 if (o == null) { 197 return true; 198 } else if (type.isInstance(o)) { 199 return true; 200 } else if (strict) { 201 throw new ClassCastException (o + " was not a " + type.getName()); } else { 203 return false; 204 } 205 } 206 }; 207 } 208 209 224 public static <E> Set <E> checkedSetByFilter(Set rawSet, Class <E> type, boolean strict) { 225 return new CheckedSet<E>(rawSet, type, strict); 226 } 227 private static final class CheckedSet<E> extends AbstractSet <E> implements Serializable { 228 229 private static final long serialVersionUID = 1L; 230 231 private final Set rawSet; 232 private final Class <E> type; 233 private final boolean strict; 234 235 public CheckedSet(Set rawSet, Class <E> type, boolean strict) { 236 this.rawSet = rawSet; 237 this.type = type; 238 this.strict = strict; 239 } 240 241 private boolean acceptEntry(Object o) { 242 if (o == null) { 243 return true; 244 } else if (type.isInstance(o)) { 245 return true; 246 } else if (strict) { 247 throw new ClassCastException (o + " was not a " + type.getName()); } else { 249 return false; 250 } 251 } 252 253 @Override 254 public Iterator <E> iterator() { 255 return new CheckedIterator<E>(rawSet.iterator()) { 256 @Override 257 protected boolean accept(Object o) { 258 return acceptEntry(o); 259 } 260 }; 261 } 262 263 @Override 264 public int size() { 265 int c = 0; 266 Iterator it = rawSet.iterator(); 267 while (it.hasNext()) { 268 if (acceptEntry(it.next())) { 269 c++; 270 } 271 } 272 return c; 273 } 274 275 @Override 276 @SuppressWarnings ("unchecked") public boolean add(E o) { 278 return rawSet.add(type.cast(o)); 279 } 280 281 @Override 282 public boolean contains(Object o) { 283 return rawSet.contains(type.cast(o)); 284 } 285 286 } 287 288 305 public static <K,V> Map <K,V> checkedMapByFilter(Map rawMap, Class <K> keyType, Class <V> valueType, boolean strict) { 306 return new CheckedMap<K,V>(rawMap, keyType, valueType, strict); 307 } 308 private static final class CheckedMap<K,V> extends AbstractMap <K,V> implements Serializable { 309 310 private static final long serialVersionUID = 1L; 311 312 private final Map rawMap; 313 private final Class <K> keyType; 314 private final Class <V> valueType; 315 private final boolean strict; 316 317 public CheckedMap(Map rawMap, Class <K> keyType, Class <V> valueType, boolean strict) { 318 this.rawMap = rawMap; 319 this.keyType = keyType; 320 this.valueType = valueType; 321 this.strict = strict; 322 } 323 324 private boolean acceptKey(Object o) { 325 if (o == null) { 326 return true; 327 } else if (keyType.isInstance(o)) { 328 return true; 329 } else if (strict) { 330 throw new ClassCastException (o + " was not a " + keyType.getName()); } else { 332 return false; 333 } 334 } 335 336 private boolean acceptValue(Object o) { 337 if (o == null) { 338 return true; 339 } else if (valueType.isInstance(o)) { 340 return true; 341 } else if (strict) { 342 throw new ClassCastException (o + " was not a " + valueType.getName()); } else { 344 return false; 345 } 346 } 347 348 private boolean acceptEntry(Map.Entry e) { 349 return acceptKey(e.getKey()) && acceptValue(e.getValue()); 350 } 351 352 private final class EntrySet extends AbstractSet <Map.Entry <K, V>> { 353 354 @Override 355 public Iterator <Map.Entry <K,V>> iterator() { 356 return new CheckedIterator<Map.Entry <K,V>>(rawMap.entrySet().iterator()) { 357 @Override 358 protected boolean accept(Object o) { 359 return acceptEntry((Map.Entry ) o); 360 } 361 }; 362 } 363 364 @Override 365 public int size() { 366 int c = 0; 367 Iterator it = rawMap.entrySet().iterator(); 368 while (it.hasNext()) { 369 if (acceptEntry((Map.Entry ) it.next())) { 370 c++; 371 } 372 } 373 return c; 374 } 375 376 } 377 @Override 378 public Set <Map.Entry <K, V>> entrySet() { 379 return new EntrySet(); 380 } 381 382 @Override 383 public V get(Object key) { 384 Object o = rawMap.get(keyType.cast(key)); 385 if (acceptValue(o)) { 386 @SuppressWarnings ("unchecked") 387 V v = (V) o; 388 return v; 389 } else { 390 return null; 391 } 392 } 393 394 @SuppressWarnings ("unchecked") 395 @Override 396 public V put(K key, V value) { 397 Object old = rawMap.put(keyType.cast(key), valueType.cast(value)); 398 if (acceptValue(old)) { 399 return (V) old; 400 } else { 401 return null; 402 } 403 } 404 405 @Override 406 public V remove(Object key) { 407 Object old = rawMap.remove(keyType.cast(key)); 408 if (acceptValue(old)) { 409 @SuppressWarnings ("unchecked") 410 V v = (V) old; 411 return v; 412 } else { 413 return null; 414 } 415 } 416 417 @Override 418 public boolean containsKey(Object key) { 419 return rawMap.containsKey(keyType.cast(key)) && 420 acceptValue(rawMap.get(key)); 421 } 422 423 @Override 424 public boolean containsValue(Object value) { 425 return super.containsValue(valueType.cast(value)); 427 } 428 429 @Override 430 public int size() { 431 int c = 0; 432 Iterator it = rawMap.entrySet().iterator(); 433 while (it.hasNext()) { 434 if (acceptEntry((Map.Entry ) it.next())) { 435 c++; 436 } 437 } 438 return c; 439 } 440 441 443 } 444 445 453 public static <E> Enumeration <E> checkedEnumerationByFilter(Enumeration rawEnum, final Class <E> type, final boolean strict) { 454 @SuppressWarnings ("unchecked") 455 Enumeration <Object > _rawEnum = rawEnum; 456 return Enumerations.<Object ,E>filter(_rawEnum, new Enumerations.Processor<Object ,E>() { 457 public E process(Object o, Collection <Object > ignore) { 458 if (o == null) { 459 return null; 460 } else { 461 try { 462 return type.cast(o); 463 } catch (ClassCastException x) { 464 if (strict) { 465 throw x; 466 } else { 467 return null; 468 } 469 } 470 } 471 } 472 }); 473 } 474 475 496 public static <E> Iterable <E> iterable(final Iterator <E> iterator) { 497 if (iterator == null) { 498 throw new NullPointerException (); 499 } 500 return new Iterable <E>() { 501 public Iterator <E> iterator() { 502 return iterator; 503 } 504 }; 505 } 506 507 528 public static <E> Iterable <E> iterable(final Enumeration <E> enumeration) { 529 if (enumeration == null) { 530 throw new NullPointerException (); 531 } 532 return new Iterable <E>() { 533 public Iterator <E> iterator() { 534 return new Iterator <E>() { 535 public boolean hasNext() { 536 return enumeration.hasMoreElements(); 537 } 538 public E next() { 539 return enumeration.nextElement(); 540 } 541 public void remove() { 542 throw new UnsupportedOperationException (); 543 } 544 }; 545 } 546 }; 547 } 548 549 } 550 | Popular Tags |