package org.limewire.ui.swing.search.model; import static org.limewire.util.Objects.compareToNull; import static org.limewire.util.Objects.compareToNullIgnoreCase; import java.util.Comparator; import org.limewire.core.api.FilePropertyKey; /** * Factory class for creating sort comparators. */ public class SortFactory { /** * Returns a search result Comparator for the specified sort option. */ @SuppressWarnings("unchecked") public static Comparator<VisualSearchResult> getSortComparator(SortOption sortOption) { switch (sortOption) { case ALBUM: return getStringPropertyPlusNameComparator(FilePropertyKey.ALBUM, true); case ARTIST: return getStringPropertyPlusNameComparator(FilePropertyKey.AUTHOR, true); case COMPANY: return getStringPropertyPlusNameComparator(FilePropertyKey.COMPANY, true); case DATE_CREATED: return new SimilarResultsGroupingDelegateComparator(getDateComparator(FilePropertyKey.DATE_CREATED, false), getNameComparator(true)); case FILE_EXTENSION: case TYPE: return new SimilarResultsGroupingComparator() { private Comparator<VisualSearchResult> nameComparator = getNameComparator(true); @Override public int doCompare(VisualSearchResult vsr1, VisualSearchResult vsr2) { int compare = compareToNull(vsr1.getFileExtension(), vsr2.getFileExtension()); if (compare == 0) { compare = nameComparator.compare(vsr1, vsr2); } return compare; } }; case CATEGORY: return new SimilarResultsGroupingComparator() { private Comparator<VisualSearchResult> nameComparator = getNameComparator(true); @Override public int doCompare(VisualSearchResult vsr1, VisualSearchResult vsr2) { int compare = compareToNull(vsr1.getCategory(), vsr2.getCategory()); if (compare == 0) { compare = nameComparator.compare(vsr1, vsr2); } return compare; } }; case LENGTH: return new SimilarResultsGroupingDelegateComparator(getLongComparator(FilePropertyKey.LENGTH, false), getNameComparator(true)); case NAME: case TITLE: return new SimilarResultsGroupingDelegateComparator(getNameComparator(true)); case PLATFORM: return getStringPropertyPlusNameComparator(FilePropertyKey.COMPANY, true); case QUALITY: return new SimilarResultsGroupingDelegateComparator(getLongComparator(FilePropertyKey.QUALITY, false), getNameComparator(true)); case RELEVANCE_ITEM: return getRelevanceComparator(); case SIZE_HIGH_TO_LOW: return new SimilarResultsGroupingComparator() { private Comparator<VisualSearchResult> nameComparator = getNameComparator(true); @Override public int doCompare(VisualSearchResult vsr1, VisualSearchResult vsr2) { int compare = compareToNull(vsr2.getSize(), vsr1.getSize(), false); if (compare == 0) { compare = nameComparator.compare(vsr1, vsr2); } return compare; } }; case SIZE_LOW_TO_HIGH: return new SimilarResultsGroupingComparator() { private Comparator<VisualSearchResult> nameComparator = getNameComparator(true); @Override public int doCompare(VisualSearchResult vsr1, VisualSearchResult vsr2) { int compare = compareToNull(vsr1.getSize(), vsr2.getSize(), false); if (compare == 0) { compare = nameComparator.compare(vsr1, vsr2); } return compare; } }; case YEAR: return new SimilarResultsGroupingComparator() { private Comparator<VisualSearchResult> nameComparator = getNameComparator(true); private Comparator<VisualSearchResult> propertyComparator = getLongComparator( FilePropertyKey.YEAR, true); @Override public int doCompare(VisualSearchResult vsr1, VisualSearchResult vsr2) { int compare = propertyComparator.compare(vsr1, vsr2); if (compare == 0) { compare = nameComparator.compare(vsr1, vsr2); } return compare; } }; default: throw new IllegalArgumentException("unknown item " + sortOption); } } /** * Returns a search result Comparator for date values. The specified key * must reference property values stored as Long objects. */ static Comparator<VisualSearchResult> getDateComparator( final FilePropertyKey key, final boolean ascending) { return new Comparator<VisualSearchResult>() { @Override public int compare(VisualSearchResult vsr1, VisualSearchResult vsr2) { Long v1 = (Long) vsr1.getProperty(key); Long v2 = (Long) vsr2.getProperty(key); return compareNullCheck(v1, v2, ascending, true); } }; } /** * Returns a search result Comparator for Long values. The specified key * must reference property values that can be converted to Long objects. */ static Comparator<VisualSearchResult> getLongComparator( final FilePropertyKey key, final boolean ascending) { return new Comparator<VisualSearchResult>() { @Override public int compare(VisualSearchResult vsr1, VisualSearchResult vsr2) { Long l1 = (Long)vsr1.getProperty(key); Long l2 = (Long)vsr2.getProperty(key); return compareNullCheck(l1, l2, ascending, true); } }; } /** * Returns a search result Comparator that compares the heading field. */ static Comparator<VisualSearchResult> getNameComparator( final boolean ascending) { return new Comparator<VisualSearchResult>() { @Override public int compare(VisualSearchResult vsr1, VisualSearchResult vsr2) { String v1 = vsr1.getHeading(); String v2 = vsr2.getHeading(); return ascending ? compareToNullIgnoreCase(v1, v2, false) : compareToNullIgnoreCase(v2, v1, false); } }; } /** * Returns a search result Comparator that compares the relevance and name * values. */ @SuppressWarnings("unchecked") static Comparator<VisualSearchResult> getRelevanceComparator() { return new SimilarResultsGroupingDelegateComparator( getRelevanceComparator(false), getNameComparator(true)); } /** * Returns a search result Comparator for relevance values with the * specified sort order. */ static Comparator<VisualSearchResult> getRelevanceComparator( final boolean ascending) { return new Comparator<VisualSearchResult>() { @Override public int compare(VisualSearchResult vsr1, VisualSearchResult vsr2) { int r1 = vsr1.getRelevance(); int r2 = vsr2.getRelevance(); return ascending ? compareToNull(r1, r2, false) : compareToNull(r2, r1, false); } }; } /** * Returns a search result Comparator for string values. The specified key * must reference property values stored as String objects. */ static Comparator<VisualSearchResult> getStringComparator( final FilePropertyKey key, final boolean ascending) { return new Comparator<VisualSearchResult>() { @Override public int compare(VisualSearchResult vsr1, VisualSearchResult vsr2) { String v1 = (String) vsr1.getProperty(key); String v2 = (String) vsr2.getProperty(key); return ascending ? compareToNullIgnoreCase(v1, v2, false) : compareToNullIgnoreCase(v2, v1, false); } }; } /** * Returns a search result Comparator that compares the specified string * property and name values. */ @SuppressWarnings("unchecked") static Comparator<VisualSearchResult> getStringPropertyPlusNameComparator( final FilePropertyKey filePropertyKey, final boolean ascending) { return new SimilarResultsGroupingDelegateComparator( getStringComparator(filePropertyKey, ascending), getNameComparator(ascending)); } /** * Compare the two specified Comparable objects, and returns a negative, * zero, or positive value if the first object is less than, equal to, or * greater than the second. If <code>ascending</code> is false, then the * sign of the return value is reversed. If <code>nullsFirst</code> is * false, then null values are treated as larger than non-null values. */ private static int compareNullCheck(Comparable c1, Comparable c2, boolean ascending, boolean nullsFirst) { return ascending ? compareToNull(c1, c2, nullsFirst) : compareToNull(c2, c1, nullsFirst); } }