commons-beansHacky solution, catching the NPE's. I have coded a clean solution, but I haven't tested it…
package com.rapidlime.pohlidame;
import java.lang.reflect.InvocationTargetException;
import java.util.Comparator;
import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.beanutils.NestedNullException;
import org.apache.commons.beanutils.PropertyUtils;
/**
*
* @author Ondrej Zizka
*/
public class NullSafeUglyBeanComparator extends BeanComparator
{
public NullSafeUglyBeanComparator( String property, Comparator comparator ) {
super( property, comparator );
}
private static Object getNullSafeProperty( Object o1, String property )
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException
{
Object val;
try {
val = PropertyUtils.getProperty( o1, property );
}
catch( NestedNullException ex ){
val = null;
}
return val;
}
private static final boolean NULL_GOES_LAST = true;
/**
* Compare two JavaBeans by their shared property.
* If {@link #getProperty} is null then the actual objects will be compared.
*
* @param o1 Object The first bean to get data from to compare against
* @param o2 Object The second bean to get data from to compare
* @return int negative or positive based on order
*/
@Override
public int compare( Object o1, Object o2 ) {
final String property = getProperty();
final Comparator comparator = getComparator();
if ( property == null ) {
// compare the actual objects
return comparator.compare( o1, o2 );
}
try {
//Object value1 = PropertyUtils.getProperty( o1, property );
//Object value2 = PropertyUtils.getProperty( o2, property );
Object value1 = getNullSafeProperty( o1, property );
Object value2 = getNullSafeProperty( o2, property );
if( null == value1 && null == value2 ) return 0;
if( null == value1 ) return NULL_GOES_LAST ? +1 : -1;
if( null == value2 ) return NULL_GOES_LAST ? +1 : -1;
return comparator.compare( value1, value2 );
}
catch ( IllegalAccessException iae ) {
throw new RuntimeException( "IllegalAccessException: " + iae.toString() );
}
catch ( InvocationTargetException ite ) {
throw new RuntimeException( "InvocationTargetException: " + ite.toString() );
}
catch ( NoSuchMethodException nsme ) {
throw new RuntimeException( "NoSuchMethodException: " + nsme.toString() );
}
}
}// class NullSafeBeanComparator