001: package org.andromda.utils.beans;
002:
003: import java.util.ArrayList;
004: import java.util.Collection;
005: import java.util.Collections;
006: import java.util.List;
007:
008: import org.andromda.core.common.ExceptionUtils;
009: import org.andromda.utils.beans.SortCriteria.Ordering;
010: import org.andromda.utils.beans.comparators.BeanComparator;
011: import org.apache.commons.collections.comparators.ComparatorChain;
012:
013: /**
014: * Provides bean sorting capabilities.
015: *
016: * <p>
017: * Sorts passed in Collections and returns
018: * sorted Lists. Performs sorting for any
019: * Class that has an associated Comparator implementation defined. If
020: * the Collection that is passed in, is not an instance of List, it will create
021: * a new ArrayList with the contents of the passed in Collection, before
022: * sorting occurs (since sorting can only be done on a java.util.List).
023: * </p>
024: *
025: * @author Chad Brandon
026: */
027: public class BeanSorter {
028: /**
029: * Performs sorting of the collection by one property to
030: * sort with more than one property see {@link sort(java.util.Collection, SortCriteria[])}.
031: *
032: * @see sort(java.util.Collection, SortCriteria[])
033: *
034: * @param beans the Collection of PersistentObjects to sort
035: * @param sortBy the property to sort by (i.e. firstName, etc). Can
036: * be a nested property such as 'person.address.street'.
037: * @param ordering the ordering of the sorting (either {@link SortCriteria#ASENDING}
038: * or {@link SortCriteria#DESCENDING})
039: * @return the sorted List
040: */
041: public static List sort(final Collection beans,
042: final String sortBy, final Ordering ordering) {
043: return sort(beans, new SortCriteria[] { new SortCriteria(
044: sortBy, ordering) });
045: }
046:
047: /**
048: * <p>
049: * Sorts the passed in Collection and returns
050: * a sorted List. Performs SQL like sorting for any
051: * Class that has an associated Comparator implementation defined. If
052: * the Collection that is passed in, is not an instance of List, it will create
053: * a new ArrayList with the contents of the passed in Collection, before
054: * sorting occurs. Since sorting can only be done on a java.util.List.
055: * </p>
056: *
057: * @param beans the Collection of PersistentObjects to sort
058: * @param sortBy an array of SortCriteria. This array of SortCriteria
059: * specifies which attributes to sort by. You can also specify whether you want
060: * {@link SortCriteria#ASCENDING} or {@link SortCriteria#DESCENDING} ordering for each attribute.
061: * Attributes to sort by, MUST be simple attributes
062: * (i.e. name, type, etc, they can not be complex objects, but the properties can be
063: * nested simple types within associated beans).
064: *
065: * @return List the sorted List
066: */
067: public static List sort(final Collection beans,
068: final SortCriteria[] sortBy) {
069: ExceptionUtils.checkNull("beans", beans);
070: ExceptionUtils.checkNull("sortBy", sortBy);
071:
072: if (sortBy.length == 0) {
073: throw new IllegalArgumentException(
074: "sortBy must contain at least one value by which to sort");
075: }
076:
077: List sorted = null;
078:
079: // - if the beans passed in, isn't assignable to List,
080: // create a new ArrayList
081: if (!(beans instanceof List)) {
082: sorted = new ArrayList(beans);
083: } else {
084: sorted = (List) beans;
085: }
086:
087: int sortByNum = sortBy.length;
088:
089: // - use the Comparator chain to provide SQL like sorting of properties
090: ComparatorChain chain = new ComparatorChain();
091: for (int ctr = 0; ctr < sortByNum; ctr++) {
092: final SortCriteria orderBy = sortBy[ctr];
093: chain.addComparator(new BeanComparator(orderBy));
094: }
095:
096: Collections.sort(sorted, chain);
097:
098: return sorted;
099: }
100: }
|