I'm using Google Guava 17.0 library. I have a class named AroundBust
containing only two properties id
of type Integer
and size
of type BigDecimal
.
This class is instantiated based on the data stored in an XML file. A java.util.List
is populated by a list of objects of this class.
This list is displayed in a PrimeFaces data table.
This list is sorted based on sort orders supplied by the data table (multiple sorting).
I'm trying sort the list as follows (in the associated JSF managed bean).
@ManagedBean
@ViewScoped
public final class AroundBustManagedBean extends LazyDataModel<AroundBust> implements Serializable {
private List<AroundBust> entireList;
private static final long serialVersionUID = 1L;
private static final class IntegerSorting {
private IntegerSorting() {}
public static Function<AroundBust, Integer> getInstance() {
return Holder.INSTANCE;
}
private enum Holder implements Function<AroundBust, Integer> {
INSTANCE {
@Override
public Integer apply(AroundBust f) {
return f.getId();
}
}
}
}
private static final class BigDecimalSorting {
private BigDecimalSorting() {}
public static Function<AroundBust, BigDecimal> getInstance() {
return Holder.INSTANCE;
}
private enum Holder implements Function<AroundBust, BigDecimal> {
INSTANCE {
@Override
public BigDecimal apply(AroundBust f) {
return f.getSize();
}
}
}
}
@Override
public List<AroundBust> load(int first, int pageSize, List<SortMeta> multiSortMeta, final Map<String, Object> filters) {
//The instance variable entireList is populated by unmarshalling the XML file in question.
int listSize = 0;
Map<String, String> map = null;
//Assuming the List parameter multiSortMeta is somehow turned into a map.
//I'm not presenting it here to reduce the code complexity.
//The sorting is performed by the code below using the Guava library.
if (map != null && !map.isEmpty()) {
Ordering<AroundBust> id = null;
Ordering<AroundBust> value = null;
Ordering<AroundBust> idValue = null;
Ordering<AroundBust> valueId = null;
for (Map.Entry<String, String> entry : map.entrySet()) {
if (entry.getKey().equalsIgnoreCase("id")) {
id = entry.getValue().equalsIgnoreCase("asc") ? Ordering.natural().onResultOf(IntegerSorting.getInstance()) : Ordering.natural().onResultOf(IntegerSorting.getInstance()).reverse();
if (value != null) {
valueId = value.compound(id);
}
} else if (entry.getKey().equalsIgnoreCase("size")) {
value = entry.getValue().equalsIgnoreCase("asc") ? Ordering.natural().onResultOf(BigDecimalSorting.getInstance()) : Ordering.natural().onResultOf(BigDecimalSorting.getInstance()).reverse();
if (id != null) {
idValue = id.compound(value);
}
}
}
if (idValue != null) {
entireList = idValue.sortedCopy(entireList);
} else if (valueId != null) {
entireList = valueId.sortedCopy(entireList);
} else if (id != null) {
entireList = id.sortedCopy(entireList);
} else if (value != null) {
entireList = value.sortedCopy(entireList);
}
} else {
//This is just a default sort order, when the data table is loaded for the first time.
entireList = Ordering.natural().onResultOf(IntegerSorting.getInstance()).reverse().sortedCopy(entireList);
}
return new ArrayList<AroundBust>(entireList.subList(first, Math.min(pageSize + first, listSize)));
}
}
The map maintains a list of fields to be sorted with the field name as a key and the sort order ("asc" for ascending order and "desc" for descending order) as its value in the exact order in which the data table column headers are clicked.
There are only two fields but it requires many conditional checks as can be seen in the code snippet.
These conditional checks are increased significantly as the number of properties/fields are increased in the class. As a result, the code may be unmanageable later on.
How to reduce this code at a minimum extent?