From 91e4f5d2d64974d285f06f285229593a4812defd Mon Sep 17 00:00:00 2001 From: drdev Date: Sun, 6 Sep 2015 00:14:34 +0000 Subject: [PATCH] Flesh out predicate building for advanced search filters --- .../src/main/java/forge/card/ColorSet.java | 14 +- .../src/main/java/forge/card/MagicColor.java | 28 ++ .../src/main/java/forge/game/GameFormat.java | 17 +- .../forge/itemmanager/AdvancedSearch.java | 475 +++++++++++++++--- 4 files changed, 455 insertions(+), 79 deletions(-) diff --git a/forge-core/src/main/java/forge/card/ColorSet.java b/forge-core/src/main/java/forge/card/ColorSet.java index c4062e46b24..db4751e2122 100644 --- a/forge-core/src/main/java/forge/card/ColorSet.java +++ b/forge-core/src/main/java/forge/card/ColorSet.java @@ -18,11 +18,11 @@ package forge.card; import java.io.Serializable; -import java.util.Iterator; -import java.util.NoSuchElementException; +import java.util.*; import com.google.common.collect.UnmodifiableIterator; +import forge.card.MagicColor.Color; import forge.card.mana.ManaCost; import forge.util.BinaryUtil; @@ -302,6 +302,16 @@ public final class ColorSet implements Comparable, Iterable, Ser return fromMask(~this.myColor & ccOther.myColor); } + public Set toEnumSet() { + List list = new ArrayList(); + for (Color c : Color.values()) { + if (hasAnyColor(c.getColormask())) { + list.add(c); + } + } + return EnumSet.copyOf(list); + } + @Override public Iterator iterator() { return new ColorIterator(); diff --git a/forge-core/src/main/java/forge/card/MagicColor.java b/forge-core/src/main/java/forge/card/MagicColor.java index 09e7b293ac7..3e5aad9aebd 100644 --- a/forge-core/src/main/java/forge/card/MagicColor.java +++ b/forge-core/src/main/java/forge/card/MagicColor.java @@ -151,4 +151,32 @@ public final class MagicColor { private Constant() { } } + + public enum Color { + WHITE(Constant.WHITE, MagicColor.WHITE), + BLUE(Constant.BLUE, MagicColor.BLUE), + BLACK(Constant.BLACK, MagicColor.BLACK), + RED(Constant.RED, MagicColor.RED), + GREEN(Constant.GREEN, MagicColor.GREEN), + COLORLESS(Constant.COLORLESS, MagicColor.COLORLESS); + + private final String name; + private final byte colormask; + + private Color(String name0, byte colormask0) { + name = name0; + colormask = colormask0; + } + + public String getName() { + return name; + } + public byte getColormask() { + return colormask; + } + @Override + public String toString() { + return name; + } + } } diff --git a/forge-game/src/main/java/forge/game/GameFormat.java b/forge-game/src/main/java/forge/game/GameFormat.java index cc10683b959..25e32750414 100644 --- a/forge-game/src/main/java/forge/game/GameFormat.java +++ b/forge-game/src/main/java/forge/game/GameFormat.java @@ -21,6 +21,7 @@ import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Lists; + import forge.StaticData; import forge.card.CardEdition; import forge.deck.CardPool; @@ -35,8 +36,10 @@ import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map.Entry; +import java.util.Set; /** @@ -293,8 +296,18 @@ public class GameFormat implements Comparable { } return NoFormat; } - - public Iterable getAllFormatsOfDeck(Deck deck) { + + public Set getAllFormatsOfCard(PaperCard card) { + Set result = new HashSet(); + for (GameFormat gf : naturallyOrdered) { + if (gf.getFilterRules().apply(card)) { + result.add(gf); + } + } + return result; + } + + public List getAllFormatsOfDeck(Deck deck) { List result = new ArrayList(); CardPool allCards = deck.getAllCardsInASinglePool(); for(GameFormat gf : naturallyOrdered) { diff --git a/forge-gui/src/main/java/forge/itemmanager/AdvancedSearch.java b/forge-gui/src/main/java/forge/itemmanager/AdvancedSearch.java index 45c445b1777..7eb2721462d 100644 --- a/forge-gui/src/main/java/forge/itemmanager/AdvancedSearch.java +++ b/forge-gui/src/main/java/forge/itemmanager/AdvancedSearch.java @@ -3,14 +3,20 @@ package forge.itemmanager; import java.util.Arrays; import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; import java.util.List; +import java.util.Set; + import com.google.common.base.Function; import com.google.common.base.Predicate; import forge.card.CardEdition; import forge.card.CardRarity; +import forge.card.CardRules; import forge.card.CardType; import forge.card.MagicColor; +import forge.card.CardType.CoreType; +import forge.card.CardType.Supertype; import forge.game.GameFormat; import forge.item.InventoryItem; import forge.item.PaperCard; @@ -20,30 +26,137 @@ import forge.util.gui.SOptionPane; public class AdvancedSearch { private enum FilterOption { - CARD_NAME("Name", PaperCard.class, FilterOperator.STRING_OPS, new StringValueSelector()), - CARD_RULES_TEXT("Rules Text", PaperCard.class, FilterOperator.STRING_OPS, new StringValueSelector()), - CARD_SET("Set", PaperCard.class, FilterOperator.SINGLE_LIST_OPS, new CustomListValueSelector(FModel.getMagicDb().getSortedEditions(), CardEdition.FN_GET_CODE)), - CARD_FORMAT("Format", PaperCard.class, FilterOperator.SINGLE_LIST_OPS, new CustomListValueSelector((List)FModel.getFormats().getOrderedList())), - CARD_COLOR("Color", PaperCard.class, FilterOperator.MULTI_LIST_OPS, new CustomListValueSelector(MagicColor.Constant.COLORS_AND_COLORLESS)), - CARD_TYPE("Type", PaperCard.class, FilterOperator.MULTI_LIST_OPS, new CustomListValueSelector(CardType.getSortedCoreAndSuperTypes())), - CARD_SUB_TYPE("Subtype", PaperCard.class, FilterOperator.MULTI_LIST_OPS, new CustomListValueSelector(CardType.getSortedSubTypes())), - CARD_CMC("CMC", PaperCard.class, FilterOperator.NUMBER_OPS, new NumericValueSelector(0, 20)), - CARD_GENERIC_COST("Generic Cost", PaperCard.class, FilterOperator.NUMBER_OPS, new NumericValueSelector(0, 20)), - CARD_POWER("Power", PaperCard.class, FilterOperator.NUMBER_OPS, new NumericValueSelector(0, 20)), - CARD_TOUGHNESS("Toughness", PaperCard.class, FilterOperator.NUMBER_OPS, new NumericValueSelector(0, 20)), - CARD_MANA_COST("Mana Cost", PaperCard.class, FilterOperator.STRING_OPS, new StringValueSelector()), - CARD_RARITY("Rarity", PaperCard.class, FilterOperator.SINGLE_LIST_OPS, new CustomListValueSelector(Arrays.asList(CardRarity.values()))); + CARD_NAME("Name", PaperCard.class, FilterOperator.STRING_OPS, new StringEvaluator() { + @Override + protected String getItemValue(PaperCard input) { + return input.getName(); + } + }), + CARD_RULES_TEXT("Rules Text", PaperCard.class, FilterOperator.STRING_OPS, new StringEvaluator() { + @Override + protected String getItemValue(PaperCard input) { + return input.getRules().getOracleText(); + } + }), + CARD_SET("Set", PaperCard.class, FilterOperator.SINGLE_LIST_OPS, new CustomListEvaluator(FModel.getMagicDb().getSortedEditions(), CardEdition.FN_GET_CODE) { + @Override + protected CardEdition getItemValue(PaperCard input) { + return FModel.getMagicDb().getEditions().get(input.getEdition()); + } + }), + CARD_FORMAT("Format", PaperCard.class, FilterOperator.SINGLE_LIST_OPS, new CustomListEvaluator((List)FModel.getFormats().getOrderedList()) { + @Override + protected GameFormat getItemValue(PaperCard input) { + throw new RuntimeException("getItemValues should be called instead"); + } + @Override + protected Set getItemValues(PaperCard input) { + return FModel.getFormats().getAllFormatsOfCard(input); + } + }), + CARD_COLOR("Color", PaperCard.class, FilterOperator.MULTI_LIST_OPS, new CustomListEvaluator(Arrays.asList(MagicColor.Color.values())) { + @Override + protected MagicColor.Color getItemValue(PaperCard input) { + throw new RuntimeException("getItemValues should be called instead"); + } + @Override + protected Set getItemValues(PaperCard input) { + return input.getRules().getColor().toEnumSet(); + } + }), + CARD_COLOR_IDENTITY("Color Identity", PaperCard.class, FilterOperator.MULTI_LIST_OPS, new CustomListEvaluator(Arrays.asList(MagicColor.Color.values())) { + @Override + protected MagicColor.Color getItemValue(PaperCard input) { + throw new RuntimeException("getItemValues should be called instead"); + } + @Override + protected Set getItemValues(PaperCard input) { + return input.getRules().getColorIdentity().toEnumSet(); + } + }), + CARD_TYPE("Type", PaperCard.class, FilterOperator.MULTI_LIST_OPS, new CustomListEvaluator(CardType.getSortedCoreAndSuperTypes()) { + @Override + protected String getItemValue(PaperCard input) { + throw new RuntimeException("getItemValues should be called instead"); + } + @Override + protected Set getItemValues(PaperCard input) { + final CardType type = input.getRules().getType(); + final Set types = new HashSet(); + for (Supertype t : type.getSupertypes()) { + types.add(t.name()); + } + for (CoreType t : type.getCoreTypes()) { + types.add(t.name()); + } + return types; + } + }), + CARD_SUB_TYPE("Subtype", PaperCard.class, FilterOperator.MULTI_LIST_OPS, new CustomListEvaluator(CardType.getSortedSubTypes()) { + @Override + protected String getItemValue(PaperCard input) { + throw new RuntimeException("getItemValues should be called instead"); + } + @Override + protected Set getItemValues(PaperCard input) { + return (Set)input.getRules().getType().getSubtypes(); + } + }), + CARD_CMC("CMC", PaperCard.class, FilterOperator.NUMBER_OPS, new NumericEvaluator(0, 20) { + @Override + protected Integer getItemValue(PaperCard input) { + return input.getRules().getManaCost().getCMC(); + } + }), + CARD_GENERIC_COST("Generic Cost", PaperCard.class, FilterOperator.NUMBER_OPS, new NumericEvaluator(0, 20) { + @Override + protected Integer getItemValue(PaperCard input) { + return input.getRules().getManaCost().getGenericCost(); + } + }), + CARD_POWER("Power", PaperCard.class, FilterOperator.NUMBER_OPS, new NumericEvaluator(0, 20) { + @Override + protected Integer getItemValue(PaperCard input) { + CardRules rules = input.getRules(); + if (rules.getType().isCreature()) { + return rules.getIntPower(); + } + return null; + } + }), + CARD_TOUGHNESS("Toughness", PaperCard.class, FilterOperator.NUMBER_OPS, new NumericEvaluator(0, 20) { + @Override + protected Integer getItemValue(PaperCard input) { + CardRules rules = input.getRules(); + if (rules.getType().isCreature()) { + return rules.getIntToughness(); + } + return null; + } + }), + CARD_MANA_COST("Mana Cost", PaperCard.class, FilterOperator.STRING_OPS, new StringEvaluator() { + @Override + protected String getItemValue(PaperCard input) { + return input.getRules().getManaCost().toString(); + } + }), + CARD_RARITY("Rarity", PaperCard.class, FilterOperator.SINGLE_LIST_OPS, new CustomListEvaluator(Arrays.asList(CardRarity.values())) { + @Override + protected CardRarity getItemValue(PaperCard input) { + return input.getRarity(); + } + }); private final String name; private final Class type; private final FilterOperator[] operatorOptions; - private final FilterValueSelector valueSelector; + private final FilterEvaluator evaluator; - private FilterOption(String name0, Class type0, FilterOperator[] operatorOptions0, FilterValueSelector valueSelector0) { + private FilterOption(String name0, Class type0, FilterOperator[] operatorOptions0, FilterEvaluator evaluator0) { name = name0; type = type0; operatorOptions = operatorOptions0; - valueSelector = valueSelector0; + evaluator = evaluator0; } @Override @@ -54,29 +167,189 @@ public class AdvancedSearch { private enum FilterOperator { //Numeric operators - EQUALS("is equal to", "%1$s=%2$d", FilterValueCount.ONE), - NOT_EQUALS("is not equal to", "%1$s<>%2$d", FilterValueCount.ONE), - GREATER_THAN("is greater than", "%1$s>%2$d", FilterValueCount.ONE), - LESS_THAN("is less than", "%1$s<%2$d", FilterValueCount.ONE), - GT_OR_EQUAL("is greater than or equal to", "%1$s>=%2$d", FilterValueCount.ONE), - LT_OR_EQUAL("is less than or equal to", "%1$s<=%2$d", FilterValueCount.ONE), - BETWEEN_INCLUSIVE("is between (inclusive)", "%2$d<=%1$s<=%3$d", FilterValueCount.TWO), - BETWEEN_EXCLUSIVE("is between (exclusive)", "%2$d<%1$s<%3$d", FilterValueCount.TWO), + EQUALS("is equal to", "%1$s=%2$d", FilterValueCount.ONE, new OperatorEvaluator() { + @Override + public boolean apply(Integer input, List values) { + if (input != null) { + return input.intValue() == values.get(0).intValue(); + } + return false; + } + }), + NOT_EQUALS("is not equal to", "%1$s<>%2$d", FilterValueCount.ONE, new OperatorEvaluator() { + @Override + public boolean apply(Integer input, List values) { + if (input != null) { + return input.intValue() != values.get(0).intValue(); + } + return true; + } + }), + GREATER_THAN("is greater than", "%1$s>%2$d", FilterValueCount.ONE, new OperatorEvaluator() { + @Override + public boolean apply(Integer input, List values) { + if (input != null) { + return input.intValue() > values.get(0).intValue(); + } + return false; + } + }), + LESS_THAN("is less than", "%1$s<%2$d", FilterValueCount.ONE, new OperatorEvaluator() { + @Override + public boolean apply(Integer input, List values) { + if (input != null) { + return input.intValue() < values.get(0).intValue(); + } + return false; + } + }), + GT_OR_EQUAL("is greater than or equal to", "%1$s>=%2$d", FilterValueCount.ONE, new OperatorEvaluator() { + @Override + public boolean apply(Integer input, List values) { + if (input != null) { + return input.intValue() >= values.get(0).intValue(); + } + return false; + } + }), + LT_OR_EQUAL("is less than or equal to", "%1$s<=%2$d", FilterValueCount.ONE, new OperatorEvaluator() { + @Override + public boolean apply(Integer input, List values) { + if (input != null) { + return input.intValue() <= values.get(0).intValue(); + } + return false; + } + }), + BETWEEN_INCLUSIVE("is between (inclusive)", "%2$d<=%1$s<=%3$d", FilterValueCount.TWO, new OperatorEvaluator() { + @Override + public boolean apply(Integer input, List values) { + if (input != null) { + int inputValue = input.intValue(); + return values.get(0).intValue() <= inputValue && inputValue <= values.get(1).intValue(); + } + return false; + } + }), + BETWEEN_EXCLUSIVE("is between (exclusive)", "%2$d<%1$s<%3$d", FilterValueCount.TWO, new OperatorEvaluator() { + @Override + public boolean apply(Integer input, List values) { + if (input != null) { + int inputValue = input.intValue(); + return values.get(0).intValue() < inputValue && inputValue < values.get(1).intValue(); + } + return false; + } + }), //String operators - IS("is", "%1$s is '%2$s'", FilterValueCount.ONE), - IS_NOT("is not", "%1$s is not '%2$s'", FilterValueCount.ONE), - CONTAINS("contains", "%1$s contains '%2$s'", FilterValueCount.ONE), - STARTS_WITH("starts with", "%1$s starts with '%2$s'", FilterValueCount.ONE), - ENDS_WITH("ends with", "%1$s ends with '%2$s'", FilterValueCount.ONE), + IS("is", "%1$s is '%2$s'", FilterValueCount.ONE, new OperatorEvaluator() { + @Override + public boolean apply(String input, List values) { + if (input != null) { + return input.toLowerCase().equals(values.get(0).toLowerCase()); + } + return false; + } + }), + IS_NOT("is not", "%1$s is not '%2$s'", FilterValueCount.ONE, new OperatorEvaluator() { + @Override + public boolean apply(String input, List values) { + if (input != null) { + return !input.toLowerCase().equals(values.get(0).toLowerCase()); + } + return true; + } + }), + CONTAINS("contains", "%1$s contains '%2$s'", FilterValueCount.ONE, new OperatorEvaluator() { + @Override + public boolean apply(String input, List values) { + if (input != null) { + return input.toLowerCase().indexOf(values.get(0).toLowerCase()) != -1; + } + return false; + } + }), + STARTS_WITH("starts with", "%1$s starts with '%2$s'", FilterValueCount.ONE, new OperatorEvaluator() { + @Override + public boolean apply(String input, List values) { + if (input != null) { + return input.toLowerCase().startsWith(values.get(0).toLowerCase()); + } + return false; + } + }), + ENDS_WITH("ends with", "%1$s ends with '%2$s'", FilterValueCount.ONE, new OperatorEvaluator() { + @Override + public boolean apply(String input, List values) { + if (input != null) { + return input.toLowerCase().endsWith(values.get(0).toLowerCase()); + } + return false; + } + }), //Custom list operators - IS_EXACTLY("is exactly", "%1$s is %2$s", FilterValueCount.MANY), - IS_ANY("is any of", "%1$s is %2$s", FilterValueCount.MANY_OR), - IS_ALL("is all of", "%1$s is %2$s", FilterValueCount.MANY_AND), - IS_NONE("is none of", "%1$s is not %2$s", FilterValueCount.MANY_OR), - INCLUDES_ANY("includes any of", "%1$s includes %2$s", FilterValueCount.MANY_OR), - INCLUDES_ALL("includes all of", "%1$s includes %2$s", FilterValueCount.MANY_AND); + IS_EXACTLY("is exactly", "%1$s is %2$s", FilterValueCount.MANY, new OperatorEvaluator() { + @Override + public boolean apply(Object input, List values) { + return false; + } + @Override + public boolean apply(Set inputs, List values) { + return false; + } + }), + IS_ANY("is any of", "%1$s is %2$s", FilterValueCount.MANY_OR, new OperatorEvaluator() { + @Override + public boolean apply(Object input, List values) { + return false; + } + @Override + public boolean apply(Set inputs, List values) { + return false; + } + }), + IS_ALL("is all of", "%1$s is %2$s", FilterValueCount.MANY_AND, new OperatorEvaluator() { + @Override + public boolean apply(Object input, List values) { + return false; + } + @Override + public boolean apply(Set inputs, List values) { + return false; + } + }), + IS_NONE("is none of", "%1$s is not %2$s", FilterValueCount.MANY_OR, new OperatorEvaluator() { + @Override + public boolean apply(Object input, List values) { + return false; + } + @Override + public boolean apply(Set inputs, List values) { + return false; + } + }), + INCLUDES_ANY("includes any of", "%1$s includes %2$s", FilterValueCount.MANY_OR, new OperatorEvaluator() { + @Override + public boolean apply(Object input, List values) { + return false; + } + @Override + public boolean apply(Set inputs, List values) { + return false; + } + }), + INCLUDES_ALL("includes all of", "%1$s includes %2$s", FilterValueCount.MANY_AND, new OperatorEvaluator() { + @Override + public boolean apply(Object input, List values) { + return false; + } + @Override + public boolean apply(Set inputs, List values) { + return false; + } + }); public static final FilterOperator[] NUMBER_OPS = new FilterOperator[] { EQUALS, NOT_EQUALS, GREATER_THAN, LESS_THAN, GT_OR_EQUAL, LT_OR_EQUAL, BETWEEN_INCLUSIVE, BETWEEN_EXCLUSIVE @@ -93,11 +366,13 @@ public class AdvancedSearch { private final String caption, formatStr; private final FilterValueCount valueCount; + private final OperatorEvaluator evaluator; - private FilterOperator(String caption0, String formatStr0, FilterValueCount valueCount0) { + private FilterOperator(String caption0, String formatStr0, FilterValueCount valueCount0, OperatorEvaluator evaluator0) { caption = caption0; formatStr = formatStr0; valueCount = valueCount0; + evaluator = evaluator0; } @Override @@ -114,20 +389,62 @@ public class AdvancedSearch { MANY_AND } - private static abstract class FilterValueSelector { - public abstract Filter createFilter(String message, FilterOption option, FilterOperator operator); + private static abstract class OperatorEvaluator { + protected abstract boolean apply(V input, List values); + + protected boolean apply(Set inputs, List values) { + return false; //available for options that have multiple inputs + } } - private static class NumericValueSelector extends FilterValueSelector { + private static abstract class FilterEvaluator { + @SuppressWarnings("unchecked") + public final Filter createFilter(String message, FilterOption option, FilterOperator operator) { + final List values = getValues(message, option, operator); + if (values == null || values.isEmpty()) { return null; } + + String caption = getCaption(values, option, operator); + + final OperatorEvaluator evaluator = (OperatorEvaluator)operator.evaluator; + Predicate predicate; + if (option.operatorOptions == FilterOperator.MULTI_LIST_OPS) { + predicate = new Predicate() { + @Override + public boolean apply(T input) { + return evaluator.apply(getItemValues(input), values); + } + }; + } + else { + predicate = new Predicate() { + @Override + public boolean apply(T input) { + return evaluator.apply(getItemValue(input), values); + } + }; + } + return new Filter(option, operator, caption, predicate); + } + + protected abstract List getValues(String message, FilterOption option, FilterOperator operator); + protected abstract String getCaption(List values, FilterOption option, FilterOperator operator); + protected abstract V getItemValue(T input); + + protected Set getItemValues(T input) { //available for options that have multiple inputs + return null; + } + } + + private static abstract class NumericEvaluator extends FilterEvaluator { private final int min, max; - public NumericValueSelector(int min0, int max0) { + public NumericEvaluator(int min0, int max0) { min = min0; max = max0; } @Override - public Filter createFilter(String message, FilterOption option, FilterOperator operator) { + protected List getValues(String message, FilterOption option, FilterOperator operator) { String msg = message; if (operator.valueCount == FilterValueCount.TWO) { msg += " (Lower Bound)"; @@ -135,64 +452,75 @@ public class AdvancedSearch { Integer lowerBound = SGuiChoose.getInteger(msg, min, max); if (lowerBound == null) { return null; } - final String caption; + final List values = new ArrayList(); + values.add(lowerBound); + if (operator.valueCount == FilterValueCount.TWO) { //prompt for upper bound if needed msg = message + " (Upper Bound)"; Integer upperBound = SGuiChoose.getInteger(msg, lowerBound, max); if (upperBound == null) { return null; } - caption = String.format(operator.formatStr, option.name, lowerBound, upperBound); + values.add(upperBound); } - else { - caption = String.format(operator.formatStr, option.name, lowerBound); - } - - return new Filter(option, operator, caption, null); - } - } - - private static class StringValueSelector extends FilterValueSelector { - public StringValueSelector() { + return values; } @Override - public Filter createFilter(String message, FilterOption option, FilterOperator operator) { - String value = SOptionPane.showInputDialog("", message); - if (value == null) { return null; } - - final String caption = String.format(operator.formatStr, option.name, value); - - return new Filter(option, operator, caption, null); + protected String getCaption(List values, FilterOption option, FilterOperator operator) { + if (operator.valueCount == FilterValueCount.TWO) { + return String.format(operator.formatStr, option.name, values.get(0), values.get(1)); + } + return String.format(operator.formatStr, option.name, values.get(0)); } } - private static class CustomListValueSelector extends FilterValueSelector { + private static abstract class StringEvaluator extends FilterEvaluator { + public StringEvaluator() { + } + + @Override + protected List getValues(String message, FilterOption option, FilterOperator operator) { + String value = SOptionPane.showInputDialog("", message); + if (value == null) { return null; } + + List values = new ArrayList(); + values.add(value); + return values; + } + + @Override + protected String getCaption(List values, FilterOption option, FilterOperator operator) { + return String.format(operator.formatStr, option.name, values.get(0)); + } + } + + private static abstract class CustomListEvaluator extends FilterEvaluator { private final Collection choices; private final Function toShortString, toLongString; - public CustomListValueSelector(Collection choices0) { + public CustomListEvaluator(Collection choices0) { this(choices0, null, null); } - public CustomListValueSelector(Collection choices0, Function toShortString0) { + public CustomListEvaluator(Collection choices0, Function toShortString0) { this(choices0, toShortString0, null); } - public CustomListValueSelector(Collection choices0, Function toShortString0, Function toLongString0) { + public CustomListEvaluator(Collection choices0, Function toShortString0, Function toLongString0) { choices = choices0; toShortString = toShortString0; toLongString = toLongString0; } @Override - public Filter createFilter(String message, FilterOption option, FilterOperator operator) { + protected List getValues(String message, FilterOption option, FilterOperator operator) { int max = choices.size(); if (operator == FilterOperator.IS_EXACTLY && option.operatorOptions == FilterOperator.SINGLE_LIST_OPS) { max = 1; } - List values = SGuiChoose.getChoices(message, 0, max, choices); - if (values == null || values.isEmpty()) { - return null; - } + return SGuiChoose.getChoices(message, 0, max, choices, null, toLongString); + } + @Override + protected String getCaption(List values, FilterOption option, FilterOperator operator) { String valuesStr; switch (operator.valueCount) { case MANY: @@ -206,11 +534,7 @@ public class AdvancedSearch { valuesStr = formatValues(values, ", ", " and "); break; } - - - final String caption = String.format(operator.formatStr, option.name, valuesStr); - - return new Filter(option, operator, caption, null); + return String.format(operator.formatStr, option.name, valuesStr); } private String formatValues(List values, String delim, String finalDelim) { @@ -239,6 +563,7 @@ public class AdvancedSearch { } } + @SuppressWarnings("unchecked") public static Filter getFilter(Class type, Filter editFilter) { //build list of filter options based on ItemManager type List options = new ArrayList(); @@ -257,7 +582,7 @@ public class AdvancedSearch { if (operator == null) { return null; } final String message = option.name + " " + operator.caption + " ?"; - return option.valueSelector.createFilter(message, option, operator); + return (Filter)option.evaluator.createFilter(message, option, operator); } public static class Filter {