📄 dbquery.java
字号:
/**
* $RCSfile: DbQuery.java,v $
* $Revision: 1.1.1.1 $
* $Date: 2002/09/09 13:50:57 $
*
* New Jive from Jdon.com.
*
* This software is the proprietary information of CoolServlets, Inc.
* Use is subject to license terms.
*/
package com.jivesoftware.forum.database;
import java.util.Date;
import java.util.Iterator;
import java.io.IOException;
import java.io.File;
import org.apache.lucene.analysis.*;
import org.apache.lucene.analysis.standard.*;
import org.apache.lucene.document.*;
import org.apache.lucene.store.*;
import org.apache.lucene.search.*;
import org.apache.lucene.queryParser.*;
import org.apache.lucene.index.*;
import com.jivesoftware.forum.*;
/**
* Database implementation of the Query interface using Lucene.
*/
public class DbQuery implements com.jivesoftware.forum.Query {
/**
* The query String to use for searching. Set it the empty String by
* default so that if the user fails to set a query String, there won't
* be errors.
*/
private String queryString = "";
private java.util.Date beforeDate = null;
private java.util.Date afterDate = null;
private User user = null;
private ForumThread thread = null;
/**
* The results of the query as an array of message ID's.
*/
private long [] results = null;
private Forum [] forums;
private DbForumFactory factory;
/**
* The maximum number of results to return with a search.
*/
private static final int MAX_RESULTS_SIZE = 1500;
private static String indexPath = null;
private static IndexReader reader;
private static Searcher searcher;
private static Directory searchDirectory = null;
private static long indexLastModified;
public DbQuery(Forum [] forums, DbForumFactory factory) {
this.forums = forums;
this.factory = factory;
}
public void setQueryString(String queryString) {
this.queryString = queryString;
//reset results
results = null;
}
public String getQueryString() {
return queryString;
}
public void setBeforeDate(java.util.Date beforeDate) {
this.beforeDate = beforeDate;
//reset results
results = null;
}
public java.util.Date getBeforeDate() {
return beforeDate;
}
public void setAfterDate(java.util.Date afterDate){
this.afterDate = afterDate;
//reset results
results = null;
}
public java.util.Date getAfterDate(){
return afterDate;
}
public User getFilteredUser() {
return user;
}
public void filterOnUser(User user) {
this.user = user;
results = null;
}
public ForumThread getFilteredThread() {
return thread;
}
public void filterOnThread(ForumThread thread) {
this.thread = thread;
results = null;
}
public int resultCount() {
if (results == null) {
executeQuery();
}
return results.length;
}
public Iterator results() {
if (results == null) {
executeQuery();
}
return new DatabaseObjectIterator(JiveGlobals.MESSAGE, results, factory);
}
public Iterator results(int startIndex, int numResults){
if (results == null) {
executeQuery();
}
int endIndex = startIndex + numResults - 1 ;
if (endIndex > results.length - 1) {
endIndex = results.length - 1;
}
int length = endIndex - startIndex + 1;
if (length < 0) {
return new DatabaseObjectIterator(JiveGlobals.MESSAGE, new long[0], factory);
}
else {
long [] resultsSubset = new long[length];
for (int i=0; i<length; i++) {
resultsSubset[i] = results[startIndex + i];
}
return new DatabaseObjectIterator(JiveGlobals.MESSAGE, resultsSubset, factory);
}
}
/**
* Execute the query and store the results in the results array.
*/
private void executeQuery() {
try {
Searcher searcher = getSearcher();
if (searcher == null) {
// Searcher can be null if the index doesn't exist.
results = new long[0];
return;
}
org.apache.lucene.search.Query bodyQuery =
QueryParser.parse(queryString, "body", DbSearchManager.analyzer);
org.apache.lucene.search.Query subjectQuery =
QueryParser.parse(queryString, "subject", DbSearchManager.analyzer);
BooleanQuery comboQuery = new BooleanQuery();
comboQuery.add(subjectQuery,false,false);
comboQuery.add(bodyQuery,false,false);
MultiFilter multiFilter = new MultiFilter(3);
int filterCount = 0;
// Forum filter -- we can ignore filtering if we are searching all
// forums in the system.
if (factory.getForumCount() != forums.length) {
String[] forumIDs = new String[forums.length];
for (int i=0; i<forumIDs.length; i++) {
forumIDs[i] = Long.toString(forums[i].getID());
}
multiFilter.add(new FieldFilter("forumID", forumIDs));
filterCount++;
}
//Date filter
if (beforeDate != null || afterDate != null) {
if (beforeDate != null && afterDate != null) {
multiFilter.add(new DateFilter("creationDate", beforeDate, afterDate));
filterCount++;
}
else if (beforeDate == null) {
multiFilter.add(DateFilter.After("creationDate", afterDate));
filterCount++;
}
else {
multiFilter.add(DateFilter.Before("creationDate", beforeDate));
filterCount++;
}
}
// User filter
if (user != null) {
String userID = Long.toString(user.getID());
multiFilter.add(new FieldFilter("userID", userID));
filterCount++;
}
// Thread filter
if (thread != null) {
String threadID = Long.toString(thread.getID());
multiFilter.add(new FieldFilter("threadID", threadID));
filterCount++;
}
Hits hits;
// Only apply filters if any are defined.
if (filterCount > 0) {
hits = searcher.search(comboQuery, multiFilter);
}
else {
hits = searcher.search(comboQuery);
}
// Don't return more search results than the maximum number allowed.
int numResults = hits.length() < MAX_RESULTS_SIZE ?
hits.length() : MAX_RESULTS_SIZE;
long [] messages = new long[numResults];
for (int i=0; i<numResults; i++) {
messages[i] = Long.parseLong( ((Document)hits.doc(i)).get("messageID") );
}
results = messages;
}
catch (Exception e) {
e.printStackTrace();
results = new long[0];
}
}
/**
* Returns a Lucene Searcher that can be used to execute queries. Lucene
* can handle index reading even while updates occur. However, in order
* for index changes to be reflected in search results, the reader must
* be re-opened whenever the modifiedDate changes.<p>
*
* The location of the index is the "search" subdirectory in [jiveHome]. If
* jiveHome is not set correctly, this method will fail.
*
* @return a Searcher that can be used to execute queries.
*/
private static Searcher getSearcher() throws IOException {
if (indexPath == null) {
//Get path of where search index should be. It should be
//the search subdirectory of [jiveHome].
String jiveHome = JiveGlobals.getJiveHome();
if (jiveHome == null) {
System.err.println("ERROR: the jiveHome property is not set.");
throw new IOException("Unable to open index for searching " +
"because jiveHome was not set.");
}
indexPath = jiveHome + File.separator + "search";
}
if (searcher == null) {
//Acquire a lock -- analyzer is a convenient object to do this on.
synchronized(DbSearchManager.analyzer) {
if (searcher == null) {
if (indexExists(indexPath)) {
searchDirectory = FSDirectory.getDirectory(indexPath, false);
reader = IndexReader.open(searchDirectory);
indexLastModified = reader.lastModified(searchDirectory);
searcher = new IndexSearcher(reader);
}
//Otherwise, the index doesn't exist, so return null.
else {
return null;
}
}
}
}
if (reader.lastModified(searchDirectory) > indexLastModified) {
synchronized (DbSearchManager.analyzer) {
if (reader.lastModified(searchDirectory) > indexLastModified) {
if (indexExists(indexPath)) {
indexLastModified = reader.lastModified(searchDirectory);
//We need to close the indexReader because it has changed.
//Re-opening it will make changes visible.
reader.close();
searchDirectory = FSDirectory.getDirectory(indexPath, false);
reader = IndexReader.open(searchDirectory);
searcher = new IndexSearcher(reader);
}
//Otherwise, the index doesn't exist, so return null.
else {
return null;
}
}
}
}
return searcher;
}
/**
* Returns true if the search index exists at the specified path.
*
* @param indexPath the path to check for the search index at.
*/
private static boolean indexExists(String indexPath) {
//Lucene always creates a file called "segments" -- if it exists, we
//assume that the search index exists.
File segments = new File(indexPath + File.separator + "segments");
return segments.exists();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -