You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@roller.apache.org by sn...@apache.org on 2005/06/09 05:19:20 UTC

svn commit: r189695 [21/67] - in /incubator/roller/trunk: ./ contrib/ contrib/lib/ contrib/plugins/ contrib/plugins/src/ contrib/plugins/src/org/ contrib/plugins/src/org/roller/ contrib/plugins/src/org/roller/presentation/ contrib/plugins/src/org/roller/presentation/velocity/ contrib/plugins/src/org/roller/presentation/velocity/plugins/ contrib/plugins/src/org/roller/presentation/velocity/plugins/acronyms/ contrib/plugins/src/org/roller/presentation/velocity/plugins/bookmarks/ contrib/plugins/src/org/roller/presentation/velocity/plugins/email/ contrib/plugins/src/org/roller/presentation/velocity/plugins/jspwiki/ contrib/plugins/src/org/roller/presentation/velocity/plugins/radeox/ contrib/plugins/src/org/roller/presentation/velocity/plugins/readmore/ contrib/plugins/src/org/roller/presentation/velocity/plugins/smileys/ contrib/plugins/src/org/roller/presentation/velocity/plugins/textile/ contrib/plugins/src/org/roller/presentation/velocity/plugins/topictag/ custom/ custom/src/ custom/web/ docs/ docs/images/ docs/installguide/ docs/installguide/old/ docs/userguide/ docs/userguide/images/ docs/userguide/old/ metadata/ metadata/database/ metadata/database/hibernate/ metadata/xdoclet/ nbproject/ personal/ personal/eclipse/ personal/testing/ sandbox/ sandbox/planetroller/ sandbox/planetroller/metadata/ sandbox/planetroller/metadata/database/ sandbox/planetroller/src/ sandbox/planetroller/src/org/ sandbox/planetroller/src/org/roller/ sandbox/planetroller/src/org/roller/tools/ sandbox/planetroller/src/org/roller/tools/planet/ sandbox/planetroller/templates/ sandbox/planetroller/test/ sandbox/planetroller/test/org/ sandbox/planetroller/test/org/roller/ sandbox/planetroller/test/org/roller/model/ sandbox/planetroller/test/org/roller/tools/ sandbox/planetroller/test/org/roller/tools/planet/ sandbox/planetroller/testdata/ sandbox/planetroller/testdata/cache/ sandbox/planetroller/testdata/output/ sandbox/standalone/ sandbox/standalone/jspwiki/ sandbox/standalone/jspwiki/default/ sandbox/standalone/jspwiki/default/images/ sandbox/standalone/lib/ sandbox/standalone/src/ sandbox/standalone/src/org/ sandbox/standalone/src/org/roller/ sandbox/standalone/src/org/roller/jspwiki/ sandbox/standalone/src/org/roller/tomcat/ sandbox/standalone/src/org/roller/util/ sandbox/standalone/tests/ sandbox/standalone/tests/org/ sandbox/standalone/tests/org/roller/ sandbox/standalone/tests/org/roller/util/ sandbox/standalone/tomcat/ src/ src/org/ src/org/roller/ src/org/roller/business/ src/org/roller/business/hibernate/ src/org/roller/business/search/ src/org/roller/business/search/operations/ src/org/roller/business/utils/ src/org/roller/config/ src/org/roller/config/runtime/ src/org/roller/model/ src/org/roller/pojos/ src/org/roller/presentation/ src/org/roller/presentation/atomapi/ src/org/roller/presentation/bookmarks/ src/org/roller/presentation/bookmarks/actions/ src/org/roller/presentation/bookmarks/formbeans/ src/org/roller/presentation/bookmarks/tags/ src/org/roller/presentation/filters/ src/org/roller/presentation/forms/ src/org/roller/presentation/newsfeeds/ src/org/roller/presentation/pagecache/ src/org/roller/presentation/pagecache/rollercache/ src/org/roller/presentation/pings/ src/org/roller/presentation/planet/ src/org/roller/presentation/tags/ src/org/roller/presentation/tags/calendar/ src/org/roller/presentation/tags/menu/ src/org/roller/presentation/util/ src/org/roller/presentation/velocity/ src/org/roller/presentation/weblog/ src/org/roller/presentation/weblog/actions/ src/org/roller/presentation/weblog/formbeans/ src/org/roller/presentation/weblog/tags/ src/org/roller/presentation/website/ src/org/roller/presentation/website/actions/ src/org/roller/presentation/website/formbeans/ src/org/roller/presentation/website/tags/ src/org/roller/presentation/xmlrpc/ src/org/roller/util/ src/org/roller/util/rome/ tests/ tests/org/ tests/org/roller/ tests/org/roller/ant/ tests/org/roller/business/ tests/org/roller/presentation/ tests/org/roller/presentation/atomapi/ tests/org/roller/presentation/bookmarks/ tests/org/roller/presentation/filters/ tests/org/roller/presentation/velocity/ tests/org/roller/presentation/velocity/plugins/ tests/org/roller/presentation/velocity/plugins/smileys/ tests/org/roller/presentation/velocity/plugins/textile/ tests/org/roller/presentation/weblog/ tests/org/roller/presentation/xmlrpc/ tests/org/roller/util/ tests/org/roller/util/rome/ tools/ tools/buildtime/ tools/buildtime/ant-1.6.2/ tools/buildtime/findbugs/ tools/buildtime/findbugs/lib/ tools/buildtime/findbugs/plugin/ tools/buildtime/mockrunner-0.3/ tools/buildtime/mockrunner-0.3/lib/ tools/buildtime/mockrunner-0.35/ tools/buildtime/mockrunner-0.35/lib/ tools/buildtime/tomcat-4.1.24/ tools/buildtime/xdoclet-1.2/ tools/buildtime/xdoclet-1.2/lib/ tools/hibernate-2.1/ tools/hibernate-2.1/lib/ tools/lib/ tools/standard-1.0.3/ tools/standard-1.0.3/lib/ tools/standard-1.0.3/tld/ tools/struts-1.2.4/ tools/struts-1.2.4/lib/ web/ web/WEB-INF/ web/WEB-INF/classes/ web/WEB-INF/classes/flavors/ web/WEB-INF/classes/themes/ web/bookmarks/ web/editor/ web/editor/images/ web/images/ web/images/editor/ web/images/midas/ web/images/preview/ web/images/smileys/ web/planet/ web/tags/ web/templates/ web/theme/ web/theme/images/ web/theme/lavender/ web/theme/scripts/ web/theme/scripts/classes/ web/themes/ web/themes/basic/ web/themes/berkley/ web/themes/berkley/images/ web/themes/brushedmetal/ web/themes/brushedmetal/images/ web/themes/cheb/ web/themes/cheb/images/ web/themes/cheb/scripts/ web/themes/clean/ web/themes/currency-i18n/ web/themes/currency-i18n/images/ web/themes/currency/ web/themes/currency/images/ web/themes/grey2/ web/themes/moonshine/ web/themes/movablemanila/ web/themes/movablemanila/images/ web/themes/pacifica/ web/themes/robot/ web/themes/rolling/ web/themes/rolling/images/ web/themes/sotto/ web/themes/sotto/images/ web/themes/sotto/styles/ web/themes/sunsets/ web/themes/sunsets/images/ web/themes/sunsets/scripts/ web/themes/sunsets/styles/ web/themes/werner/ web/themes/x2/ web/themes/x2/images/ web/themes/x2/scripts/ web/themes/x2/styles/ web/weblog/ web/website/

