pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / src / java / org / apache / lucene / search / MultiCollector.java
1 package org.apache.lucene.search;
2
3 /**
4  * Licensed to the Apache Software Foundation (ASF) under one or more
5  * contributor license agreements.  See the NOTICE file distributed with
6  * this work for additional information regarding copyright ownership.
7  * The ASF licenses this file to You under the Apache License, Version 2.0
8  * (the "License"); you may not use this file except in compliance with
9  * the License.  You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 import java.io.IOException;
21
22 import org.apache.lucene.index.IndexReader;
23 import org.apache.lucene.search.Collector;
24 import org.apache.lucene.search.Scorer;
25
26 /**
27  * A {@link Collector} which allows running a search with several
28  * {@link Collector}s. It offers a static {@link #wrap} method which accepts a
29  * list of collectors and wraps them with {@link MultiCollector}, while
30  * filtering out the <code>null</code> null ones.
31  */
32 public class MultiCollector extends Collector {
33
34   /**
35    * Wraps a list of {@link Collector}s with a {@link MultiCollector}. This
36    * method works as follows:
37    * <ul>
38    * <li>Filters out the <code>null</code> collectors, so they are not used
39    * during search time.
40    * <li>If the input contains 1 real collector (i.e. non-<code>null</code> ),
41    * it is returned.
42    * <li>Otherwise the method returns a {@link MultiCollector} which wraps the
43    * non-<code>null</code> ones.
44    * </ul>
45    * 
46    * @throws IllegalArgumentException
47    *           if either 0 collectors were input, or all collectors are
48    *           <code>null</code>.
49    */
50   public static Collector wrap(Collector... collectors) {
51     // For the user's convenience, we allow null collectors to be passed.
52     // However, to improve performance, these null collectors are found
53     // and dropped from the array we save for actual collection time.
54     int n = 0;
55     for (Collector c : collectors) {
56       if (c != null) {
57         n++;
58       }
59     }
60
61     if (n == 0) {
62       throw new IllegalArgumentException("At least 1 collector must not be null");
63     } else if (n == 1) {
64       // only 1 Collector - return it.
65       Collector col = null;
66       for (Collector c : collectors) {
67         if (c != null) {
68           col = c;
69           break;
70         }
71       }
72       return col;
73     } else if (n == collectors.length) {
74       return new MultiCollector(collectors);
75     } else {
76       Collector[] colls = new Collector[n];
77       n = 0;
78       for (Collector c : collectors) {
79         if (c != null) {
80           colls[n++] = c;
81         }
82       }
83       return new MultiCollector(colls);
84     }
85   }
86   
87   private final Collector[] collectors;
88
89   private MultiCollector(Collector... collectors) {
90     this.collectors = collectors;
91   }
92
93   @Override
94   public boolean acceptsDocsOutOfOrder() {
95     for (Collector c : collectors) {
96       if (!c.acceptsDocsOutOfOrder()) {
97         return false;
98       }
99     }
100     return true;
101   }
102
103   @Override
104   public void collect(int doc) throws IOException {
105     for (Collector c : collectors) {
106       c.collect(doc);
107     }
108   }
109
110   @Override
111   public void setNextReader(IndexReader reader, int o) throws IOException {
112     for (Collector c : collectors) {
113       c.setNextReader(reader, o);
114     }
115   }
116
117   @Override
118   public void setScorer(Scorer s) throws IOException {
119     for (Collector c : collectors) {
120       c.setScorer(s);
121     }
122   }
123
124 }