/*
* Copyright 2011 Blazebit
*/
package com.blazebit.comparator;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* This comparator is able to compare objects on a specified index which are part of a Collection or an Array.
*
* @author Thomas Herzog
*/
public class GenericCollectionComparator<T> extends GenericComparator<T> {
private final int index;
/**
* @param field
* @param index
*/
public GenericCollectionComparator(String field, int index) {
super(field);
this.index = index;
}
@Override
@SuppressWarnings("unchecked")
public int compare(T object1, T object2) {
Integer result = compareNullObjects(object1, object2);
if (result == null) {
result = super.compare((T) get(object1, index), (T) get(object2, index));
}
return result;
}
/*
* Borrowed from Apache Commons Collections to avoid the dependency
*/
private static Object get(Object object, int index) {
if (index < 0) {
throw new IndexOutOfBoundsException("Index cannot be negative: "
+ index);
}
if (object instanceof Map) {
Map<?, ?> map = (Map<?, ?>) object;
Iterator<?> iterator = map.entrySet().iterator();
return get(iterator, index);
} else if (object instanceof List) {
return ((List<?>) object).get(index);
} else if (object instanceof Object[]) {
return ((Object[]) object)[index];
} else if (object instanceof Iterator) {
Iterator<?> it = (Iterator<?>) object;
while (it.hasNext()) {
index--;
if (index == -1) {
return it.next();
} else {
it.next();
}
}
throw new IndexOutOfBoundsException("Entry does not exist: "
+ index);
} else if (object instanceof Collection) {
Iterator<?> iterator = ((Collection<?>) object).iterator();
return get(iterator, index);
} else if (object instanceof Enumeration) {
Enumeration<?> it = (Enumeration<?>) object;
while (it.hasMoreElements()) {
index--;
if (index == -1) {
return it.nextElement();
} else {
it.nextElement();
}
}
throw new IndexOutOfBoundsException("Entry does not exist: "
+ index);
} else if (object == null) {
throw new IllegalArgumentException("Unsupported object type: null");
} else {
try {
return Array.get(object, index);
} catch (IllegalArgumentException ex) {
throw new IllegalArgumentException("Unsupported object type: "
+ object.getClass().getName());
}
}
}
}