Added: incubator/roller/trunk/src/org/roller/business/search/operations/ReadFromIndexOperation.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/business/search/operations/ReadFromIndexOperation.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/business/search/operations/ReadFromIndexOperation.java (added)
+++ incubator/roller/trunk/src/org/roller/business/search/operations/ReadFromIndexOperation.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,47 @@
+
+package org.roller.business.search.operations;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.roller.business.IndexManagerImpl;
+
+/**
+ * @author aim4min
+ */
+public abstract class ReadFromIndexOperation extends IndexOperation
+{
+
+    /**
+     * @param manager
+     */
+    public ReadFromIndexOperation(IndexManagerImpl mgr)
+    {
+        super(mgr);
+    }
+
+    private static Log mLogger = LogFactory.getFactory().getInstance(
+            ReadFromIndexOperation.class);
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Runnable#run()
+     */
+    public final void run()
+    {
+        try
+        {
+            manager.getReadWriteLock().readLock().acquire();
+            doRun();
+        }
+        catch (InterruptedException e)
+        {
+            mLogger.info("Error acquiring read lock on index", e);
+        }
+        finally
+        {
+            manager.getReadWriteLock().readLock().release();
+        }
+    }
+
+}
\ No newline at end of file

Added: incubator/roller/trunk/src/org/roller/business/search/operations/RebuildUserIndexOperation.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/business/search/operations/RebuildUserIndexOperation.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/business/search/operations/RebuildUserIndexOperation.java (added)
+++ incubator/roller/trunk/src/org/roller/business/search/operations/RebuildUserIndexOperation.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,158 @@
+/*
+ * Created on Jul 16, 2003
+ *
+ * Authored by: Mindaugas Idzelis  (min@idzelis.com)
+ */
+package org.roller.business.search.operations;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.Date;
+import java.util.Iterator;
+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.roller.RollerException;
+import org.roller.business.IndexManagerImpl;
+import org.roller.business.search.FieldConstants;
+import org.roller.business.search.IndexUtil;
+import org.roller.model.Roller;
+import org.roller.model.RollerFactory;
+import org.roller.model.WeblogManager;
+import org.roller.pojos.WeblogEntryData;
+import org.roller.pojos.WebsiteData;
+
+
+/**
+ * @author aim4min
+ *
+ * An index operation that rebuilds a given users index (or all indexes.)
+ */
+public class RebuildUserIndexOperation extends WriteToIndexOperation
+{
+    //~ Static fields/initializers =============================================
+
+    private static Log mLogger =
+        LogFactory.getFactory().getInstance(RebuildUserIndexOperation.class);
+
+    //~ Instance fields ========================================================
+
+    private WebsiteData website;
+
+    //~ 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 RebuildUserIndexOperation(IndexManagerImpl mgr, WebsiteData website)
+    {
+        super(mgr);
+        this.website = website;
+    }
+
+    //~ Methods ================================================================
+
+    /* (non-Javadoc)
+     * @see java.lang.Runnable#run()
+     */
+    public void doRun()
+    {
+        Date start = new Date();
+
+        IndexReader reader = beginDeleting();
+
+        try
+        {
+            if (reader != null)
+            {
+                String userName = null;
+                if (website != null && website.getUser() != null)
+                {
+                    userName = website.getUser().getUserName();
+                }
+                Term tUsername =
+                    IndexUtil.getTerm(FieldConstants.USERNAME, userName);
+
+                if (tUsername != null)
+                {
+                    reader.delete(tUsername);
+                }
+                else
+                {
+                    Term all =
+                        IndexUtil.getTerm(FieldConstants.CONSTANT,
+                                          FieldConstants.CONSTANT_V);
+                    reader.delete(all);
+                }
+            }
+        }
+        catch (IOException e)
+        {
+            mLogger.info("Problems deleting doc from index", e);
+        }
+        finally
+        {
+            endDeleting();
+        }
+
+        IndexWriter writer = beginWriting();
+
+        Roller roller = RollerFactory.getRoller();
+        try
+        {
+            roller.begin();
+            if (writer != null)
+            {
+                WeblogManager weblogManager = roller.getWeblogManager();
+
+                List entries = weblogManager .getWeblogEntries(
+                    website,                 // userName
+                    null,                   // startDate
+                    new Date(),             // endDate // don't index 'future' entries
+                    null,                   // catName
+                    WeblogManager.PUB_ONLY, // status
+                    null);    
+
+                for (Iterator wbItr = entries.iterator(); wbItr.hasNext();) 
+                {
+                    WeblogEntryData entry = (WeblogEntryData) 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.getUser().getUserName() + "' in '" + length + "' seconds");
+        }
+    }
+}

Added: incubator/roller/trunk/src/org/roller/business/search/operations/RemoveEntryOperation.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/business/search/operations/RemoveEntryOperation.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/business/search/operations/RemoveEntryOperation.java (added)
+++ incubator/roller/trunk/src/org/roller/business/search/operations/RemoveEntryOperation.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,73 @@
+/*
+ * Created on Jul 16, 2003
+ * Authored by: Mindaugas Idzelis  (min@idzelis.com)
+ *
+ */
+package org.roller.business.search.operations;
+
+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.Term;
+import org.roller.business.IndexManagerImpl;
+import org.roller.business.search.FieldConstants;
+import org.roller.pojos.WeblogEntryData;
+
+
+/**
+ * @author aim4min
+ *
+ * An operation that removes the weblog from the index.
+ */
+public class RemoveEntryOperation extends WriteToIndexOperation
+{
+    //~ Static fields/initializers =============================================
+
+    private static Log mLogger =
+        LogFactory.getFactory().getInstance(RemoveEntryOperation.class);
+
+    //~ Instance fields ========================================================
+
+    private WeblogEntryData data;
+
+    //~ Constructors ===========================================================
+
+    /**
+     *
+     */
+    public RemoveEntryOperation(IndexManagerImpl mgr, WeblogEntryData data)
+    {
+        super(mgr);
+        this.data = data;
+    }
+
+    //~ Methods ================================================================
+
+    /* (non-Javadoc)
+     * @see java.lang.Runnable#run()
+     */
+    public void doRun()
+    {
+        IndexReader reader = beginDeleting();
+        try
+        {
+            if (reader != null)
+            {
+                Term term = new Term(FieldConstants.ID, data.getId());
+                reader.delete(term);
+            }
+        }
+        catch (IOException e)
+        {
+            mLogger.error("Error deleting doc from index", e);
+        }
+        finally
+        {
+            endDeleting();
+        }
+    }
+
+ 
+}

Added: incubator/roller/trunk/src/org/roller/business/search/operations/RemoveUserIndexOperation.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/business/search/operations/RemoveUserIndexOperation.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/business/search/operations/RemoveUserIndexOperation.java (added)
+++ incubator/roller/trunk/src/org/roller/business/search/operations/RemoveUserIndexOperation.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,97 @@
+/*
+ * Created on Jul 16, 2003
+ *
+ * Authored by: Mindaugas Idzelis  (min@idzelis.com)
+ */
+package org.roller.business.search.operations;
+
+import java.io.IOException;
+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.Term;
+import org.roller.business.IndexManagerImpl;
+import org.roller.business.search.FieldConstants;
+import org.roller.business.search.IndexUtil;
+import org.roller.pojos.UserData;
+
+
+/**
+ * @author aim4min
+ *
+ * An index operation that rebuilds a given users index (or all indexes.)
+ */
+public class RemoveUserIndexOperation extends WriteToIndexOperation
+{
+    //~ Static fields/initializers =============================================
+
+    private static Log mLogger =
+        LogFactory.getFactory().getInstance(RemoveUserIndexOperation.class);
+
+    //~ Instance fields ========================================================
+
+    private UserData user;
+
+    //~ 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 RemoveUserIndexOperation(IndexManagerImpl mgr, UserData user)
+    {
+        super(mgr);
+        this.user = user;
+    }
+
+    //~ Methods ================================================================
+
+    /* (non-Javadoc)
+     * @see java.lang.Runnable#run()
+     */
+    public void doRun()
+    {
+        Date start = new Date();
+
+        IndexReader reader = beginDeleting();
+
+        try
+        {
+            if (reader != null)
+            {
+                String userName = null;
+                if (user != null)
+                {
+                    userName = user.getUserName();
+                }
+                Term tUsername =
+                    IndexUtil.getTerm(FieldConstants.USERNAME, userName);
+
+                if (tUsername != null)
+                {
+                    reader.delete(tUsername);
+                }
+            }
+        }
+        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 (user != null)
+        {
+            mLogger.info("Completed deleting indices for '" +
+                            user.getUserName() + "' in '" + length + "' seconds");
+        }
+    }
+}

Added: incubator/roller/trunk/src/org/roller/business/search/operations/SearchOperation.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/business/search/operations/SearchOperation.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/business/search/operations/SearchOperation.java (added)
+++ incubator/roller/trunk/src/org/roller/business/search/operations/SearchOperation.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,162 @@
+/*
+ * Created on Jul 18, 2003
+ * Authored by: Mindaugas Idzelis  (min@idzelis.com)
+ */
+package org.roller.business.search.operations;
+
+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.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.roller.business.IndexManagerImpl;
+import org.roller.business.search.FieldConstants;
+import org.roller.business.search.IndexUtil;
+import org.roller.model.IndexManager;
+
+
+/**
+ * @author aim4min
+ *
+ * An operation that searches the index.
+ */
+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 Sort SORTER = new Sort( new SortField(
+        FieldConstants.PUBLISHED, SortField.STRING, true) );
+
+    //~ Instance fields ========================================================
+
+    private String term;
+    private String username;
+    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, new StandardAnalyzer());
+
+            Term tUsername =
+                IndexUtil.getTerm(FieldConstants.USERNAME, username);
+
+            if (tUsername != null)
+            {
+                BooleanQuery bQuery = new BooleanQuery();
+                bQuery.add(query, true, false);
+                bQuery.add(new TermQuery(tUsername), true, false);
+                query = bQuery;
+            }
+            
+            Term tCategory =
+                IndexUtil.getTerm(FieldConstants.CATEGORY, category);
+
+            if (tCategory != null)
+            {
+                BooleanQuery bQuery = new BooleanQuery();
+                bQuery.add(query, true, false);
+                bQuery.add(new TermQuery(tCategory), true, false);
+                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 setUsername(String username)
+    {
+        this.username = username;
+    }
+
+    /**
+     * @param parameter
+     */
+    public void setCategory(String category)
+    {
+        this.category = category;
+    }
+
+}

