001: /*
002: * NEMESIS-FORUM.
003: * Copyright (C) 2002 David Laurent(lithium2@free.fr). All rights reserved.
004: *
005: * Copyright (c) 2000 The Apache Software Foundation. All rights reserved.
006: *
007: * Copyright (C) 2001 Yasna.com. All rights reserved.
008: *
009: * Copyright (C) 2000 CoolServlets.com. All rights reserved.
010: *
011: * NEMESIS-FORUM. is free software; you can redistribute it and/or
012: * modify it under the terms of the Apache Software License, Version 1.1,
013: * or (at your option) any later version.
014: *
015: * NEMESIS-FORUM core framework, NEMESIS-FORUM backoffice, NEMESIS-FORUM frontoffice
016: * application are parts of NEMESIS-FORUM and are distributed under
017: * same terms of licence.
018: *
019: *
020: * NEMESIS-FORUM includes software developed by the Apache Software Foundation (http://www.apache.org/)
021: * and software developed by CoolServlets.com (http://www.coolservlets.com).
022: * and software developed by Yasna.com (http://www.yasna.com).
023: *
024: */
025:
026: package org.nemesis.forum.search;
027:
028: import java.io.File;
029: import java.util.Date;
030: import java.util.Iterator;
031:
032: import org.apache.commons.logging.Log;
033: import org.apache.commons.logging.LogFactory;
034: import org.apache.lucene.analysis.Analyzer;
035: import org.apache.lucene.analysis.standard.StandardAnalyzer;
036: import org.apache.lucene.document.Document;
037: import org.apache.lucene.index.IndexReader;
038: import org.apache.lucene.queryParser.QueryParser;
039: import org.apache.lucene.search.BooleanQuery;
040: import org.apache.lucene.search.DateFilter;
041: import org.apache.lucene.search.Hits;
042: import org.apache.lucene.search.IndexSearcher;
043: import org.apache.lucene.search.Query;
044: import org.nemesis.forum.Forum;
045: import org.nemesis.forum.ForumThread;
046: import org.nemesis.forum.User;
047: import org.nemesis.forum.config.ConfigLoader;
048:
049: /**
050: * @author dlaurent
051: */
052: public class Searcher {
053: static protected Log log = LogFactory.getLog(Searcher.class);
054:
055: private static Analyzer analyzer = new StandardAnalyzer();
056: private static final int MAX_RESULTS_SIZE = 500;
057:
058: private int[] results = null;
059:
060: private String queryString = "";
061: private Date beforeDate = null;
062: private Date afterDate = null;
063: private User user = null;
064: private ForumThread thread = null;
065:
066: private Forum forum = null;
067:
068: public Searcher(Forum forum) {
069: this .forum = forum;
070: }
071:
072: public void setQueryString(String queryString) {
073: this .queryString = queryString;
074: results = null;
075: }
076:
077: public String getQueryString() {
078: return queryString;
079: }
080:
081: public void setBeforeDate(Date beforeDate) {
082: this .beforeDate = beforeDate;
083: results = null;
084: }
085:
086: public Date getBeforeDate() {
087: return beforeDate;
088: }
089:
090: public void setAfterDate(Date afterDate) {
091: this .afterDate = afterDate;
092: results = null;
093: }
094:
095: public Date getAfterDate() {
096: return afterDate;
097: }
098:
099: public User getFilteredUser() {
100: return user;
101: }
102:
103: public void filterOnUser(User user) {
104: this .user = user;
105: results = null;
106: }
107:
108: public ForumThread getFilteredThread() {
109: return thread;
110: }
111:
112: public void filterOnThread(ForumThread thread) {
113: this .thread = thread;
114: results = null;
115: }
116:
117: public int resultCount() {
118: if (results == null) {
119: executeQuery();
120: }
121: return results.length;
122: }
123:
124: public Iterator results() {
125: if (results == null) {
126: executeQuery();
127: }
128: return new QueryIterator(forum, results);
129: }
130:
131: public Iterator results(int startIndex, int numResults) {
132: if (results == null) {
133: executeQuery();
134: }
135: return new QueryIterator(forum, results, startIndex, numResults);
136: }
137:
138: private void executeQuery() {
139: IndexReader reader = null;
140: try {
141: reader = IndexReader.open(new File(ConfigLoader
142: .getInstance().getConfig().getDataDir(), "index"));
143: IndexSearcher searcher = new IndexSearcher(reader);
144:
145: Query bodyQuery = QueryParser.parse(queryString, "body",
146: analyzer);
147: Query subjectQuery = QueryParser.parse(queryString,
148: "subject", analyzer);
149: String forumID = Integer.toString(forum.getID());
150: BooleanQuery comboQuery = new BooleanQuery();
151: comboQuery.add(subjectQuery, false, false);
152: comboQuery.add(bodyQuery, false, false);
153:
154: MultiFilter multiFilter = new MultiFilter(3);
155:
156: //Forum filter
157: multiFilter.add(new FieldFilter("forumID", forumID));
158:
159: //Date filter
160: if (beforeDate != null || afterDate != null) {
161: if (beforeDate != null && afterDate != null) {
162: multiFilter.add(new DateFilter("creationDate",
163: beforeDate, afterDate));
164: } else if (beforeDate == null) {
165: multiFilter.add(DateFilter.After("creationDate",
166: afterDate));
167: } else {
168: multiFilter.add(DateFilter.Before("creationDate",
169: beforeDate));
170: }
171: }
172:
173: //User filter
174: if (user != null) {
175: String userID = Integer.toString(user.getID());
176: multiFilter.add(new FieldFilter("userID", userID));
177: }
178:
179: //Thread filter
180: if (thread != null) {
181: String threadID = Integer.toString(thread.getID());
182: multiFilter.add(new FieldFilter("threadID", threadID));
183: }
184:
185: Hits hits = searcher.search(comboQuery, multiFilter);
186: //Don't return more search results than the maximum number allowed.
187: int numResults = hits.length() < MAX_RESULTS_SIZE ? hits
188: .length() : MAX_RESULTS_SIZE;
189: int[] messages = new int[numResults];
190: for (int i = 0; i < numResults; i++) {
191: messages[i] = Integer.parseInt(((Document) hits.doc(i))
192: .get("messageID"));
193: }
194: results = messages;
195:
196: } catch (Throwable e) {
197: log.error("", e);
198: results = new int[0];
199: } finally {
200: try {
201: reader.close();
202: } catch (Exception e) {
203: }
204:
205: }
206: }
207:
208: }
|