pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / contrib / queryparser / src / java / org / apache / lucene / queryParser / ext / ExtendableQueryParser.java
1 package org.apache.lucene.queryParser.ext;
2
3 /**
4  * Licensed to the Apache Software Foundation (ASF) under one or more
5  * contributor license agreements.  See the NOTICE file distributed with
6  * this work for additional information regarding copyright ownership.
7  * The ASF licenses this file to You under the Apache License, Version 2.0
8  * (the "License"); you may not use this file except in compliance with
9  * the License.  You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 import org.apache.lucene.analysis.Analyzer;
21 import org.apache.lucene.queryParser.ParseException;
22 import org.apache.lucene.queryParser.QueryParser;
23 import org.apache.lucene.queryParser.ext.Extensions.Pair;
24 import org.apache.lucene.search.Query;
25 import org.apache.lucene.util.Version;
26
27 /**
28  * The {@link ExtendableQueryParser} enables arbitrary query parser extension
29  * based on a customizable field naming scheme. The lucene query syntax allows
30  * implicit and explicit field definitions as query prefix followed by a colon
31  * (':') character. The {@link ExtendableQueryParser} allows to encode extension
32  * keys into the field symbol associated with a registered instance of
33  * {@link ParserExtension}. A customizable separation character separates the
34  * extension key from the actual field symbol. The {@link ExtendableQueryParser}
35  * splits (@see {@link Extensions#splitExtensionField(String, String)}) the
36  * extension key from the field symbol and tries to resolve the associated
37  * {@link ParserExtension}. If the parser can't resolve the key or the field
38  * token does not contain a separation character, {@link ExtendableQueryParser}
39  * yields the same behavior as its super class {@link QueryParser}. Otherwise,
40  * if the key is associated with a {@link ParserExtension} instance, the parser
41  * builds an instance of {@link ExtensionQuery} to be processed by
42  * {@link ParserExtension#parse(ExtensionQuery)}.If a extension field does not
43  * contain a field part the default field for the query will be used.
44  * <p>
45  * To guarantee that an extension field is processed with its associated
46  * extension, the extension query part must escape any special characters like
47  * '*' or '['. If the extension query contains any whitespace characters, the
48  * extension query part must be enclosed in quotes.
49  * Example ('_' used as separation character):
50  * <pre>
51  *   title_customExt:"Apache Lucene\?" OR content_customExt:prefix\*
52  * </pre>
53  * 
54  * Search on the default field:
55  * <pre>
56  *   _customExt:"Apache Lucene\?" OR _customExt:prefix\*
57  * </pre>
58  * </p>
59  * <p>
60  * The {@link ExtendableQueryParser} itself does not implement the logic how
61  * field and extension key are separated or ordered. All logic regarding the
62  * extension key and field symbol parsing is located in {@link Extensions}.
63  * Customized extension schemes should be implemented by sub-classing
64  * {@link Extensions}.
65  * </p>
66  * <p>
67  * For details about the default encoding scheme see {@link Extensions}.
68  * </p>
69  * 
70  * @see Extensions
71  * @see ParserExtension
72  * @see ExtensionQuery
73  */
74 public class ExtendableQueryParser extends QueryParser {
75
76   private final String defaultField;
77   private final Extensions extensions;
78
79   /**
80    * Default empty extensions instance
81    */
82   private static final Extensions DEFAULT_EXTENSION = new Extensions();
83
84   /**
85    * Creates a new {@link ExtendableQueryParser} instance
86    * 
87    * @param matchVersion
88    *          the lucene version to use.
89    * @param f
90    *          the default query field
91    * @param a
92    *          the analyzer used to find terms in a query string
93    */
94   public ExtendableQueryParser(final Version matchVersion, final String f,
95       final Analyzer a) {
96     this(matchVersion, f, a, DEFAULT_EXTENSION);
97
98   }
99
100   /**
101    * Creates a new {@link ExtendableQueryParser} instance
102    * 
103    * @param matchVersion
104    *          the lucene version to use.
105    * @param f
106    *          the default query field
107    * @param a
108    *          the analyzer used to find terms in a query string
109    * @param ext
110    *          the query parser extensions
111    */
112   public ExtendableQueryParser(final Version matchVersion, final String f,
113       final Analyzer a, final Extensions ext) {
114     super(matchVersion, f, a);
115     this.defaultField = f;
116     this.extensions = ext;
117   }
118
119   /**
120    * Returns the extension field delimiter character.
121    * 
122    * @return the extension field delimiter character.
123    */
124   public char getExtensionFieldDelimiter() {
125     return extensions.getExtensionFieldDelimiter();
126   }
127
128   @Override
129   protected Query getFieldQuery(final String field, final String queryText, boolean quoted)
130       throws ParseException {
131     final Pair<String,String> splitExtensionField = this.extensions
132         .splitExtensionField(defaultField, field);
133     final ParserExtension extension = this.extensions
134         .getExtension(splitExtensionField.cud);
135     if (extension != null) {
136       return extension.parse(new ExtensionQuery(this, splitExtensionField.cur,
137           queryText));
138     }
139     return super.getFieldQuery(field, queryText, quoted);
140   }
141
142 }