Added: incubator/roller/trunk/src/org/roller/business/search/operations/WriteToIndexOperation.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/business/search/operations/WriteToIndexOperation.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/business/search/operations/WriteToIndexOperation.java (added)
+++ incubator/roller/trunk/src/org/roller/business/search/operations/WriteToIndexOperation.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,54 @@
+/*
+ * Created on Aug 12, 2003
+ *
+ * To change the template for this generated file go to
+ * Window>Preferences>Java>Code Generation>Code and Comments
+ */
+package org.roller.business.search.operations;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.roller.business.IndexManagerImpl;
+
+/**
+ * @author aim4min
+ *
+ * To change the template for this generated type comment go to
+ * Window>Preferences>Java>Code Generation>Code and Comments
+ */
+public abstract class WriteToIndexOperation extends IndexOperation {
+
+	/**
+     * @param manager
+     */
+    public WriteToIndexOperation(IndexManagerImpl mgr)
+    {
+        super(mgr);
+    }
+
+    private static Log mLogger =
+		LogFactory.getFactory().getInstance(WriteToIndexOperation.class);
+		  
+	/* (non-Javadoc)
+	 * @see java.lang.Runnable#run()
+	 */
+	public void run() 
+    {
+		try 
+        {
+            manager.getReadWriteLock().writeLock().acquire();
+            mLogger.info("Starting search index operation");
+            doRun();
+            mLogger.info("Search index operation complete");
+		} 
+        catch (InterruptedException e) 
+        {
+			mLogger.error("Error acquiring write lock on index", e);
+		} 
+        finally 
+        {
+			manager.getReadWriteLock().writeLock().release();
+		}
+        manager.resetSharedReader();
+	}
+}

