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 }