package jalview.datamodel.features; import jalview.datamodel.SequenceFeature; import jalview.util.MessageManager; import jalview.util.matcher.Condition; import jalview.util.matcher.Matcher; import jalview.util.matcher.MatcherI; /** * An immutable class that models one or more match conditions, each of which is * applied to the value obtained by lookup given the match key. *

* For example, the value provider could be a SequenceFeature's attributes map, * and the conditions might be *

* * @author gmcarstairs * */ public class FeatureMatcher implements FeatureMatcherI { /* * a dummy matcher that comes in useful for the 'add a filter' gui row */ public static final FeatureMatcherI NULL_MATCHER = FeatureMatcher .byLabel(Condition.values()[0], ""); private static final String COLON = ":"; /* * if true, match is against feature description */ final private boolean byLabel; /* * if true, match is against feature score */ final private boolean byScore; /* * if not null, match is against feature attribute [sub-attribute] */ final private String[] key; final private MatcherI matcher; /** * A factory constructor method for a matcher that applies its match condition * to the feature label (description) * * @param cond * @param pattern * @return */ public static FeatureMatcher byLabel(Condition cond, String pattern) { return new FeatureMatcher(new Matcher(cond, pattern), true, false, null); } /** * A factory constructor method for a matcher that applies its match condition * to the feature score * * @param cond * @param pattern * @return */ public static FeatureMatcher byScore(Condition cond, String pattern) { return new FeatureMatcher(new Matcher(cond, pattern), false, true, null); } /** * A factory constructor method for a matcher that applies its match condition * to the named feature attribute [and optional sub-attribute] * * @param cond * @param pattern * @param attName * @return */ public static FeatureMatcher byAttribute(Condition cond, String pattern, String... attName) { return new FeatureMatcher(new Matcher(cond, pattern), false, false, attName); } private FeatureMatcher(Matcher m, boolean forLabel, boolean forScore, String[] theKey) { key = theKey; matcher = m; byLabel = forLabel; byScore = forScore; } @Override public boolean matches(SequenceFeature feature) { String value = byLabel ? feature.getDescription() : (byScore ? String.valueOf(feature.getScore()) : feature.getValueAsString(key)); return matcher.matches(value); } @Override public String[] getAttribute() { return key; } @Override public MatcherI getMatcher() { return matcher; } /** * Answers a string description of this matcher, suitable for display, debugging * or logging. The format may change in future. */ @Override public String toString() { StringBuilder sb = new StringBuilder(); if (byLabel) { sb.append(MessageManager.getString("label.label")); } else if (byScore) { sb.append(MessageManager.getString("label.score")); } else { sb.append(String.join(COLON, key)); } Condition condition = matcher.getCondition(); sb.append(" ").append(condition.toString().toLowerCase()); if (condition.isNumeric()) { sb.append(" ").append(matcher.getPattern()); } else if (condition.needsAPattern()) { sb.append(" '").append(matcher.getPattern()).append("'"); } return sb.toString(); } @Override public boolean isByLabel() { return byLabel; } @Override public boolean isByScore() { return byScore; } }