Added: incubator/roller/trunk/src/org/roller/business/search/operations/package.html
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/business/search/operations/package.html?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/business/search/operations/package.html (added)
+++ incubator/roller/trunk/src/org/roller/business/search/operations/package.html Wed Jun  8 20:18:46 2005
@@ -0,0 +1,9 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title></title>
+</head>
+<body>
+Weblog search operations using Lucene.<br>
+</body>
+</html>

Added: incubator/roller/trunk/src/org/roller/business/search/package.html
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/business/search/package.html?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/business/search/package.html (added)
+++ incubator/roller/trunk/src/org/roller/business/search/package.html Wed Jun  8 20:18:46 2005
@@ -0,0 +1,9 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title></title>
+</head>
+<body>
+Weblog search implementation using Lucene.<br>
+</body>
+</html>

Added: incubator/roller/trunk/src/org/roller/business/utils/ConsistencyCheck.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/business/utils/ConsistencyCheck.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/business/utils/ConsistencyCheck.java (added)
+++ incubator/roller/trunk/src/org/roller/business/utils/ConsistencyCheck.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,315 @@
+
+package org.roller.business.utils;
+
+import java.io.FileInputStream;
+import java.sql.*;
+import java.util.*;
+
+/**
+ * Roller database consistency checker.<br />
+ * Don't run this unless you know what you are doing!</br >
+ * 
+ * <p>Configuration:<br />
+ * 
+ * Program looks in current directory for db.properties file with database
+ * connection properties driverClassName and connectionUrl. 
+ * 
+ * Program expects JDBC driver jar to be on classpath.</p>
+ * 
+ * <p>Usage:<br />
+ * 
+ * java -cp ./WEB-INF/lib/rollerbeans.jar org.roller.business.utils.ConsistencyCheck<br />
+ * 
+ * <br />Options:<br />
+ * -v Verbose<br />
+ * -d Delete orphans</p>
+ */
+public class ConsistencyCheck 
+{
+    /** 
+     * Consistency checker, find and optionally delete orphans. 
+     */
+    public static void main(String[] args) throws Exception
+    {
+        Properties props = new Properties();
+        props.load(new FileInputStream("rollerdb.properties"));
+        Connection con = createConnection(props,"");
+        
+        boolean delete = false;
+        boolean verbose = false;
+        if (args.length > 0) 
+        {
+            if ("-purge".equals(args[0])) 
+            {
+                delete = true;
+            }
+            else if ("-v".equals(args[0]))
+            {
+                verbose = true;
+            }
+        }        
+        
+        findAndDeleteOrphans(con, delete, verbose);
+    }
+    
+    /** 
+     * Create connection based on properties:<br/>
+     * - driverClassName<br/>
+     * - connectionUrl<br/>
+     * - userName<br/>
+     * - password<br/>
+     */
+    public static Connection createConnection(Properties props, String prefix) 
+        throws Exception
+    {
+        Connection con = null;
+        if (prefix == null) 
+        {
+            prefix = "";
+        }
+        String driverClassName = props.getProperty(prefix+"driverClassName");
+        String connectionUrl = props.getProperty(prefix+"connectionUrl");
+        String userName = props.getProperty(prefix+"userName");
+        String password = props.getProperty(prefix+"password");
+        
+        Class.forName(driverClassName);
+        if (userName != null && password != null)
+        {
+           con = DriverManager.getConnection(connectionUrl, userName, password);
+        }
+        else
+        {
+           con = DriverManager.getConnection(connectionUrl);
+        }
+        return con;
+    }
+    
+    /** Find and optionally delete all safely deletable orphans. */
+    public static void findAndDeleteOrphans(Connection con, boolean delete, boolean verbose) 
+        throws SQLException
+    {
+        // websites with bad user?
+        findOrphans(con, "website", "userid", "rolleruser", delete, verbose);
+        
+        // userroles with bad user?
+        findOrphans(con, "userrole", "userid", "rolleruser", delete, verbose);
+        
+        // folders with bad website?
+        findOrphans(con, "folder", "websiteid", "website", delete, verbose);
+        
+        // bookmarks with bad folder?
+        findOrphans(con, "bookmark", "folderid", "folder", delete, verbose);
+        
+        // weblogcategories with bad website?
+        findOrphans(con, "weblogcategory", "websiteid", "website", delete, verbose);
+        
+        // weblogcategoryassocs with bad category?
+        findOrphans(con, "weblogcategoryassoc", "categoryid", "weblogcategory", delete, verbose);
+        
+        // weblog entries with bad website?
+        findOrphans(con, "weblogentry", "websiteid", "website", delete, verbose);
+                
+        // comments with bad weblogentry?
+        findOrphans(con, "comment", "entryid", "weblogentry", delete, verbose);
+        
+        // Referers with bad website?
+        findOrphans(con, "referer", "websiteid", "website", delete, verbose);
+        
+        // Referers with bad website?
+        findOrphans(con, "referer", "entryid", "weblogentry", delete, verbose);              
+        
+        if (delete)
+        {
+            correctWeblogEntries(con);
+            correctWebsites(con);
+            correctFolderTrees(con, delete);
+        }
+    }
+    
+    /**
+     * @param con
+     * @param delete
+     */
+    private static void correctFolderTrees(Connection con, boolean delete) throws SQLException
+    {
+        PreparedStatement rootStatement = con.prepareStatement(
+            "select a.id from folder as f, folderassoc as a where "+
+            "f.websiteid=? and f.id=a.folderid and "+
+            "a.relation='PARENT' and a.ancestorid is null");
+        PreparedStatement childrenStatement = con.prepareStatement(
+            "select id from folderassoc where ancestorid=?");
+
+        // loop through all websites
+        Statement websitesStatement = con.createStatement();
+        ResultSet websitesResultSet = 
+            websitesStatement.executeQuery("select id from website");
+        while (websitesResultSet.next()) 
+        {
+            String websiteId = websitesResultSet.getString(1);
+            //debug("Website "+websiteId);
+            
+            // find root folder(s)
+            List rootIds = new LinkedList();
+            rootStatement.clearParameters();
+            rootStatement.setString(1, websiteId);
+            ResultSet rootResultSet = rootStatement.executeQuery();
+            while (rootResultSet.next())
+            {
+                rootIds.add(rootResultSet.getString(1));
+            }
+            if (rootIds.size() > 1) 
+            {
+                // too many roots, need to figure out which are bogus
+                Iterator rootIter = rootIds.iterator();
+                while (rootIter.hasNext())
+                {
+                    String rootId = (String)rootIter.next();
+                    childrenStatement.clearParameters();
+                    childrenStatement.setString(1, rootId);
+                    ResultSet childrenResultSet = childrenStatement.executeQuery();
+                    List childIds = new LinkedList();
+                    while (childrenResultSet.next()) 
+                    {
+                        childIds.add(childrenResultSet.getString(1));
+                    }
+                    if (childIds.size() == 0)
+                    {
+                        debug("Folder "+rootId+" in website "+websiteId+"is a bogus root folder!");
+                    }
+                }
+            }
+            else if (rootIds.size() == 0)
+            {
+                debug("Website "+websiteId+" has no root folder!");
+            }
+        }
+    }
+
+    private static void correctWeblogEntries(Connection con) throws SQLException
+    {
+        List entries = findOrphans(con, "weblogentry", "categoryid", "weblogcategory", false, false);
+        Iterator entryIter = entries.iterator();
+        while (entryIter.hasNext())
+        {
+            String entryid = (String) entryIter.next();
+            Statement websiteSt = con.createStatement();
+            ResultSet websiteRs = websiteSt.executeQuery(
+                "select websiteid from weblogentry where id="+entryid);
+            websiteRs.first();
+            String websiteid = websiteRs.getString(0);
+            
+            String rootid = getRootCategoryId(con, websiteid);
+            Statement st = con.createStatement();
+            st.executeUpdate("update weblogentry set categoryid='"+rootid+"' "
+                           +" where id='"+entryid+"'");
+        }   
+    }
+    
+    public static void correctWebsites(Connection con) throws SQLException
+    {
+        List websites = findOrphans(con, "website", "defaultcatid", "weblogcategory", false, false);
+        Iterator websiteIter = websites.iterator();
+        while (websiteIter.hasNext())
+        {
+            String websiteid = (String) websiteIter.next();
+            String rootid = getRootCategoryId(con, websiteid);
+            Statement st = con.createStatement();
+            st.executeUpdate("update website set defaultcatid='"+rootid+"' "
+                    +" where id='"+websiteid+"'");
+        }
+    
+        websites = findOrphans(con, "website", "bloggercatid", "weblogcategory", false, false);
+        websiteIter = websites.iterator();
+        while (websiteIter.hasNext())
+        {
+            String websiteid = (String) websiteIter.next();
+            String rootid = getRootCategoryId(con, websiteid);
+            Statement st = con.createStatement();
+            st.executeUpdate("update website set bloggercatid='"+rootid+"' "
+                            +"where id='"+websiteid+"'");
+        }
+    }
+    
+    public static String getRootCategoryId(Connection con, String websiteid)
+        throws SQLException
+    {
+        Statement st = con.createStatement();
+        String query = 
+            "select c.id from weblogcategory as c, weblogcategoryassoc as a "
+            +"where a.categoryid=c.id and a.ancestorid is null "
+            +"and c.websiteid ='"+websiteid+"'";
+        //System.out.println(query);
+        ResultSet rs = st.executeQuery(query);        
+        rs.next();
+        return rs.getString(1);
+    }
+    
+    /** Find orphans, records in a manytable that refer to a onetable that 
+     * no longer exists.
+     * @param con       Database connection to be used.
+     * @param manytable Name of the manytable.
+     * @param fkname    Name of the foreign key field in the manytable.
+     * @param onetable  Name of the onetable.
+     * @param delete    True if orphans in manytable are to be deleted.
+     * @return          List of orphans found (will be empty if delete is true.
+     * @throws SQLException
+     */
+    public static List findOrphans(
+        Connection con, String manytable, String fkname, String onetable, boolean delete, boolean verbose) 
+        throws SQLException
+    {
+        List orphans = new LinkedList();
+        
+        Statement stall = con.createStatement();
+        ResultSet rsall = stall.executeQuery(
+            "select id,"+fkname+" as fk from "+manytable);
+        while (rsall.next()) 
+        {
+            String id = rsall.getString("id");
+            String fk = rsall.getString("fk");
+            if (fk != null)
+            {
+                Statement stone = con.createStatement();
+                ResultSet rsone = stone.executeQuery(
+                    "select id from "+onetable+" where id='"+fk+"' limit 1");
+                if (!rsone.next()) 
+                {
+                    orphans.add(id);  
+                    System.out.println("   Found orphan in "+manytable+" id="+id); 
+                }                
+            }
+        } 
+        
+        if (!delete)
+        {
+            debug("Orphans found in "+manytable+" = "+orphans.size());
+            if (verbose)
+            {
+                Iterator iter = orphans.iterator();
+                while (iter.hasNext())
+                {
+                    String id = (String) iter.next();
+                    debug("   "+manytable+" id="+id);
+                }
+            }
+        }
+        else
+        {
+            debug("Deleting orphans found in "+manytable+" count = "+orphans.size());            
+            Iterator iter = orphans.iterator();
+            while (iter.hasNext())
+            {
+                String id = (String) iter.next();
+                Statement stdel = con.createStatement();
+                stdel.executeUpdate("delete from "+manytable+" where id='"+id+"'");
+            }
+            orphans = new LinkedList();
+        }
+        return orphans;
+    }
+    
+    private static void debug(String msg) 
+    {
+        System.out.println("DEBUG: "+msg);   
+    }
+}

