001    package com.sptci.prevayler;
002    
003    import org.apache.lucene.index.IndexReader;
004    import org.apache.lucene.search.IndexSearcher;
005    
006    import java.io.IOException;
007    import java.util.logging.Level;
008    
009    /**
010     * A thread used to close an {@link org.apache.lucene.index.IndexReader} and
011     * its associated {@link org.apache.lucene.search.IndexSearcher} after all
012     * references to the index reader have been cleared.
013     *
014     * <p>&copy; Copyright 2008 <a href='http://sptci.com/' target='_top'>Sans
015     * Pareil Technologies, Inc.</a></p>
016     *
017     * @author Rakesh 2008-11-20
018     * @version $Id: IndexCloser.java 22 2008-11-24 19:04:25Z sptrakesh $
019     */
020    class IndexCloser extends Thread
021    {
022      /** The index reader that is to be closed. */
023      private final IndexReader reader;
024    
025      /** The index search to be closed after the reader is closed. */
026      private final IndexSearcher searcher;
027    
028      /**
029       * Create a new index closer to close the specified reader and searchers.
030       *
031       * @param reader The reader instance to close.
032       * @param searcher The searcher instance to close.
033       */
034      IndexCloser( final IndexReader reader, final IndexSearcher searcher )
035      {
036        this.reader = reader;
037        this.searcher = searcher;
038      }
039    
040      /**
041       * Close the index reader and then sleep until the reader has really been
042       * closed.  Once closed close the searcher as well.
043       *
044       * @see #closeReader()
045       * @see #checkClosed()
046       */
047      @Override
048      public void run()
049      {
050        closeReader();
051        checkClosed();
052        closeSearcher();
053      }
054    
055      /** Close the {@link #reader} instance. */
056      private void closeReader()
057      {
058        try
059        {
060          reader.close();
061        }
062        catch ( IOException ex )
063        {
064          StorageSystem.logger.log( Level.WARNING,
065              "Error closing index reader", ex );
066        }
067      }
068    
069      /** Loop through until the {@link #reader} has been closed. */
070      private void checkClosed()
071      {
072        boolean notClosed = true;
073        while ( notClosed )
074        {
075          try
076          {
077            reader.isCurrent();
078            sleep( 100 );
079          }
080          catch ( InterruptedException e )
081          {
082            // Ignore
083          }
084          catch ( Exception e )
085          {
086            notClosed = false;
087          }
088        }
089      }
090    
091      /** Close the {@link #searcher} instance. */
092      private void closeSearcher()
093      {
094        try
095        {
096          searcher.close();
097        }
098        catch ( IOException ex )
099        {
100          StorageSystem.logger.log( Level.WARNING,
101              "Error closing index searcher", ex );
102        }
103      }
104    }