View Javadoc

1   /*
2    * ModeShape (http://www.modeshape.org)
3    * See the COPYRIGHT.txt file distributed with this work for information
4    * regarding copyright ownership.  Some portions may be licensed
5    * to Red Hat, Inc. under one or more contributor license agreements.
6    * See the AUTHORS.txt file in the distribution for a full listing of 
7    * individual contributors.
8    *
9    * ModeShape is free software. Unless otherwise indicated, all code in ModeShape
10   * is licensed to you under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation; either version 2.1 of
12   * the License, or (at your option) any later version.
13   * 
14   * ModeShape is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this software; if not, write to the Free
21   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23   */
24  package org.modeshape.search.lucene.query;
25  
26  import org.apache.lucene.index.IndexReader;
27  import org.apache.lucene.search.Explanation;
28  import org.apache.lucene.search.Query;
29  import org.apache.lucene.search.Scorer;
30  import org.apache.lucene.search.Searcher;
31  import org.apache.lucene.search.Similarity;
32  import org.apache.lucene.search.Weight;
33  
34  /**
35   * A Lucene {@link Query} implementation that always matches no documents.
36   */
37  public class MatchNoneQuery extends Query {
38  
39      private static final long serialVersionUID = 1L;
40  
41      /**
42       * Construct a query that always returns no documents.
43       */
44      public MatchNoneQuery() {
45      }
46  
47      /**
48       * {@inheritDoc}
49       * 
50       * @see org.apache.lucene.search.Query#createWeight(org.apache.lucene.search.Searcher)
51       */
52      @Override
53      public Weight createWeight( Searcher searcher ) {
54          return new NoneWeight();
55      }
56  
57      /**
58       * {@inheritDoc}
59       * 
60       * @see org.apache.lucene.search.Query#clone()
61       */
62      @Override
63      public Object clone() {
64          return new MatchNoneQuery();
65      }
66  
67      /**
68       * {@inheritDoc}
69       * 
70       * @see org.apache.lucene.search.Query#toString(java.lang.String)
71       */
72      @Override
73      public String toString( String field ) {
74          return "NO DOCS";
75      }
76  
77      /**
78       * Calculates query weights and builds query scores for our NOT queries.
79       */
80      protected class NoneWeight extends Weight {
81          private static final long serialVersionUID = 1L;
82  
83          protected NoneWeight() {
84          }
85  
86          /**
87           * {@inheritDoc}
88           * 
89           * @see org.apache.lucene.search.Weight#getQuery()
90           */
91          @Override
92          public Query getQuery() {
93              return MatchNoneQuery.this;
94          }
95  
96          /**
97           * {@inheritDoc}
98           * <p>
99           * This implementation always returns a weight factor of 1.0.
100          * </p>
101          * 
102          * @see org.apache.lucene.search.Weight#getValue()
103          */
104         @Override
105         public float getValue() {
106             return 1.0f; // weight factor of 1.0
107         }
108 
109         /**
110          * {@inheritDoc}
111          * <p>
112          * This implementation always returns a normalization factor of 1.0.
113          * </p>
114          * 
115          * @see org.apache.lucene.search.Weight#sumOfSquaredWeights()
116          */
117         @Override
118         public float sumOfSquaredWeights() {
119             return 1.0f; // normalization factor of 1.0
120         }
121 
122         /**
123          * {@inheritDoc}
124          * <p>
125          * This implementation always does nothing, as there is nothing to normalize.
126          * </p>
127          * 
128          * @see org.apache.lucene.search.Weight#normalize(float)
129          */
130         @Override
131         public void normalize( float norm ) {
132             // No need to do anything here
133         }
134 
135         /**
136          * {@inheritDoc}
137          * 
138          * @see org.apache.lucene.search.Weight#scorer(org.apache.lucene.index.IndexReader, boolean, boolean)
139          */
140         @Override
141         public Scorer scorer( IndexReader reader,
142                               boolean scoreDocsInOrder,
143                               boolean topScorer ) {
144             return new NoneScorer();
145         }
146 
147         /**
148          * {@inheritDoc}
149          * 
150          * @see org.apache.lucene.search.Weight#explain(org.apache.lucene.index.IndexReader, int)
151          */
152         @Override
153         public Explanation explain( IndexReader reader,
154                                     int doc ) {
155             return new Explanation(getValue(), "NO VALUES");
156         }
157     }
158 
159     /**
160      * A scorer for the NOT query that iterates over documents (in increasing docId order), using the given scorer implementation
161      * for the operand of the NOT.
162      */
163     protected static class NoneScorer extends Scorer {
164         private int docId = -1;
165 
166         protected NoneScorer() {
167             // We don't care which Similarity we have, because we don't use it. So get the default.
168             super(Similarity.getDefault());
169         }
170 
171         /**
172          * {@inheritDoc}
173          * 
174          * @see org.apache.lucene.search.DocIdSetIterator#docID()
175          */
176         @Override
177         public int docID() {
178             return docId;
179         }
180 
181         /**
182          * {@inheritDoc}
183          * 
184          * @see org.apache.lucene.search.DocIdSetIterator#nextDoc()
185          */
186         @Override
187         public int nextDoc() {
188             docId = Scorer.NO_MORE_DOCS;
189             return docId;
190         }
191 
192         /**
193          * {@inheritDoc}
194          * 
195          * @see org.apache.lucene.search.DocIdSetIterator#advance(int)
196          */
197         @Override
198         public int advance( int target ) {
199             return Scorer.NO_MORE_DOCS;
200         }
201 
202         /**
203          * {@inheritDoc}
204          * <p>
205          * This method always returns a score of 1.0 for the current document, since only those documents that satisfy the NOT are
206          * scored by this scorer.
207          * </p>
208          * 
209          * @see org.apache.lucene.search.Scorer#score()
210          */
211         @Override
212         public float score() {
213             return 1.0f;
214         }
215     }
216 }