001: /*
002: * regain - A file search engine providing plenty of formats
003: * Copyright (C) 2004 Til Schneider
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: *
019: * Contact: Til Schneider, info@murfman.de
020: *
021: * CVS information:
022: * $RCSfile$
023: * $Source$
024: * $Date: 2005-08-20 13:20:15 +0200 (Sa, 20 Aug 2005) $
025: * $Author: til132 $
026: * $Revision: 174 $
027: */
028: package net.sf.regain.search.results;
029:
030: import java.io.IOException;
031:
032: import net.sf.regain.RegainException;
033:
034: import org.apache.lucene.document.Document;
035: import org.apache.lucene.search.Hits;
036:
037: /**
038: * Holds the results of a search on a multiple indexes.
039: *
040: * @author Til Schneider, www.murfman.de
041: */
042: public class MultipleSearchResults implements SearchResults {
043:
044: /**
045: * The results of from the single searches that should be merged by this
046: * MultipleSearchResults.
047: */
048: private SingleSearchResults[] mChildResultsArr;
049:
050: /** The merged hits. */
051: private MergedHits mMergedHits;
052:
053: /** The cached search time. */
054: private int mSearchTime = -1;
055:
056: /**
057: * Creates a new instance of MultipleSearchResults.
058: *
059: * @param childResultsArr The results of from the single searches that should
060: * be merged by this MultipleSearchResults.
061: */
062: public MultipleSearchResults(SingleSearchResults[] childResultsArr) {
063: mChildResultsArr = childResultsArr;
064:
065: Hits[] hitsArr = new Hits[mChildResultsArr.length];
066: for (int i = 0; i < hitsArr.length; i++) {
067: hitsArr[i] = mChildResultsArr[i].getHits();
068: }
069: mMergedHits = new MergedHits(hitsArr);
070: }
071:
072: /**
073: * Gets the number of hits the search had.
074: *
075: * @return the number of hits the search had.
076: */
077: public int getHitCount() {
078: return mMergedHits.length();
079: }
080:
081: /**
082: * Gets the document of one hit.
083: *
084: * @param index The index of the hit.
085: * @return the document of one hit.
086: *
087: * @throws RegainException If getting the document failed.
088: * @see Document
089: */
090: public Document getHitDocument(int index) throws RegainException {
091: try {
092: return mMergedHits.doc(index);
093: } catch (IOException exc) {
094: throw new RegainException(
095: "Error while getting document of merged search hit #"
096: + index, exc);
097: }
098: }
099:
100: /**
101: * Gets the score of one hit.
102: *
103: * @param index The index of the hit.
104: * @return the score of one hit.
105: *
106: * @throws RegainException If getting the score failed.
107: * @see Hits#score(int)
108: */
109: public float getHitScore(int index) throws RegainException {
110: try {
111: return mMergedHits.score(index);
112: } catch (IOException exc) {
113: throw new RegainException(
114: "Error while getting score of merged search hit #"
115: + index, exc);
116: }
117: }
118:
119: /**
120: * Gets the SingleSearchResults a certain hit came from.
121: *
122: * @param index The index of the hit in the merged hits.
123: * @return The SingleSearchResults the hit came from.
124: * @throws RegainException If getting the index of the SingleSearchResults failed.
125: */
126: private SingleSearchResults getResultsForHit(int index)
127: throws RegainException {
128: // Get the hits index from the MergedHits
129: int hitsIndex = mMergedHits.getHitsIndex(index);
130:
131: // NOTE: As we added the hits in the same order as our child results
132: // to MergedHits, the hits index is at the same time the results index.
133: return mChildResultsArr[hitsIndex];
134: }
135:
136: /**
137: * Gets the url from a hit and rewrites it according to the rewrite rules
138: * specified in the index config.
139: *
140: * @param index The index of the hit to get the URL for.
141: * @return The url of the wanted hit.
142: * @throws RegainException If getting the hit document failed.
143: */
144: public String getHitUrl(int index) throws RegainException {
145: // Get the SingleSearchResults the hit came from
146: SingleSearchResults results = getResultsForHit(index);
147:
148: // Get the index of the hit in the SingleSearchResults
149: int hitsPosition = mMergedHits.getHitsPosition(index);
150:
151: // Get the hit URL
152: return results.getHitUrl(hitsPosition);
153: }
154:
155: /**
156: * Gets the name of the index a hit comes from.
157: *
158: * @param index The index of the hit to get the index name for.
159: * @return The name of the index a hit comes from.
160: * @throws RegainException If getting the index name failed.
161: */
162: public String getHitIndexName(int index) throws RegainException {
163: // Get the SingleSearchResults the hit came from
164: SingleSearchResults results = getResultsForHit(index);
165:
166: // Get the index of the hit in the SingleSearchResults
167: int hitsPosition = mMergedHits.getHitsPosition(index);
168:
169: // Gets the index name;
170: return results.getHitIndexName(hitsPosition);
171: }
172:
173: /**
174: * Gets whether a hit should be opened in a new window.
175: *
176: * @param index The index of the hit.
177: * @return Whether the hit should be opened in a new window.
178: * @throws RegainException If the hit could not be read.
179: */
180: public boolean getOpenHitInNewWindow(int index)
181: throws RegainException {
182: // Get the SingleSearchResults the hit came from
183: SingleSearchResults results = getResultsForHit(index);
184:
185: // Get the index of the hit in the SingleSearchResults
186: int hitsPosition = mMergedHits.getHitsPosition(index);
187:
188: // Get whether a hit should be opened in a new window.
189: return results.getOpenHitInNewWindow(hitsPosition);
190: }
191:
192: /**
193: * Gets whether the file-to-http-bridge should be used for a certain hit.
194: * <p>
195: * Mozilla browsers have a security mechanism that blocks loading file-URLs
196: * from pages loaded via http. To be able to load files from the search
197: * results, regain offers the file-to-http-bridge that provides all files that
198: * are listed in the index via http.
199: *
200: * @param index The index of the hit.
201: * @return Whether the file-to-http-bridge should be used.
202: * @throws RegainException If the hit could not be read.
203: */
204: public boolean getUseFileToHttpBridgeForHit(int index)
205: throws RegainException {
206: // Get the SingleSearchResults the hit came from
207: SingleSearchResults results = getResultsForHit(index);
208:
209: // Get the index of the hit in the SingleSearchResults
210: int hitsPosition = mMergedHits.getHitsPosition(index);
211:
212: // Get whether a hit should be opened in a new window.
213: return results.getUseFileToHttpBridgeForHit(hitsPosition);
214: }
215:
216: /**
217: * Gets the time the search took in milliseconds.
218: *
219: * @return The search time.
220: */
221: public int getSearchTime() {
222: if (mSearchTime == -1) {
223: mSearchTime = 0;
224: for (int i = 0; i < mChildResultsArr.length; i++) {
225: mSearchTime += mChildResultsArr[i].getSearchTime();
226: }
227: }
228:
229: return mSearchTime;
230: }
231:
232: }
|