diff options
Diffstat (limited to 'src/com/vaadin/data/util/DefaultItemSorter.java')
-rw-r--r-- | src/com/vaadin/data/util/DefaultItemSorter.java | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/src/com/vaadin/data/util/DefaultItemSorter.java b/src/com/vaadin/data/util/DefaultItemSorter.java new file mode 100644 index 0000000000..4a99714212 --- /dev/null +++ b/src/com/vaadin/data/util/DefaultItemSorter.java @@ -0,0 +1,197 @@ +package com.vaadin.data.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; + +import com.vaadin.data.Container; +import com.vaadin.data.Item; +import com.vaadin.data.Property; +import com.vaadin.data.Container.Sortable; + +/** + * Provides a default implementation of an ItemSorter. The + * <code>DefaultItemSorter</code> adheres to the + * {@link Sortable#sort(Object[], boolean[])} rules and sorts the container + * according to the properties given using + * {@link #setSortProperties(Sortable, Object[], boolean[])}. + * <p> + * A Comparator is used for comparing the individual <code>Property</code> + * values. The comparator can be set using the constructor. If no comparator is + * provided a default comparator is used. + * + */ +public class DefaultItemSorter implements ItemSorter { + + private java.lang.Object[] sortPropertyIds; + private boolean[] sortDirections; + private Container container; + private Comparator<Object> propertyValueComparator; + + /** + * Constructs a DefaultItemSorter using the default <code>Comparator</code> + * for comparing <code>Property</code>values. + * + */ + public DefaultItemSorter() { + this(new DefaultPropertyValueComparator()); + } + + /** + * Constructs a DefaultItemSorter which uses the <code>Comparator</code> + * indicated by the <code>propertyValueComparator</code> parameter for + * comparing <code>Property</code>values. + * + * @param propertyValueComparator + * The comparator to use when comparing individual + * <code>Property</code> values + */ + public DefaultItemSorter(Comparator<Object> propertyValueComparator) { + this.propertyValueComparator = propertyValueComparator; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.ItemSorter#compare(java.lang.Object, + * java.lang.Object) + */ + public int compare(Object o1, Object o2) { + Item item1 = container.getItem(o1); + Item item2 = container.getItem(o2); + + for (int i = 0; i < sortPropertyIds.length; i++) { + + int result = compareProperty(sortPropertyIds[i], sortDirections[i], + item1, item2); + + // If order can be decided + if (result != 0) { + return result; + } + + } + + return 0; + } + + /** + * Compares the property indicated by <code>propertyId</code> in the items + * indicated by <code>item1</code> and <code>item2</code> for order. Returns + * a negative integer, zero, or a positive integer as the property value in + * the first item is less than, equal to, or greater than the property value + * in the second item. If the <code>sortDirection</code> is false the + * returned value is negated. + * <p> + * The comparator set for this <code>DefaultItemSorter</code> is used for + * comparing the two property values. + * + * @param propertyId + * The property id for the property that is used for comparison. + * @param sortDirection + * The direction of the sort. A false value negates the result. + * @param item1 + * The first item to compare. + * @param item2 + * The second item to compare. + * @return + */ + protected int compareProperty(Object propertyId, boolean sortDirection, + Item item1, Item item2) { + + // Get the properties to compare + final Property property1 = item1.getItemProperty(propertyId); + final Property property2 = item2.getItemProperty(propertyId); + + // Get the values to compare + final Object value1 = (property1 == null) ? null : property1.getValue(); + final Object value2 = (property2 == null) ? null : property2.getValue(); + + // Result of the comparison + int r = 0; + if (sortDirection) { + r = propertyValueComparator.compare(value1, value2); + } else { + r = propertyValueComparator.compare(value2, value1); + } + + return r; + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.ItemSorter#setSortProperties(com.vaadin.data.Container + * .Sortable, java.lang.Object[], boolean[]) + */ + public void setSortProperties(Container.Sortable container, + Object[] propertyId, boolean[] ascending) { + this.container = container; + + // Removes any non-sortable property ids + final List<Object> ids = new ArrayList<Object>(); + final List<Boolean> orders = new ArrayList<Boolean>(); + final Collection sortable = container.getSortableContainerPropertyIds(); + for (int i = 0; i < propertyId.length; i++) { + if (sortable.contains(propertyId[i])) { + ids.add(propertyId[i]); + orders.add(Boolean.valueOf(i < ascending.length ? ascending[i] + : true)); + } + } + + sortPropertyIds = ids.toArray(); + sortDirections = new boolean[orders.size()]; + for (int i = 0; i < sortDirections.length; i++) { + sortDirections[i] = (orders.get(i)).booleanValue(); + } + + } + + /** + * Provides a default comparator used for comparing {@link Property} values. + * The <code>DefaultPropertyValueComparator</code> assumes all objects it + * compares can be cast to Comparable. + * + */ + public static class DefaultPropertyValueComparator implements + Comparator<Object> { + + public int compare(Object o1, Object o2) { + int r = 0; + // Normal non-null comparison + if (o1 != null && o2 != null) { + // FIXME: Use standard Boolean comparison as Boolean implements + // Comaprable since JDK1.5 + if ((o1 instanceof Boolean) && (o2 instanceof Boolean)) { + if (o1.equals(o2)) { + r = 0; // both have the same boolean value + } else if (((Boolean) o1).booleanValue()) { + return 1; // true is greater than false + } else { + return -1; + } + } else { + // Assume the objects can be cast to Comparable, throw + // ClassCastException otherwise. + r = ((Comparable) o1).compareTo(o2); + } + } else if (o1 == o2) { + // Objects are equal if both are null + r = 0; + } else { + if (o1 == null) { + r = -1; // null is less than non-null + } else { + r = 1; // non-null is greater than null + } + } + + return r; + } + + } + +} |