📄 dbsearchmanager.java
字号:
/**
* $RCSfile: DbSearchManager.java,v $
* $Revision: 1.1.1.1 $
* $Date: 2002/09/09 13:50:58 $
*
* 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.sql.*;
import java.util.*;
import java.util.Date;
import java.io.*;
import org.apache.lucene.document.*;
import org.apache.lucene.analysis.*;
import org.apache.lucene.analysis.standard.*;
import org.apache.lucene.index.*;
import org.apache.lucene.store.*;
import com.jivesoftware.forum.*;
import com.jivesoftware.forum.util.*;
import com.jivesoftware.util.*;
import com.jivesoftware.util.TimerTask;
import org.apache.lucene.analysis.cn.*;
/**
* Database implementation of SearchManager using the Lucene search package.
* Search indexes are stored in the "search" subdirectory of <tt>jiveHome</tt>.
*/
class DbSearchManager implements SearchManager, Runnable {
/** DATABASE QUERIES **/
private static final String MESSAGES_BEFORE_DATE =
"SELECT jiveMessage.messageID, jiveMessage.userID, jiveMessage.threadID, " +
"jiveMessage.forumID, subject, body, jiveMessage.creationDate " +
"FROM jiveMessage, jiveForum " +
"WHERE jiveForum.forumID=jiveMessage.forumID " +
"AND messageID >= ? AND messageID < ? " +
"AND jiveMessage.modifiedDate < ? " +
"AND jiveMessage.modValue >= jiveForum.modMinThreadVal";
private static final String MESSAGES_BEFORE_DATE_COUNT =
"SELECT count(1) " +
"FROM jiveMessage, jiveForum " +
"WHERE jiveForum.forumID=jiveMessage.forumID " +
"AND jiveMessage.modValue >= jiveForum.modMinThreadVal " +
"AND jiveMessage.modifiedDate < ?";
private static final String MESSAGES_SINCE_DATE =
"SELECT jiveMessage.messageID, jiveMessage.userID, jiveMessage.threadID, " +
"jiveMessage.forumID, subject, body, jiveMessage.creationDate " +
"FROM jiveMessage, jiveForum " +
"WHERE jiveForum.forumID=jiveMessage.forumID " +
"AND jiveMessage.modValue >= jiveForum.modMinThreadVal " +
"AND jiveMessage.modifiedDate > ? AND jiveMessage.modifiedDate < ?";
private static final String MESSAGES_SINCE_DATE_COUNT =
"SELECT count(1) " +
"FROM jiveMessage, jiveForum " +
"WHERE jiveForum.forumID=jiveMessage.forumID " +
"AND jiveMessage.modValue >= jiveForum.modMinThreadVal " +
"AND jiveMessage.modifiedDate > ? AND jiveMessage.modifiedDate < ?";
private static final String MESSAGE_IDS_SINCE_DATE =
"SELECT jiveMessage.messageID " +
"FROM jiveMessage, jiveForum " +
"WHERE jiveForum.forumID=jiveMessage.forumID " +
"AND jiveMessage.modValue >= jiveForum.modMinThreadVal " +
"AND jiveMessage.modifiedDate > ? AND jiveMessage.modifiedDate < ?";
private static final String HIGHEST_MESSAGE_ID =
"SELECT MAX(messageID) FROM jiveMessage";
/**
* The number of messages to retrieve at once during index rebuilds.
*/
private static final int BLOCK_SIZE = 500;
/**
* Path to where index is stored.
*/
private static String indexPath = null;
/**
* The analyzer governs how words are tokenized. The standard anaylyzer
* does a decent job in most cases, but could be replaced under certain
* circumstances. We make the analyzer protected so that the DbQuery class
* can also reference it (indexing and searching should use the same
* analyzer).
*/
protected static Analyzer analyzer = new ChineseAnalyzer();
/**
* Indicates whether search is on or off at a global level. If off, index
* add and delete operations will be ignored, and auto-indexing will be
* disabled.
*/
private boolean searchEnabled = true;
/**
* Indicates whether auto-indexing should be on or off. When on, an update
* will be run at the "updateInterval".
*/
private boolean autoIndexEnabled = true;
/**
* Maintains the amount of time in minutes should elapse before the next
* index auto-update.
*/
private int autoIndexInterval;
/**
* Maintains the time that the last index took place.
*/
private Date lastIndexed;
/**
* True if the indexer is busy. False otherwise.
*/
private boolean busy = false;
// Values used to calculate the current percent complete.
int currentCount = 0;
int totalCount = -1;
private Object lock = new Object();
/**
* The scheduled task for auto-indexing.
*/
private TimerTask timerTask = null;
/**
* Creates a new DbSearchIndexer. It attempts to load properties for
* the update interval and when the last index occured from the Jive
* properties then starts the indexing thread.
*/
public DbSearchManager() {
// Default to performing updates ever 10 minutes.
autoIndexInterval = 10;
// If the update interval property exists, use that
String interval = JiveGlobals.getJiveProperty("search.autoIndexInterval");
try {
autoIndexInterval = Integer.parseInt(interval);
}
catch (Exception e) { /* ignore */ }
// Determine if search should be turned on.
String enabled = JiveGlobals.getJiveProperty("search.enabled");
try {
searchEnabled = Boolean.valueOf(enabled).booleanValue();
}
catch (Exception e) { }
// Determine if auto-indexing should be turned on.
String index = JiveGlobals.getJiveProperty("search.autoIndexEnabled");
try {
autoIndexEnabled = Boolean.valueOf(index).booleanValue();
}
catch (Exception e) { }
// Attempt to get the last updated time from the Jive properties
String lastInd = JiveGlobals.getJiveProperty("search.lastIndexed");
try {
lastIndexed = new Date(Long.parseLong(lastInd));
}
catch (Exception e) {
// Something went wrong. Therefore, set lastIndexed far into the
// past so that we'll do a full re-index. If you've time travelled
// backwards too far with this code, this could be a problem.
lastIndexed = new Date(0);
}
// If autoIndexing is turned on, schedule indexing task.
if (autoIndexEnabled) {
timerTask = TaskEngine.scheduleTask(
this,autoIndexInterval*JiveGlobals.MINUTE,
autoIndexInterval*JiveGlobals.MINUTE);
}
}
public int getAutoIndexInterval() {
return autoIndexInterval;
}
public void setAutoIndexInterval(int minutes) {
this.autoIndexInterval = minutes;
JiveGlobals.setJiveProperty("search.autoIndexInterval",
"" + autoIndexInterval);
// Restart indexer with new schedule.
if (timerTask != null) {
timerTask.cancel();
}
timerTask = TaskEngine.scheduleTask(
this,autoIndexInterval*JiveGlobals.MINUTE,
autoIndexInterval*JiveGlobals.MINUTE);
}
public Date getLastIndexedDate() {
return lastIndexed;
}
public boolean isSearchEnabled() {
return searchEnabled;
}
public void setSearchEnabled(boolean searchEnabled) {
this.searchEnabled = searchEnabled;
JiveGlobals.setJiveProperty("search.enabled", String.valueOf(searchEnabled));
}
public boolean isBusy() {
return busy;
}
public synchronized int getPercentComplete() {
if (!busy) {
return -1;
}
// If we're busy but the total count hasn't been set yet, return 0.
if (totalCount == -1 || totalCount == 0) {
return 0;
}
else {
return (int)(((double)currentCount/(double)totalCount)*100.0);
}
}
public boolean isAutoIndexEnabled() {
return autoIndexEnabled;
}
public void setAutoIndexEnabled(boolean enabled) {
// If we are switching from off to on, enable indexer
if (!autoIndexEnabled && enabled) {
if (timerTask != null) {
timerTask.cancel();
}
timerTask = TaskEngine.scheduleTask(
this,autoIndexInterval*JiveGlobals.MINUTE,
autoIndexInterval*JiveGlobals.MINUTE);
}
// Otherwise, if switching from on to off, disable indexer.
else if (autoIndexEnabled && !enabled) {
if (timerTask != null) {
timerTask.cancel();
}
}
autoIndexEnabled = enabled;
JiveGlobals.setJiveProperty("search.autoIndexEnabled", "" + enabled);
}
public synchronized void addToIndex(ForumMessage message) {
if (!searchEnabled) {
return;
}
IndexWriter writer = null;
try {
writer = getWriter(false);
long messageID = message.getID();
long userID = -1;
if (!message.isAnonymous()) {
userID = message.getUser().getID();
}
long threadID = message.getForumThread().getID();
long forumID = message.getForumThread().getForum().getID();
String subject = message.getUnfilteredSubject();
String body = message.getUnfilteredBody();
addMessageToIndex(messageID, userID, threadID, forumID,
subject, body, message.getCreationDate(), writer);
}
catch (IOException ioe) {
ioe.printStackTrace();
}
finally{
try { writer.close(); }
catch (Exception e) { }
}
}
public synchronized void removeFromIndex(ForumMessage message) {
if (!searchEnabled) {
return;
}
try {
long [] toDelete = new long [] { message.getID() };
deleteMessagesFromIndex(toDelete);
}
catch (IOException ioe) {
ioe.printStackTrace();
}
}
public synchronized void updateIndex() {
if (!searchEnabled) {
return;
}
// Add a task to the task engine to update the index.
TaskEngine.addTask(new IndexTask(false));
}
public synchronized void rebuildIndex() {
if (!searchEnabled) {
return;
}
// Add a task to the task engine to update the index.
TaskEngine.addTask(new IndexTask(true));
}
public synchronized void optimize() {
if (busy) {
return;
}
try {
IndexWriter writer = getWriter(false);
if (writer != null) {
writer.optimize();
}
}
catch (IOException ioe) {
ioe.printStackTrace();
}
}
//OTHER METHODS//
/**
* Auto-indexing logic. It will automatically be scheduled to run at the
* desired interval if auto-indexing is turned on.
*/
public synchronized void run() {
// Do nothing if searching is disabled.
if (!searchEnabled) {
return;
}
// Add a task to the task engine to update the index.
TaskEngine.addTask(new IndexTask(false));
}
/**
* Indexes an indivual message. The writer is assumed to be open when
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -