1 package org.apache.lucene.queryParser.ext;
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
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;
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.
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):
51 * title_customExt:"Apache Lucene\?" OR content_customExt:prefix\*
54 * Search on the default field:
56 * _customExt:"Apache Lucene\?" OR _customExt:prefix\*
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
67 * For details about the default encoding scheme see {@link Extensions}.
71 * @see ParserExtension
74 public class ExtendableQueryParser extends QueryParser {
76 private final String defaultField;
77 private final Extensions extensions;
80 * Default empty extensions instance
82 private static final Extensions DEFAULT_EXTENSION = new Extensions();
85 * Creates a new {@link ExtendableQueryParser} instance
88 * the lucene version to use.
90 * the default query field
92 * the analyzer used to find terms in a query string
94 public ExtendableQueryParser(final Version matchVersion, final String f,
96 this(matchVersion, f, a, DEFAULT_EXTENSION);
101 * Creates a new {@link ExtendableQueryParser} instance
103 * @param matchVersion
104 * the lucene version to use.
106 * the default query field
108 * the analyzer used to find terms in a query string
110 * the query parser extensions
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;
120 * Returns the extension field delimiter character.
122 * @return the extension field delimiter character.
124 public char getExtensionFieldDelimiter() {
125 return extensions.getExtensionFieldDelimiter();
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,
139 return super.getFieldQuery(field, queryText, quoted);