001: /*
002: * $Header: /cvsroot/mvnforum/mvnforum/src/com/mvnforum/search/attachment/AttachmentSearchQuery.java,v 1.7 2007/10/16 05:41:00 lexuanttkhtn Exp $
003: * $Author: lexuanttkhtn $
004: * $Revision: 1.7 $
005: * $Date: 2007/10/16 05:41:00 $
006: *
007: * ====================================================================
008: *
009: * Copyright (C) 2002-2007 by MyVietnam.net
010: *
011: * All copyright notices regarding mvnForum MUST remain
012: * intact in the scripts and in the outputted HTML.
013: * The "powered by" text/logo with a link back to
014: * http://www.mvnForum.com and http://www.MyVietnam.net in
015: * the footer of the pages MUST remain visible when the pages
016: * are viewed on the internet or intranet.
017: *
018: * This program is free software; you can redistribute it and/or modify
019: * it under the terms of the GNU General Public License as published by
020: * the Free Software Foundation; either version 2 of the License, or
021: * any later version.
022: *
023: * This program is distributed in the hope that it will be useful,
024: * but WITHOUT ANY WARRANTY; without even the implied warranty of
025: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
026: * GNU General Public License for more details.
027: *
028: * You should have received a copy of the GNU General Public License
029: * along with this program; if not, write to the Free Software
030: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
031: *
032: * Support can be obtained from support forums at:
033: * http://www.mvnForum.com/mvnforum/index
034: *
035: * Correspondence and Marketing Questions can be sent to:
036: * info at MyVietnam net
037: *
038: * @author: Minh Nguyen
039: * @author: Dejan Krsmanovic dejan_krsmanovic@yahoo.com
040: */
041: package com.mvnforum.search.attachment;
042:
043: import java.io.IOException;
044: import java.sql.Timestamp;
045: import java.util.ArrayList;
046: import java.util.Collection;
047: import java.util.Iterator;
048:
049: import net.myvietnam.mvncore.exception.DatabaseException;
050: import net.myvietnam.mvncore.exception.ObjectNotFoundException;
051:
052: import org.apache.commons.logging.Log;
053: import org.apache.commons.logging.LogFactory;
054: import org.apache.lucene.analysis.Analyzer;
055: import org.apache.lucene.document.DateTools;
056: import org.apache.lucene.document.Document;
057: import org.apache.lucene.document.DateTools.Resolution;
058: import org.apache.lucene.index.Term;
059: import org.apache.lucene.queryParser.ParseException;
060: import org.apache.lucene.queryParser.QueryParser;
061: import org.apache.lucene.search.BooleanClause;
062: import org.apache.lucene.search.BooleanQuery;
063: import org.apache.lucene.search.Filter;
064: import org.apache.lucene.search.Hits;
065: import org.apache.lucene.search.IndexSearcher;
066: import org.apache.lucene.search.Query;
067: import org.apache.lucene.search.RangeFilter;
068: import org.apache.lucene.search.TermQuery;
069: import org.apache.lucene.store.Directory;
070:
071: import com.mvnforum.auth.MVNForumPermission;
072: import com.mvnforum.db.AttachmentBean;
073: import com.mvnforum.db.DAOFactory;
074: import com.mvnforum.db.ForumBean;
075: import com.mvnforum.db.ForumCache;
076: import com.mvnforum.service.MvnForumServiceFactory;
077: import com.mvnforum.service.SearchService;
078:
079: public class AttachmentSearchQuery {
080:
081: private static Log log = LogFactory
082: .getLog(AttachmentSearchQuery.class);
083:
084: // constant for search by time
085: public static final int SEARCH_ANY_DATE = 0;
086:
087: public static final int SEARCH_NEWER = 1;
088: public static final int SEARCH_OLDER = 2;
089:
090: private int forumId = 0;
091:
092: private String searchString = null;
093: private String searchFileName = null;
094:
095: private Timestamp fromDate = null;
096: private Timestamp toDate = null;
097:
098: private int hitCount = 0;
099: private Collection searchResult = null;
100:
101: /**
102: * Id of forum where post belongs. Set to -1 if all forums should be searched
103: * @param forumId
104: */
105: public void setForumId(int forumId) {
106: this .forumId = forumId;
107: }
108:
109: /**
110: * Set string that should be searched for.
111: * @param searchString
112: */
113: public void setSearchString(String searchString) {
114: this .searchString = searchString;
115: }
116:
117: public void setSearchFileName(String searchFileName) {
118: this .searchFileName = searchFileName;
119: }
120:
121: public void setFromDate(Timestamp fromDate) {
122: this .fromDate = fromDate;
123: }
124:
125: public void setToDate(Timestamp toDate) {
126: this .toDate = toDate;
127: }
128:
129: // Note that with IndexSearcher, the directory is closed automatically
130: protected IndexSearcher getSearcher(Directory directory)
131: throws IOException {
132: try {
133: IndexSearcher searcher = new IndexSearcher(directory);
134: return searcher;
135: } catch (IOException ex) {
136: // we throw new IOException because the original exception
137: // contain sensitive directory information
138: log
139: .error(
140: "Cannot access the lucene search index for query. Please check if you have configed mvnForumHome properly. You can also go to Admin Zone to rebuild the Lucene index files.",
141: ex);
142: //@todo : localize me
143: throw new IOException(
144: "Cannot access the lucene search index. Please report this error to web site Administrator (check mvnForumHome or rebuild Lucene index).");
145: }
146: }
147:
148: public void searchDocuments(int offset, int rowsToReturn,
149: MVNForumPermission permission) throws IOException,
150: DatabaseException, ObjectNotFoundException {
151:
152: // Now check if at least one of these input is present: key, filename
153: if ((searchString == null || searchString.equals(""))
154: && (searchFileName == null || searchFileName.equals(""))) {
155: // should throw an Exception here, if not, later call getAttachmentResult() will return null
156: return;
157: }
158: //Build the query
159: BooleanQuery query = new BooleanQuery();
160: //query.add(BooleanClause.)
161:
162: try {
163: Query desQuery = getDescriptionQuery();
164: if (desQuery != null) {
165: query.add(desQuery, BooleanClause.Occur.MUST);
166: log.debug("desQuery = " + desQuery);
167: }
168:
169: Query fileNameQuery = getFileNameQuery();
170: if (fileNameQuery != null) {
171: query.add(fileNameQuery, BooleanClause.Occur.MUST);
172: log.debug("fileNameQuery = " + fileNameQuery);
173: }
174:
175: Query categoryForumQuery = getCategoryForumQuery(permission);
176: if (categoryForumQuery != null) {
177: log.debug("categoryForumQuery = " + categoryForumQuery);
178: query.add(categoryForumQuery, BooleanClause.Occur.MUST);
179: }
180: } catch (ParseException e) {
181: log.error("Cannot parse the search query", e);
182: }
183: log.debug("booleanQuery = " + query);
184:
185: RangeFilter dateFilter = null;
186: //Add date filter if some of dates provided
187: if (fromDate != null && toDate != null) {
188: dateFilter = new RangeFilter(
189: AttachmentIndexer.FIELD_ATTACHMENT_DATE, DateTools
190: .dateToString(fromDate,
191: Resolution.MILLISECOND), DateTools
192: .dateToString(toDate,
193: Resolution.MILLISECOND), true, true);
194: } else if (fromDate != null) {
195: dateFilter = RangeFilter.More(
196: AttachmentIndexer.FIELD_ATTACHMENT_DATE, DateTools
197: .dateToString(fromDate,
198: Resolution.MILLISECOND));
199: } else if (toDate != null) {
200: dateFilter = RangeFilter.Less(
201: AttachmentIndexer.FIELD_ATTACHMENT_DATE, DateTools
202: .dateToString(toDate,
203: Resolution.MILLISECOND));
204: }
205:
206: Filter filter = null;
207:
208: if (dateFilter != null) {
209: filter = dateFilter;
210: }
211: //Now search the documents
212: Directory directory = null;
213: IndexSearcher searcher = null;
214: try {
215: SearchService service = MvnForumServiceFactory
216: .getMvnForumService().getSearchService();
217: directory = service.getSearchAttachmentIndexDir();
218:
219: //directory.
220: searcher = getSearcher(directory);
221:
222: //If filter set then use it
223: Hits attachHits = null;
224: if (filter != null) {
225: attachHits = searcher.search(query, filter);
226: } else {
227: attachHits = searcher.search(query);
228: }
229:
230: hitCount = attachHits.length();
231:
232: searchResult = getAttachments(attachHits, offset,
233: rowsToReturn);
234: } catch (IOException ex) {
235: throw ex;
236: } finally {
237: // NOTE that we don't close directory because searcher.close() already do that
238: if (searcher != null) {
239: try {
240: searcher.close();
241: } catch (IOException ex) {
242: log.debug("Error closing Lucene IndexSearcher", ex);
243: }
244: }
245: }
246: }
247:
248: public int getHitCount() {
249: return hitCount;
250: }
251:
252: public Collection getAttachmentResult() {
253: if (searchResult == null) {
254: //create an empty list, in case result is null
255: searchResult = new ArrayList();
256: }
257: return searchResult;
258: }
259:
260: private Collection getAttachments(Hits attachHits, int offset,
261: int rowsToReturn) throws IOException,
262: ObjectNotFoundException, DatabaseException {
263:
264: if (offset < 0)
265: throw new IllegalArgumentException(
266: "The offset < 0 is not allowed.");
267: if (rowsToReturn <= 0)
268: throw new IllegalArgumentException(
269: "The rowsToReturn <= 0 is not allowed.");
270: //int count = offset + rowsToReturn;
271: //int hitCount = getHitCount();
272: ArrayList retValue = new ArrayList(hitCount);
273: for (int i = offset; (i < offset + rowsToReturn)
274: && (i < hitCount); i++) {
275: Document attachDocument = attachHits.doc(i);
276: int attachDocumentID = Integer.parseInt(attachDocument
277: .get(AttachmentIndexer.FIELD_ATTACHMENT_ID));
278: AttachmentBean attachBean = DAOFactory.getAttachmentDAO()
279: .getAttachment(attachDocumentID);
280: retValue.add(attachBean);
281: }
282: return retValue;
283: }
284:
285: private Query getDescriptionQuery() throws ParseException {
286: if (searchString == null || searchString.equals("")) {
287: return null;
288: }
289:
290: Analyzer analyzer = AttachmentIndexer.getAnalyzer();
291: BooleanQuery descriptionQuery = new BooleanQuery();
292: Query DesQuery = new QueryParser(
293: AttachmentIndexer.FIELD_ATTACHMENT_DESCRIPTION,
294: analyzer).parse(searchString);
295: descriptionQuery.add(DesQuery, BooleanClause.Occur.SHOULD);
296: return descriptionQuery;
297: }
298:
299: private Query getFileNameQuery() throws ParseException {
300: if (searchFileName == null || searchFileName.equals("")) {
301: return null;
302: }
303:
304: Analyzer analyzer = AttachmentIndexer.getAnalyzer();
305: BooleanQuery fileNameQuery = new BooleanQuery();
306: Query nameQuery = new QueryParser(
307: AttachmentIndexer.FIELD_ATTACHMENT_NAME, analyzer)
308: .parse(searchFileName);
309: fileNameQuery.add(nameQuery, BooleanClause.Occur.SHOULD);
310: return fileNameQuery;
311: }
312:
313: private Query getCategoryForumQuery(MVNForumPermission permission)
314: throws DatabaseException {
315: BooleanQuery categoryForumQuery = new BooleanQuery();
316: if (forumId == 0) {
317: // search all forum
318: Collection forumBeans = ForumCache.getInstance().getBeans();
319: for (Iterator iter = forumBeans.iterator(); iter.hasNext();) {
320: ForumBean forumBean = (ForumBean) iter.next();
321: int currentForumID = forumBean.getForumID();
322: if ((forumBean.getForumStatus() != ForumBean.FORUM_STATUS_DISABLED)
323: && permission.canGetAttachment(currentForumID)) {
324:
325: Term forumTerm = new Term(
326: AttachmentIndexer.FIELD_FORUM_ID, String
327: .valueOf(currentForumID));
328: Query forumQuery = new TermQuery(forumTerm);
329: categoryForumQuery.add(forumQuery,
330: BooleanClause.Occur.SHOULD);
331: }
332: }
333: } else if (forumId > 0) {
334: // search in forum
335: Term forumTerm = new Term(AttachmentIndexer.FIELD_FORUM_ID,
336: String.valueOf(forumId));
337: Query forumQuery = new TermQuery(forumTerm);
338: categoryForumQuery
339: .add(forumQuery, BooleanClause.Occur.MUST);
340: } else if (forumId < 0) {
341: // search in category
342: int categoryID = -forumId;//category is the negative value of forumID in this case
343: Collection forumBeans = ForumCache.getInstance().getBeans();
344: for (Iterator iter = forumBeans.iterator(); iter.hasNext();) {
345: ForumBean forumBean = (ForumBean) iter.next();
346: if (forumBean.getCategoryID() == categoryID) {
347: int currentForumID = forumBean.getForumID();
348: if ((forumBean.getForumStatus() != ForumBean.FORUM_STATUS_DISABLED)
349: && permission
350: .canGetAttachment(currentForumID)) {
351:
352: Term forumTerm = new Term(
353: AttachmentIndexer.FIELD_FORUM_ID,
354: String.valueOf(currentForumID));
355: Query forumQuery = new TermQuery(forumTerm);
356: categoryForumQuery.add(forumQuery,
357: BooleanClause.Occur.SHOULD);
358: }
359: }
360: }
361: }
362: return categoryForumQuery;
363: }
364:
365: }
|