You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@roller.apache.org by gh...@apache.org on 2012/05/20 13:16:26 UTC

svn commit: r1340676 [1/2] - in /roller/trunk: ./ weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/ weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/ weblogger-web/src/main/java/org/apa...

Author: ghuber
Date: Sun May 20 11:16:25 2012
New Revision: 1340676

URL: http://svn.apache.org/viewvc?rev=1340676&view=rev
Log:
Upgrade to lucene 3.6

Modified:
    roller/trunk/pom.xml
    roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/FieldConstants.java
    roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/IndexManagerImpl.java
    roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/IndexUtil.java
    roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/IndexOperation.java
    roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/ReIndexEntryOperation.java
    roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/RebuildWebsiteIndexOperation.java
    roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/RemoveEntryOperation.java
    roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/RemoveWebsiteIndexOperation.java
    roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/SearchOperation.java
    roller/trunk/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/model/SearchResultsFeedModel.java
    roller/trunk/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/model/SearchResultsModel.java
    roller/trunk/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/EntryAdd.java
    roller/trunk/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/EntryBase.java
    roller/trunk/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/EntryEdit.java
    roller/trunk/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/EntryRemove.java

Modified: roller/trunk/pom.xml
URL: http://svn.apache.org/viewvc/roller/trunk/pom.xml?rev=1340676&r1=1340675&r2=1340676&view=diff
==============================================================================
--- roller/trunk/pom.xml (original)
+++ roller/trunk/pom.xml Sun May 20 11:16:25 2012
@@ -183,8 +183,7 @@
             <dependency>
                 <groupId>org.apache.lucene</groupId>
                 <artifactId>lucene-core</artifactId>
-                <version>2.9.0</version>
-                <scope>compile</scope>
+                <version>3.6.0</version>
             </dependency>
 
             <dependency>

Modified: roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/FieldConstants.java
URL: http://svn.apache.org/viewvc/roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/FieldConstants.java?rev=1340676&r1=1340675&r2=1340676&view=diff
==============================================================================
--- roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/FieldConstants.java (original)
+++ roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/FieldConstants.java Sun May 20 11:16:25 2012
@@ -18,24 +18,33 @@
 /* Created on Jul 19, 2003 */
 package org.apache.roller.weblogger.business.search;
 
+import org.apache.lucene.util.Version;
+
 /**
  * Field constants for indexing blog entries and comments.
- * @author Mindaugas Idzelis  (min@idzelis.com)
+ * 
+ * @author Mindaugas Idzelis (min@idzelis.com)
  */
