1 package jalview.util.matcher;
3 import java.util.Objects;
4 import java.util.regex.Pattern;
7 * A bean to describe one attribute-based filter
9 public class Matcher implements MatcherI
12 * the comparison condition
17 * the string pattern as entered, or the regex, to compare to
18 * also holds the string form of float value if a numeric condition
23 * the pattern in upper case, for non-case-sensitive matching
25 String uppercasePattern;
28 * the compiled regex if using a pattern match condition
29 * (reserved for possible future enhancement)
34 * the value to compare to for a numerical condition
44 * @throws NumberFormatException
45 * if a numerical condition is specified with a non-numeric
47 * @throws NullPointerException
48 * if a null condition or comparison string is specified
50 public Matcher(Condition cond, String compareTo)
52 Objects.requireNonNull(cond);
56 value = Float.valueOf(compareTo);
57 pattern = String.valueOf(value);
58 uppercasePattern = pattern;
65 uppercasePattern = pattern.toUpperCase();
69 // if we add regex conditions (e.g. matchesPattern), then
70 // pattern should hold the raw regex, and
71 // regexPattern = Pattern.compile(compareTo);
75 * Constructor for a numerical match condition. Note that if a string
76 * comparison condition is specified, this will be converted to a comparison
77 * with the float value as string
82 public Matcher(Condition cond, float compareTo)
84 this(cond, String.valueOf(compareTo));
90 @SuppressWarnings("incomplete-switch")
92 public boolean matches(String val)
94 if (condition.isNumeric())
99 * treat a null value (no such attribute) as
100 * failing any numerical filter condition
102 return val == null ? false : matches(Float.valueOf(val));
103 } catch (NumberFormatException e)
110 * a null value matches a negative condition, fails a positive test
114 return condition == Condition.NotContains
115 || condition == Condition.NotMatches
116 || condition == Condition.NotPresent;
119 String upper = val.toUpperCase().trim();
120 boolean matched = false;
123 matched = upper.equals(uppercasePattern);
126 matched = !upper.equals(uppercasePattern);
129 matched = upper.indexOf(uppercasePattern) > -1;
132 matched = upper.indexOf(uppercasePattern) == -1;
144 * Applies a numerical comparison match condition
149 @SuppressWarnings("incomplete-switch")
150 boolean matches(float f)
152 if (!condition.isNumeric())
154 return matches(String.valueOf(f));
157 boolean matched = false;
163 matched = f <= value;
166 matched = f == value;
169 matched = f != value;
175 matched = f >= value;
185 * A simple hash function that guarantees that when two objects are equal,
186 * they have the same hashcode
189 public int hashCode()
191 return pattern.hashCode() + condition.hashCode() + (int) value;
195 * equals is overridden so that we can safely remove Matcher objects from
196 * collections (e.g. delete an attribute match condition for a feature colour)
199 public boolean equals(Object obj)
201 if (obj == null || !(obj instanceof Matcher))
205 Matcher m = (Matcher) obj;
206 if (condition != m.condition || value != m.value)
212 return m.pattern == null;
214 return uppercasePattern.equals(m.uppercasePattern);
218 public Condition getCondition()
224 public String getPattern()
230 public float getFloatValue()
236 public String toString()
238 StringBuilder sb = new StringBuilder();
239 sb.append(condition.toString()).append(" ");
240 if (condition.isNumeric())
246 sb.append("'").append(pattern).append("'");
249 return sb.toString();