001: /*
002: * $Header$
003: * $Revision: 7067 $
004: * $Date: 2007-07-09 02:45:41 -0700 $
005: *
006: * ====================================================================
007: *
008: * Copyright 1999-2004 The Apache Software Foundation
009: *
010: * Licensed under the Apache License, Version 2.0 (the "License");
011: * you may not use this file except in compliance with the License.
012: * You may obtain a copy of the License at
013: *
014: * http://www.apache.org/licenses/LICENSE-2.0
015: *
016: * Unless required by applicable law or agreed to in writing, software
017: * distributed under the License is distributed on an "AS IS" BASIS,
018: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
019: * See the License for the specific language governing permissions and
020: * limitations under the License.
021: *
022: */
023: package org.apache.slide.index.lucene.expressions;
024:
025: import java.io.IOException;
026: import java.io.StringReader;
027: import java.util.ArrayList;
028:
029: import org.apache.lucene.analysis.Token;
030: import org.apache.lucene.analysis.TokenStream;
031: import org.apache.lucene.index.Term;
032: import org.apache.lucene.queryParser.QueryParser;
033: import org.apache.lucene.search.BooleanQuery;
034: import org.apache.lucene.search.PhraseQuery;
035: import org.apache.lucene.search.PrefixQuery;
036: import org.apache.lucene.search.Query;
037: import org.apache.lucene.search.TermQuery;
038: import org.apache.lucene.search.WildcardQuery;
039: import org.apache.slide.index.lucene.Index;
040: import org.apache.slide.index.lucene.IndexConfiguration;
041: import org.apache.slide.search.BadQueryException;
042: import org.jdom.Element;
043:
044: /**
045: * Implements the <code>contains</code> expression.
046: */
047: public class ContainsExpression extends AbstractLuceneExpression {
048:
049: public ContainsExpression(Index index, Element element,
050: boolean negated) throws BadQueryException {
051: super (index);
052:
053: IndexConfiguration config = index.getConfiguration();
054: String literal = element.getText();
055: String locale = element.getAttributeValue("locale", "");
056:
057: String fieldName = Index.CONTENT_FIELD_NAME;
058: if (!locale.equals("")) {
059: fieldName = fieldName.concat("_").concat(locale);
060: }
061:
062: try {
063: // use queryparser to make the query here
064: parseQuery(config, fieldName, literal);
065: } catch (Exception e) {
066:
067: index.getLogger().debug(
068: "ContainsExpression: Couldn't parse query! Falling back to default. query: "
069: + literal, e);
070:
071: if (!index.getConfiguration().isCaseSensitive())
072: literal = literal.toLowerCase();
073:
074: int starPos = literal.indexOf('*');
075: int qmPos = literal.indexOf('?');
076: if (starPos != -1 || qmPos != -1) {
077: if (starPos == literal.length() - 1 && qmPos == -1) {
078: // some thing like "word*"
079: // TODO the .toLowerCase() should depend from the Analyzer
080: setQuery(new PrefixQuery(
081: new Term(Index.CONTENT_FIELD_NAME, literal
082: .substring(0, literal.length() - 1))));
083: } else {
084: // TODO dito
085: setQuery(new WildcardQuery(new Term(
086: Index.CONTENT_FIELD_NAME, literal)));
087: }
088: } else {
089: termOrPhraseQuery(config, fieldName, literal);
090: }
091: }
092:
093: // TODO
094: if (negated) {
095: setQuery(negateQuery(getQuery()));
096: }
097: }
098:
099: private void parseQuery(IndexConfiguration config, String field,
100: String text) throws Exception {
101: QueryParser parser = new QueryParser(field, config
102: .getAnalyzer());
103: Query query = parser.parse(text);
104: setQuery(query);
105: }
106:
107: private void termOrPhraseQuery(IndexConfiguration config,
108: String field, String text) {
109: TokenStream ts = config.getAnalyzer().tokenStream(field,
110: new StringReader(text));
111:
112: ArrayList tokens = new ArrayList(20);
113: try {
114: for (Token t = ts.next(); t != null; t = ts.next()) {
115: tokens.add(t.termText());
116: }
117: } catch (IOException e) {
118: // should not happen, because we are reading from StringReader
119: }
120:
121: if (tokens.size() > 1) {
122: PhraseQuery phraseQuery = new PhraseQuery();
123: for (int i = 0, l = tokens.size(); i < l; i++) {
124: phraseQuery
125: .add(new Term(field, (String) tokens.get(i)));
126: }
127: setQuery(phraseQuery);
128: } else if (tokens.size() == 1) {
129: setQuery(new TermQuery(new Term(field, (String) tokens
130: .get(0))));
131: } else {
132: // TODO NOP query???
133: setQuery(new BooleanQuery());
134: }
135: }
136: }
|