001package org.andromda.utils.beans;
002
003import java.io.Serializable;
004import java.util.Collection;
005import org.andromda.core.common.ClassUtils;
006import org.andromda.core.common.ExceptionUtils;
007
008/**
009 * Used to contain sort criteria.
010 *
011 * @author Chad Brandon
012 */
013public class SortCriteria implements Serializable
014{
015    private static final long serialVersionUID = 34L;
016    /**
017     * Creates a SortCriteria object with the default ascending ordering and nulls
018     * placed first.
019     *
020     * @param sortBy the property to sort by, this can
021     *        be nested (i.e. person.name.firstName will be sorted).
022     */
023    public SortCriteria(final String sortBy)
024    {
025        this(sortBy, true);
026    }
027
028    /**
029     * Creates a new instance of this SortCriteria class.
030     *
031     * @param sortBy the property to sort by, this can
032     *        be nested (i.e. person.name.firstName will be sorted).
033     * @param nullsFirst whether or not nulls will be placed first or last when sorting occurs.
034     */
035    public SortCriteria(
036        final String sortBy,
037        final boolean nullsFirst)
038    {
039        this(sortBy, Ordering.ASCENDING, nullsFirst);
040    }
041
042    /**
043     * Creates a new instance of this SortCriteria class.
044     *
045     * @param sortBy the property to sort by, this can
046     *        be nested (i.e. person.name.firstName will be sorted).
047     * @param ordering the ordering to sort by: {@link Ordering#ASCENDING} or {@link Ordering#DESCENDING}.
048     */
049    public SortCriteria(
050        final String sortBy,
051        final Ordering ordering)
052    {
053        this(sortBy, ordering, true);
054    }
055
056    /**
057     * Creates a new instance of this SortCriteria class.
058     *
059     * @param sortBy the property to sort by, this can
060     *        be nested (i.e. person.name.firstName will be sorted).
061     * @param ordering the ordering to sort by: {@link Ordering#ASCENDING} or {@link Ordering#DESCENDING}.
062     * @param nullsFirst whether or not nulls will be placed first or last when sorting occurs.
063     */
064    public SortCriteria(
065        final String sortBy,
066        final Ordering ordering,
067        final boolean nullsFirst)
068    {
069        ExceptionUtils.checkEmpty(
070            "sortBy",
071            sortBy);
072        try
073        {
074            if (ordering != null)
075            {
076                final Collection validOrderings = ClassUtils.getStaticFieldValues(
077                        String.class,
078                        SortCriteria.class);
079                if (validOrderings.contains(ordering))
080                {
081                    throw new IllegalArgumentException("ordering must be of one of the following types: " +
082                        validOrderings);
083                }
084            }
085        }
086        catch (final Throwable throwable)
087        {
088            throw new SortException(throwable);
089        }
090        this.sortBy = sortBy;
091        this.ordering = ordering;
092        this.nullsFirst = nullsFirst;
093    }
094
095    /**
096     * The ordering by which sorting shall occur.
097     */
098    private Ordering ordering;
099
100    /**
101     * Gets the current ordering to be used.
102     *
103     * @return Ordering
104     */
105    public Ordering getOrdering()
106    {
107        return ordering;
108    }
109
110    /**
111     * Sets the ordering to use for sorting.
112     *
113     * @param ordering the ordering.
114     */
115    public void setOrdering(final Ordering ordering)
116    {
117        this.ordering = ordering;
118    }
119
120    /**
121     * Stores the name of the property to sort by.
122     */
123    private String sortBy;
124
125    /**
126     * Gets the sort by name.
127     *
128     * @return String
129     */
130    public String getSortBy()
131    {
132        return sortBy;
133    }
134
135    /**
136     * Sets the name of the property by which to sort.
137     *
138     * @param sortBy the name of the property by which to sort.
139     */
140    public void setSortBy(final String sortBy)
141    {
142        this.sortBy = sortBy;
143    }
144
145    private boolean nullsFirst;
146
147    /**
148     * @return the nullsFirst
149     */
150    public boolean isNullsFirst()
151    {
152        return nullsFirst;
153    }
154
155    /**
156     * @param nullsFirst the nullsFirst to set
157     */
158    public void setNullsFirst(boolean nullsFirst)
159    {
160        this.nullsFirst = nullsFirst;
161    }
162
163    /**
164     * Represents the types of ordering that may occur when sorting
165     * with the {@link BeanSorter}.
166     *
167     * @author Chad Brandon
168     */
169    public static final class Ordering
170    {
171        /**
172         * Indicates sorting should be performed <em>ascending</em>.
173         */
174        public static final Ordering ASCENDING = new Ordering("ASCENDING");
175
176        /**
177         * Indicates sorting should be performed <em>descending</em>.
178         */
179        public static final Ordering DESCENDING = new Ordering("DESCENDING");
180
181        /**
182         * The actual value of the enumeration.
183         */
184        private String value;
185
186        private Ordering(final String ordering)
187        {
188            this.value = ordering;
189        }
190
191        /**
192         * @see Object#toString()
193         */
194        public String toString()
195        {
196            return this.value;
197        }
198    }
199}