001: package org.apache.lucene.queryParser.surround.query;
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.util.List;
021: import java.util.Iterator;
022:
023: import java.io.IOException;
024:
025: import org.apache.lucene.index.IndexReader;
026: import org.apache.lucene.search.Query;
027: import org.apache.lucene.search.spans.SpanNearQuery;
028: import org.apache.lucene.search.spans.SpanQuery;
029:
030: public class DistanceQuery extends ComposedQuery implements
031: DistanceSubQuery {
032: public DistanceQuery(List queries, boolean infix, int opDistance,
033: String opName, boolean ordered) {
034: super (queries, infix, opName);
035: this .opDistance = opDistance; /* the distance indicated in the operator */
036: this .ordered = ordered;
037: }
038:
039: private int opDistance;
040:
041: public int getOpDistance() {
042: return opDistance;
043: }
044:
045: private boolean ordered;
046:
047: public boolean subQueriesOrdered() {
048: return ordered;
049: }
050:
051: public String distanceSubQueryNotAllowed() {
052: Iterator sqi = getSubQueriesIterator();
053: while (sqi.hasNext()) {
054: Object leq = sqi.next();
055: if (leq instanceof DistanceSubQuery) {
056: DistanceSubQuery dsq = (DistanceSubQuery) leq;
057: String m = dsq.distanceSubQueryNotAllowed();
058: if (m != null) {
059: return m;
060: }
061: } else {
062: return "Operator " + getOperatorName()
063: + " does not allow subquery " + leq.toString();
064: }
065: }
066: return null; /* subqueries acceptable */
067: }
068:
069: public void addSpanQueries(SpanNearClauseFactory sncf)
070: throws IOException {
071: Query snq = getSpanNearQuery(sncf.getIndexReader(), sncf
072: .getFieldName(), getWeight(), sncf
073: .getBasicQueryFactory());
074: sncf.addSpanNearQuery(snq);
075: }
076:
077: public Query makeLuceneQueryFieldNoBoost(final String fieldName,
078: final BasicQueryFactory qf) {
079: return new Query() {
080:
081: public String toString(String fn) {
082: return getClass().toString() + " " + fieldName + " ("
083: + fn + "?)";
084: }
085:
086: public Query rewrite(IndexReader reader) throws IOException {
087: return getSpanNearQuery(reader, fieldName, getBoost(),
088: qf);
089: }
090:
091: };
092: }
093:
094: public Query getSpanNearQuery(IndexReader reader, String fieldName,
095: float boost, BasicQueryFactory qf) throws IOException {
096: SpanQuery[] spanNearClauses = new SpanQuery[getNrSubQueries()];
097: Iterator sqi = getSubQueriesIterator();
098: int qi = 0;
099: while (sqi.hasNext()) {
100: SpanNearClauseFactory sncf = new SpanNearClauseFactory(
101: reader, fieldName, qf);
102:
103: ((DistanceSubQuery) sqi.next()).addSpanQueries(sncf);
104: if (sncf.size() == 0) { /* distance operator requires all sub queries */
105: while (sqi.hasNext()) { /* produce evt. error messages but ignore results */
106: ((DistanceSubQuery) sqi.next())
107: .addSpanQueries(sncf);
108: sncf.clear();
109: }
110: return SrndQuery.theEmptyLcnQuery;
111: }
112:
113: spanNearClauses[qi] = sncf.makeSpanNearClause();
114:
115: qi++;
116: }
117:
118: SpanNearQuery r = new SpanNearQuery(spanNearClauses,
119: getOpDistance() - 1, subQueriesOrdered());
120: r.setBoost(boost);
121: return r;
122: }
123: }
|