001 package edu.nrao.sss.sort; 002 003 import java.util.Comparator; 004 005 /** 006 * A {@link SortKey sort key} and {@link Comparator comparator} that works with 007 * the enumeration elements returned by a method that is found reflectively. 008 * <p> 009 * Clients of this class must provide the name of a public, no argument, method 010 * that returns an {@code Enum} and that is present in classes of the 011 * parameterized type {@code T}. The method created from that name is called 012 * on the objects to be compared, and the enumeration elements returned from 013 * those methods are what is actually compared.</p> 014 * <p> 015 * Because this class is a {@link SortKey}, you may configure its instances with 016 * a particular {@code SortOrder}. Because it is also an {@link EnumSortKey}, 017 * you may specify a custom ordering. You may place instances of this 018 * class in a {@link CompoundComparator}.</p> 019 * <p> 020 * <b><u>Example</u></b><br/> 021 * Let there be a class, <tt>Person</tt>, that has the following 022 * attributes, each of which is an enumeration: 023 * <tt>gender</tt> and <tt>handedness</tt>. 024 * Furthermore, assume the normal convention 025 * for the getters (e.g., <tt>getGender()</tt>). 026 * If you are studying the distribution of handedness by age and gender, 027 * you might want to sort a collection of people by age, gender, and 028 * handedness. You could do this without writing any new 029 * classes by doing as follows:</p> 030 * <pre> 031 * ReflectiveIntSortKey<Person> ageKey = 032 * new ReflectiveIntSortKey<Person>("getAge"); 033 * 034 * ReflectiveEnumSortKey<Person,Gender> sexKey = 035 * new ReflectiveEnumSortKey<Person,Gender>("getGender"); 036 * 037 * ReflectiveEnumSortKey<Person,Handedness> handKey = 038 * new ReflectiveEnumSortKey<Person,Handedness>("getHandedness"); 039 * 040 * CompoundComparator<Person> comparator = 041 * new CompoundComparator<Person>(ageKey, sexKey, handKey); 042 * 043 * Collections.sort(population, comparator); 044 * </pre> 045 * <p> 046 * <b>Version Info:</b> 047 * <table style="margin-left:2em"> 048 * <tr><td>$Revision: 593 $</td></tr> 049 * <tr><td>$Date: 2007-05-07 15:54:14 -0600 (Mon, 07 May 2007) $</td></tr> 050 * <tr><td>$Author: dharland $</td></tr> 051 * </table></p> 052 * 053 * @author David M. Harland 054 * @since 2007-05-07 055 */ 056 public final class ReflectiveEnumSortKey<T, E extends Enum<E>> 057 extends EnumSortKey<E> 058 implements Comparator<T> 059 { 060 private ReflectiveSortHelper<E, T> helper; 061 062 /** 063 * Creates a new instance that will base its comparison on the {@code Integer} 064 * returned by the method with the given name. 065 * 066 * @param methodName the name of a public, no argument, method that belongs 067 * to objects of type {@code T} and that returns an 068 * {@link Enum}). If there is any 069 * trouble creating or calling the method with this name, 070 * it will be treated as if it returns <i>null</i>. 071 */ 072 public ReflectiveEnumSortKey(String methodName) 073 { 074 helper = new ReflectiveSortHelper<E, T>(methodName, (E)null); 075 } 076 077 /** 078 * Sets the name of the method used for making comparisons. 079 * 080 * @param newMethodName the name of a public, no argument, method that belongs 081 * to objects of type {@code T} and that returns an 082 * {@code Integer} (or {@code in}). If there is any 083 * trouble creating or calling the method with this name, 084 * it will be treated as if it returns a {@code Integer} 085 * of {@link Integer#MIN_VALUE}. 086 */ 087 public void setMethodName(String newMethodName) 088 { 089 helper.setMethodName(newMethodName); 090 } 091 092 /* (non-Javadoc) 093 * @see Comparator#compare(Object, Object) 094 */ 095 public int compare(T o1, T o2) 096 { 097 return compareObjects(helper.getValue(o1), helper.getValue(o2)); 098 } 099 }