package hirondelle.stocks.table;
import java.util.Comparator;
import hirondelle.stocks.quotes.Quote;
public final class QuoteSorterFactory {
public static Comparator<Quote> getSorter(QuoteField aField) {
Comparator<Quote> result = null;
if ( aField == QuoteField.Stock ) {
result = STOCK_SORTER;
}
else if ( aField == QuoteField.Price ) {
result = PRICE_SORTER;
}
else if ( aField == QuoteField.Change) {
result = CHANGE_SORTER;
}
else if ( aField == QuoteField.Profit ) {
result = PROFIT_SORTER;
}
else if ( aField == QuoteField.PercentChange ) {
result = PERCENT_CHANGE_SORTER;
}
else if ( aField == QuoteField.PercentProfit ) {
result = PERCENT_PROFIT_SORTER;
}
else {
throw new AssertionError("Unknown quote field: " + aField);
}
return result;
}
private QuoteSorterFactory(){
throw new AssertionError();
}
private static final Comparator<Quote> STOCK_SORTER = new StockSorter();
private static final Comparator<Quote> PRICE_SORTER = new PriceSorter();
private static final Comparator<Quote> CHANGE_SORTER = new ChangeSorter();
private static final Comparator<Quote> PROFIT_SORTER = new ProfitSorter();
private static final Comparator<Quote> PERCENT_CHANGE_SORTER =
new PercentChangeSorter()
;
private static final Comparator<Quote> PERCENT_PROFIT_SORTER =
new PercentProfitSorter()
;
private static final int BEFORE = -1;
private static final int EQUAL = 0;
private static final int AFTER = 1;
private static final int REVERSE = -1;
private static abstract class QuoteSorter implements Comparator<Quote> {
@Override public final int compare(Quote aThis, Quote aThat){
if (aThis == aThat) return EQUAL;
int result = compareFields(aThis, aThat);
if (result == EQUAL) {
assert aThis.equals(aThat) : "compareTo inconsistent with equals.";
}
return result;
}
abstract int compareFields(Quote aThis, Quote aThat);
}
private static final class StockSorter extends QuoteSorter {
@Override public int compareFields(Quote aThis, Quote aThat){
int comparison = compareStock(aThis, aThat);
if ( comparison != EQUAL ) return comparison;
comparison = comparePrice(aThis, aThat);
if ( comparison != EQUAL ) return comparison;
return compareChange(aThis, aThat);
}
}
private static final class PriceSorter extends QuoteSorter {
@Override public int compareFields(Quote aThis, Quote aThat){
int comparison = comparePrice(aThis, aThat);
if ( comparison != EQUAL ) return comparison;
comparison = compareStock(aThis, aThat);
if ( comparison != EQUAL ) return comparison;
return compareChange(aThis, aThat);
}
}
private static final class ChangeSorter extends QuoteSorter {
@Override public int compareFields(Quote aThis, Quote aThat){
int comparison = compareChange(aThis, aThat);
if ( comparison != EQUAL ) return comparison;
comparison = compareStock(aThis, aThat);
if ( comparison != EQUAL ) return comparison;
return comparePrice(aThis, aThat);
}
}
private static int compareStock(Quote aThis, Quote aThat){
return aThis.getStock().compareTo(aThat.getStock());
}
private static int comparePrice(Quote aThis, Quote aThat){
return REVERSE * aThis.getPrice().compareTo(aThat.getPrice());
}
private static int compareChange(Quote aThis, Quote aThat){
return REVERSE * aThis.getChange().compareTo(aThat.getChange());
}
private static abstract class DerivedFieldSorter extends QuoteSorter {
@Override public final int compareFields(Quote aThis, Quote aThat){
int comparison = compareDerivedField(aThis, aThat);
if (comparison != EQUAL) return comparison;
return fStockSorter.compareFields(aThis, aThat);
}
abstract int compareDerivedField(Quote aThis, Quote aThat);
private QuoteSorter fStockSorter = new StockSorter();
}
private static final class ProfitSorter extends DerivedFieldSorter {
@Override public int compareDerivedField(Quote aThis, Quote aThat){
return REVERSE * aThis.getProfit().compareTo(aThat.getProfit());
}
}
private static final class PercentProfitSorter extends DerivedFieldSorter {
@Override public int compareDerivedField(Quote aThis, Quote aThat){
if (
aThis.getPercentProfit().compareTo(aThat.getPercentProfit()) <= 0
) return AFTER;
if (
aThis.getPercentProfit().compareTo(aThat.getPercentProfit()) > 0
) return BEFORE;
return EQUAL;
}
}
private static final class PercentChangeSorter extends DerivedFieldSorter {
@Override public int compareDerivedField(Quote aThis, Quote aThat){
if (
aThis.getPercentChange().compareTo(aThat.getPercentChange()) <= 0
) return AFTER;
if (
aThis.getPercentChange().compareTo(aThat.getPercentChange()) > 0
) return BEFORE;
return EQUAL;
}
}
}