KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > repo > search > impl > lucene > QueryParser


1 /* Generated By:JavaCC: Do not edit this line. QueryParser.java */
2 package org.alfresco.repo.search.impl.lucene;
3
4 import java.io.IOException JavaDoc;
5 import java.io.StringReader JavaDoc;
6 import java.text.DateFormat JavaDoc;
7 import java.util.Date JavaDoc;
8 import java.util.Locale JavaDoc;
9 import java.util.Vector JavaDoc;
10
11 import org.apache.lucene.analysis.Analyzer;
12 import org.apache.lucene.analysis.TokenStream;
13 import org.apache.lucene.document.DateField;
14 import org.apache.lucene.index.Term;
15 import org.apache.lucene.search.BooleanClause;
16 import org.apache.lucene.search.BooleanQuery;
17 import org.apache.lucene.search.FuzzyQuery;
18 import org.apache.lucene.search.PhraseQuery;
19 import org.apache.lucene.search.PrefixQuery;
20 import org.apache.lucene.search.Query;
21 import org.apache.lucene.search.RangeQuery;
22 import org.apache.lucene.search.TermQuery;
23 import org.apache.lucene.search.WildcardQuery;
24
25 /**
26  * This class is generated by JavaCC. The only method that clients should need
27  * to call is <a HREF="#parse">parse()</a>.
28  *
29  * The syntax for query strings is as follows:
30  * A Query is a series of clauses.
31  * A clause may be prefixed by:
32  * <ul>
33  * <li> a plus (<code>+</code>) or a minus (<code>-</code>) sign, indicating
34  * that the clause is required or prohibited respectively; or
35  * <li> a term followed by a colon, indicating the field to be searched.
36  * This enables one to construct queries which search multiple fields.
37  * </ul>
38  *
39  * A clause may be either:
40  * <ul>
41  * <li> a term, indicating all the documents that contain this term; or
42  * <li> a nested query, enclosed in parentheses. Note that this may be used
43  * with a <code>+</code>/<code>-</code> prefix to require any of a set of
44  * terms.
45  * </ul>
46  *
47  * Thus, in BNF, the query grammar is:
48  * <pre>
49  * Query ::= ( Clause )*
50  * Clause ::= ["+", "-"] [&lt;TERM&gt; ":"] ( &lt;TERM&gt; | "(" Query ")" )
51  * </pre>
52  *
53  * <p>
54  * Examples of appropriately formatted queries can be found in the <a
55  * HREF="http://jakarta.apache.org/lucene/src/test/org/apache/lucene/queryParser/TestQueryParser.java">test cases</a>.
56  * </p>
57  *
58  * @author Brian Goetz
59  * @author Peter Halacsy
60  * @author Tatu Saloranta
61  */

