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 {@code String}s 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 a {@code String} 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 strings returned from those methods 013 * 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 a {@link StringSortKey}, you 017 * may tell it to ignore differences in case. 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>PostalAddress</tt>, that has the following 022 * attributes, each of which is a <tt>String</tt>: 023 * <tt>state, city, postalCode</tt>. Furthermore, assume the normal convention 024 * for the getters (e.g., <tt>getCity()</tt>). You could sort a collection of 025 * addresses by state, then city, then postal code, without writing any new 026 * classes by doing this:</p> 027 * <pre> 028 * ReflectiveStringSortKey<Address> stateKey = 029 * new ReflectiveStringSortKey<Address>("getState"); 030 * 031 * ReflectiveStringSortKey<Address> cityKey = 032 * new ReflectiveStringSortKey<Address>("getCity"); 033 * 034 * ReflectiveStringSortKey<Address> codeKey = 035 * new ReflectiveStringSortKey<Address>("getPostalCode"); 036 * 037 * CompoundComparator<Address> comparator = 038 * new CompoundComparator<Address>(stateKey, cityKey, codeKey); 039 * 040 * Collections.sort(myAddresses, comparator); 041 * </pre> 042 * <p> 043 * <b>Version Info:</b> 044 * <table style="margin-left:2em"> 045 * <tr><td>$Revision: 593 $</td></tr> 046 * <tr><td>$Date: 2007-05-07 15:54:14 -0600 (Mon, 07 May 2007) $</td></tr> 047 * <tr><td>$Author: dharland $</td></tr> 048 * </table></p> 049 * 050 * @author David M. Harland 051 * @since 2007-05-04 052 */ 053 public final class ReflectiveStringSortKey<T> 054 extends StringSortKey 055 implements Comparator<T> 056 { 057 private ReflectiveSortHelper<String, T> helper; 058 059 /** 060 * Creates a new instance that will base its comparison on the {@code String} 061 * returned by the method with the given name. 062 * 063 * @param methodName the name of a public, no argument, method that belongs 064 * to objects of type {@code T} and that returns a 065 * {@code String}. If there is any trouble creating or 066 * calling the method with this name, it will be treated 067 * as if it returns a {@code String} of <i>null</i>. 068 */ 069 public ReflectiveStringSortKey(String methodName) 070 { 071 helper = new ReflectiveSortHelper<String, T>(methodName, (String)null); 072 } 073 074 /** 075 * Sets the name of the method used for making comparisons. 076 * 077 * @param newMethodName the name of a public, no argument, method that belongs 078 * to objects of type {@code T} and that returns a 079 * {@code String}. If there is any trouble creating or 080 * calling the method with this name, it will be treated 081 * as if it returns a {@code String} of <i>null</i>. 082 */ 083 public void setMethodName(String newMethodName) 084 { 085 helper.setMethodName(newMethodName); 086 } 087 088 /* (non-Javadoc) 089 * @see Comparator#compare(Object, Object) 090 */ 091 public int compare(T o1, T o2) 092 { 093 return compareObjects(helper.getValue(o1), helper.getValue(o2)); 094 } 095 }