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; 019 020import java.io.Serializable; 021import java.util.AbstractMap; 022import java.util.AbstractSet; 023import java.util.Collection; 024import java.util.Comparator; 025import java.util.Iterator; 026import java.util.NoSuchElementException; 027import java.util.Set; 028import java.util.SortedMap; 029import java.util.SortedSet; 030 031/** 032 * Collection utility methods. 033 * @author Paul Ferraro 034 */ 035public class Collections 036{ 037 public static final SortedSet<?> EMPTY_SORTED_SET = new EmptySortedSet<Object>(); 038 public static final SortedMap<?, ?> EMPTY_SORTED_MAP = new EmptySortedMap<Object, Object>(); 039 static final Iterator<?> EMPTY_ITERATOR = new EmptyIterator<Object>(); 040 static final Comparator<?> NATURAL_COMPARATOR = new NaturalComparator<Object>(); 041 042 /** 043 * Returns an iterator over an empty collection. 044 * @param <E> the collection type 045 * @return a collection iterator 046 */ 047 @SuppressWarnings("unchecked") 048 static <E> Iterator<E> emptyIterator() 049 { 050 return (Iterator<E>) EMPTY_ITERATOR; 051 } 052 053 /** 054 * Returns a comparator using the natural ordering of comparable objects. 055 * @param <E> the collection type 056 * @return a comparator 057 */ 058 @SuppressWarnings("unchecked") 059 static <E> Comparator<E> naturalComparator() 060 { 061 return (Comparator<E>) NATURAL_COMPARATOR; 062 } 063 064 /** 065 * Like {@link java.util.Collections#emptySet()}, but returns a sorted set. 066 * @param <E> a collection type 067 * @return an empty sorted set 068 */ 069 @SuppressWarnings("unchecked") 070 public static <E> SortedSet<E> emptySortedSet() 071 { 072 return (SortedSet<E>) EMPTY_SORTED_SET; 073 } 074 075 /** 076 * Like {@link java.util.Collections#emptyMap()}, but returns a sorted map. 077 * @param <K> the map's key type 078 * @param <V> the map's value type 079 * @return an empty sorted map 080 */ 081 @SuppressWarnings("unchecked") 082 public static <K, V> SortedMap<K, V> emptySortedMap() 083 { 084 return (SortedMap<K, V>) EMPTY_SORTED_MAP; 085 } 086 087 /** 088 * Like {@link java.util.Collections#singleton(Object)}, but returns a sorted set. 089 * @param <E> 090 * @param element 091 * @return a sorted set containing the single element. 092 */ 093 public static <E> SortedSet<E> singletonSortedSet(E element) 094 { 095 return new SingletonSortedSet<E>(element); 096 } 097 098 /** 099 * Like {@link java.util.Collections#singletonMap(Object, Object)}, but returns a sorted map. 100 * @param <K> 101 * @param <V> 102 * @param key 103 * @param value 104 * @return a sorted map containing the single key, value pair. 105 */ 106 public static <K, V> SortedMap<K, V> singletonSortedMap(K key, V value) 107 { 108 return new SingletonSortedMap<K, V>(key, value); 109 } 110 111 static class NaturalComparator<E> implements Comparator<E>, Serializable 112 { 113 private static final long serialVersionUID = 984839581274651936L; 114 115 @SuppressWarnings("unchecked") 116 @Override 117 public int compare(E object1, E object2) 118 { 119 return ((Comparable<E>) object1).compareTo(object2); 120 } 121 } 122 123 static class EmptyIterator<E> implements Iterator<E> 124 { 125 @Override 126 public boolean hasNext() 127 { 128 return false; 129 } 130 131 @Override 132 public E next() 133 { 134 throw new NoSuchElementException(); 135 } 136 137 @Override 138 public void remove() 139 { 140 throw new UnsupportedOperationException(); 141 } 142 } 143 144 static class EmptySortedSet<E> extends AbstractSet<E> implements SortedSet<E>, Serializable 145 { 146 private static final long serialVersionUID = 8614249160102450427L; 147 148 @Override 149 public Iterator<E> iterator() 150 { 151 return emptyIterator(); 152 } 153 154 @Override 155 public boolean contains(Object object) 156 { 157 return false; 158 } 159 160 @Override 161 public boolean containsAll(Collection<?> c) 162 { 163 return c.isEmpty(); 164 } 165 166 @Override 167 public boolean isEmpty() 168 { 169 return true; 170 } 171 172 @Override 173 public int size() 174 { 175 return 0; 176 } 177 178 @Override 179 public Comparator<? super E> comparator() 180 { 181 return null; 182 } 183 184 @Override 185 public E first() 186 { 187 throw new NoSuchElementException(); 188 } 189 190 @Override 191 public SortedSet<E> headSet(E toElement) 192 { 193 return emptySortedSet(); 194 } 195 196 @Override 197 public E last() 198 { 199 throw new NoSuchElementException(); 200 } 201 202 @Override 203 public SortedSet<E> subSet(E fromElement, E toElement) 204 { 205 return emptySortedSet(); 206 } 207 208 @Override 209 public SortedSet<E> tailSet(E fromElement) 210 { 211 return emptySortedSet(); 212 } 213 } 214 215 static class EmptySortedMap<K, V> extends AbstractMap<K, V> implements SortedMap<K, V>, Serializable 216 { 217 private static final long serialVersionUID = -7955186590936566806L; 218 219 @Override 220 public boolean containsKey(Object object) 221 { 222 return false; 223 } 224 225 @Override 226 public boolean containsValue(Object object) 227 { 228 return false; 229 } 230 231 @Override 232 public V get(Object object) 233 { 234 return null; 235 } 236 237 @Override 238 public boolean isEmpty() 239 { 240 return true; 241 } 242 243 @Override 244 public Set<K> keySet() 245 { 246 return java.util.Collections.emptySet(); 247 } 248 249 @Override 250 public int size() 251 { 252 return 0; 253 } 254 255 @Override 256 public Collection<V> values() 257 { 258 return java.util.Collections.emptySet(); 259 } 260 261 @Override 262 public Set<java.util.Map.Entry<K, V>> entrySet() 263 { 264 return java.util.Collections.emptySet(); 265 } 266 267 @Override 268 public Comparator<? super K> comparator() 269 { 270 return null; 271 } 272 273 @Override 274 public K firstKey() 275 { 276 throw new NoSuchElementException(); 277 } 278 279 @Override 280 public SortedMap<K, V> headMap(K toKey) 281 { 282 return emptySortedMap(); 283 } 284 285 @Override 286 public K lastKey() 287 { 288 throw new NoSuchElementException(); 289 } 290 291 @Override 292 public SortedMap<K, V> subMap(K fromKey, K toKey) 293 { 294 return emptySortedMap(); 295 } 296 297 @Override 298 public SortedMap<K, V> tailMap(K fromKey) 299 { 300 return emptySortedMap(); 301 } 302 } 303 304 static class SingletonIterator<E> implements Iterator<E> 305 { 306 private final E element; 307 private boolean hasNext = true; 308 309 SingletonIterator(E element) 310 { 311 this.element = element; 312 } 313 314 @Override 315 public boolean hasNext() 316 { 317 return this.hasNext; 318 } 319 320 @Override 321 public E next() 322 { 323 if (!this.hasNext) 324 { 325 throw new NoSuchElementException(); 326 } 327 328 this.hasNext = false; 329 330 return this.element; 331 } 332 333 @Override 334 public void remove() 335 { 336 throw new UnsupportedOperationException(); 337 } 338 } 339 340 static class NullComparator<E> implements Comparator<E>, Serializable 341 { 342 private static final long serialVersionUID = -8178822438438191299L; 343 344 @Override 345 public int compare(E object1, E object2) 346 { 347 return 0; 348 } 349 } 350 351 static class SingletonSortedSet<E> extends AbstractSet<E> implements SortedSet<E>, Serializable 352 { 353 private static final long serialVersionUID = -7831170170325623175L; 354 355 private final E element; 356 357 SingletonSortedSet(E element) 358 { 359 this.element = element; 360 } 361 362 @Override 363 public Iterator<E> iterator() 364 { 365 return new SingletonIterator<E>(this.element); 366 } 367 368 @Override 369 public int size() 370 { 371 return 1; 372 } 373 374 @Override 375 public boolean contains(Object object) 376 { 377 return this.element.equals(object); 378 } 379 380 @Override 381 public boolean isEmpty() 382 { 383 return false; 384 } 385 386 @Override 387 public Comparator<? super E> comparator() 388 { 389 return null; 390 } 391 392 @Override 393 public E first() 394 { 395 return this.element; 396 } 397 398 @Override 399 public SortedSet<E> headSet(E toElement) 400 { 401 return (naturalComparator().compare(this.element, toElement) < 0) ? this : Collections.<E>emptySortedSet(); 402 } 403 404 @Override 405 public E last() 406 { 407 return this.element; 408 } 409 410 @Override 411 public SortedSet<E> subSet(E fromElement, E toElement) 412 { 413 Comparator<E> comparator = naturalComparator(); 414 415 return ((comparator.compare(this.element, toElement) < 0) && (comparator.compare(this.element, fromElement) >= 0)) ? this : Collections.<E>emptySortedSet(); 416 } 417 418 @Override 419 public SortedSet<E> tailSet(E fromElement) 420 { 421 return (naturalComparator().compare(this.element, fromElement) >= 0) ? this : Collections.<E>emptySortedSet(); 422 } 423 } 424 425 static class SingletonSortedMap<K, V> extends AbstractMap<K, V> implements SortedMap<K, V>, Serializable 426 { 427 private static final long serialVersionUID = -3229163217706447957L; 428 429 private final Entry<K, V> entry; 430 431 SingletonSortedMap(K key, V value) 432 { 433 this.entry = new SimpleImmutableEntry<K, V>(key, value); 434 } 435 436 @Override 437 public boolean containsKey(Object object) 438 { 439 return this.entry.getKey().equals(object); 440 } 441 442 @Override 443 public boolean containsValue(Object object) 444 { 445 return this.entry.getValue().equals(object); 446 } 447 448 @Override 449 public V get(Object object) 450 { 451 return this.entry.getKey().equals(object) ? this.entry.getValue() : null; 452 } 453 454 @Override 455 public boolean isEmpty() 456 { 457 return false; 458 } 459 460 @Override 461 public Set<K> keySet() 462 { 463 return java.util.Collections.singleton(this.entry.getKey()); 464 } 465 466 @Override 467 public int size() 468 { 469 return 1; 470 } 471 472 @Override 473 public Collection<V> values() 474 { 475 return java.util.Collections.singleton(this.entry.getValue()); 476 } 477 478 @Override 479 public Set<java.util.Map.Entry<K, V>> entrySet() 480 { 481 return java.util.Collections.singleton(this.entry); 482 } 483 484 @Override 485 public Comparator<? super K> comparator() 486 { 487 return null; 488 } 489 490 @Override 491 public K firstKey() 492 { 493 return this.entry.getKey(); 494 } 495 496 @Override 497 public SortedMap<K, V> headMap(K toKey) 498 { 499 return (naturalComparator().compare(this.entry.getKey(), toKey) < 0) ? this : Collections.<K, V>emptySortedMap(); 500 } 501 502 @Override 503 public K lastKey() 504 { 505 return this.entry.getKey(); 506 } 507 508 @Override 509 public SortedMap<K, V> subMap(K fromKey, K toKey) 510 { 511 Comparator<K> comparator = naturalComparator(); 512 513 return ((comparator.compare(this.entry.getKey(), toKey) < 0) && (comparator.compare(this.entry.getKey(), fromKey) >= 0)) ? this : Collections.<K, V>emptySortedMap(); 514 } 515 516 @Override 517 public SortedMap<K, V> tailMap(K fromKey) 518 { 519 return (naturalComparator().compare(this.entry.getKey(), fromKey) >= 0) ? this : Collections.<K, V>emptySortedMap(); 520 } 521 } 522 523 private Collections() 524 { 525 // Hide constructor 526 } 527}