001: package org.apache.lucene.search;
002:
003: /**
004: * Licensed to the Apache Software Foundation (ASF) under one or more
005: * contributor license agreements. See the NOTICE file distributed with
006: * this work for additional information regarding copyright ownership.
007: * The ASF licenses this file to You under the Apache License, Version 2.0
008: * (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS,
015: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: * See the License for the specific language governing permissions and
017: * limitations under the License.
018: */
019:
020: import java.io.IOException;
021:
022: import org.apache.lucene.index.IndexReader;
023: import org.apache.lucene.index.Term;
024: import org.apache.lucene.util.ToStringUtils;
025:
026: /**
027: * A {@link Query} that matches documents containing a subset of terms provided
028: * by a {@link FilteredTermEnum} enumeration.
029: * <P>
030: * <code>MultiTermQuery</code> is not designed to be used by itself.
031: * <BR>
032: * The reason being that it is not intialized with a {@link FilteredTermEnum}
033: * enumeration. A {@link FilteredTermEnum} enumeration needs to be provided.
034: * <P>
035: * For example, {@link WildcardQuery} and {@link FuzzyQuery} extend
036: * <code>MultiTermQuery</code> to provide {@link WildcardTermEnum} and
037: * {@link FuzzyTermEnum}, respectively.
038: */
039: public abstract class MultiTermQuery extends Query {
040: private Term term;
041:
042: /** Constructs a query for terms matching <code>term</code>. */
043: public MultiTermQuery(Term term) {
044: this .term = term;
045: }
046:
047: /** Returns the pattern term. */
048: public Term getTerm() {
049: return term;
050: }
051:
052: /** Construct the enumeration to be used, expanding the pattern term. */
053: protected abstract FilteredTermEnum getEnum(IndexReader reader)
054: throws IOException;
055:
056: public Query rewrite(IndexReader reader) throws IOException {
057: FilteredTermEnum enumerator = getEnum(reader);
058: BooleanQuery query = new BooleanQuery(true);
059: try {
060: do {
061: Term t = enumerator.term();
062: if (t != null) {
063: TermQuery tq = new TermQuery(t); // found a match
064: tq.setBoost(getBoost() * enumerator.difference()); // set the boost
065: query.add(tq, BooleanClause.Occur.SHOULD); // add to query
066: }
067: } while (enumerator.next());
068: } finally {
069: enumerator.close();
070: }
071: return query;
072: }
073:
074: /** Prints a user-readable version of this query. */
075: public String toString(String field) {
076: StringBuffer buffer = new StringBuffer();
077: if (!term.field().equals(field)) {
078: buffer.append(term.field());
079: buffer.append(":");
080: }
081: buffer.append(term.text());
082: buffer.append(ToStringUtils.boost(getBoost()));
083: return buffer.toString();
084: }
085:
086: public boolean equals(Object o) {
087: if (this == o)
088: return true;
089: if (!(o instanceof MultiTermQuery))
090: return false;
091:
092: final MultiTermQuery multiTermQuery = (MultiTermQuery) o;
093:
094: if (!term.equals(multiTermQuery.term))
095: return false;
096:
097: return getBoost() == multiTermQuery.getBoost();
098: }
099:
100: public int hashCode() {
101: return term.hashCode() + Float.floatToRawIntBits(getBoost());
102: }
103: }
|