EntryComparator.java
package org.microspace.table.query.sql;
import java.io.Serializable;
import java.util.Comparator;
import java.util.List;
import org.microspace.table.Entry;
import org.microspace.table.column.Accessor;
import org.microspace.table.column.GetSetPair;
import org.microspace.table.query.SqlFormat;
import org.microspace.util.PojoUtil;
/**
* Generic Comparator of Entry objects.
*
* @author Gaspar Sinai - {@literal gaspar.sinai@microspace.org}
* @version 2017-07-29
* @param <T> The type of the Table.
*/
public class EntryComparator<T> implements Comparator<Entry<T>>, Serializable {
private static final long serialVersionUID = -1558132359899475455L;
public enum Type {
ASC(true),
DESC(false),
SKIP(false);
final boolean ascending;
private Type (boolean ascending) {
this.ascending = ascending;
}
public boolean getAscending() {
return ascending;
}
}
final Class<T> tableClass;
final GetSetPair<T> getSetPairs[];
final String columnEscList[];
final Type[] types;
final Type sortByUpdateTime;
@SuppressWarnings("unchecked")
public EntryComparator (Class<T> tableClass, Type sortByUpdateTime,
List<String> columnList, List<Type> types, List<String> columnListEsc) {
this.sortByUpdateTime = sortByUpdateTime;
this.tableClass = tableClass;
this.types = types.toArray(new Type[types.size()]);
this.columnEscList = columnListEsc.toArray(new String[columnListEsc.size()]);
this.getSetPairs = (GetSetPair<T>[]) new GetSetPair<?>[columnList.size()];
Accessor<T> accessor = PojoUtil.getUnannotateAccessor(tableClass);
int i=0;
for (String column : columnList) {
GetSetPair<T> getSetPair = accessor.getGetSetPair(column);
if (getSetPair == null) {
throw new IllegalArgumentException ("Field Not Found: " + column);
}
getSetPairs[i++] = getSetPair;
}
String[] columnListArray = new String[columnList.size()];
columnList.toArray(columnListArray);
}
@Override
public int compare(Entry<T> o1, Entry<T> o2) {
int ret;
for (int i=0; i<getSetPairs.length; i++) {
if (types[i] == Type.SKIP) continue;
boolean ascending = types[i] == Type.ASC;
ret = compareField(o1, o2, i, ascending);
if (ret != 0) return ret;
}
if (sortByUpdateTime == Type.SKIP) {
return 0;
}
ret = o1.getUpdateCount().compareTo (o2.getUpdateCount());
return sortByUpdateTime == Type.ASC ? ret : -ret;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private int compareField (Entry<T> o1, Entry<T> o2, int index, boolean ascending) {
Object field1 = getSetPairs[index].get(o1.getSpaceEntry());
Object field2 = getSetPairs[index].get(o2.getSpaceEntry());
if (field1 == null && field2 == null) return 0;
if (field1 == null) return ascending ? -1 : 1;
if (field2 == null) return ascending ? 1 : -1;
int ret;
if (field1 instanceof Comparable) {
ret = ((Comparable)field1).compareTo(field2);
} else {
ret = field1.toString().compareTo(field2.toString());
}
return ascending ? ret : -ret;
}
public String constructSqlString (SqlFormat format) {
if (getSetPairs.length == 0) {
return "";
}
StringBuffer ret = new StringBuffer();
ret.append("ORDER BY ");
String comma = "";
for (int i= 0; i< getSetPairs.length; i++) {
if (types[i] == Type.SKIP) {
continue;
}
GetSetPair<T> gs = getSetPairs[i];
ret.append(comma);
comma =", ";
String esc = columnEscList[i];
if (format == SqlFormat.GIGASPACES) {
esc = "`";
}
ret.append(esc);
ret.append(gs.getName());
ret.append(esc);
if (types[i] == Type.DESC) {
ret.append(" DESC");
}
}
return ret.toString();
}
}