-public final class FieldConstants {    
-    public static final String ANCHOR = "anchor";
-    public static final String UPDATED = "updated";
-    public static final String ID = "id";
-    public static final String USERNAME = "username";
-    public static final String CATEGORY = "cat";
-    public static final String TITLE = "title";
-    public static final String PUBLISHED = "published";
-    public static final String CONTENT = "content";
-    public static final String CONTENT_STORED = "content_stored";
-    public static final String C_CONTENT = "comment";
-    public static final String C_EMAIL = "email";
-    public static final String C_NAME = "name";
-    public static final String CONSTANT = "constant";
-    public static final String CONSTANT_V = "v"; //must be lowercase, or match the transform rules of the analyzer
-    public static final String WEBSITE_HANDLE = "handle";
+public final class FieldConstants {
+
+	// Set what version we are on
+	public static final Version LUCENE_VERSION = Version.LUCENE_36;
+
+	public static final String ANCHOR = "anchor";
+	public static final String UPDATED = "updated";
+	public static final String ID = "id";
+	public static final String USERNAME = "username";
+	public static final String CATEGORY = "cat";
+	public static final String TITLE = "title";
+	public static final String PUBLISHED = "published";
+	public static final String CONTENT = "content";
+	public static final String CONTENT_STORED = "content_stored";
+	public static final String C_CONTENT = "comment";
+	public static final String C_EMAIL = "email";
+	public static final String C_NAME = "name";
+	public static final String CONSTANT = "constant";
+	public static final String CONSTANT_V = "v"; // must be lowercase, or match
+													// the transform rules of
+													// the analyzer
+	public static final String WEBSITE_HANDLE = "handle";
 }

Modified: roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/IndexManagerImpl.java
URL: http://svn.apache.org/viewvc/roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/IndexManagerImpl.java?rev=1340676&r1=1340675&r2=1340676&view=diff
==============================================================================
--- roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/IndexManagerImpl.java (original)
+++ roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/IndexManagerImpl.java Sun May 20 11:16:25 2012
@@ -26,9 +26,11 @@ import java.util.concurrent.locks.Reentr
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.LimitTokenCountAnalyzer;
 import org.apache.lucene.analysis.standard.StandardAnalyzer;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.FSDirectory;
 import org.apache.lucene.store.RAMDirectory;
@@ -45,331 +47,370 @@ import org.apache.roller.weblogger.pojos
 import org.apache.roller.weblogger.pojos.Weblog;
 import org.apache.roller.weblogger.config.WebloggerConfig;
 
-
 /**
- * Lucene implementation of IndexManager. This is the central entry point 
- * into the Lucene searching API.
+ * Lucene implementation of IndexManager. This is the central entry point into
+ * the Lucene searching API.
+ * 
  * @author Mindaugas Idzelis (min@idzelis.com)
  * @author mraible (formatting and making indexDir configurable)
  */
 @com.google.inject.Singleton
 public class IndexManagerImpl implements IndexManager {
-    //~ Static fields/initializers
-    // =============================================
-    
-    private IndexReader reader;
-    private final Weblogger roller;
-    
-    static Log mLogger = LogFactory.getFactory().getInstance(
-            IndexManagerImpl.class);
-    
-    //~ Instance fields
-    // ========================================================
-    
-    private boolean searchEnabled = true;
-    
-    File indexConsistencyMarker;
-    
-    private boolean useRAMIndex = false;
-    
-    private RAMDirectory fRAMindex;
-    
-    private String indexDir = null;
-    
-    private boolean inconsistentAtStartup = false;
-    
-    private ReadWriteLock rwl = new ReentrantReadWriteLock();
-    
-    //~ Constructors
-    // ===========================================================
-    
-    /**
-     * Creates a new lucene index manager. This should only be created once.
-     * Creating the index manager more than once will definately result in
-     * errors. The preferred way of getting an index is through the
-     * RollerContext.
-     *
-     * @param indexDir -
-     *            the path to the index directory
-     */
-    @com.google.inject.Inject
-    protected IndexManagerImpl(Weblogger roller) {
-        this.roller = roller;
-
-        // check config to see if the internal search is enabled
-        String enabled = WebloggerConfig.getProperty("search.enabled");
-        if("false".equalsIgnoreCase(enabled))
-            this.searchEnabled = false;
-        
-        // we also need to know what our index directory is
-        // Note: system property expansion is now handled by WebloggerConfig
-        String searchIndexDir = WebloggerConfig.getProperty("search.index.dir");
-        this.indexDir = searchIndexDir.replace('/', File.separatorChar);
-        
-        // a little debugging
-        mLogger.info("search enabled: " + this.searchEnabled);
-        mLogger.info("index dir: " + this.indexDir);
-        
-        String test = indexDir + File.separator + ".index-inconsistent";
-        indexConsistencyMarker = new File(test);
-    }
-    
-    
-    /**
-     * @inheritDoc
-     */
-    public void initialize() throws InitializationException {
-        
-        // only initialize the index if search is enabled
-        if (this.searchEnabled) {
-            
-            // 1. If inconsistency marker exists.
-            //     Delete index
-            // 2. if we're using RAM index
-            //     load ram index wrapper around index
-            //
-            if (indexConsistencyMarker.exists()) {
-                getFSDirectory(true);
-                inconsistentAtStartup = true;
-                mLogger.debug("Index inconsistent: marker exists");
-            } else {
-                try {
-                    File makeIndexDir = new File(indexDir);
-                    if (!makeIndexDir.exists()) {
-                        makeIndexDir.mkdirs();
-                        inconsistentAtStartup = true;
-                        mLogger.debug("Index inconsistent: new");
-                    }
-                    indexConsistencyMarker.createNewFile();
-                } catch (IOException e) {
-                    mLogger.error(e);
-                }
-            }
-            
-            if (indexExists()) {
-                if (useRAMIndex) {
-                    Directory filesystem = getFSDirectory(false);                    
-                    try {
-                        fRAMindex = new RAMDirectory(filesystem);
-                    } catch (IOException e) {
-                        mLogger.error("Error creating in-memory index", e);
-                    }
-                }
-            } else {
-                mLogger.debug("Creating index");
-                inconsistentAtStartup = true;
-                if (useRAMIndex) {
-                    fRAMindex = new RAMDirectory();
-                    createIndex(fRAMindex);
-                } else {
-                    createIndex(getFSDirectory(true));
-                }
-            }
-            
-            if (isInconsistentAtStartup()) {
-                mLogger.info(
-                    "Index was inconsistent. Rebuilding index in the background...");
-                try {
-                    rebuildWebsiteIndex();
-                } catch (WebloggerException e) {
-                    mLogger.error("ERROR: scheduling re-index operation");
-                }
-            } else {
-                mLogger.info("Index initialized and ready for use.");
-            }
-        }
-        
-    }
-    
-    
-    //~ Methods
-    // ================================================================
-    
-    public void rebuildWebsiteIndex() throws WebloggerException {
-        scheduleIndexOperation(
-                new RebuildWebsiteIndexOperation(roller, this, null));
-    }
-    
-    public void rebuildWebsiteIndex(Weblog website) throws WebloggerException {
-        scheduleIndexOperation(
-                new RebuildWebsiteIndexOperation(roller, this, website));
-    }
-    
-    public void removeWebsiteIndex(Weblog website) throws WebloggerException {
-        scheduleIndexOperation(
-                new RemoveWebsiteIndexOperation(roller, this, website));
-    }
-    
-    public void addEntryIndexOperation(WeblogEntry entry) throws WebloggerException {
-        AddEntryOperation addEntry = new AddEntryOperation(roller, this, entry);
-        scheduleIndexOperation(addEntry);
-    }
-    
-    public void addEntryReIndexOperation(WeblogEntry entry) throws WebloggerException {
-        ReIndexEntryOperation reindex = new ReIndexEntryOperation(roller, this, entry);
-        scheduleIndexOperation(reindex);
-    }
-    
-    public void removeEntryIndexOperation(WeblogEntry entry) throws WebloggerException {
-        RemoveEntryOperation removeOp = new RemoveEntryOperation(roller, this, entry);
-        executeIndexOperationNow(removeOp);
-    }
-    
-    public ReadWriteLock getReadWriteLock() {
-        return rwl;
-    }
-    
-    public boolean isInconsistentAtStartup() {
-        return inconsistentAtStartup;
-    }
-    
-    /**
-     * This is the analyzer that will be used to tokenize comment text.
-     *
-     * @return Analyzer to be used in manipulating the database.
-     */
-    public static final Analyzer getAnalyzer() {
-        return new StandardAnalyzer();
-    }
-    
-    private void scheduleIndexOperation(final IndexOperation op) {
-        try {
-            // only if search is enabled
-            if(this.searchEnabled) {
-                mLogger.debug("Starting scheduled index operation: "+op.getClass().getName());
-                roller.getThreadManager().executeInBackground(op);
-            }
-        } catch (InterruptedException e) {
-            mLogger.error("Error executing operation", e);
-        }
-    }
-    
-    /**
-     * @param search
-     */
-    public void executeIndexOperationNow(final IndexOperation op) {
-        try {
-            // only if search is enabled
-            if(this.searchEnabled) {
-                mLogger.debug("Executing index operation now: "+op.getClass().getName());
-                roller.getThreadManager().executeInForeground(op);
-            }
-        } catch (InterruptedException e) {
-            mLogger.error("Error executing operation", e);
-        }
-    }
-    
-    public synchronized void resetSharedReader() {
-        reader = null;
-    }
-    public synchronized IndexReader getSharedIndexReader() {
-        if (reader == null) {
-            try {
-                reader = IndexReader.open(getIndexDirectory());
-            } catch (IOException e) {
-            }
-        }
-        return reader;
-    }
-    
-    /**
-     * Get the directory that is used by the lucene index. This method will
-     * return null if there is no index at the directory location. If we are
-     * using a RAM index, the directory will be a ram directory.
-     *
-     * @return Directory The directory containing the index, or null if error.
-     */
-    public Directory getIndexDirectory() {
-        if (useRAMIndex) {
-            return fRAMindex;
-        } else {
-            return getFSDirectory(false);
-        }
-    }
-    
-    private boolean indexExists() {
-        return IndexReader.indexExists(indexDir);
-    }
-    
-    Directory getFSDirectory(boolean delete) {
-        Directory directory = null;
-        
-        try {
-            directory = FSDirectory.getDirectory(indexDir, delete);
-        } catch (IOException e) {
-            mLogger.error("Problem accessing index directory", e);
-        }
-        
-        return directory;
-    }
-    
-    private void createIndex(Directory dir) {
-        IndexWriter writer = null;
-        
-        try {
-            writer = new IndexWriter(dir, IndexManagerImpl.getAnalyzer(), true);
-        } catch (IOException e) {
-            mLogger.error("Error creating index", e);
-        } finally {
-            try {
-                if (writer != null) {
-                    writer.close();
-                }
-            } catch (IOException e) {
-            }
-        }
-    }
-    
-    private IndexOperation getSaveIndexOperation() {
-        return new WriteToIndexOperation(this) {
-            public void doRun() {
-                Directory dir = getIndexDirectory();
-                Directory fsdir = getFSDirectory(true);
-                
-                IndexWriter writer = null;
-                
-                try {
-                    writer = new IndexWriter(fsdir, IndexManagerImpl
-                            .getAnalyzer(), true);
-                    
-                    writer.addIndexes(new Directory[] { dir });
-                    indexConsistencyMarker.delete();
-                } catch (IOException e) {
-                    mLogger.error("Problem saving index to disk", e);
-                    
-                    // Delete the directory, since there was a problem saving
-                    // the RAM contents
-                    getFSDirectory(true);
-                } finally {
-                    try {
-                        if (writer != null)
-                            writer.close();
-                    } catch (IOException e1) {
-                        mLogger.warn("Unable to close IndexWriter.");
-                    }
-                }
-                
-            }
-        };
-    }
-    
-    public void release() {
-        // no-op
-    }
-    
-    public void shutdown() {
-        if (useRAMIndex) {
-            scheduleIndexOperation(getSaveIndexOperation());
-        } else {
-            indexConsistencyMarker.delete();
-        }
-        
-        try {
-            if (reader != null)
-                reader.close();
-        } catch (IOException e) {
-            // won't happen, since it was
-        }
-    }
+	// ~ Static fields/initializers
+	// =============================================
+
+	private IndexReader reader;
+	private final Weblogger roller;
+
+	static Log mLogger = LogFactory.getFactory().getInstance(
+			IndexManagerImpl.class);
+
+	// ~ Instance fields
+	// ========================================================
+
+	private boolean searchEnabled = true;
+
+	File indexConsistencyMarker;
+
+	private boolean useRAMIndex = false;
+
+	private RAMDirectory fRAMindex;
+
+	private String indexDir = null;
+
+	private boolean inconsistentAtStartup = false;
+
+	private ReadWriteLock rwl = new ReentrantReadWriteLock();
+
+	// ~ Constructors
+	// ===========================================================
+
+	/**
+	 * Creates a new lucene index manager. This should only be created once.
+	 * Creating the index manager more than once will definately result in
+	 * errors. The preferred way of getting an index is through the
+	 * RollerContext.
+	 * 
+	 * @param indexDir
+	 *            - the path to the index directory
+	 */
+	@com.google.inject.Inject
+	protected IndexManagerImpl(Weblogger roller) {
+		this.roller = roller;
+
+		// check config to see if the internal search is enabled
+		String enabled = WebloggerConfig.getProperty("search.enabled");
+		if ("false".equalsIgnoreCase(enabled))
+			this.searchEnabled = false;
+
+		// we also need to know what our index directory is
+		// Note: system property expansion is now handled by WebloggerConfig
+		String searchIndexDir = WebloggerConfig.getProperty("search.index.dir");
+		this.indexDir = searchIndexDir.replace('/', File.separatorChar);
+
+		// a little debugging
+		mLogger.info("search enabled: " + this.searchEnabled);
+		mLogger.info("index dir: " + this.indexDir);
+
+		String test = indexDir + File.separator + ".index-inconsistent";
+		indexConsistencyMarker = new File(test);
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	public void initialize() throws InitializationException {
+
+		// only initialize the index if search is enabled
+		if (this.searchEnabled) {
+
+			// 1. If inconsistency marker exists.
+			// Delete index
+			// 2. if we're using RAM index
+			// load ram index wrapper around index
+			//
+			if (indexConsistencyMarker.exists()) {
+				getFSDirectory(true);
+				inconsistentAtStartup = true;
+				mLogger.debug("Index inconsistent: marker exists");
+			} else {
+				try {
+					File makeIndexDir = new File(indexDir);
+					if (!makeIndexDir.exists()) {
+						makeIndexDir.mkdirs();
+						inconsistentAtStartup = true;
+						mLogger.debug("Index inconsistent: new");
+					}
+					indexConsistencyMarker.createNewFile();
+				} catch (IOException e) {
+					mLogger.error(e);
+				}
+			}
+
+			if (indexExists()) {
+				if (useRAMIndex) {
+					Directory filesystem = getFSDirectory(false);
+					try {
+						fRAMindex = new RAMDirectory(filesystem);
+					} catch (IOException e) {
+						mLogger.error("Error creating in-memory index", e);
+					}
+				}
+			} else {
+				mLogger.debug("Creating index");
+				inconsistentAtStartup = true;
+				if (useRAMIndex) {
+					fRAMindex = new RAMDirectory();
+					createIndex(fRAMindex);
+				} else {
+					createIndex(getFSDirectory(true));
+				}
+			}
+
+			if (isInconsistentAtStartup()) {
+				mLogger.info("Index was inconsistent. Rebuilding index in the background...");
+				try {
+					rebuildWebsiteIndex();
+				} catch (WebloggerException e) {
+					mLogger.error("ERROR: scheduling re-index operation");
+				}
+			} else {
+				mLogger.info("Index initialized and ready for use.");
+			}
+		}
+
+	}
+
+	// ~ Methods
+	// ================================================================
+
+	public void rebuildWebsiteIndex() throws WebloggerException {
+		scheduleIndexOperation(new RebuildWebsiteIndexOperation(roller, this,
+				null));
+	}
+
+	public void rebuildWebsiteIndex(Weblog website) throws WebloggerException {
+		scheduleIndexOperation(new RebuildWebsiteIndexOperation(roller, this,
+				website));
+	}
+
+	public void removeWebsiteIndex(Weblog website) throws WebloggerException {
+		scheduleIndexOperation(new RemoveWebsiteIndexOperation(roller, this,
+				website));
+	}
+
+	public void addEntryIndexOperation(WeblogEntry entry)
+			throws WebloggerException {
+		AddEntryOperation addEntry = new AddEntryOperation(roller, this, entry);
+		scheduleIndexOperation(addEntry);
+	}
+
+	public void addEntryReIndexOperation(WeblogEntry entry)
+			throws WebloggerException {
+		ReIndexEntryOperation reindex = new ReIndexEntryOperation(roller, this,
+				entry);
+		scheduleIndexOperation(reindex);
+	}
+
+	public void removeEntryIndexOperation(WeblogEntry entry)
+			throws WebloggerException {
+		RemoveEntryOperation removeOp = new RemoveEntryOperation(roller, this,
+				entry);
+		executeIndexOperationNow(removeOp);
+	}
+
+	public ReadWriteLock getReadWriteLock() {
+		return rwl;
+	}
+
+	public boolean isInconsistentAtStartup() {
+		return inconsistentAtStartup;
+	}
+
+	/**
+	 * This is the analyzer that will be used to tokenize comment text.
+	 * 
+	 * @return Analyzer to be used in manipulating the database.
+	 */
+	public static final Analyzer getAnalyzer() {
+		return new StandardAnalyzer(FieldConstants.LUCENE_VERSION);
+	}
+
+	private void scheduleIndexOperation(final IndexOperation op) {
+		try {
+			// only if search is enabled
+			if (this.searchEnabled) {
+				mLogger.debug("Starting scheduled index operation: "
+						+ op.getClass().getName());
+				roller.getThreadManager().executeInBackground(op);
+			}
+		} catch (InterruptedException e) {
+			mLogger.error("Error executing operation", e);
+		}
+	}
+
+	/**
+	 * @param search
+	 */
+	public void executeIndexOperationNow(final IndexOperation op) {
+		try {
+			// only if search is enabled
+			if (this.searchEnabled) {
+				mLogger.debug("Executing index operation now: "
+						+ op.getClass().getName());
+				roller.getThreadManager().executeInForeground(op);
+			}
+		} catch (InterruptedException e) {
+			mLogger.error("Error executing operation", e);
+		}
+	}
+
+	public synchronized void resetSharedReader() {
+		reader = null;
+	}
+
+	public synchronized IndexReader getSharedIndexReader() {
+		if (reader == null) {
+			try {
+				reader = IndexReader.open(getIndexDirectory());
+			} catch (IOException e) {
+			}
+		}
+		return reader;
+	}
+
+	/**
+	 * Get the directory that is used by the lucene index. This method will
+	 * return null if there is no index at the directory location. If we are
+	 * using a RAM index, the directory will be a ram directory.
+	 * 
+	 * @return Directory The directory containing the index, or null if error.
+	 */
+	public Directory getIndexDirectory() {
+		if (useRAMIndex) {
+			return fRAMindex;
+		} else {
+			return getFSDirectory(false);
+		}
+	}
+
+	private boolean indexExists() {
+		try {
+			return IndexReader.indexExists(getIndexDirectory());
+		} catch (IOException e) {
+			mLogger.error("Problem accessing index directory", e);
+		}
+		return false;
+	}
+
+	private Directory getFSDirectory(boolean delete) {
+		
+		Directory directory = null;
+
+		try {
+
+			directory = FSDirectory.open(new File(indexDir));
+
+			if (delete && directory != null) {
+				String[] files = directory.listAll(); // clear old files
+				for (int i = 0; i < files.length; i++) {
+					File file = new File(indexDir, files[i]);
+					if (!file.delete())
+						throw new IOException("couldn't delete " + files[i]);
+				}
+			}
+
+		} catch (IOException e) {
+			mLogger.error("Problem accessing index directory", e);
+		}
+
+		return directory;
+
+	}
+
+	private void createIndex(Directory dir) {
+		IndexWriter writer = null;
+
+		try {
+
+			IndexWriterConfig config = new IndexWriterConfig(
+					FieldConstants.LUCENE_VERSION, new LimitTokenCountAnalyzer(
+							IndexManagerImpl.getAnalyzer(),
+							IndexWriterConfig.DEFAULT_TERM_INDEX_INTERVAL));
+
+			writer = new IndexWriter(dir, config);
+
+		} catch (IOException e) {
+			mLogger.error("Error creating index", e);
+		} finally {
+			try {
+				if (writer != null) {
+					writer.close();
+				}
+			} catch (IOException e) {
+			}
+		}
+	}
+
+	private IndexOperation getSaveIndexOperation() {
+		return new WriteToIndexOperation(this) {
+			public void doRun() {
+				Directory dir = getIndexDirectory();
+				Directory fsdir = getFSDirectory(true);
+
+				IndexWriter writer = null;
+
+				try {
+					IndexWriterConfig config = new IndexWriterConfig(
+							FieldConstants.LUCENE_VERSION,
+							new LimitTokenCountAnalyzer(
+									IndexManagerImpl.getAnalyzer(),
+									IndexWriterConfig.DEFAULT_TERM_INDEX_INTERVAL));
+
+					writer = new IndexWriter(fsdir, config);
+
+					writer.addIndexes(new Directory[] { dir });
+
+					writer.commit();
+
+					indexConsistencyMarker.delete();
+					
+				} catch (IOException e) {
+					mLogger.error("Problem saving index to disk", e);
+
+					// Delete the directory, since there was a problem saving
+					// the RAM contents
+					getFSDirectory(true);
+				} finally {
+					try {
+						if (writer != null)
+							writer.close();
+					} catch (IOException e1) {
+						mLogger.warn("Unable to close IndexWriter.");
+					}
+				}
+
+			}
+		};
+	}
+
+	public void release() {
+		// no-op
+	}
+
+	public void shutdown() {
+		if (useRAMIndex) {
+			scheduleIndexOperation(getSaveIndexOperation());
+		} else {
+			indexConsistencyMarker.delete();
+		}
+
+		try {
+			if (reader != null)
+				reader.close();
+		} catch (IOException e) {
+			// won't happen, since it was
+		}
+	}
 
 }

Modified: roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/IndexUtil.java
URL: http://svn.apache.org/viewvc/roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/IndexUtil.java?rev=1340676&r1=1340675&r2=1340676&view=diff
==============================================================================
--- roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/IndexUtil.java (original)
+++ roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/IndexUtil.java Sun May 20 11:16:25 2012
@@ -18,44 +18,71 @@
 /* Created on Jul 20, 2003 */
 package org.apache.roller.weblogger.business.search;
 
+import java.io.IOException;
+import java.io.StringReader;
+
 import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.analysis.Token;
+import org.apache.lucene.analysis.LengthFilter;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
 import org.apache.lucene.index.Term;
-import org.apache.roller.weblogger.business.search.IndexManagerImpl;
-
-import java.io.IOException;
-import java.io.StringReader;
 
 /**
  * Class containing helper methods.
+ * 
  * @author Mindaugas Idzelis (min@idzelis.com)
  */
 public class IndexUtil {
-    
-    /**
-     * Create a lucene term from the first token of the input string.
-     *
-     * @param field The lucene document field to create a term with
-     * @param input The input you wish to convert into a term
-     * @return Lucene search term
-     */
-    public static final Term getTerm(String field, String input) {
-        if (input==null || field==null) return null;
-        Analyzer analyer = IndexManagerImpl.getAnalyzer();
-        TokenStream tokens = analyer.tokenStream(field,
-                new StringReader(input));
-        
-        Token token = null;
-        Term term = null;
-        try {
-            token = tokens.next();
-        } catch (IOException e) {}
-        if (token!=null) {
-            String termt = token.termText();
-            term = new Term(field,termt);
-        }
-        return term;
-    }
-    
+
+	/**
+	 * Create a lucene term from the first token of the input string.
+	 * 
+	 * @param field
+	 *            The lucene document field to create a term with
+	 * @param input
+	 *            The input you wish to convert into a term
+	 * 
+	 * @return Lucene search term
+	 */
+	public static final Term getTerm(String field, String input) {
+
+		if (input == null || field == null)
+			return null;
+
+		Analyzer analyer = IndexManagerImpl.getAnalyzer();
+		TokenStream tokens = analyer
+				.tokenStream(field, new StringReader(input));
+
+		Term term = null;
+
+		// LengthFilter(EnablePositionIncrements ..) If true, this TokenFilter
+		// will preserve positions of the incoming tokens (ie, accumulate and
+		// set position increments of the removed tokens). Generally, true is
+		// best as it does not lose information (positions of the original
+		// tokens) during indexing. When set, when a token is stopped (omitted),
+		// the position increment of the following token is incremented.
+
+		// Min length 3 characters
+		tokens = new LengthFilter(true, tokens, 3, Integer.MAX_VALUE);
+
+		CharTermAttribute termAtt = (CharTermAttribute) tokens
+				.addAttribute(CharTermAttribute.class);
+
+		try {
+
+			tokens.reset();
+
+			if (tokens.incrementToken()) {
+				// System.out.println("token: " + tokens);
+				String termt = termAtt.toString();
+				term = new Term(field, termt);
+			}
+
+		} catch (IOException e) {
+			// ignored
+		}
+
+		return term;
+	}
+
 }

Modified: roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/IndexOperation.java
URL: http://svn.apache.org/viewvc/roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/IndexOperation.java?rev=1340676&r1=1340675&r2=1340676&view=diff
==============================================================================
--- roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/IndexOperation.java (original)
+++ roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/IndexOperation.java Sun May 20 11:16:25 2012
@@ -24,205 +24,198 @@ import java.util.List;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.lucene.analysis.LimitTokenCountAnalyzer;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
-import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.IndexWriter;
-import org.apache.roller.weblogger.business.search.IndexManagerImpl;
+import org.apache.lucene.index.IndexWriterConfig;
 import org.apache.roller.weblogger.business.search.FieldConstants;
-import org.apache.roller.weblogger.pojos.WeblogEntryComment;
+import org.apache.roller.weblogger.business.search.IndexManagerImpl;
+import org.apache.roller.weblogger.config.WebloggerConfig;
 import org.apache.roller.weblogger.pojos.WeblogCategory;
 import org.apache.roller.weblogger.pojos.WeblogEntry;
+import org.apache.roller.weblogger.pojos.WeblogEntryComment;
 import org.apache.roller.weblogger.util.Utilities;
-import org.apache.roller.weblogger.config.WebloggerConfig;
 
 /**
- * This is the base class for all index operation. 
- * These operations include:<br>
- *    SearchOperation<br>
- *    AddWeblogOperation<br>
- *    RemoveWeblogOperation<br>
- *    RebuildUserIndexOperation
- *
+ * This is the base class for all index operation. These operations include:<br>
+ * SearchOperation<br>
+ * AddWeblogOperation<br>
+ * RemoveWeblogOperation<br>
+ * RebuildUserIndexOperation
+ * 
  * @author Mindaugas Idzelis (min@idzelis.com)
  */
 public abstract class IndexOperation implements Runnable {
 
-    private static Log mLogger = LogFactory.getFactory().getInstance(IndexOperation.class);
+	private static Log mLogger = LogFactory.getFactory().getInstance(
+			IndexOperation.class);
 
-    //~ Instance fields
-    // ========================================================
-    protected IndexManagerImpl manager;
-    private IndexReader reader;
-    private IndexWriter writer;
-
-    //~ Constructors
-    // ===========================================================
-    public IndexOperation(IndexManagerImpl manager) {
-        this.manager = manager;
-    }
-
-    //~ Methods
-    // ================================================================
-    protected Document getDocument(WeblogEntry data) {
-
-        // Actual comment content is indexed only if search.index.comments
-        // is true or absent from the (static) configuration properties.
-        // If false in the configuration, comments are treated as if empty.
-        boolean indexComments =
-            WebloggerConfig.getBooleanProperty("search.index.comments", true);
-
-        String commentContent = "";
-        String commentEmail = "";
-        String commentName = "";
-        if (indexComments) {
-            List comments = data.getComments();
-            if (comments != null) {
-                StringBuffer commentEmailBuf = new StringBuffer();
-                StringBuffer commentContentBuf = new StringBuffer();
-                StringBuffer commentNameBuf = new StringBuffer();
-                for (Iterator cItr = comments.iterator(); cItr.hasNext();) {
-                    WeblogEntryComment comment = (WeblogEntryComment) cItr.next();
-                    if (comment.getContent() != null) {
-                        commentContentBuf.append(comment.getContent());
-                        commentContentBuf.append(",");
-                    }
-                    if (comment.getEmail() != null) {
-                        commentEmailBuf.append(comment.getEmail());
-                        commentEmailBuf.append(",");
-                    }
-                    if (comment.getName() != null) {
-                        commentNameBuf.append(comment.getName());
-                        commentNameBuf.append(",");
-                    }
-                }
-                commentEmail = commentEmailBuf.toString();
-                commentContent = commentContentBuf.toString();
-                commentName = commentNameBuf.toString();
-            }
-        }
-
-        Document doc = new Document();
-
-        // keyword
-        doc.add(new Field(FieldConstants.ID, data.getId(),
-                Field.Store.YES, Field.Index.NOT_ANALYZED));
-
-        // keyword
-        doc.add(new Field(FieldConstants.WEBSITE_HANDLE,
-                data.getWebsite().getHandle(),
-                Field.Store.YES, Field.Index.NOT_ANALYZED));
-
-        // unindexed
-        doc.add(new Field(FieldConstants.ANCHOR,
-                data.getAnchor(),
-                Field.Store.YES, Field.Index.NO));
-
-        // text
-        doc.add(new Field(FieldConstants.USERNAME,
-                data.getCreator().getUserName(),
-                Field.Store.YES, Field.Index.ANALYZED));
-
-        // text
-        doc.add(new Field(FieldConstants.TITLE,
-                data.getTitle(), 
-                Field.Store.YES, Field.Index.ANALYZED));
-
-        // index the entry text, but don't store it - moved to end of block
-        // unstored
-        doc.add(new Field(FieldConstants.CONTENT,
-                data.getText(),
-                Field.Store.NO, Field.Index.ANALYZED));
-
-        // store an abbreviated version of the entry text, but don't index
-        // unindexed
-        doc.add(new Field(FieldConstants.CONTENT_STORED,
-                Utilities.truncateNicely(Utilities.removeHTML(data.getText()), 240, 260, "..."),
-                Field.Store.YES, Field.Index.NO));
-
-        // keyword
-        doc.add(new Field(FieldConstants.UPDATED,
-                data.getUpdateTime().toString(),
-                Field.Store.YES, Field.Index.NOT_ANALYZED));
-
-        // keyword
-        doc.add(new Field(FieldConstants.PUBLISHED,
-                data.getPubTime().toString(),
-                Field.Store.YES, Field.Index.NOT_ANALYZED));
-
-        // index Comments
-        // unstored
-        doc.add(new Field(FieldConstants.C_CONTENT,
-                commentContent,
-                Field.Store.NO, Field.Index.ANALYZED));
-        // unstored
-        doc.add(new Field(FieldConstants.C_EMAIL,
-                commentEmail,
-                Field.Store.NO, Field.Index.ANALYZED));
-        // unstored
-        doc.add(new Field(FieldConstants.C_NAME,
-                commentName,
-                Field.Store.NO, Field.Index.ANALYZED));
-
-        // unstored
-        doc.add(new Field(FieldConstants.CONSTANT,
-                FieldConstants.CONSTANT_V,
-                Field.Store.NO, Field.Index.ANALYZED));
-
-        // index Category
-        WeblogCategory categorydata = data.getCategory();
-        Field category = (categorydata == null)
-                // unstored
-                ? new Field(FieldConstants.CATEGORY, "", Field.Store.NO, Field.Index.ANALYZED)
-                // text
-                : new Field(FieldConstants.CATEGORY, categorydata.getName(), Field.Store.YES, Field.Index.ANALYZED);
-        doc.add(category);
-
-        return doc;
-    }
-
-    protected IndexReader beginDeleting() {
-        try {
-            reader = IndexReader.open(manager.getIndexDirectory());
-        } catch (IOException e) {
-        }
-
-        return reader;
-    }
-
-    protected void endDeleting() {
-        if (reader != null) {
-            try {
-                reader.close();
-            } catch (IOException e) {
-                mLogger.error("ERROR closing reader");
-            }
-        }
-    }
-
-    protected IndexWriter beginWriting() {
-        try {
-            writer = new IndexWriter(manager.getIndexDirectory(), IndexManagerImpl.getAnalyzer(), false);
-        } catch (IOException e) {
-            mLogger.error("ERROR creating writer", e);
-        }
-
-        return writer;
-    }
-
-    protected void endWriting() {
-        if (writer != null) {
-            try {
-                writer.close();
-            } catch (IOException e) {
-                mLogger.error("ERROR closing writer", e);
-            }
-        }
-    }
-
-    public void run() {
-        doRun();
-    }
+	// ~ Instance fields
+	// ========================================================
+	protected IndexManagerImpl manager;
+	private IndexWriter writer;
+
+	// ~ Constructors
+	// ===========================================================
+	public IndexOperation(IndexManagerImpl manager) {
+		this.manager = manager;
+	}
+
+	// ~ Methods
+	// ================================================================
+	protected Document getDocument(WeblogEntry data) {
+
+		// Actual comment content is indexed only if search.index.comments
+		// is true or absent from the (static) configuration properties.
+		// If false in the configuration, comments are treated as if empty.
+		boolean indexComments = WebloggerConfig.getBooleanProperty(
+				"search.index.comments", true);
+
+		String commentContent = "";
+		String commentEmail = "";
+		String commentName = "";
+		if (indexComments) {
+			List comments = data.getComments();
+			if (comments != null) {
+				StringBuilder commentEmailBld = new StringBuilder();
+				StringBuilder commentContentBld = new StringBuilder();
+				StringBuilder commentNameBld = new StringBuilder();
+				for (Iterator cItr = comments.iterator(); cItr.hasNext();) {
+					WeblogEntryComment comment = (WeblogEntryComment) cItr
+							.next();
+					if (comment.getContent() != null) {
+						commentContentBld.append(comment.getContent());
+						commentContentBld.append(",");
+					}
+					if (comment.getEmail() != null) {
+						commentEmailBld.append(comment.getEmail());
+						commentEmailBld.append(",");
+					}
+					if (comment.getName() != null) {
+						commentNameBld.append(comment.getName());
+						commentNameBld.append(",");
+					}
+				}
+				commentEmail = commentEmailBld.toString();
+				commentContent = commentContentBld.toString();
+				commentName = commentNameBld.toString();
+			}
+		}
+
+		Document doc = new Document();
+
+		// keyword
+		doc.add(new Field(FieldConstants.ID, data.getId(), Field.Store.YES,
+				Field.Index.NOT_ANALYZED));
+
+		// keyword
+		doc.add(new Field(FieldConstants.WEBSITE_HANDLE, data.getWebsite()
+				.getHandle(), Field.Store.YES, Field.Index.NOT_ANALYZED));
+
+		// unindexed
+		doc.add(new Field(FieldConstants.ANCHOR, data.getAnchor(),
+				Field.Store.YES, Field.Index.NO));
+
+		// text
+		doc.add(new Field(FieldConstants.USERNAME, data.getCreator()
+				.getUserName(), Field.Store.YES, Field.Index.ANALYZED));
+
+		// text
+		doc.add(new Field(FieldConstants.TITLE, data.getTitle(),
+				Field.Store.YES, Field.Index.ANALYZED));
+
+		// index the entry text, but don't store it - moved to end of block
+		// unstored
+		doc.add(new Field(FieldConstants.CONTENT, data.getText(),
+				Field.Store.NO, Field.Index.ANALYZED));
+
+		// store an abbreviated version of the entry text, but don't index
+		// unindexed
+		doc.add(new Field(FieldConstants.CONTENT_STORED, Utilities
+				.truncateNicely(Utilities.removeHTML(data.getText()), 240, 260,
+						"..."), Field.Store.YES, Field.Index.NO));
+
+		// keyword
+		doc.add(new Field(FieldConstants.UPDATED, data.getUpdateTime()
+				.toString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
+
+		// keyword
+		doc.add(new Field(FieldConstants.PUBLISHED, data.getPubTime()
+				.toString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
+
+		// index Comments
+		// unstored
+		doc.add(new Field(FieldConstants.C_CONTENT, commentContent,
+				Field.Store.NO, Field.Index.ANALYZED));
+		// unstored
+		doc.add(new Field(FieldConstants.C_EMAIL, commentEmail, Field.Store.NO,
+				Field.Index.ANALYZED));
+		// unstored
+		doc.add(new Field(FieldConstants.C_NAME, commentName, Field.Store.NO,
+				Field.Index.ANALYZED));
+
+		// unstored
+		doc.add(new Field(FieldConstants.CONSTANT, FieldConstants.CONSTANT_V,
+				Field.Store.NO, Field.Index.ANALYZED));
+
+		// index Category
+		WeblogCategory categorydata = data.getCategory();
+		Field category = (categorydata == null)
+		// unstored
+		? new Field(FieldConstants.CATEGORY, "", Field.Store.NO,
+				Field.Index.ANALYZED)
+		// text
+				: new Field(FieldConstants.CATEGORY, categorydata.getName(),
+						Field.Store.YES, Field.Index.ANALYZED);
+		doc.add(category);
+
+		return doc;
+	}
+
+	/**
+	 * Begin writing.
+	 *
+	 * @return the index writer
+	 */
+	protected IndexWriter beginWriting() {
+		try {
+
+			// Limit to 1000 tokens.
+			LimitTokenCountAnalyzer analyzer = new LimitTokenCountAnalyzer(
+					IndexManagerImpl.getAnalyzer(), 1000);
+
+			IndexWriterConfig config = new IndexWriterConfig(
+					FieldConstants.LUCENE_VERSION, analyzer);
+
+			writer = new IndexWriter(manager.getIndexDirectory(), config);
+
+		} catch (IOException e) {
+			mLogger.error("ERROR creating writer", e);
+		}
+
+		return writer;
+	}
+
+	/**
+	 * End writing.
+	 */
+	protected void endWriting() {
+		if (writer != null) {
+			try {
+				writer.close();
+			} catch (IOException e) {
+				mLogger.error("ERROR closing writer", e);
+			}
+		}
+	}
+
+	/**
+	 * @see java.lang.Runnable#run()
+	 */
+	public void run() {
+		doRun();
+	}
 
-    protected abstract void doRun();
+	protected abstract void doRun();
 }

Modified: roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/ReIndexEntryOperation.java
URL: http://svn.apache.org/viewvc/roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/ReIndexEntryOperation.java?rev=1340676&r1=1340675&r2=1340676&view=diff
==============================================================================
--- roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/ReIndexEntryOperation.java (original)
+++ roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/ReIndexEntryOperation.java Sun May 20 11:16:25 2012
@@ -22,80 +22,80 @@ import java.io.IOException;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.IndexWriter;
 import org.apache.lucene.index.Term;
 import org.apache.roller.weblogger.WebloggerException;
-import org.apache.roller.weblogger.business.search.IndexManagerImpl;
-import org.apache.roller.weblogger.business.search.FieldConstants;
-import org.apache.roller.weblogger.business.Weblogger;
 import org.apache.roller.weblogger.business.WeblogEntryManager;
+import org.apache.roller.weblogger.business.Weblogger;
+import org.apache.roller.weblogger.business.search.FieldConstants;
+import org.apache.roller.weblogger.business.search.IndexManagerImpl;
 import org.apache.roller.weblogger.pojos.WeblogEntry;
 
 /**
  * An operation that adds a new log entry into the index.
+ * 
  * @author Mindaugas Idzelis (min@idzelis.com)
  */
 public class ReIndexEntryOperation extends WriteToIndexOperation {
-    
-    //~ Static fields/initializers =============================================
-    
-    private static Log mLogger =
-            LogFactory.getFactory().getInstance(AddEntryOperation.class);
-    
-    //~ Instance fields ========================================================
-    
-    private WeblogEntry data;
-    private Weblogger roller;
-    
-    //~ Constructors ===========================================================
-    
-    /**
-     * Adds a web log entry into the index.
-     */
-    public ReIndexEntryOperation(Weblogger roller, IndexManagerImpl mgr,WeblogEntry data) {
-        super(mgr);
-        this.roller = roller;
-        this.data = data;
-    }
-    
-    //~ Methods ================================================================
-    
-    public void doRun() {
-        
-        // since this operation can be run on a separate thread we must treat
-        // the weblog object passed in as a detached object which is proned to
-        // lazy initialization problems, so requery for the object now
-        try {
-            WeblogEntryManager wMgr = roller.getWeblogEntryManager();
-            this.data = wMgr.getWeblogEntry(this.data.getId());
-        } catch (WebloggerException ex) {
-            mLogger.error("Error getting weblogentry object", ex);
-            return;
-        }
-        
-        IndexReader reader = beginDeleting();
-        try {
-            if (reader != null) {
-                Term term = new Term(FieldConstants.ID, data.getId());
-                reader.deleteDocuments(term);
-            }
-        } catch (IOException e) {
-            mLogger.error("Error deleting doc from index", e);
-        } finally {
-            endDeleting();
-        }
-        
-        IndexWriter writer = beginWriting();
-        try {
-            if (writer != null) {
-                writer.addDocument(getDocument(data));
-            }
-        } catch (IOException e) {
-            mLogger.error("Problems adding doc to index", e);
-        } finally {
-            if (roller != null) roller.release();
-            endWriting();
-        }
-    }
+
+	// ~ Static fields/initializers
+	// =============================================
+
+	private static Log mLogger = LogFactory.getFactory().getInstance(
+			AddEntryOperation.class);
+
+	// ~ Instance fields
+	// ========================================================
+
+	private WeblogEntry data;
+	private Weblogger roller;
+
+	// ~ Constructors
+	// ===========================================================
+
+	/**
+	 * Adds a web log entry into the index.
+	 */
+	public ReIndexEntryOperation(Weblogger roller, IndexManagerImpl mgr,
+			WeblogEntry data) {
+		super(mgr);
+		this.roller = roller;
+		this.data = data;
+	}
+
+	// ~ Methods
+	// ================================================================
+
+	public void doRun() {
+
+		// since this operation can be run on a separate thread we must treat
+		// the weblog object passed in as a detached object which is proned to
+		// lazy initialization problems, so requery for the object now
+		try {
+			WeblogEntryManager wMgr = roller.getWeblogEntryManager();
+			this.data = wMgr.getWeblogEntry(this.data.getId());
+		} catch (WebloggerException ex) {
+			mLogger.error("Error getting weblogentry object", ex);
+			return;
+		}
+
+		IndexWriter writer = beginWriting();
+		try {
+			if (writer != null) {
+
+				// Delete Doc
+				Term term = new Term(FieldConstants.ID, data.getId());
+				writer.deleteDocuments(term);
+
+				// Add Doc
+				writer.addDocument(getDocument(data));
+			}
+		} catch (IOException e) {
+			mLogger.error("Problems adding/deleting doc to index", e);
+		} finally {
+			if (roller != null)
+				roller.release();
+			endWriting();
+		}
+	}
 }

Modified: roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/RebuildWebsiteIndexOperation.java
URL: http://svn.apache.org/viewvc/roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/RebuildWebsiteIndexOperation.java?rev=1340676&r1=1340675&r2=1340676&view=diff
==============================================================================
--- roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/RebuildWebsiteIndexOperation.java (original)
+++ roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/RebuildWebsiteIndexOperation.java Sun May 20 11:16:25 2012
@@ -18,7 +18,6 @@
 /* Created on Jul 16, 2003 */
 package org.apache.roller.weblogger.business.search.operations;
 
-import java.io.IOException;
 import java.text.MessageFormat;
 import java.util.Date;
 import java.util.Iterator;
@@ -26,136 +25,137 @@ import java.util.List;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.IndexWriter;
 import org.apache.lucene.index.Term;
 import org.apache.roller.weblogger.WebloggerException;
-import org.apache.roller.weblogger.business.search.IndexManagerImpl;
+import org.apache.roller.weblogger.business.WeblogEntryManager;
+import org.apache.roller.weblogger.business.Weblogger;
 import org.apache.roller.weblogger.business.search.FieldConstants;
+import org.apache.roller.weblogger.business.search.IndexManagerImpl;
 import org.apache.roller.weblogger.business.search.IndexUtil;
-import org.apache.roller.weblogger.business.Weblogger;
-import org.apache.roller.weblogger.business.WeblogEntryManager;
-import org.apache.roller.weblogger.pojos.WeblogEntry;
 import org.apache.roller.weblogger.pojos.Weblog;
+import org.apache.roller.weblogger.pojos.WeblogEntry;
 
 /**
  * An index operation that rebuilds a given users index (or all indexes).
+ * 
  * @author Mindaugas Idzelis (min@idzelis.com)
  */
 public class RebuildWebsiteIndexOperation extends WriteToIndexOperation {
-    
-    //~ Static fields/initializers =============================================
-    
-    private static Log mLogger =
-        LogFactory.getFactory().getInstance(RebuildWebsiteIndexOperation.class);
-    
-    //~ Instance fields ========================================================
-    
-    private Weblog website;
-    private Weblogger roller;
-    
-    //~ Constructors ===========================================================
-    
-    /**
-     * Create a new operation that will recreate an index.
-     *
-     * @param website The website to rebuild the index for, or null for all users.
-     */
-    public RebuildWebsiteIndexOperation(Weblogger roller, IndexManagerImpl mgr, Weblog website) {
-        super(mgr);
-        this.roller = roller;
-        this.website = website;
-    }
-    
-    //~ Methods ================================================================
-    
-    public void doRun() {
-
-        Date start = new Date();
-        
-        // since this operation can be run on a separate thread we must treat
-        // the weblog object passed in as a detached object which is proned to
-        // lazy initialization problems, so requery for the object now
-        if ( this.website != null) {
-            mLogger.debug("Reindexining weblog " + website.getHandle());
-            try {
-                this.website = roller.getWeblogManager().getWeblog(this.website.getId());
-            } catch (WebloggerException ex) {
-                mLogger.error("Error getting website object", ex);
-                return;
-            }
-        } else {
-            mLogger.debug("Reindexining entire site");
-        }
-
-        IndexReader reader = beginDeleting();
-        
-        try {
-            if (reader != null) {
-                Term tWebsite = null;
-                if (website != null) {
-                    tWebsite = IndexUtil.getTerm(
-                            FieldConstants.WEBSITE_HANDLE, website.getHandle());
-                }
-                if (tWebsite != null) {
-                    reader.deleteDocuments(tWebsite);
-                } else {
-                    Term all =
-                            IndexUtil.getTerm(FieldConstants.CONSTANT,
-                            FieldConstants.CONSTANT_V);
-                    reader.deleteDocuments(all);
-                }
-            }
-        } catch (IOException e) {
-            mLogger.info("Problems deleting doc from index", e);
-        } finally {
-            endDeleting();
-        }
-        
-        IndexWriter writer = beginWriting();
-        
-        try {
-            if (writer != null) {
-                WeblogEntryManager weblogManager = roller.getWeblogEntryManager();
-                List entries = weblogManager .getWeblogEntries(                        
-                        website,                   // website            
-                        null,
-                        null,                      // startDate
-                        null,                      // endDate
-                        null,                      // catName
-                        null,WeblogEntry.PUBLISHED, // status
-                        null,                      // text
-                        null,                      // sortby (null means pubTime)
-                        null, 
-                        null,
-                        0, -1);     // offset, length, locale
-                mLogger.debug("Entries to index: " + entries.size());
-                for (Iterator wbItr = entries.iterator(); wbItr.hasNext();) {
-                    WeblogEntry entry = (WeblogEntry) wbItr.next();
-                    writer.addDocument(getDocument(entry));
-                    mLogger.debug(
-                            MessageFormat.format("Indexed entry {0}: {1}",
-                            new Object[] {entry.getPubTime(), entry.getAnchor()}));
-                }
-                // release the database connection
-                roller.release();
-            }
-        } catch (Exception e) {
-            mLogger.error("ERROR adding doc to index", e);
-        } finally {
-            endWriting();
-            if (roller != null) roller.release();
-        }
-        
-        Date end = new Date();
-        double length = (end.getTime() - start.getTime()) / (double) 1000;
-        
-        if (website == null) {
-            mLogger.info(
-                    "Completed rebuilding index for all users in '" + length + "' secs");
-        } else {
-            mLogger.info("Completed rebuilding index for website handle: '" +
-                    website.getHandle() + "' in '" + length + "' seconds");
-        }
-    }
+
+	// ~ Static fields/initializers
+	// =============================================
+
+	private static Log mLogger = LogFactory.getFactory().getInstance(
+			RebuildWebsiteIndexOperation.class);
+
+	// ~ Instance fields
+	// ========================================================
+
+	private Weblog website;
+	private Weblogger roller;
+
+	// ~ Constructors
+	// ===========================================================
+
+	/**
+	 * Create a new operation that will recreate an index.
+	 * 
+	 * @param website
+	 *            The website to rebuild the index for, or null for all users.
+	 */
+	public RebuildWebsiteIndexOperation(Weblogger roller, IndexManagerImpl mgr,
+			Weblog website) {
+		super(mgr);
+		this.roller = roller;
+		this.website = website;
+	}
+
+	// ~ Methods
+	// ================================================================
+
+	public void doRun() {
+
+		Date start = new Date();
+
+		// since this operation can be run on a separate thread we must treat
+		// the weblog object passed in as a detached object which is proned to
+		// lazy initialization problems, so requery for the object now
+		if (this.website != null) {
+			mLogger.debug("Reindexining weblog " + website.getHandle());
+			try {
+				this.website = roller.getWeblogManager().getWeblog(
+						this.website.getId());
+			} catch (WebloggerException ex) {
+				mLogger.error("Error getting website object", ex);
+				return;
+			}
+		} else {
+			mLogger.debug("Reindexining entire site");
+		}
+
+		IndexWriter writer = beginWriting();
+
+		try {
+			if (writer != null) {
+
+				// Delete Doc
+				Term tWebsite = null;
+				if (website != null) {
+					tWebsite = IndexUtil.getTerm(FieldConstants.WEBSITE_HANDLE,
+							website.getHandle());
+				}
+				if (tWebsite != null) {
+					writer.deleteDocuments(tWebsite);
+				} else {
+					Term all = IndexUtil.getTerm(FieldConstants.CONSTANT,
+							FieldConstants.CONSTANT_V);
+					writer.deleteDocuments(all);
+				}
+
+				// Add Doc
+				WeblogEntryManager weblogManager = roller
+						.getWeblogEntryManager();
+				List entries = weblogManager.getWeblogEntries(website, // website
+						null, null, // startDate
+						null, // endDate
+						null, // catName
+						null, WeblogEntry.PUBLISHED, // status
+						null, // text
+						null, // sortby (null means pubTime)
+						null, null, 0, -1); // offset, length, locale
+
+				mLogger.debug("Entries to index: " + entries.size());
+
+				for (Iterator wbItr = entries.iterator(); wbItr.hasNext();) {
+					WeblogEntry entry = (WeblogEntry) wbItr.next();
+					writer.addDocument(getDocument(entry));
+					mLogger.debug(MessageFormat.format(
+							"Indexed entry {0}: {1}",
+							new Object[] { entry.getPubTime(),
+									entry.getAnchor() }));
+				}
+
+				// release the database connection
+				roller.release();
+			}
+		} catch (Exception e) {
+			mLogger.error("ERROR adding/deleting doc to index", e);
+		} finally {
+			endWriting();
+			if (roller != null)
+				roller.release();
+		}
+
+		Date end = new Date();
+		double length = (end.getTime() - start.getTime()) / (double) 1000;
+
+		if (website == null) {
+			mLogger.info("Completed rebuilding index for all users in '"
+					+ length + "' secs");
+		} else {
+			mLogger.info("Completed rebuilding index for website handle: '"
+					+ website.getHandle() + "' in '" + length + "' seconds");
+		}
+	}
 }

Modified: roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/RemoveEntryOperation.java
URL: http://svn.apache.org/viewvc/roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/RemoveEntryOperation.java?rev=1340676&r1=1340675&r2=1340676&view=diff
==============================================================================
--- roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/RemoveEntryOperation.java (original)
+++ roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/RemoveEntryOperation.java Sun May 20 11:16:25 2012
@@ -22,67 +22,71 @@ import java.io.IOException;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexWriter;
 import org.apache.lucene.index.Term;
 import org.apache.roller.weblogger.WebloggerException;
-import org.apache.roller.weblogger.business.Weblogger;
 import org.apache.roller.weblogger.business.WeblogEntryManager;
-import org.apache.roller.weblogger.business.search.IndexManagerImpl;
+import org.apache.roller.weblogger.business.Weblogger;
 import org.apache.roller.weblogger.business.search.FieldConstants;
+import org.apache.roller.weblogger.business.search.IndexManagerImpl;
 import org.apache.roller.weblogger.pojos.WeblogEntry;
 
-
 /**
  * An operation that removes the weblog from the index.
+ * 
  * @author Mindaugas Idzelis (min@idzelis.com)
  */
 public class RemoveEntryOperation extends WriteToIndexOperation {
-    
-    //~ Static fields/initializers =============================================
-    
-    private static Log mLogger =
-            LogFactory.getFactory().getInstance(RemoveEntryOperation.class);
-    
-    //~ Instance fields ========================================================
-    
-    private WeblogEntry data;
-    private Weblogger roller;
-    
-    //~ Constructors ===========================================================
-    
-    public RemoveEntryOperation(Weblogger roller, IndexManagerImpl mgr,WeblogEntry data) {
-        super(mgr);
-        this.roller = roller;
-        this.data = data;
-    }
-    
-    //~ Methods ================================================================
-    
-    public void doRun() {
-        
-        // since this operation can be run on a separate thread we must treat
-        // the weblog object passed in as a detached object which is proned to
-        // lazy initialization problems, so requery for the object now
-        try {
-            WeblogEntryManager wMgr = roller.getWeblogEntryManager();
-            this.data = wMgr.getWeblogEntry(this.data.getId());
-        } catch (WebloggerException ex) {
-            mLogger.error("Error getting weblogentry object", ex);
-            return;
-        }
-        
-        IndexReader reader = beginDeleting();
-        try {
-            if (reader != null) {
-                Term term = new Term(FieldConstants.ID, data.getId());
-                reader.deleteDocuments(term);
-            }
-        } catch (IOException e) {
-            mLogger.error("Error deleting doc from index", e);
-        } finally {
-            endDeleting();
-        }
-    }
-    
-    
+
+	// ~ Static fields/initializers
+	// =============================================
+
+	private static Log mLogger = LogFactory.getFactory().getInstance(
+			RemoveEntryOperation.class);
+
+	// ~ Instance fields
+	// ========================================================
+
+	private WeblogEntry data;
+	private Weblogger roller;
+
+	// ~ Constructors
+	// ===========================================================
+
+	public RemoveEntryOperation(Weblogger roller, IndexManagerImpl mgr,
+			WeblogEntry data) {
+		super(mgr);
+		this.roller = roller;
+		this.data = data;
+	}
+
+	// ~ Methods
+	// ================================================================
+
+	public void doRun() {
+
+		// since this operation can be run on a separate thread we must treat
+		// the weblog object passed in as a detached object which is proned to
+		// lazy initialization problems, so requery for the object now
+		try {
+			WeblogEntryManager wMgr = roller.getWeblogEntryManager();
+			this.data = wMgr.getWeblogEntry(this.data.getId());
+		} catch (WebloggerException ex) {
+			mLogger.error("Error getting weblogentry object", ex);
+			return;
+		}
+
+		IndexWriter writer = beginWriting();
+		try {
+			if (writer != null) {
+				Term term = new Term(FieldConstants.ID, data.getId());
+				writer.deleteDocuments(term);
+			}
+		} catch (IOException e) {
+			mLogger.error("Error deleting doc from index", e);
+		} finally {
+			endWriting();
+		}
+	}
+
 }

Modified: roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/RemoveWebsiteIndexOperation.java
URL: http://svn.apache.org/viewvc/roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/RemoveWebsiteIndexOperation.java?rev=1340676&r1=1340675&r2=1340676&view=diff
==============================================================================
--- roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/RemoveWebsiteIndexOperation.java (original)
+++ roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/RemoveWebsiteIndexOperation.java Sun May 20 11:16:25 2012
@@ -23,85 +23,93 @@ import java.util.Date;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexWriter;
 import org.apache.lucene.index.Term;
 import org.apache.roller.weblogger.WebloggerException;
 import org.apache.roller.weblogger.business.Weblogger;
-import org.apache.roller.weblogger.business.search.IndexManagerImpl;
 import org.apache.roller.weblogger.business.search.FieldConstants;
+import org.apache.roller.weblogger.business.search.IndexManagerImpl;
 import org.apache.roller.weblogger.business.search.IndexUtil;
 import org.apache.roller.weblogger.pojos.Weblog;
 
-
 /**
  * An index operation that rebuilds a given users index (or all indexes).
- * @author Mindaugas Idzelis  (min@idzelis.com)
+ * 
+ * @author Mindaugas Idzelis (min@idzelis.com)
  */
 public class RemoveWebsiteIndexOperation extends WriteToIndexOperation {
-    
-    //~ Static fields/initializers =============================================
-    
-    private static Log mLogger =
-            LogFactory.getFactory().getInstance(RemoveWebsiteIndexOperation.class);
-    
-    //~ Instance fields ========================================================
-    
-    private Weblog website;
-    private Weblogger roller;
-    
-    //~ Constructors ===========================================================
-    
-    /**
-     * Create a new operation that will recreate an index.
-     * @param website The website to rebuild the index for, or null for all sites.
-     */
-    public RemoveWebsiteIndexOperation(Weblogger roller, IndexManagerImpl mgr, Weblog website) {
-        super(mgr);
-        this.roller = roller;
-        this.website = website;
-    }
-    
-    //~ Methods ================================================================
-    
-    public void doRun() {
-        Date start = new Date();
-        
-        // since this operation can be run on a separate thread we must treat
-        // the weblog object passed in as a detached object which is proned to
-        // lazy initialization problems, so requery for the object now
-        try {
-            this.website = roller.getWeblogManager().getWeblog(this.website.getId());
-        } catch (WebloggerException ex) {
-            mLogger.error("Error getting website object", ex);
-            return;
-        }
-        
-        IndexReader reader = beginDeleting();
-        try {
-            if (reader != null) {
-                String handle = null;
-                if (website != null) {
-                    handle = website.getHandle();
-                }
-                Term tHandle =
-                        IndexUtil.getTerm(FieldConstants.WEBSITE_HANDLE, handle);
-                
-                if (tHandle != null) {
-                    reader.deleteDocuments(tHandle);
-                }
-            }
-        } catch (IOException e) {
-            mLogger.info("Problems deleting doc from index", e);
-        } finally {
-            endDeleting();
-        }
-        
-        Date end = new Date();
-        double length = (end.getTime() - start.getTime()) / (double) 1000;
-        
-        if (website != null) {
-            mLogger.info("Completed deleting indices for website '" +
-                    website.getName() + "' in '" + length + "' seconds");
-        }
-    }
+
+	// ~ Static fields/initializers
+	// =============================================
+
+	private static Log mLogger = LogFactory.getFactory().getInstance(
+			RemoveWebsiteIndexOperation.class);
+
+	// ~ Instance fields
+	// ========================================================
+
+	private Weblog website;
+	private Weblogger roller;
+
+	// ~ Constructors
+	// ===========================================================
+
+	/**
+	 * Create a new operation that will recreate an index.
+	 * 
+	 * @param website
+	 *            The website to rebuild the index for, or null for all sites.
+	 */
+	public RemoveWebsiteIndexOperation(Weblogger roller, IndexManagerImpl mgr,
+			Weblog website) {
+		super(mgr);
+		this.roller = roller;
+		this.website = website;
+	}
+
+	// ~ Methods
+	// ================================================================
+
+	public void doRun() {
+		Date start = new Date();
+
+		// since this operation can be run on a separate thread we must treat
+		// the weblog object passed in as a detached object which is proned to
+		// lazy initialization problems, so requery for the object now
+		try {
+			this.website = roller.getWeblogManager().getWeblog(
+					this.website.getId());
+		} catch (WebloggerException ex) {
+			mLogger.error("Error getting website object", ex);
+			return;
+		}
+
+		IndexWriter writer = beginWriting();
+		try {
+			if (writer != null) {
+				String handle = null;
+				if (website != null) {
+					handle = website.getHandle();
+				}
+				Term tHandle = IndexUtil.getTerm(FieldConstants.WEBSITE_HANDLE,
+						handle);
+
+				if (tHandle != null) {
+					writer.deleteDocuments(tHandle);
+				}
+			}
+		} catch (IOException e) {
+			mLogger.info("Problems deleting doc from index", e);
+		} finally {
+			endWriting();
+		}
+
+		Date end = new Date();
+		double length = (end.getTime() - start.getTime()) / (double) 1000;
+
+		if (website != null) {
+			mLogger.info("Completed deleting indices for website '"
+					+ website.getName() + "' in '" + length + "' seconds");
+		}
+	}
 }

Modified: roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/SearchOperation.java
URL: http://svn.apache.org/viewvc/roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/SearchOperation.java?rev=1340676&r1=1340675&r2=1340676&view=diff
==============================================================================
--- roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/SearchOperation.java (original)
+++ roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/search/operations/SearchOperation.java Sun May 20 11:16:25 2012
@@ -22,152 +22,209 @@ import java.io.IOException;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.lucene.analysis.standard.StandardAnalyzer;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.queryParser.MultiFieldQueryParser;
 import org.apache.lucene.queryParser.ParseException;
 import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanQuery;
-import org.apache.lucene.search.Hits;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.Sort;
 import org.apache.lucene.search.SortField;
 import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.util.Version;
-import org.apache.roller.weblogger.business.search.IndexManagerImpl;
+import org.apache.lucene.search.TopFieldDocs;
 import org.apache.roller.weblogger.business.search.FieldConstants;
-import org.apache.roller.weblogger.business.search.IndexUtil;
 import org.apache.roller.weblogger.business.search.IndexManager;
-
+import org.apache.roller.weblogger.business.search.IndexManagerImpl;
+import org.apache.roller.weblogger.business.search.IndexUtil;
 
 /**
  * An operation that searches the index.
+ * 
  * @author Mindaugas Idzelis (min@idzelis.com)
  */
 public class SearchOperation extends ReadFromIndexOperation {
 
-    //~ Static fields/initializers =============================================
-    
-    private static Log mLogger =
-            LogFactory.getFactory().getInstance(SearchOperation.class);
-    
-    private static String[] SEARCH_FIELDS = new String[] {
-        FieldConstants.CONTENT,
-        FieldConstants.TITLE,
-        FieldConstants.C_CONTENT,
-        FieldConstants.CATEGORY
-    };
-
-    private static BooleanClause.Occur[] SEARCH_FLAGS = new BooleanClause.Occur[] {
-        BooleanClause.Occur.SHOULD,
-        BooleanClause.Occur.SHOULD,
-        BooleanClause.Occur.SHOULD, 
-        BooleanClause.Occur.SHOULD
-    };
-
-    private static Sort SORTER = new Sort( new SortField(
-            FieldConstants.PUBLISHED, SortField.STRING, true) );
-    
-    //~ Instance fields ========================================================
-    
-    private String term;
-    private String websiteHandle;
-    private String category;
-    private Hits searchresults;
-    private String parseError;
-    
-    //~ Constructors ===========================================================
-    
-    /**
-     * Create a new operation that searches the index.
-     */
-    public SearchOperation(IndexManager mgr) {
-        // TODO: finish moving  IndexManager to backend, so this cast is not needed
-        super((IndexManagerImpl)mgr);
-    }
-    
-    //~ Methods ================================================================
-    
-    public void setTerm(String term) {
-        this.term = term;
-    }
-    
-    /* (non-Javadoc)
-     * @see java.lang.Runnable#run()
-     */
-    public void doRun() {
-        searchresults = null;
-        
-        IndexSearcher searcher = null;
-        
-        try {
-            IndexReader reader = manager.getSharedIndexReader();
-            searcher = new IndexSearcher(reader);
-
-            Query query = MultiFieldQueryParser.parse(term,
-                SEARCH_FIELDS, SEARCH_FLAGS,
-                new StandardAnalyzer(Version.LUCENE_CURRENT));
-            
-            Term tUsername =
-                IndexUtil.getTerm(FieldConstants.WEBSITE_HANDLE, websiteHandle);
-            
-            if (tUsername != null) {
-                BooleanQuery bQuery = new BooleanQuery();
-                bQuery.add(query, BooleanClause.Occur.MUST);
-                bQuery.add(new TermQuery(tUsername), BooleanClause.Occur.MUST);
-                query = bQuery;
-            }
-            
-            Term tCategory =
-                IndexUtil.getTerm(FieldConstants.CATEGORY, category);
-            
-            if (tCategory != null) {
-                BooleanQuery bQuery = new BooleanQuery();
-                bQuery.add(query, BooleanClause.Occur.MUST);
-                bQuery.add(new TermQuery(tCategory), BooleanClause.Occur.MUST);
-                query = bQuery;
-            }
-            searchresults = searcher.search(query, null/*Filter*/, SORTER);
-
-        } catch (IOException e) {
-            mLogger.error("Error searching index", e);
-            parseError = e.getMessage();
-
-        } catch (ParseException e) {
-            // who cares?
-            parseError = e.getMessage();
-        }
-        // don't need to close the reader, since we didn't do any writing!
-    }
-    
-    public Hits getResults() {
-        return searchresults;
-    }
-    
-    public int getResultsCount() {
-        if (searchresults == null) return -1;
-        
-        return searchresults.length();
-    }
-    
-    public String getParseError() {
-        return parseError;
-    }
-    
-    /**
-     * @param string
-     */
-    public void setWebsiteHandle(String websiteHandle) {
-        this.websiteHandle = websiteHandle;
-    }
-    
-    /**
-     * @param parameter
-     */
-    public void setCategory(String category) {
-        this.category = category;
-    }
-    
+	// ~ Static fields/initializers
+	// =============================================
+
+	private static Log mLogger = LogFactory.getFactory().getInstance(
+			SearchOperation.class);
+
+	private static String[] SEARCH_FIELDS = new String[] {
+			FieldConstants.CONTENT, FieldConstants.TITLE,
+			FieldConstants.C_CONTENT, FieldConstants.CATEGORY };
+
+	// private static BooleanClause.Occur[] SEARCH_FLAGS = new
+	// BooleanClause.Occur[] {
+	// BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD,
+	// BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD };
+
+	private static Sort SORTER = new Sort(new SortField(
+			FieldConstants.PUBLISHED, SortField.STRING, true));
+
+	// ~ Instance fields
+	// ========================================================
+
+	private IndexSearcher searcher;
+	private TopFieldDocs searchresults;
+
+	private String term;
+	private String websiteHandle;
+	private String category;
+	private String parseError;
+
+	private int nMax = 500; // Limit documents.
+
+	// ~ Constructors
+	// ===========================================================
+
+	/**
+	 * Create a new operation that searches the index.
+	 */
+	public SearchOperation(IndexManager mgr) {
+		// TODO: finish moving IndexManager to backend, so this cast is not
+		// needed
+		super((IndexManagerImpl) mgr);
+	}
+
+	// ~ Methods
+	// ================================================================
+
+	public void setTerm(String term) {
+		this.term = term;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Runnable#run()
+	 */
+	public void doRun() {
+		searchresults = null;
+
+		searcher = null;
+
+		try {
+			IndexReader reader = manager.getSharedIndexReader();
+			searcher = new IndexSearcher(reader);
+
+			// Query query = MultiFieldQueryParser.parse(
+			// FieldConstants.LUCENE_VERSION, term, SEARCH_FIELDS,
+			// SEARCH_FLAGS, IndexManagerImpl.getAnalyzer());
+
+			MultiFieldQueryParser multiParser = new MultiFieldQueryParser(
+					FieldConstants.LUCENE_VERSION, SEARCH_FIELDS,
+					IndexManagerImpl.getAnalyzer());
+
+			// Make it an AND by default. Comment this out for an or (default)
+			multiParser.setDefaultOperator(MultiFieldQueryParser.Operator.AND);
+
+			// Create a query object out of our term
+			Query query = multiParser.parse(term);
+
+			Term tUsername = IndexUtil.getTerm(FieldConstants.WEBSITE_HANDLE,
+					websiteHandle);
+
+			if (tUsername != null) {
+				BooleanQuery bQuery = new BooleanQuery();
+				bQuery.add(query, BooleanClause.Occur.MUST);
+				bQuery.add(new TermQuery(tUsername), BooleanClause.Occur.MUST);
+				query = bQuery;
+			}
+
+			Term tCategory = IndexUtil.getTerm(FieldConstants.CATEGORY,
+					category);
+
+			if (tCategory != null) {
+				BooleanQuery bQuery = new BooleanQuery();
+				bQuery.add(query, BooleanClause.Occur.MUST);
+				bQuery.add(new TermQuery(tCategory), BooleanClause.Occur.MUST);
+				query = bQuery;
+			}
+
+			searchresults = searcher.search(query, null/* Filter */, nMax,
+					SORTER);
+
+		} catch (IOException e) {
+			mLogger.error("Error searching index", e);
+			parseError = e.getMessage();
+
+		} catch (ParseException e) {
+			// who cares?
+			parseError = e.getMessage();
+		}
+		// don't need to close the reader, since we didn't do any writing!
+	}
+
+	/**
+	 * Gets the searcher.
+	 * 
+	 * @return the searcher
+	 */
+	public IndexSearcher getSearcher() {
+		return searcher;
+	}
+
+	/**
+	 * Sets the searcher.
+	 * 
+	 * @param searcher
+	 *            the new searcher
+	 */
+	public void setSearcher(IndexSearcher searcher) {
+		this.searcher = searcher;
+	}
+
+	/**
+	 * Gets the results.
+	 * 
+	 * @return the results
+	 */
+	public TopFieldDocs getResults() {
+		return searchresults;
+	}
+
+	/**
+	 * Gets the results count.
+	 * 
+	 * @return the results count
+	 */
+	public int getResultsCount() {
+		if (searchresults == null)
+			return -1;
+
+		return searchresults.totalHits;
+	}
+
+	/**
+	 * Gets the parses the error.
+	 * 
+	 * @return the parses the error
+	 */
+	public String getParseError() {
+		return parseError;
+	}
+
+	/**
+	 * Sets the website handle.
+	 * 
+	 * @param websiteHandle
+	 *            the new website handle
+	 */
+	public void setWebsiteHandle(String websiteHandle) {
+		this.websiteHandle = websiteHandle;
+	}
+
+	/**
+	 * Sets the category.
+	 * 
+	 * @param category
+	 *            the new category
+	 */
+	public void setCategory(String category) {
+		this.category = category;
+	}
+
 }