1 package com.imcode.util; 2 3 import org.apache.commons.collections.ComparatorUtils; 4 5 import java.util.Comparator; 6 import java.io.Serializable; 7 8 public abstract class ChainableReversibleNullComparator implements Comparator, Serializable { 9 10 public ChainableReversibleNullComparator chain( Comparator comparator ) { 11 return new ComparatorWrapper( ComparatorUtils.chainedComparator( this, comparator ) ); 12 } 13 14 public ChainableReversibleNullComparator reversed() { 15 return new ComparatorWrapper( ComparatorUtils.reversedComparator( this ) ); 16 } 17 18 public ChainableReversibleNullComparator nullsFirst() { 19 return new ComparatorWrapper( this ) { 20 public int compare( Object o1, Object o2 ) { 21 try { 22 return super.compare( o1, o2 ); 23 } catch (NullPointerException npe) { 24 return compareNulls( wrappedComparator, o1, o2 ); 25 } 26 } 27 }; 28 } 29 30 public ChainableReversibleNullComparator nullsLast() { 31 return new ComparatorWrapper( this ) { 32 public int compare( Object o1, Object o2 ) { 33 try { 34 return super.compare( o1, o2 ); 35 } catch (NullPointerException npe) { 36 return -compareNulls( wrappedComparator, o1, o2 ); 37 } 38 } 39 }; 40 } 41 42 private int compareNulls( Comparator comparator, Object o1, Object o2 ) { 43 boolean value1IsNull = false; 44 boolean value2IsNull = false; 45 try { 46 comparator.compare( o1, o1 ); 47 } catch ( NullPointerException npe ) { 48 value1IsNull = true; 49 } 50 try { 51 comparator.compare( o2, o2 ); 52 } catch ( NullPointerException npe ) { 53 value2IsNull = true; 54 } 55 if ( value1IsNull && value2IsNull ) { 56 return 0; 57 } else if ( value1IsNull ) { 58 return -1; 59 } else if ( value2IsNull ) { 60 return +1; 61 } 62 return 0 ; 63 } 64 65 }