add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / contrib / queryparser / src / java / org / apache / lucene / queryParser / surround / query / DistanceQuery.java
1 package org.apache.lucene.queryParser.surround.query;
2 /**
3  * Licensed to the Apache Software Foundation (ASF) under one or more
4  * contributor license agreements.  See the NOTICE file distributed with
5  * this work for additional information regarding copyright ownership.
6  * The ASF licenses this file to You under the Apache License, Version 2.0
7  * (the "License"); you may not use this file except in compliance with
8  * the License.  You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19
20 import java.util.List;
21 import java.util.Iterator;
22
23 import java.io.IOException;
24
25 import org.apache.lucene.index.IndexReader;
26 import org.apache.lucene.search.Query;
27 import org.apache.lucene.search.spans.SpanNearQuery;
28 import org.apache.lucene.search.spans.SpanQuery;
29
30 public class DistanceQuery extends ComposedQuery implements DistanceSubQuery {
31   public DistanceQuery(
32       List<SrndQuery> queries,
33       boolean infix,
34       int opDistance,
35       String opName,
36       boolean ordered) {
37     super(queries, infix, opName);
38     this.opDistance = opDistance; /* the distance indicated in the operator */
39     this.ordered = ordered;
40   }
41
42   private int opDistance;
43   public int getOpDistance() {return opDistance;}
44   
45   private boolean ordered;
46   public boolean subQueriesOrdered() {return ordered;}
47   
48   public String distanceSubQueryNotAllowed() {
49     Iterator<?> sqi = getSubQueriesIterator();
50     while (sqi.hasNext()) {
51       Object leq = sqi.next();
52       if (leq instanceof DistanceSubQuery) {
53         DistanceSubQuery dsq = (DistanceSubQuery) leq;
54         String m = dsq.distanceSubQueryNotAllowed();
55         if (m != null) {
56           return m; 
57         }
58       } else {
59         return "Operator " + getOperatorName() + " does not allow subquery " + leq.toString();
60       }
61     }
62     return null; /* subqueries acceptable */
63   }
64
65   
66   public void addSpanQueries(SpanNearClauseFactory sncf) throws IOException {
67     Query snq = getSpanNearQuery(sncf.getIndexReader(),
68                                   sncf.getFieldName(),
69                                   getWeight(),
70                                   sncf.getBasicQueryFactory());
71     sncf.addSpanNearQuery(snq);
72   }
73
74   @Override
75   public Query makeLuceneQueryFieldNoBoost(final String fieldName, final BasicQueryFactory qf) {
76     return new Query () {
77       
78       @Override
79       public String toString(String fn) {
80         return getClass().toString() + " " + fieldName + " (" + fn + "?)";
81       }
82       
83       @Override
84       public Query rewrite(IndexReader reader) throws IOException {
85         return getSpanNearQuery(reader, fieldName, getBoost(), qf);
86       }
87       
88     };
89   }
90   
91   public Query getSpanNearQuery(
92           IndexReader reader,
93           String fieldName,
94           float boost,
95           BasicQueryFactory qf) throws IOException {
96     SpanQuery[] spanNearClauses = new SpanQuery[getNrSubQueries()];
97     Iterator<?> sqi = getSubQueriesIterator();
98     int qi = 0;
99     while (sqi.hasNext()) {
100       SpanNearClauseFactory sncf = new SpanNearClauseFactory(reader, fieldName, qf);
101       
102       ((DistanceSubQuery)sqi.next()).addSpanQueries(sncf);
103       if (sncf.size() == 0) { /* distance operator requires all sub queries */
104         while (sqi.hasNext()) { /* produce evt. error messages but ignore results */
105           ((DistanceSubQuery)sqi.next()).addSpanQueries(sncf);
106           sncf.clear();
107         }
108         return SrndQuery.theEmptyLcnQuery;
109       }
110       
111       spanNearClauses[qi] = sncf.makeSpanNearClause();
112
113       qi++;
114     }
115     
116     SpanNearQuery r = new SpanNearQuery(spanNearClauses, getOpDistance() - 1, subQueriesOrdered());
117     r.setBoost(boost);
118     return r;
119   }
120 }
121