package org.nemesis.forum.search;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.StopAnalyzer;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.nemesis.forum.Authorization;
import org.nemesis.forum.Forum;
import org.nemesis.forum.ForumFactory;
import org.nemesis.forum.ForumThread;
import org.nemesis.forum.Message;
import org.nemesis.forum.TreeWalker;
import org.nemesis.forum.impl.DbForumMessage;
import org.nemesis.forum.impl.DbForumThread;
import org.nemesis.forum.config.ConfigLoader;
import org.nemesis.forum.config.Constants;
import org.nemesis.forum.event.ForumEvent;
import org.nemesis.forum.event.ForumListener;
import org.nemesis.forum.exception.UnauthorizedException;
/**
* @author dlaurent
*
*
*/
public class Indexer implements ForumListener {
static protected Log log = LogFactory.getLog(Indexer.class);
private static boolean autoIndex=ConfigLoader.getInstance().getConfig().isAutoIndex();
final private static String PATH = ConfigLoader.getInstance().getConfig().getDataDir() + File.separator + "index";
private static Object indexLock = new Object();
private static Analyzer analyzer = new StopAnalyzer();
static {
Indexer i = new Indexer();
DbForumMessage.addListener(i);
DbForumThread.addListener(i);
}
public void objectCreated(ForumEvent event) {
log.debug("Indexer.objectCreated()");
if (autoIndex)
index((Message) event.getSource());
}
public void objectModified(ForumEvent event) {
log.debug("Indexer.objectModified()");
if (!autoIndex)return;
remove((Message) event.getSource());
index((Message) event.getSource());
}
public void objectDeleted(ForumEvent event) {
log.debug("Indexer.objectDeleted()");
if (autoIndex)
remove((Message) event.getSource());
}
private static void remove(Message m) {
//remove recursive from index if doc not approved
TreeWalker walker = m.getForumThread().treeWalker();
removeFromIndex(m, walker);
}
private static void removeFromIndex(Message m, TreeWalker walker) {
synchronized (indexLock) {
log.debug("Indexer.removeFromIndex()" + m.getID());
Term term = new Term("messageID", m.getID() + "");
try {
IndexReader reader = IndexReader.open(new File(PATH));
reader.delete(term);
reader.close();
} catch (IOException e) {
log.error("impossible de supprimer le message " + m.getID() + " de l'index ", e);
}
}
for (int i = 0; i < walker.getChildCount(m); i++) {
removeFromIndex(walker.getChild(m, i), walker);
}
}
private static void index(Message m) {
TreeWalker walker = m.getForumThread().treeWalker();
addToIndex(m, walker);
}
private static void addToIndex(Message m, TreeWalker walker) {
if (!m.isApproved())
return;
synchronized (indexLock) {
log.debug("Indexer.addFromIndex()" + m.getID());
IndexWriter writer = null;
try {
if (IndexReader.indexExists(PATH)) {
writer = new IndexWriter(new File(PATH), new StopAnalyzer(), false);
} else {
writer = new IndexWriter(new File(PATH), new StopAnalyzer(), true);
}
writer.addDocument(MessageDocument.getDocument(m));
} catch (Exception e) {
log.error("addToIndex", e);
} finally {
try {
writer.close();
} catch (Exception e) {
}
}
}
for (int i = 0; i < walker.getChildCount(m); i++) {
addToIndex(walker.getChild(m, i), walker);
}
}
public static void flush(Authorization auth) throws UnauthorizedException{
ForumFactory forumFactory = ForumFactory.getInstance(auth);
if(! forumFactory.getPermissions(auth).get(Constants.SYSTEM_ADMIN)) throw new UnauthorizedException();
try {
IndexWriter writer = new IndexWriter(new File(PATH), new StopAnalyzer(), true);
writer.close();
} catch (IOException e) {
log.error("impossible de flusher l'index ", e);
}
}
public static void reindex(Authorization auth) throws UnauthorizedException{
ForumFactory forumFactory = ForumFactory.getInstance(auth);
if(! forumFactory.getPermissions(auth).get(Constants.SYSTEM_ADMIN)) throw new UnauthorizedException();
//ok system admin
flush(auth);
Forum f=null;
ForumThread ft=null;
for(Iterator it=forumFactory.forums();it.hasNext();){
f=(Forum)it.next();
for(Iterator it2=f.threads();it2.hasNext();){
ft=(ForumThread)it2.next();
index(ft.getRootMessage());
}
}
}
/**
* @return
*/
public static boolean isAutoIndex() {
return autoIndex;
}
/**
* @param b
*/
public static void setAutoIndex(boolean b,Authorization auth) throws UnauthorizedException {
ForumFactory forumFactory = ForumFactory.getInstance(auth);
if(! forumFactory.getPermissions(auth).get(Constants.SYSTEM_ADMIN)) throw new UnauthorizedException();
autoIndex = b;
}
}