001: /*
002: * Copyright 2004-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.compass.core.lucene.engine.queryparser;
018:
019: import org.apache.commons.logging.Log;
020: import org.apache.commons.logging.LogFactory;
021: import org.apache.lucene.analysis.Analyzer;
022: import org.apache.lucene.queryParser.CompassMultiFieldQueryParser;
023: import org.apache.lucene.queryParser.CompassQueryParser;
024: import org.apache.lucene.queryParser.ParseException;
025: import org.apache.lucene.queryParser.QueryParser;
026: import org.apache.lucene.search.Query;
027: import org.compass.core.CompassException;
028: import org.compass.core.config.CompassConfigurable;
029: import org.compass.core.config.CompassMappingAware;
030: import org.compass.core.config.CompassSettings;
031: import org.compass.core.config.ConfigurationException;
032: import org.compass.core.config.SearchEngineFactoryAware;
033: import org.compass.core.engine.SearchEngineFactory;
034: import org.compass.core.engine.SearchEngineQueryParseException;
035: import org.compass.core.lucene.LuceneEnvironment;
036: import org.compass.core.mapping.CompassMapping;
037:
038: /**
039: * The deafult Lucene query parser. Uses {@link org.compass.core.lucene.LuceneEnvironment.QueryParser#DEFAULT_PARSER_ALLOW_LEADING_WILDCARD}
040: *
041: * @author kimchy
042: */
043: public class DefaultLuceneQueryParser implements LuceneQueryParser,
044: CompassMappingAware, SearchEngineFactoryAware,
045: CompassConfigurable {
046:
047: private static Log log = LogFactory
048: .getLog(DefaultLuceneQueryParser.class);
049:
050: private CompassMapping mapping;
051:
052: private SearchEngineFactory searchEngineFactory;
053:
054: private boolean allowLeadingWildcard;
055:
056: private boolean allowConstantScorePrefixQuery;
057:
058: private QueryParser.Operator defaultOperator;
059:
060: public void configure(CompassSettings settings)
061: throws CompassException {
062: allowLeadingWildcard = settings
063: .getSettingAsBoolean(
064: LuceneEnvironment.QueryParser.DEFAULT_PARSER_ALLOW_LEADING_WILDCARD,
065: true);
066: allowConstantScorePrefixQuery = settings
067: .getSettingAsBoolean(
068: LuceneEnvironment.QueryParser.DEFAULT_PARSER_ALLOW_CONSTANT_SCORE_PREFIX_QUERY,
069: true);
070: String sDefaultOperator = settings
071: .getSetting(
072: LuceneEnvironment.QueryParser.DEFAULT_PARSER_DEFAULT_OPERATOR,
073: "AND");
074: if ("and".equalsIgnoreCase(sDefaultOperator)) {
075: defaultOperator = QueryParser.Operator.AND;
076: } else if ("or".equalsIgnoreCase(sDefaultOperator)) {
077: defaultOperator = QueryParser.Operator.OR;
078: } else {
079: throw new ConfigurationException(
080: "Defualt query string operator ["
081: + sDefaultOperator + "] not recognized.");
082: }
083: if (log.isDebugEnabled()) {
084: log
085: .debug("Query Parser configured with allowLeadingWildcard ["
086: + allowLeadingWildcard
087: + "] and allowConstantScorePrefixQuery ["
088: + allowConstantScorePrefixQuery + "]");
089: }
090: }
091:
092: public void setCompassMapping(CompassMapping mapping) {
093: this .mapping = mapping;
094: }
095:
096: public void setSearchEngineFactory(
097: SearchEngineFactory searchEngineFactory) {
098: this .searchEngineFactory = searchEngineFactory;
099: }
100:
101: public QueryHolder parse(String property,
102: QueryParser.Operator operator, Analyzer analyzer,
103: boolean forceAnalyzer, String queryString)
104: throws SearchEngineQueryParseException {
105: CompassQueryParser queryParser = createQueryParser(property,
106: analyzer, forceAnalyzer);
107: queryParser.setDefaultOperator(getOperator(operator));
108: queryParser.setAllowLeadingWildcard(allowLeadingWildcard);
109: queryParser
110: .setAllowConstantScorePrefixQuery(allowConstantScorePrefixQuery);
111: try {
112: Query query = queryParser.parse(queryString);
113: return new QueryHolder(query, queryParser
114: .isSuggestedQuery());
115: } catch (ParseException e) {
116: throw new SearchEngineQueryParseException(queryString, e);
117: } catch (IllegalArgumentException e) {
118: throw new SearchEngineQueryParseException(queryString, e);
119: } finally {
120: queryParser.close();
121: }
122: }
123:
124: public QueryHolder parse(String[] properties,
125: QueryParser.Operator operator, Analyzer analyzer,
126: boolean forceAnalyzer, String queryString)
127: throws SearchEngineQueryParseException {
128: CompassMultiFieldQueryParser queryParser = createMultiQueryParser(
129: properties, analyzer, forceAnalyzer);
130: queryParser.setDefaultOperator(getOperator(operator));
131: queryParser.setAllowLeadingWildcard(allowLeadingWildcard);
132: queryParser
133: .setAllowConstantScorePrefixQuery(allowConstantScorePrefixQuery);
134: try {
135: Query query = queryParser.parse(queryString);
136: return new QueryHolder(query, queryParser
137: .isSuggestedQuery());
138: } catch (ParseException e) {
139: throw new SearchEngineQueryParseException(queryString, e);
140: } catch (IllegalArgumentException e) {
141: throw new SearchEngineQueryParseException(queryString, e);
142: } finally {
143: queryParser.close();
144: }
145: }
146:
147: private QueryParser.Operator getOperator(
148: QueryParser.Operator operator) {
149: if (operator == null) {
150: return defaultOperator;
151: }
152: return operator;
153: }
154:
155: protected CompassMapping getMapping() {
156: return mapping;
157: }
158:
159: protected SearchEngineFactory getSearchEngineFactory() {
160: return searchEngineFactory;
161: }
162:
163: protected CompassQueryParser createQueryParser(String property,
164: Analyzer analyzer, boolean forceAnalyzer) {
165: return new CompassQueryParser(property, analyzer, mapping,
166: searchEngineFactory, forceAnalyzer);
167: }
168:
169: protected CompassMultiFieldQueryParser createMultiQueryParser(
170: String[] properties, Analyzer analyzer,
171: boolean forceAnalyzer) {
172: return new CompassMultiFieldQueryParser(properties, analyzer,
173: mapping, searchEngineFactory, forceAnalyzer);
174: }
175:
176: }
|