2 package net.sf.jabref.search;
4 import java.util.regex.*;
5 import net.sf.jabref.*;
8 class SearchExpressionTreeParser extends TreeParser;
11 importVocab = SearchExpressionParser;
12 exportVocab = SearchExpressionTreeParser;
16 private static final int MATCH_EXACT = 0;
17 private static final int MATCH_CONTAINS = 1;
18 private static final int MATCH_DOES_NOT_CONTAIN = 2;
20 private BibtexEntry bibtexEntry;
21 private Object[] searchKeys;
23 private static final int PSEUDOFIELD_TYPE = 1;
25 public int apply(AST ast, BibtexEntry bibtexEntry) throws antlr.RecognitionException {
26 this.bibtexEntry = bibtexEntry;
27 // specification of fields to search is done in the search expression itself
28 this.searchKeys = bibtexEntry.getAllFields();
29 return tSearchExpression(ast) ? 1 : 0;
35 // ---------- Condition and Expressions ----------
37 tSearchExpression returns [boolean ret = false;] throws PatternSyntaxException
39 boolean a = false, b = false;
41 : // predicates for and/or used to evaluate 2nd expression only if necessary
42 #( And a=tSearchExpression ( {a}? b=tSearchExpression | . ) ) { ret = a && b; }
44 #( Or a=tSearchExpression ( {!a}? b=tSearchExpression | . ) ) { ret = a || b; }
46 #( Not a=tSearchExpression ) { ret = !a; }
51 tSearchType returns [ int matchType = 0; ]
53 LITERAL_contains { matchType = MATCH_CONTAINS; }
55 LITERAL_matches { matchType = MATCH_EXACT; }
57 EQUAL { matchType = MATCH_CONTAINS; }
59 EEQUAL { matchType = MATCH_EXACT; }
61 NEQUAL { matchType = MATCH_DOES_NOT_CONTAIN; }
64 tExpressionSearch returns [ boolean ret = false; ] throws PatternSyntaxException
69 #( ExpressionSearch var_f:RegularExpression matchType=tSearchType var_v:RegularExpression
71 Pattern fieldSpec = ((RegExNode)var_f).getPattern();
72 Pattern valueSpec = ((RegExNode)var_v).getPattern();
74 boolean noSuchField = true;
75 // this loop iterates over all regular keys, then over pseudo keys like "type"
76 for (int i = 0; i < searchKeys.length + PSEUDOFIELD_TYPE && !ret; ++i) {
78 switch (i - searchKeys.length + 1) {
79 case PSEUDOFIELD_TYPE:
80 if (!fieldSpec.matcher("entrytype").matches())
82 content = bibtexEntry.getType().getName();
84 default: // regular field
85 if (!fieldSpec.matcher(searchKeys[i].toString()).matches())
87 content = (String)bibtexEntry.getField(searchKeys[i].toString());
92 Matcher matcher = valueSpec.matcher(content);
98 ret = matcher.matches();
100 case MATCH_DOES_NOT_CONTAIN:
101 ret = !matcher.find();
105 if (noSuchField && matchType == MATCH_DOES_NOT_CONTAIN)
106 ret = true; // special case