Added: incubator/roller/trunk/src/org/roller/business/utils/PasswordUtility.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/business/utils/PasswordUtility.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/business/utils/PasswordUtility.java (added)
+++ incubator/roller/trunk/src/org/roller/business/utils/PasswordUtility.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,275 @@
+
+package org.roller.business.utils;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.Enumeration;
+import java.util.Properties;
+import org.roller.util.Utilities;
+
+/**
+ * Roller password utility: don't run this unless you know what you are doing!</br >
+ * 
+ * <p>Configuration:<br />
+ * 
+ * Program looks in current directory for db.properties file with database
+ * connection properties driverClassName and connectionUrl. 
+ * 
+ * Program expects JDBC driver jar to be on classpath.</p>
+ * 
+ * <p>Usage:<br />
+ * 
+ * java -cp ./WEB-INF/lib/rollerbeans.jar;./jdbc.jar org.roller.business.utils.PasswordUtility<br />
+ * 
+ * <br />Options:<br />
+ * 
+ * -save &lt;file-name&gt;: Save username/passwords in property file<br />
+ * -encrypt               : turn on encryption and encrypt passwords<br />
+ * -restore &lt;file-name>   : turn off encryption and restore passwords from file<br />
+ * -reset &lt;username&gt; &lt;password&gt;: reset users password<br />
+ * -grant_admin &lt;username&gt;<br />
+ * -revoke_admin &lt;username&gt;</p>
+ */
+public class PasswordUtility 
+{
+    public static void main(String[] args) throws Exception
+    {
+        Properties props = new Properties();
+        props.load(new FileInputStream("rollerdb.properties"));
+        
+        String algorithm = props.getProperty("algorithm");
+        
+        Connection con = ConsistencyCheck.createConnection(props,"");
+        
+        if (args.length == 2 && args[0].equals("-save")) 
+        {
+            savePasswords(con, args[1]);
+        }
+        else if (args.length == 1 && args[0].equals("-encrypt")) 
+        {
+            encryptionOn(con, algorithm);
+        }
+        else if (args.length == 2 && args[0].equals("-restore")) 
+        {
+            encryptionOff(con, args[1]);
+        }
+        else if (args.length == 3 && args[0].equals("-reset")) 
+        {
+            resetPassword(con, args[1], args[2], algorithm);
+        }
+        else if (args.length == 2 && args[0].equals("-grant_admin")) 
+        {
+            grantAdmin(con, args[1]);
+        }
+        else if (args.length == 2 && args[0].equals("-revoke_admin")) 
+        {
+            revokeAdmin(con, args[1]);
+        }
+        else 
+        {
+            System.out.println("");
+            System.out.println("USAGE: save passwords to a properties file");
+            System.out.println("   rollerpw -save <file-name>");
+            System.out.println("");
+            System.out.println("USAGE: turn ON password encryption and encrypt existing passwords");
+            System.out.println("   rollerpw -encrypt");
+            System.out.println("");
+            System.out.println("USAGE: turn OFF password encryption and restore saved passwords");
+            System.out.println("   rollerpw -restore <file-name>");
+            System.out.println("");
+            System.out.println("USAGE: reset a user password");
+            System.out.println("   rollerpw -password <username> <new-password>");
+            System.out.println("");
+            System.out.println("USAGE: grant admin rights to user");
+            System.out.println("   rollerpw -grant_admin <username>");
+            System.out.println("");
+            System.out.println("USAGE: revoke admin right from user");
+            System.out.println("   rollerpw -revoke_admin <username>");
+            System.out.println("");
+        }
+    }
+    
+    /** 
+     * Saves usernames and passwords to properties file, passwords keyed by usernames 
+     */
+    private static void savePasswords(
+                    Connection con, String fileName) throws Exception
+    {
+        Properties newprops = new Properties();
+        PreparedStatement userquery = con.prepareStatement(
+           "select username,passphrase from rolleruser");
+        ResultSet users = userquery.executeQuery();
+        while (users.next()) 
+        {
+            String username = users.getString(1);
+            String passphrase = users.getString(2);
+            newprops.put(username, passphrase);
+        }
+        FileOutputStream fos = new FileOutputStream(fileName);
+        newprops.save(fos, "Generated by Roller Password Utility");
+        fos.close();
+    }
+
+    /** 
+     * Encrypt all passwords in rolleruser and turn ON encryption flag in rollerconfig
+     */
+    private static void encryptionOn(
+                    Connection con, String algorithm) throws Exception
+    {
+        PreparedStatement userQuery = con
+        	.prepareStatement("select username,passphrase from rolleruser");
+        PreparedStatement userUpdate = con
+        	.prepareStatement("update rolleruser set passphrase=? where username=?");
+        PreparedStatement configUpdate = con
+			.prepareStatement("update rollerconfig set encryptpasswords=?");
+
+        Properties props = new Properties();
+        ResultSet users = userQuery.executeQuery();
+        while (users.next())
+        {
+            String username = users.getString(1);
+            String passphrase = users.getString(2);
+            props.put(username, passphrase);
+        }
+        Enumeration usernames = props.keys();
+        while (usernames.hasMoreElements())
+        {
+            String username = (String)usernames.nextElement();
+            String passphrase = (String)props.get(username);
+            userUpdate.clearParameters();
+            userUpdate.setString(1, Utilities.encodePassword(passphrase, algorithm));
+            userUpdate.setString(2, username);
+            userUpdate.executeUpdate();
+        }
+        
+        configUpdate.setBoolean(1, true);
+        configUpdate.executeUpdate();
+    }
+
+    /** 
+     * Restore passwords in rolleruser and turn OFF encryption flag in rollerconfig
+     */
+    private static void encryptionOff(
+                    Connection con, String fileName) throws Exception
+    {
+        PreparedStatement userUpdate = con
+			.prepareStatement("update rolleruser set passphrase=? where username=?");
+        PreparedStatement configUpdate = con
+			.prepareStatement("update rollerconfig set encryptpasswords=?");
+
+        Properties props = new Properties();
+        props.load(new FileInputStream(fileName));
+        Enumeration usernames = props.keys();
+        while (usernames.hasMoreElements())
+        {
+            String username = (String)usernames.nextElement();
+            String password = (String)props.get(username);
+            userUpdate.clearParameters();
+            userUpdate.setString(1, password);
+            userUpdate.setString(2, username);
+            userUpdate.executeUpdate();
+        }
+        
+        configUpdate.setBoolean(1, false);
+        configUpdate.executeUpdate();
+    }
+
+    /** 
+     * Reset user's password to specified value using specified algorythm (if needed) 
+     */
+    private static void resetPassword(
+                    Connection con, String username, String password, String algorithm) 
+    	    throws Exception
+    {
+		PreparedStatement encryptionQuery = 
+            con.prepareStatement("select encryptpasswords from rollerconfig");
+		PreparedStatement userUpdate = 
+            con.prepareStatement("update rolleruser set passphrase=? where username=?");
+		
+		ResultSet rs = encryptionQuery.executeQuery();
+		rs.next();
+		boolean encryption = rs.getBoolean(1);
+		
+		String newpassword = 
+		    encryption ? Utilities.encodePassword(password, algorithm) : password;
+		userUpdate.setString(1, newpassword);
+		userUpdate.setString(2, username);
+		userUpdate.executeUpdate();
+    }   
+    
+    /**
+     * Grant admin role to user by adding admin role for user to userrole table
+     */
+    private static void grantAdmin(Connection con, String userName) throws Exception
+    {
+        // Find userid of specified user
+        String userid = null;
+        PreparedStatement userQuery = con.prepareStatement(
+           "select id from rolleruser where username=?");    
+        userQuery.setString(1, userName);
+        ResultSet userRS = userQuery.executeQuery();
+        if (!userRS.next()) 
+        {
+            System.err.println("ERROR: username not found in database");
+            return;
+        }
+        else 
+        {
+            userid = userRS.getString(1);
+        }
+        
+        // Is user already an admin?
+        PreparedStatement roleQuery = con.prepareStatement(
+           "select username from userrole where username=? and rolename='admin'");
+        roleQuery.setString(1, userName);
+        ResultSet roleRS = roleQuery.executeQuery();
+        if (!roleRS.next()) // then no, user is not admin
+        {
+            // Add admin role for user
+            PreparedStatement adminInsert = con.prepareStatement(
+               "insert into userrole (id,rolename,username,userid) values (?,?,?,?)");
+            adminInsert.setString(1, userName);
+            adminInsert.setString(2, "admin");
+            adminInsert.setString(3, userName);
+            adminInsert.setString(4, userid);
+            adminInsert.executeUpdate();
+            System.out.println("User granted admin role");
+        }
+        else 
+        {
+            System.out.println("User was already an admin");
+        }
+    }
+
+    /**
+     * Revoke admin role from user by removing admin role from userrole table
+     */
+    private static void revokeAdmin(Connection con, String userName) throws Exception
+    {
+        // Find userid of specified user
+        String userid = null;
+        PreparedStatement userQuery = con.prepareStatement(
+           "select id from rolleruser where username=?");    
+        userQuery.setString(1, userName);
+        ResultSet userRS = userQuery.executeQuery();
+        if (!userRS.next()) 
+        {
+            System.err.println("ERROR: username not found in database");
+            return;
+        }
+        else 
+        {
+            userid = userRS.getString(1);
+        }
+        
+        // Delete user's admin entries from userrole table
+        PreparedStatement roleDelete = con.prepareStatement(
+           "delete from userrole where userid=? and rolename='admin'");
+        roleDelete.setString(1, userid);
+        roleDelete.executeUpdate();
+    }
+}