You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DefaultItemSorter.java 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*
  2. @VaadinApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.data.util;
  5. import java.io.Serializable;
  6. import java.util.ArrayList;
  7. import java.util.Collection;
  8. import java.util.Comparator;
  9. import java.util.List;
  10. import com.vaadin.data.Container;
  11. import com.vaadin.data.Container.Sortable;
  12. import com.vaadin.data.Item;
  13. import com.vaadin.data.Property;
  14. /**
  15. * Provides a default implementation of an ItemSorter. The
  16. * <code>DefaultItemSorter</code> adheres to the
  17. * {@link Sortable#sort(Object[], boolean[])} rules and sorts the container
  18. * according to the properties given using
  19. * {@link #setSortProperties(Sortable, Object[], boolean[])}.
  20. * <p>
  21. * A Comparator is used for comparing the individual <code>Property</code>
  22. * values. The comparator can be set using the constructor. If no comparator is
  23. * provided a default comparator is used.
  24. *
  25. */
  26. public class DefaultItemSorter implements ItemSorter {
  27. private java.lang.Object[] sortPropertyIds;
  28. private boolean[] sortDirections;
  29. private Container container;
  30. private Comparator<Object> propertyValueComparator;
  31. /**
  32. * Constructs a DefaultItemSorter using the default <code>Comparator</code>
  33. * for comparing <code>Property</code>values.
  34. *
  35. */
  36. public DefaultItemSorter() {
  37. this(new DefaultPropertyValueComparator());
  38. }
  39. /**
  40. * Constructs a DefaultItemSorter which uses the <code>Comparator</code>
  41. * indicated by the <code>propertyValueComparator</code> parameter for
  42. * comparing <code>Property</code>values.
  43. *
  44. * @param propertyValueComparator
  45. * The comparator to use when comparing individual
  46. * <code>Property</code> values
  47. */
  48. public DefaultItemSorter(Comparator<Object> propertyValueComparator) {
  49. this.propertyValueComparator = propertyValueComparator;
  50. }
  51. /*
  52. * (non-Javadoc)
  53. *
  54. * @see com.vaadin.data.util.ItemSorter#compare(java.lang.Object,
  55. * java.lang.Object)
  56. */
  57. public int compare(Object o1, Object o2) {
  58. Item item1 = container.getItem(o1);
  59. Item item2 = container.getItem(o2);
  60. /*
  61. * Items can be null if the container is filtered. Null is considered
  62. * "less" than not-null.
  63. */
  64. if (item1 == null) {
  65. if (item2 == null) {
  66. return 0;
  67. } else {
  68. return 1;
  69. }
  70. } else if (item2 == null) {
  71. return -1;
  72. }
  73. for (int i = 0; i < sortPropertyIds.length; i++) {
  74. int result = compareProperty(sortPropertyIds[i], sortDirections[i],
  75. item1, item2);
  76. // If order can be decided
  77. if (result != 0) {
  78. return result;
  79. }
  80. }
  81. return 0;
  82. }
  83. /**
  84. * Compares the property indicated by <code>propertyId</code> in the items
  85. * indicated by <code>item1</code> and <code>item2</code> for order. Returns
  86. * a negative integer, zero, or a positive integer as the property value in
  87. * the first item is less than, equal to, or greater than the property value
  88. * in the second item. If the <code>sortDirection</code> is false the
  89. * returned value is negated.
  90. * <p>
  91. * The comparator set for this <code>DefaultItemSorter</code> is used for
  92. * comparing the two property values.
  93. *
  94. * @param propertyId
  95. * The property id for the property that is used for comparison.
  96. * @param sortDirection
  97. * The direction of the sort. A false value negates the result.
  98. * @param item1
  99. * The first item to compare.
  100. * @param item2
  101. * The second item to compare.
  102. * @return a negative, zero, or positive integer if the property value in
  103. * the first item is less than, equal to, or greater than the
  104. * property value in the second item. Negated if
  105. * {@code sortDirection} is false.
  106. */
  107. protected int compareProperty(Object propertyId, boolean sortDirection,
  108. Item item1, Item item2) {
  109. // Get the properties to compare
  110. final Property property1 = item1.getItemProperty(propertyId);
  111. final Property property2 = item2.getItemProperty(propertyId);
  112. // Get the values to compare
  113. final Object value1 = (property1 == null) ? null : property1.getValue();
  114. final Object value2 = (property2 == null) ? null : property2.getValue();
  115. // Result of the comparison
  116. int r = 0;
  117. if (sortDirection) {
  118. r = propertyValueComparator.compare(value1, value2);
  119. } else {
  120. r = propertyValueComparator.compare(value2, value1);
  121. }
  122. return r;
  123. }
  124. /*
  125. * (non-Javadoc)
  126. *
  127. * @see
  128. * com.vaadin.data.util.ItemSorter#setSortProperties(com.vaadin.data.Container
  129. * .Sortable, java.lang.Object[], boolean[])
  130. */
  131. public void setSortProperties(Container.Sortable container,
  132. Object[] propertyId, boolean[] ascending) {
  133. this.container = container;
  134. // Removes any non-sortable property ids
  135. final List<Object> ids = new ArrayList<Object>();
  136. final List<Boolean> orders = new ArrayList<Boolean>();
  137. final Collection<?> sortable = container
  138. .getSortableContainerPropertyIds();
  139. for (int i = 0; i < propertyId.length; i++) {
  140. if (sortable.contains(propertyId[i])) {
  141. ids.add(propertyId[i]);
  142. orders.add(Boolean.valueOf(i < ascending.length ? ascending[i]
  143. : true));
  144. }
  145. }
  146. sortPropertyIds = ids.toArray();
  147. sortDirections = new boolean[orders.size()];
  148. for (int i = 0; i < sortDirections.length; i++) {
  149. sortDirections[i] = (orders.get(i)).booleanValue();
  150. }
  151. }
  152. /**
  153. * Provides a default comparator used for comparing {@link Property} values.
  154. * The <code>DefaultPropertyValueComparator</code> assumes all objects it
  155. * compares can be cast to Comparable.
  156. *
  157. */
  158. public static class DefaultPropertyValueComparator implements
  159. Comparator<Object>, Serializable {
  160. @SuppressWarnings("unchecked")
  161. public int compare(Object o1, Object o2) {
  162. int r = 0;
  163. // Normal non-null comparison
  164. if (o1 != null && o2 != null) {
  165. // Assume the objects can be cast to Comparable, throw
  166. // ClassCastException otherwise.
  167. r = ((Comparable<Object>) o1).compareTo(o2);
  168. } else if (o1 == o2) {
  169. // Objects are equal if both are null
  170. r = 0;
  171. } else {
  172. if (o1 == null) {
  173. r = -1; // null is less than non-null
  174. } else {
  175. r = 1; // non-null is greater than null
  176. }
  177. }
  178. return r;
  179. }
  180. }
  181. }