62
63 public class QueryParser implements QueryParserConstants {
64
65   private static final int CONJ_NONE = 0;
66   private static final int CONJ_AND = 1;
67   private static final int CONJ_OR = 2;
68
69   private static final int MOD_NONE = 0;
70   private static final int MOD_NOT = 10;
71   private static final int MOD_REQ = 11;
72
73   public static final int DEFAULT_OPERATOR_OR = 0;
74   public static final int DEFAULT_OPERATOR_AND = 1;
75
76   /** The actual operator that parser uses to combine query terms */
77   private int operator = DEFAULT_OPERATOR_OR;
78
79   /**
80    * Whether terms of wildcard and prefix queries are to be automatically
81    * lower-cased or not. Default is <code>true</code>.
82    */

83   boolean lowercaseWildcardTerms = true;
84
85   Analyzer analyzer;
86   String JavaDoc field;
87   int phraseSlop = 0;
88   float fuzzyMinSim = FuzzyQuery.defaultMinSimilarity;
89   Locale JavaDoc locale = Locale.getDefault();
90
91   /** Parses a query string, returning a {@link org.apache.lucene.search.Query}.
92    * @param query the query string to be parsed.
93    * @param field the default field for query terms.
94    * @param analyzer used to find terms in the query text.
95    * @throws ParseException if the parsing fails
96    */

97   static public Query parse(String JavaDoc query, String JavaDoc field, Analyzer analyzer)
98        throws ParseException {
99     QueryParser parser = new QueryParser(field, analyzer);
100     return parser.parse(query);
101   }
102
103   /** Constructs a query parser.
104    * @param f the default field for query terms.
105    * @param a used to find terms in the query text.
106    */

107   public QueryParser(String JavaDoc f, Analyzer a) {
108     this(new FastCharStream(new StringReader JavaDoc("")));
109     analyzer = a;
110     field = f;
111   }
112
113   /** Parses a query string, returning a
114    * <a HREF="lucene.search.Query.html">Query</a>.
115    * @param query the query string to be parsed.
116    * @throws ParseException if the parsing fails
117    */

118   public Query parse(String JavaDoc query) throws ParseException {
119     ReInit(new FastCharStream(new StringReader JavaDoc(query)));
120     try {
121       return Query(field);
122     }
123     catch (TokenMgrError tme) {
124       throw new ParseException(tme.getMessage());
125     }
126     catch (BooleanQuery.TooManyClauses tmc) {
127       throw new ParseException("Too many boolean clauses");
128     }
129   }
130
131    /**
132    * @return Returns the analyzer.
133    */

134   public Analyzer getAnalyzer() {
135     return analyzer;
136   }
137
138   /**
139    * @return Returns the field.
140    */

141   public String JavaDoc getField() {
142     return field;
143   }
144
145    /**
146    * Get the default minimal similarity for fuzzy queries.
147    */

148   public float getFuzzyMinSim() {
149       return fuzzyMinSim;
150   }
151   /**
152    *Set the default minimum similarity for fuzzy queries.
153    */

154   public void setFuzzyMinSim(float fuzzyMinSim) {
155       this.fuzzyMinSim = fuzzyMinSim;
156   }
157
158   /**
159    * Sets the default slop for phrases. If zero, then exact phrase matches
160    * are required. Default value is zero.
161    */

162   public void setPhraseSlop(int phraseSlop) {
163     this.phraseSlop = phraseSlop;
164   }
165
166   /**
167    * Gets the default slop for phrases.
168    */

169   public int getPhraseSlop() {
170     return phraseSlop;
171   }
172
173   /**
174    * Sets the boolean operator of the QueryParser.
175    * In classic mode (<code>DEFAULT_OPERATOR_OR</code>) terms without any modifiers
176    * are considered optional: for example <code>capital of Hungary</code> is equal to
177    * <code>capital OR of OR Hungary</code>.<br/>
178    * In <code>DEFAULT_OPERATOR_AND</code> terms are considered to be in conjuction: the
179    * above mentioned query is parsed as <code>capital AND of AND Hungary</code>
180    */

181   public void setOperator(int operator) {
182     this.operator = operator;
183   }
184
185   /**
186    * Gets implicit operator setting, which will be either DEFAULT_OPERATOR_AND
187    * or DEFAULT_OPERATOR_OR.
188    */

189   public int getOperator() {
190     return operator;
191   }
192
193   public void setLowercaseWildcardTerms(boolean lowercaseWildcardTerms) {
194     this.lowercaseWildcardTerms = lowercaseWildcardTerms;
195   }
196
197   public boolean getLowercaseWildcardTerms() {
198     return lowercaseWildcardTerms;
199   }
200
201   /**
202    * Set locale used by date range parsing.
203    */

204   public void setLocale(Locale JavaDoc locale) {
205     this.locale = locale;
206   }
207
208   /**
209    * Returns current locale, allowing access by subclasses.
210    */

211   public Locale JavaDoc getLocale() {
212     return locale;
213   }
214
215    protected void addClause(Vector JavaDoc clauses, int conj, int mods, Query q) {
216     boolean required, prohibited;
217
218     // If this term is introduced by AND, make the preceding term required,
219
// unless it's already prohibited
220
if (clauses.size() > 0 && conj == CONJ_AND) {
221       BooleanClause c = (BooleanClause) clauses.elementAt(clauses.size()-1);
222       if (!c.prohibited)
223         c.required = true;
224     }
225
226     if (clauses.size() > 0 && operator == DEFAULT_OPERATOR_AND && conj == CONJ_OR) {
227       // If this term is introduced by OR, make the preceding term optional,
228
// unless it's prohibited (that means we leave -a OR b but +a OR b-->a OR b)
229
// notice if the input is a OR b, first term is parsed as required; without
230
// this modification a OR b would parsed as +a OR b
231
BooleanClause c = (BooleanClause) clauses.elementAt(clauses.size()-1);
232       if (!c.prohibited)
233         c.required = false;
234     }
235
236     // We might have been passed a null query; the term might have been
237
// filtered away by the analyzer.
238
if (q == null)
239       return;
240
241     if (operator == DEFAULT_OPERATOR_OR) {
242       // We set REQUIRED if we're introduced by AND or +; PROHIBITED if
243
// introduced by NOT or -; make sure not to set both.
244
prohibited = (mods == MOD_NOT);
245       required = (mods == MOD_REQ);
246       if (conj == CONJ_AND && !prohibited) {
247         required = true;
248       }
249     } else {
250       // We set PROHIBITED if we're introduced by NOT or -; We set REQUIRED
251
// if not PROHIBITED and not introduced by OR
252
prohibited = (mods == MOD_NOT);
253       required = (!prohibited && conj != CONJ_OR);
254     }
255     clauses.addElement(new BooleanClause(q, required, prohibited));
256   }
257
258   /**
259    * Note that parameter analyzer is ignored. Calls inside the parser always
260    * use class member analyser. This method will be deprecated and substituted
261    * by {@link #getFieldQuery(String, String)} in future versions of Lucene.
262    * Currently overwriting either of these methods works.
263    *
264    * @exception ParseException throw in overridden method to disallow
265    */

266   protected Query getFieldQuery(String JavaDoc field,
267                                                     Analyzer analyzer,
268                                                     String JavaDoc queryText) throws ParseException {
269     return getFieldQuery(field, queryText);
270   }
271
272   /**
273    * @exception ParseException throw in overridden method to disallow
274    */

275   protected Query getFieldQuery(String JavaDoc field, String JavaDoc queryText) throws ParseException {
276     // Use the analyzer to get all the tokens, and then build a TermQuery,
277
// PhraseQuery, or nothing based on the term count
278

279     TokenStream source = analyzer.tokenStream(field,
280                                               new StringReader JavaDoc(queryText));
281     Vector JavaDoc v = new Vector JavaDoc();
282     org.apache.lucene.analysis.Token t;
283
284     while (true) {
285       try {
286         t = source.next();
287       }
288       catch (IOException JavaDoc e) {
289         t = null;
290       }
291       if (t == null)
292         break;
293       v.addElement(t.termText());
294     }
295     try {
296       source.close();
297     }
298     catch (IOException JavaDoc e) {
299       // ignore
300
}
301
302     if (v.size() == 0)
303       return null;
304     else if (v.size() == 1)
305       return new TermQuery(new Term(field, (String JavaDoc) v.elementAt(0)));
306     else {
307       PhraseQuery q = new PhraseQuery();
308       q.setSlop(phraseSlop);
309       for (int i=0; i<v.size(); i++) {
310         q.add(new Term(field, (String JavaDoc) v.elementAt(i)));
311       }
312       return q;
313     }
314   }
315
316   /**
317    * Base implementation delegates to {@link #getFieldQuery(String, Analyzer, String)}.
318    * This method may be overwritten, for example, to return
319    * a SpanNearQuery instead of a PhraseQuery.
320    *
321    * Note that parameter analyzer is ignored. Calls inside the parser always
322    * use class member analyser. This method will be deprecated and substituted
323    * by {@link #getFieldQuery(String, String, int)} in future versions of Lucene.
324    * Currently overwriting either of these methods works.
325    *
326    * @exception ParseException throw in overridden method to disallow
327    */

328   protected Query getFieldQuery(String JavaDoc field,
329                                                     Analyzer analyzer,
330                                                     String JavaDoc queryText,
331                                                     int slop) throws ParseException {
332     return getFieldQuery(field, queryText, slop);
333   }
334
335   /**
336    * Base implementation delegates to {@link #getFieldQuery(String,String)}.
337    * This method may be overridden, for example, to return
338    * a SpanNearQuery instead of a PhraseQuery.
339    *
340    * @exception ParseException throw in overridden method to disallow
341    */

342   protected Query getFieldQuery(String JavaDoc field, String JavaDoc queryText, int slop)
343         throws ParseException {
344     Query query = getFieldQuery(field, queryText);
345
346     if (query instanceof PhraseQuery) {
347       ((PhraseQuery) query).setSlop(slop);
348     }
349
350     return query;
351   }
352
353   /**
354    * Note that parameter analyzer is ignored. Calls inside the parser always
355    * use class member analyser. This method will be deprecated and substituted
356    * by {@link #getRangeQuery(String, String, String, boolean)} in future versions of Lucene.
357    * Currently overwriting either of these methods works.
358    *
359    * @exception ParseException throw in overridden method to disallow
360    */

361   protected Query getRangeQuery(String JavaDoc field,
362       Analyzer analyzer,
363       String JavaDoc part1,
364       String JavaDoc part2,
365       boolean inclusive) throws ParseException {
366     return getRangeQuery(field, part1, part2, inclusive);
367   }
368
369   /**
370    * @exception ParseException throw in overridden method to disallow
371    */

372   protected Query getRangeQuery(String JavaDoc field,
373                                 String JavaDoc part1,
374                                 String JavaDoc part2,
375                                 boolean inclusive) throws ParseException
376   {
377     try {
378       DateFormat JavaDoc df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
379       df.setLenient(true);
380       Date JavaDoc d1 = df.parse(part1);
381       Date JavaDoc d2 = df.parse(part2);
382       part1 = DateField.dateToString(d1);
383       part2 = DateField.dateToString(d2);
384     }
385     catch (Exception JavaDoc e) { }
386
387     return new RangeQuery(new Term(field, part1),
388                           new Term(field, part2),
389                           inclusive);
390   }
391
392   /**
393    * Factory method for generating query, given a set of clauses.
394    * By default creates a boolean query composed of clauses passed in.
395    *
396    * Can be overridden by extending classes, to modify query being
397    * returned.
398    *
399    * @param clauses Vector that contains {@link BooleanClause} instances
400    * to join.
401    *
402    * @return Resulting {@link Query} object.
403    * @exception ParseException throw in overridden method to disallow
404    */

405   protected Query getBooleanQuery(Vector JavaDoc clauses) throws ParseException
406   {
407     BooleanQuery query = new BooleanQuery();
408     for (int i = 0; i < clauses.size(); i++) {
409   query.add((BooleanClause)clauses.elementAt(i));
410     }
411     return query;
412   }
413
414   /**
415    * Factory method for generating a query. Called when parser
416    * parses an input term token that contains one or more wildcard
417    * characters (? and *), but is not a prefix term token (one
418    * that has just a single * character at the end)
419    *<p>
420    * Depending on settings, prefix term may be lower-cased
421    * automatically. It will not go through the default Analyzer,
422    * however, since normal Analyzers are unlikely to work properly
423    * with wildcard templates.
424    *<p>
425    * Can be overridden by extending classes, to provide custom handling for
426    * wildcard queries, which may be necessary due to missing analyzer calls.
427    *
428    * @param field Name of the field query will use.
429    * @param termStr Term token that contains one or more wild card
430    * characters (? or *), but is not simple prefix term
431    *
432    * @return Resulting {@link Query} built for the term
433    * @exception ParseException throw in overridden method to disallow
434    */

435   protected Query getWildcardQuery(String JavaDoc field, String JavaDoc termStr) throws ParseException
436   {
437     if (lowercaseWildcardTerms) {
438   termStr = termStr.toLowerCase();
439     }
440     Term t = new Term(field, termStr);
441     return new WildcardQuery(t);
442   }
443
444   /**
445    * Factory method for generating a query (similar to
446    * ({@link #getWildcardQuery}). Called when parser parses an input term
447    * token that uses prefix notation; that is, contains a single '*' wildcard
448    * character as its last character. Since this is a special case
449    * of generic wildcard term, and such a query can be optimized easily,
450    * this usually results in a different query object.
451    *<p>
452    * Depending on settings, a prefix term may be lower-cased
453    * automatically. It will not go through the default Analyzer,
454    * however, since normal Analyzers are unlikely to work properly
455    * with wildcard templates.
456    *<p>
457    * Can be overridden by extending classes, to provide custom handling for
458    * wild card queries, which may be necessary due to missing analyzer calls.
459    *
460    * @param field Name of the field query will use.
461    * @param termStr Term token to use for building term for the query
462    * (<b>without</b> trailing '*' character!)
463    *
464    * @return Resulting {@link Query} built for the term
465    * @exception ParseException throw in overridden method to disallow
466    */

467   protected Query getPrefixQuery(String JavaDoc field, String JavaDoc termStr) throws ParseException
468   {
469     if (lowercaseWildcardTerms) {
470   termStr = termStr.toLowerCase();
471     }
472     Term t = new Term(field, termStr);
473     return new PrefixQuery(t);
474   }
475
476   /**
477    * Factory method for generating a query (similar to
478    * ({@link #getWildcardQuery}). Called when parser parses
479    * an input term token that has the fuzzy suffix (~) appended.
480    *
481    * @param field Name of the field query will use.
482    * @param termStr Term token to use for building term for the query
483    *
484    * @return Resulting {@link Query} built for the term
485    * @exception ParseException throw in overridden method to disallow
486    */

487   protected Query getFuzzyQuery(String JavaDoc field, String JavaDoc termStr) throws ParseException {
488     return getFuzzyQuery(field, termStr, fuzzyMinSim);
489   }
490
491   /**
492    * Factory method for generating a query (similar to
493    * ({@link #getWildcardQuery}). Called when parser parses
494    * an input term token that has the fuzzy suffix (~floatNumber) appended.
495    *
496    * @param field Name of the field query will use.
497    * @param termStr Term token to use for building term for the query
498    * @param minSimilarity the minimum similarity required for a fuzzy match
499    *
500    * @return Resulting {@link Query} built for the term
501    * @exception ParseException throw in overridden method to disallow
502    */

503   protected Query getFuzzyQuery(String JavaDoc field, String JavaDoc termStr, float minSimilarity) throws ParseException
504   {
505     Term t = new Term(field, termStr);
506     return new FuzzyQuery(t, minSimilarity);
507   }
508
509   /**
510    * Returns a String where the escape char has been
511    * removed, or kept only once if there was a double escape.
512    */

513   private String JavaDoc discardEscapeChar(String JavaDoc input) {
514     char[] caSource = input.toCharArray();
515     char[] caDest = new char[caSource.length];
516     int j = 0;
517     for (int i = 0; i < caSource.length; i++) {
518       if ((caSource[i] != '\\') || (i > 0 && caSource[i-1] == '\\')) {
519         caDest[j++]=caSource[i];
520       }
521     }
522     return new String JavaDoc(caDest, 0, j);
523   }
524
525   /**
526    * Returns a String where those characters that QueryParser
527    * expects to be escaped are escaped, i.e. preceded by a <code>\</code>.
528    */

529   public static String JavaDoc escape(String JavaDoc s) {
530     StringBuilder JavaDoc sb = new StringBuilder JavaDoc(s.length());
531     for (int i = 0; i < s.length(); i++) {
532       char c = s.charAt(i);
533       // NOTE: keep this in sync with _ESCAPED_CHAR below!
534
if (c == '\\' || c == '+' || c == '-' || c == '!' || c == '(' || c == ')' || c == ':'
535         || c == '^' || c == '[' || c == ']' || c == '\"' || c == '{' || c == '}' || c == '~'
536         || c == '*' || c == '?') {
537         sb.append('\\');
538       }
539       sb.append(c);
540     }
541     return sb.toString();
542   }
543
544   public static void main(String JavaDoc[] args) throws Exception JavaDoc {
545     QueryParser qp = new QueryParser("field",
546                            new org.apache.lucene.analysis.SimpleAnalyzer());
547     Query q = qp.parse(args[0]);
548     System.out.println(q.toString("field"));
549   }
550
551 // * Query ::= ( Clause )*
552
// * Clause ::= ["+", "-"] [<TERM> ":"] ( <TERM> | "(" Query ")" )
553
final public int Conjunction() throws ParseException {
554   int ret = CONJ_NONE;
555     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
556     case AND:
557     case OR:
558       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
559       case AND:
560         jj_consume_token(AND);
561             ret = CONJ_AND;
562         break;
563       case OR:
564         jj_consume_token(OR);
565               ret = CONJ_OR;
566         break;
567       default:
568         jj_la1[0] = jj_gen;
569         jj_consume_token(-1);
570         throw new ParseException();
571       }
572       break;
573     default:
574       jj_la1[1] = jj_gen;
575       ;
576     }
577     {if (true) return ret;}
578     throw new Error JavaDoc("Missing return statement in function");
579   }
580
581   final public int Modifiers() throws ParseException {
582   int ret = MOD_NONE;
583     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
584     case NOT:
585     case PLUS:
586     case MINUS:
587       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
588       case PLUS:
589         jj_consume_token(PLUS);
590               ret = MOD_REQ;
591         break;
592       case MINUS:
593         jj_consume_token(MINUS);
594                  ret = MOD_NOT;
595         break;
596       case NOT:
597         jj_consume_token(NOT);
598                ret = MOD_NOT;
599         break;
600       default:
601         jj_la1[2] = jj_gen;
602         jj_consume_token(-1);
603         throw new ParseException();
604       }
605       break;
606     default:
607       jj_la1[3] = jj_gen;
608       ;
609     }
610     {if (true) return ret;}
611     throw new Error JavaDoc("Missing return statement in function");
612   }
613
614   final public Query Query(String JavaDoc field) throws ParseException {
615   Vector JavaDoc clauses = new Vector JavaDoc();
616   Query q, firstQuery=null;
617   int conj, mods;
618     mods = Modifiers();
619     q = Clause(field);
620     addClause(clauses, CONJ_NONE, mods, q);
621     if (mods == MOD_NONE)
622         firstQuery=q;
623     label_1:
624     while (true) {
625       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
626       case AND:
627       case OR:
628       case NOT:
629       case PLUS:
630       case MINUS:
631       case LPAREN:
632       case QUOTED:
633       case TERM:
634       case PREFIXTERM:
635       case WILDTERM:
636       case RANGEIN_START:
637       case RANGEEX_START:
638       case NUMBER:
639         ;
640         break;
641       default:
642         jj_la1[4] = jj_gen;
643         break label_1;
644       }
645       conj = Conjunction();
646       mods = Modifiers();
647       q = Clause(field);
648       addClause(clauses, conj, mods, q);
649     }
650       if (clauses.size() == 1 && firstQuery != null)
651         {if (true) return firstQuery;}
652       else {
653   {if (true) return getBooleanQuery(clauses);}
654       }
655     throw new Error JavaDoc("Missing return statement in function");
656   }
657
658   final public Query Clause(String JavaDoc field) throws ParseException {
659   Query q;
660   Token fieldToken=null, boost=null;
661     if (jj_2_1(2)) {
662       fieldToken = jj_consume_token(TERM);
663       jj_consume_token(COLON);
664       field=discardEscapeChar(fieldToken.image);
665     } else {
666       ;
667     }
668     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
669     case QUOTED:
670     case TERM:
671     case PREFIXTERM:
672     case WILDTERM:
673     case RANGEIN_START:
674     case RANGEEX_START:
675     case NUMBER:
676       q = Term(field);
677       break;
678     case LPAREN:
679       jj_consume_token(LPAREN);
680       q = Query(field);
681       jj_consume_token(RPAREN);
682       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
683       case CARAT:
684         jj_consume_token(CARAT);
685         boost = jj_consume_token(NUMBER);
686         break;
687       default:
688         jj_la1[5] = jj_gen;
689         ;
690       }
691       break;
692     default:
693       jj_la1[6] = jj_gen;
694       jj_consume_token(-1);
695       throw new ParseException();
696     }
697       if (boost != null) {
698         float f = (float)1.0;
699   try {
700     f = Float.valueOf(boost.image).floatValue();
701           q.setBoost(f);
702   } catch (Exception JavaDoc ignored) { }
703       }
704       {if (true) return q;}
705     throw new Error JavaDoc("Missing return statement in function");
706   }
707
708   final public Query Term(String JavaDoc field) throws ParseException {
709   Token term, boost=null, fuzzySlop=null, goop1, goop2;
710   boolean prefix = false;
711   boolean wildcard = false;
712   boolean fuzzy = false;
713   boolean rangein = false;
714   Query q;
715     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
716     case TERM:
717     case PREFIXTERM:
718     case WILDTERM:
719     case NUMBER:
720       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
721       case TERM:
722         term = jj_consume_token(TERM);
723         break;
724       case PREFIXTERM:
725         term = jj_consume_token(PREFIXTERM);
726                              prefix=true;
727         break;
728       case WILDTERM:
729         term = jj_consume_token(WILDTERM);
730                            wildcard=true;
731         break;
732       case NUMBER:
733         term = jj_consume_token(NUMBER);
734         break;
735       default:
736         jj_la1[7] = jj_gen;
737         jj_consume_token(-1);
738         throw new ParseException();
739       }
740       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
741       case FUZZY_SLOP:
742         fuzzySlop = jj_consume_token(FUZZY_SLOP);
743                                 fuzzy=true;
744         break;
745       default:
746         jj_la1[8] = jj_gen;
747         ;
748       }
749       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
750       case CARAT:
751         jj_consume_token(CARAT);
752         boost = jj_consume_token(NUMBER);
753         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
754         case FUZZY_SLOP:
755           fuzzySlop = jj_consume_token(FUZZY_SLOP);
756                                                          fuzzy=true;
757           break;
758         default:
759           jj_la1[9] = jj_gen;
760           ;
761         }
762         break;
763       default:
764         jj_la1[10] = jj_gen;
765         ;
766       }
767        String JavaDoc termImage=discardEscapeChar(term.image);
768        if (wildcard) {
769        q = getWildcardQuery(field, termImage);
770        } else if (prefix) {
771          q = getPrefixQuery(field,
772            discardEscapeChar(term.image.substring
773           (0, term.image.length()-1)));
774        } else if (fuzzy) {
775           float fms = fuzzyMinSim;
776           try {
777             fms = Float.valueOf(fuzzySlop.image.substring(1)).floatValue();
778           } catch (Exception JavaDoc ignored) { }
779          if(fms < 0.0f || fms > 1.0f){
780            {if (true) throw new ParseException("Minimum similarity for a FuzzyQuery has to be between 0.0f and 1.0f !");}
781          }
782          if(fms == fuzzyMinSim)
783            q = getFuzzyQuery(field, termImage);
784          else
785            q = getFuzzyQuery(field, termImage, fms);
786        } else {
787          q = getFieldQuery(field, analyzer, termImage);
788        }
789       break;
790     case RANGEIN_START:
791       jj_consume_token(RANGEIN_START);
792       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
793       case RANGEIN_GOOP:
794         goop1 = jj_consume_token(RANGEIN_GOOP);
795         break;
796       case RANGEIN_QUOTED:
797         goop1 = jj_consume_token(RANGEIN_QUOTED);
798         break;
799       default:
800         jj_la1[11] = jj_gen;
801         jj_consume_token(-1);
802         throw new ParseException();
803       }
804       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
805       case RANGEIN_TO:
806         jj_consume_token(RANGEIN_TO);
807         break;
808       default:
809         jj_la1[12] = jj_gen;
810         ;
811       }
812       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
813       case RANGEIN_GOOP:
814         goop2 = jj_consume_token(RANGEIN_GOOP);
815         break;
816       case RANGEIN_QUOTED:
817         goop2 = jj_consume_token(RANGEIN_QUOTED);
818         break;
819       default:
820         jj_la1[13] = jj_gen;
821         jj_consume_token(-1);
822         throw new ParseException();
823       }
824       jj_consume_token(RANGEIN_END);
825       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
826       case CARAT:
827         jj_consume_token(CARAT);
828         boost = jj_consume_token(NUMBER);
829         break;
830       default:
831         jj_la1[14] = jj_gen;
832         ;
833       }
834           if (goop1.kind == RANGEIN_QUOTED) {
835             goop1.image = goop1.image.substring(1, goop1.image.length()-1);
836           } else {
837             goop1.image = discardEscapeChar(goop1.image);
838           }
839           if (goop2.kind == RANGEIN_QUOTED) {
840             goop2.image = goop2.image.substring(1, goop2.image.length()-1);
841       } else {
842         goop2.image = discardEscapeChar(goop2.image);
843       }
844           q = getRangeQuery(field, analyzer, goop1.image, goop2.image, true);
845       break;
846     case RANGEEX_START:
847       jj_consume_token(RANGEEX_START);
848       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
849       case RANGEEX_GOOP:
850         goop1 = jj_consume_token(RANGEEX_GOOP);
851         break;
852       case RANGEEX_QUOTED:
853         goop1 = jj_consume_token(RANGEEX_QUOTED);
854         break;
855       default:
856         jj_la1[15] = jj_gen;
857         jj_consume_token(-1);
858         throw new ParseException();
859       }
860       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
861       case RANGEEX_TO:
862         jj_consume_token(RANGEEX_TO);
863         break;
864       default:
865         jj_la1[16] = jj_gen;
866         ;
867       }
868       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
869       case RANGEEX_GOOP:
870         goop2 = jj_consume_token(RANGEEX_GOOP);
871         break;
872       case RANGEEX_QUOTED:
873         goop2 = jj_consume_token(RANGEEX_QUOTED);
874         break;
875       default:
876         jj_la1[17] = jj_gen;
877         jj_consume_token(-1);
878         throw new ParseException();
879       }
880       jj_consume_token(RANGEEX_END);
881       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
882       case CARAT:
883         jj_consume_token(CARAT);
884         boost = jj_consume_token(NUMBER);
885         break;
886       default:
887         jj_la1[18] = jj_gen;
888         ;
889       }
890           if (goop1.kind == RANGEEX_QUOTED) {
891             goop1.image = goop1.image.substring(1, goop1.image.length()-1);
892           } else {
893             goop1.image = discardEscapeChar(goop1.image);
894           }
895           if (goop2.kind == RANGEEX_QUOTED) {
896             goop2.image = goop2.image.substring(1, goop2.image.length()-1);
897       } else {
898         goop2.image = discardEscapeChar(goop2.image);
899       }
900
901           q = getRangeQuery(field, analyzer, goop1.image, goop2.image, false);
902       break;
903     case QUOTED:
904       term = jj_consume_token(QUOTED);
905       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
906       case FUZZY_SLOP:
907         fuzzySlop = jj_consume_token(FUZZY_SLOP);
908         break;
909       default:
910         jj_la1[19] = jj_gen;
911         ;
912       }
913       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
914       case CARAT:
915         jj_consume_token(CARAT);
916         boost = jj_consume_token(NUMBER);
917         break;
918       default:
919         jj_la1[20] = jj_gen;
920         ;
921       }
922          int s = phraseSlop;
923
924          if (fuzzySlop != null) {
925            try {
926              s = Float.valueOf(fuzzySlop.image.substring(1)).intValue();
927            }
928            catch (Exception JavaDoc ignored) { }
929          }
930          q = getFieldQuery(field, analyzer, term.image.substring(1, term.image.length()-1), s);
931       break;
932     default:
933       jj_la1[21] = jj_gen;
934       jj_consume_token(-1);
935       throw new ParseException();
936     }
937     if (boost != null) {
938       float f = (float) 1.0;
939       try {
940         f = Float.valueOf(boost.image).floatValue();
941       }
942       catch (Exception JavaDoc ignored) {
943     /* Should this be handled somehow? (defaults to "no boost", if
944      * boost number is invalid)
945      */

946       }
947
948       // avoid boosting null queries, such as those caused by stop words
949
if (q != null) {
950         q.setBoost(f);
951       }
952     }
953     {if (true) return q;}
954     throw new Error JavaDoc("Missing return statement in function");
955   }
956
957   final private boolean jj_2_1(int xla) {
958     jj_la = xla; jj_lastpos = jj_scanpos = token;
959     try { return !jj_3_1(); }
960     catch(LookaheadSuccess ls) { return true; }
961     finally { jj_save(0, xla); }
962   }
963
964   final private boolean jj_3_1() {
965     if (jj_scan_token(TERM)) return true;
966     if (jj_scan_token(COLON)) return true;
967     return false;
968   }
969
970   public QueryParserTokenManager token_source;
971   public Token token, jj_nt;
972   private int jj_ntk;
973   private Token jj_scanpos, jj_lastpos;
974   private int jj_la;
975   public boolean lookingAhead = false;
976   private boolean jj_semLA;
977   private int jj_gen;
978   final private int[] jj_la1 = new int[22];
979   static private int[] jj_la1_0;
980   static {
981       jj_la1_0();
982    }
983    private static void jj_la1_0() {
984       jj_la1_0 = new int[] {0x180,0x180,0xe00,0xe00,0xfb1f80,0x8000,0xfb1000,0x9a0000,0x40000,0x40000,0x8000,0xc000000,0x1000000,0xc000000,0x8000,0xc0000000,0x10000000,0xc0000000,0x8000,0x40000,0x8000,0xfb0000,};
985    }
986   final private JJCalls[] jj_2_rtns = new JJCalls[1];
987   private boolean jj_rescan = false;
988   private int jj_gc = 0;
989
990   public QueryParser(CharStream stream) {
991     token_source = new QueryParserTokenManager(stream);
992     token = new Token();
993     jj_ntk = -1;
994     jj_gen = 0;
995     for (int i = 0; i < 22; i++) jj_la1[i] = -1;
996     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
997   }
998
999   public void ReInit(CharStream stream) {
1000    token_source.ReInit(stream);
1001    token = new Token();
1002    jj_ntk = -1;
1003    jj_gen = 0;
1004    for (int i = 0; i < 22; i++) jj_la1[i] = -1;
1005    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1006  }
1007
1008  public QueryParser(QueryParserTokenManager tm) {
1009    token_source = tm;
1010    token = new Token();
1011    jj_ntk = -1;
1012    jj_gen = 0;
1013    for (int i = 0; i < 22; i++) jj_la1[i] = -1;
1014    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1015  }
1016
1017  public void ReInit(QueryParserTokenManager tm) {
1018    token_source = tm;
1019    token = new Token();
1020    jj_ntk = -1;
1021    jj_gen = 0;
1022    for (int i = 0; i < 22; i++) jj_la1[i] = -1;
1023    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1024  }
1025
1026  final private Token jj_consume_token(int kind) throws ParseException {
1027    Token oldToken;
1028    if ((oldToken = token).next != null) token = token.next;
1029    else token = token.next = token_source.getNextToken();
1030    jj_ntk = -1;
1031    if (token.kind == kind) {
1032      jj_gen++;
1033      if (++jj_gc > 100) {
1034        jj_gc = 0;
1035        for (int i = 0; i < jj_2_rtns.length; i++) {
1036          JJCalls c = jj_2_rtns[i];
1037          while (c != null) {
1038            if (c.gen < jj_gen) c.first = null;
1039            c = c.next;
1040          }
1041        }
1042      }
1043      return token;
1044    }
1045    token = oldToken;
1046    jj_kind = kind;
1047    throw generateParseException();
1048  }
1049
1050  static private final class LookaheadSuccess extends java.lang.Error JavaDoc { }
1051  final private LookaheadSuccess jj_ls = new LookaheadSuccess();
1052  final private boolean jj_scan_token(int kind) {
1053    if (jj_scanpos == jj_lastpos) {
1054      jj_la--;
1055      if (jj_scanpos.next == null) {
1056        jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
1057      } else {
1058        jj_lastpos = jj_scanpos = jj_scanpos.next;
1059      }
1060    } else {
1061      jj_scanpos = jj_scanpos.next;
1062    }
1063    if (jj_rescan) {
1064      int i = 0; Token tok = token;
1065      while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
1066      if (tok != null) jj_add_error_token(kind, i);
1067    }
1068    if (jj_scanpos.kind != kind) return true;
1069    if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
1070    return false;
1071  }
1072
1073  final public Token getNextToken() {
1074    if (token.next != null) token = token.next;
1075    else token = token.next = token_source.getNextToken();
1076    jj_ntk = -1;
1077    jj_gen++;
1078    return token;
1079  }
1080
1081  final public Token getToken(int index) {
1082    Token t = lookingAhead ? jj_scanpos : token;
1083    for (int i = 0; i < index; i++) {
1084      if (t.next != null) t = t.next;
1085      else t = t.next = token_source.getNextToken();
1086    }
1087    return t;
1088  }
1089
1090  final private int jj_ntk() {
1091    if ((jj_nt=token.next) == null)
1092      return (jj_ntk = (token.next=token_source.getNextToken()).kind);
1093    else
1094      return (jj_ntk = jj_nt.kind);
1095  }
1096
1097  private java.util.Vector JavaDoc jj_expentries = new java.util.Vector JavaDoc();
1098  private int[] jj_expentry;
1099  private int jj_kind = -1;
1100  private int[] jj_lasttokens = new int[100];
1101  private int jj_endpos;
1102
1103  private void jj_add_error_token(int kind, int pos) {
1104    if (pos >= 100) return;
1105    if (pos == jj_endpos + 1) {
1106      jj_lasttokens[jj_endpos++] = kind;
1107    } else if (jj_endpos != 0) {
1108      jj_expentry = new int[jj_endpos];
1109      for (int i = 0; i < jj_endpos; i++) {
1110        jj_expentry[i] = jj_lasttokens[i];
1111      }
1112      boolean exists = false;
1113      for (java.util.Enumeration JavaDoc e = jj_expentries.elements(); e.hasMoreElements();) {
1114        int[] oldentry = (int[])(e.nextElement());
1115        if (oldentry.length == jj_expentry.length) {
1116          exists = true;
1117          for (int i = 0; i < jj_expentry.length; i++) {
1118            if (oldentry[i] != jj_expentry[i]) {
1119              exists = false;
1120              break;
1121            }
1122          }
1123          if (exists) break;
1124        }
1125      }
1126      if (!exists) jj_expentries.addElement(jj_expentry);
1127      if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
1128    }
1129  }
1130
1131  public ParseException generateParseException() {
1132    jj_expentries.removeAllElements();
1133    boolean[] la1tokens = new boolean[32];
1134    for (int i = 0; i < 32; i++) {
1135      la1tokens[i] = false;
1136    }
1137    if (jj_kind >= 0) {
1138      la1tokens[jj_kind] = true;
1139      jj_kind = -1;
1140    }
1141    for (int i = 0; i < 22; i++) {
1142      if (jj_la1[i] == jj_gen) {
1143        for (int j = 0; j < 32; j++) {
1144          if ((jj_la1_0[i] & (1<<j)) != 0) {
1145            la1tokens[j] = true;
1146          }
1147        }
1148      }
1149    }
1150    for (int i = 0; i < 32; i++) {
1151      if (la1tokens[i]) {
1152        jj_expentry = new int[1];
1153        jj_expentry[0] = i;
1154        jj_expentries.addElement(jj_expentry);
1155      }
1156    }
1157    jj_endpos = 0;
1158    jj_rescan_token();
1159    jj_add_error_token(0, 0);
1160    int[][] exptokseq = new int[jj_expentries.size()][];
1161    for (int i = 0; i < jj_expentries.size(); i++) {
1162      exptokseq[i] = (int[])jj_expentries.elementAt(i);
1163    }
1164    return new ParseException(token, exptokseq, tokenImage);
1165  }
1166
1167  final public void enable_tracing() {
1168  }
1169
1170  final public void disable_tracing() {
1171  }
1172
1173  final private void jj_rescan_token() {
1174    jj_rescan = true;
1175    for (int i = 0; i < 1; i++) {
1176      JJCalls p = jj_2_rtns[i];
1177      do {
1178        if (p.gen > jj_gen) {
1179          jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
1180          switch (i) {
1181            case 0: jj_3_1(); break;
1182          }
1183        }
1184        p = p.next;
1185      } while (p != null);
1186    }
1187    jj_rescan = false;
1188  }
1189
1190  final private void jj_save(int index, int xla) {
1191    JJCalls p = jj_2_rtns[index];
1192    while (p.gen > jj_gen) {
1193      if (p.next == null) { p = p.next = new JJCalls(); break; }
1194      p = p.next;
1195    }
1196    p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
1197  }
1198
1199  static final class JJCalls {
1200    int gen;
1201    Token first;
1202    int arg;
1203    JJCalls next;
1204  }
1205
1206}
1207
Popular Tags