📄 chatsearchmanager.java
字号:
if (stopWords.size() > 0) {
Class[] params = new Class[]{String[].class};
try {
Constructor constructor = c.getConstructor(params);
Object[] initargs = {(String[])stopWords.toArray(new String[stopWords.size()])};
analyzer = (Analyzer)constructor.newInstance(initargs);
}
catch (NoSuchMethodException e) {
// no String[] parameter to the constructor
analyzer = (Analyzer)c.newInstance();
}
}
else {
analyzer = (Analyzer)c.newInstance();
}
return analyzer;
}
private void loadLastUpdated() {
Connection con = null;
PreparedStatement pstmt = null;
ResultSet result = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_DATES);
pstmt.setLong(1, workgroup.getID());
result = pstmt.executeQuery();
while (result.next()) {
lastUpdated = new Date(Long.parseLong(result.getString(1)));
lastOptimization = new Date(Long.parseLong(result.getString(2)));
lastExecution = lastUpdated;
}
}
catch (Exception ex) {
ComponentManagerFactory.getComponentManager().getLog().error(ex);
}
finally {
try {
if (pstmt != null) {
pstmt.close();
}
}
catch (Exception e) {
ComponentManagerFactory.getComponentManager().getLog().error(e);
}
try {
if (result != null) {
result.close();
}
}
catch (SQLException e) {
ComponentManagerFactory.getComponentManager().getLog().error(e);
}
try {
if (con != null) {
con.close();
}
}
catch (Exception e) {
ComponentManagerFactory.getComponentManager().getLog().error(e);
}
}
}
/**
* Deletes the existing index and creates it again indexing the chats that took place
* since a given date. The lower limit date is calculated as the max number of days since a
* chat took place. There is a global property that holds the max number of days as well as
* a workgroup property that may redefine the default global value.
*
* @throws IOException if the directory cannot be read/written to, or there is a problem
* adding a document to the index.
*/
public synchronized void rebuildIndex() throws IOException {
// Calculate the max number of days based on the defined properties
int numDays = Integer.parseInt(JiveGlobals.getProperty("workgroup.search.maxdays", "365"));
String workgroupDays = workgroup.getProperties().getProperty("search.maxdays");
if (workgroupDays != null) {
numDays = Integer.parseInt(workgroupDays);
}
Calendar since = Calendar.getInstance();
since.add(Calendar.DATE, numDays * -1);
// Get the chats that took place since the specified date and add them to the index
rebuildIndex(since.getTime());
}
/**
* Updates the index file with new chats that took place since the last added chat to the
* index. If the index file is missing or a chat was never added to the index file then
* {@link #rebuildIndex} will be used instead.
*
* @param forceUpdate true if the index should be updated despite of the execution frequency.
* @throws IOException if the directory cannot be read/written to, or it does not exist, or
* there is a problem adding a document to the index.
*/
public synchronized void updateIndex(boolean forceUpdate) throws IOException {
// Check that the index files exist
File dir = new File(searchDirectory);
boolean create = !dir.exists() || !dir.isDirectory();
if (lastUpdated == null || create) {
// Recreate the index since it was never created or the index files disappeared
rebuildIndex();
}
else {
if (forceUpdate || (System.currentTimeMillis() - lastExecution.getTime()) / 60000 > getExecutionFrequency()) {
List<ChatInformation> chatsInformation = getChatsInformation(lastUpdated);
if (!chatsInformation.isEmpty()) {
// Reset the number of transcripts pending to be added to the index
pendingTranscripts.set(0);
Date lastDate = null;
IndexWriter writer = getWriter(false);
for (ChatInformation chat : chatsInformation) {
addTranscriptToIndex(chat, writer);
lastDate = chat.getCreationDate();
}
// Check if we need to optimize the index. The index is optimized once a day
if ((System.currentTimeMillis() - lastOptimization.getTime()) / ONE_HOUR >
getOptimizationFrequency()) {
writer.optimize();
// Update the optimized date
lastOptimization = new Date();
}
writer.close();
closeSearcherReader();
// Reset the filters cache
cachedFilters.clear();
// Update the last updated date
lastUpdated = lastDate;
// Save the last updated and optimized dates to the database
saveDates();
}
// Update the last time the update process was executed
lastExecution = new Date();
}
}
}
public void delete() {
try {
searcherLock.writeLock().lock();
try {
closeSearcherReader();
}
catch (IOException e) {
// Ignore.
}
// Delete index files
String[] files = new File(searchDirectory).list();
for (int i = 0; i < files.length; i++) {
File file = new File(searchDirectory, files[i]);
file.delete();
}
new File(searchDirectory).delete();
// Delete dates from the database
deleteDates();
// Remove this instance from the list of instances
instances.remove(workgroup.getJID().getNode());
// Remove this instance as a listener of the workgroup events
WorkgroupEventDispatcher.removeListener(this);
}
finally {
searcherLock.writeLock().unlock();
}
}
/**
* 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 modificationDate changes.<p>
* <p/>
* The location of the index is the "index" subdirectory in [jiveHome].
*
* @return a Searcher that can be used to execute queries.
*/
public Searcher getSearcher() throws IOException {
synchronized (indexerAnalyzer) {
if (searcherReader == null) {
if (searchDirectory != null && IndexReader.indexExists(searchDirectory)) {
searcherReader = IndexReader.open(searchDirectory);
searcher = new IndexSearcher(searcherReader);
}
else {
// Log warnings.
if (searchDirectory == null) {
ComponentManagerFactory.getComponentManager().getLog().warn("Search " +
"directory not set, you must rebuild the index.");
}
else if (!IndexReader.indexExists(searchDirectory)) {
ComponentManagerFactory.getComponentManager().getLog().warn("Search " +
"directory " + searchDirectory + " does not appear to " +
"be a valid search index. You must rebuild the index.");
}
return null;
}
}
}
return searcher;
}
Analyzer getAnalyzer() {
return indexerAnalyzer;
}
void putFilter(String key, Filter filter) {
cachedFilters.put(key, filter);
}
Filter getFilter(String key) {
return cachedFilters.get(key);
}
/**
* Closes the reader used by the searcher to indicate that a change to the index was made.
* A new searcher will be opened the next time one is requested.
*
* @throws IOException if an error occurs while closing the reader.
*/
private void closeSearcherReader() throws IOException {
if (searcherReader != null) {
try {
searcherLock.writeLock().lock();
searcherReader.close();
}
finally {
searcherReader = null;
searcherLock.writeLock().unlock();
}
}
}
/**
* Returns information about the chats that took place since a given date. The result is
* sorted from oldest chats to newest chats.
*
* @param since the date to use as the lower limit.
* @return information about the chats that took place since a given date.
*/
private List<ChatInformation> getChatsInformation(Date since) {
List<ChatInformation> chats = new ArrayList<ChatInformation>();
Connection con = null;
PreparedStatement pstmt = null;
ResultSet result = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(CHATS_SINCE_DATE);
pstmt.setLong(1, workgroup.getID());
pstmt.setString(2, StringUtils.dateToMillis(since));
result = pstmt.executeQuery();
while (result.next()) {
String sessionID = result.getString(1);
String transcript = result.getString(2);
String startTime = result.getString(3);
ChatNotes chatNotes = new ChatNotes();
String notes = chatNotes.getNotes(sessionID);
// Create a ChatInformation with the retrieved information
ChatInformation chatInfo = new ChatInformation(sessionID, transcript, startTime, notes);
if (chatInfo.getTranscript() != null) {
chats.add(chatInfo);
}
}
result.close();
// For each ChatInformation add the agents involved in the chat
for (ChatInformation chatInfo : chats) {
pstmt.close();
pstmt = con.prepareStatement(AGENTS_IN_SESSION);
pstmt.setString(1, chatInfo.getSessionID());
result = pstmt.executeQuery();
while (result.next()) {
chatInfo.getAgentJIDs().add(result.getString(1));
}
result.close();
}
}
catch (Exception ex) {
ComponentManagerFactory.getComponentManager().getLog().error(ex);
// Reset the answer if an error happened
chats = new ArrayList<ChatInformation>();
}
finally {
try {
if (pstmt != null) {
pstmt.close();
}
}
catch (Exception e) {
ComponentManagerFactory.getComponentManager().getLog().error(e);
}
try {
if (result != null) {
result.close();
}
}
catch (SQLException e) {
ComponentManagerFactory.getComponentManager().getLog().error(e);
}
try {
if (con != null) {
con.close();
}
}
catch (Exception e) {
ComponentManagerFactory.getComponentManager().getLog().error(e);
}
try {
if (result != null) {
result.close();
}
}
catch (Exception e) {
ComponentManagerFactory.getComponentManager().getLog().error(e);
}
}
// Return the chats order by startTime
return chats;
}
/**
* Retrieves information about each transcript that took place since the specified date and
* adds it to the index.<p>
* <p/>
* Note: In order to cope with large volumes of data we don't want to load
* all the information into memory. Therefore, for each retrieved row we create a
* ChatInformation instance and add it to the index.
*
* @param since the date to use as the lower limit.
* @throws IOException if rebuilding the index fails.
*/
private void rebuildIndex(Date since) throws IOException {
Date lastDate = null;
IndexWriter writer = getWriter(true);
Connection con = null;
PreparedStatement pstmt = null;
ResultSet result = null;
try {
// TODO Review logic for JDBC drivers that load all the answer into memory
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(CHATS_SINCE_DATE);
pstmt.setLong(1, workgroup.getID());
pstmt.setString(2, StringUtils.dateToMillis(since));
result = pstmt.executeQuery();
while (result.next()) {
String sessionID = result.getString(1);
String transcript = result.getString(2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -