knguyen     2005/04/22 15:11:05 CEST

  Modified files:
    core/src/java/org/jahia/services/search SearchIndexer.java 
                                            SearchManager.java 
  Added files:
    core/src/java/org/jahia/services/search/lucene 
                                                   
AbstractLuceneSearchHandler.java 
                                                   
AbstractLuceneSearchIndexer.java 
    core/src/java/org/jahia/services/search/lucene/fs 
                                                      
LuceneSearchHandlerImpl.java 
                                                      LuceneSearchIndexer.java 
    core/src/java/org/jahia/services/search/lucene/jdbc 
                                                        
JDBCDirectoryManagerWrapper.java 
                                                        
LuceneJDBCSearchHandlerImpl.java 
                                                        
LuceneJDBCSearchIndexer.java 
  Removed files:
    core/src/java/org/jahia/services/search/lucene 
                                                   LuceneSearchHandlerImpl.java 
                                                   LuceneSearchIndexer.java 
  Log:
  - rprovide for testing a jdbc implementation version of lucene indexer
  
  Revision  Changes    Path
  1.2       +4 -2      
jahia/core/src/java/org/jahia/services/search/SearchIndexer.java
http://jahia.mine.nu:8080/cgi-bin/cvsweb.cgi/jahia/core/src/java/org/jahia/services/search/SearchIndexer.java.diff?r1=1.1&r2=1.2&f=h
  1.2       +1 -1      
jahia/core/src/java/org/jahia/services/search/SearchManager.java
http://jahia.mine.nu:8080/cgi-bin/cvsweb.cgi/jahia/core/src/java/org/jahia/services/search/SearchManager.java.diff?r1=1.1&r2=1.2&f=h
  1.1       +179 -0    
jahia/core/src/java/org/jahia/services/search/lucene/AbstractLuceneSearchHandler.java
 (new)
http://jahia.mine.nu:8080/cgi-bin/cvsweb.cgi/jahia/core/src/java/org/jahia/services/search/lucene/AbstractLuceneSearchHandler.java?rev=1.1&content-type=text/plain
  1.1       +551 -0    
jahia/core/src/java/org/jahia/services/search/lucene/AbstractLuceneSearchIndexer.java
 (new)
http://jahia.mine.nu:8080/cgi-bin/cvsweb.cgi/jahia/core/src/java/org/jahia/services/search/lucene/AbstractLuceneSearchIndexer.java?rev=1.1&content-type=text/plain
  1.2       +0 -197    
jahia/core/src/java/org/jahia/services/search/lucene/LuceneSearchHandlerImpl.java
 (dead)
http://jahia.mine.nu:8080/cgi-bin/cvsweb.cgi/jahia/core/src/java/org/jahia/services/search/lucene/LuceneSearchHandlerImpl.java?rev=1.1&content-type=text/plain
  1.4       +0 -543    
jahia/core/src/java/org/jahia/services/search/lucene/LuceneSearchIndexer.java 
(dead)
http://jahia.mine.nu:8080/cgi-bin/cvsweb.cgi/jahia/core/src/java/org/jahia/services/search/lucene/LuceneSearchIndexer.java?rev=1.3&content-type=text/plain
  1.1       +104 -0    
jahia/core/src/java/org/jahia/services/search/lucene/fs/LuceneSearchHandlerImpl.java
 (new)
http://jahia.mine.nu:8080/cgi-bin/cvsweb.cgi/jahia/core/src/java/org/jahia/services/search/lucene/fs/LuceneSearchHandlerImpl.java?rev=1.1&content-type=text/plain
  1.1       +110 -0    
jahia/core/src/java/org/jahia/services/search/lucene/fs/LuceneSearchIndexer.java
 (new)
http://jahia.mine.nu:8080/cgi-bin/cvsweb.cgi/jahia/core/src/java/org/jahia/services/search/lucene/fs/LuceneSearchIndexer.java?rev=1.1&content-type=text/plain
  1.1       +46 -0     
jahia/core/src/java/org/jahia/services/search/lucene/jdbc/JDBCDirectoryManagerWrapper.java
 (new)
http://jahia.mine.nu:8080/cgi-bin/cvsweb.cgi/jahia/core/src/java/org/jahia/services/search/lucene/jdbc/JDBCDirectoryManagerWrapper.java?rev=1.1&content-type=text/plain
  1.1       +88 -0     
jahia/core/src/java/org/jahia/services/search/lucene/jdbc/LuceneJDBCSearchHandlerImpl.java
 (new)
http://jahia.mine.nu:8080/cgi-bin/cvsweb.cgi/jahia/core/src/java/org/jahia/services/search/lucene/jdbc/LuceneJDBCSearchHandlerImpl.java?rev=1.1&content-type=text/plain
  1.1       +118 -0    
jahia/core/src/java/org/jahia/services/search/lucene/jdbc/LuceneJDBCSearchIndexer.java
 (new)
http://jahia.mine.nu:8080/cgi-bin/cvsweb.cgi/jahia/core/src/java/org/jahia/services/search/lucene/jdbc/LuceneJDBCSearchIndexer.java?rev=1.1&content-type=text/plain
  
  
  
  Index: SearchIndexer.java
  ===================================================================
  RCS file: 
/home/cvs/repository/jahia/core/src/java/org/jahia/services/search/SearchIndexer.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- SearchIndexer.java        28 Feb 2005 16:10:19 -0000      1.1
  +++ SearchIndexer.java        22 Apr 2005 13:11:03 -0000      1.2
  @@ -16,8 +16,10 @@
   
       public abstract void removeDocument(RemovableDocument document);
   
  -    public abstract void setSearchHandler(SearchHandlerImpl 
searchHandlerImpl);
  +    public abstract void setSearchHandler(SearchHandler searchHandler);
   
  -    public abstract SearchHandlerImpl getSearchHandler();
  +    public abstract SearchHandler getSearchHandler();
  +
  +    public abstract void start() throws Exception;
   
   }
  
  
  
  Index: SearchManager.java
  ===================================================================
  RCS file: 
/home/cvs/repository/jahia/core/src/java/org/jahia/services/search/SearchManager.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- SearchManager.java        28 Feb 2005 16:10:19 -0000      1.1
  +++ SearchManager.java        22 Apr 2005 13:11:03 -0000      1.2
  @@ -21,7 +21,7 @@
       static public String DEFAULT_SEARCH_HANDLER_NAME = "default";
   
       static public String DEFAULT_SEARCH_HANDLER_CLASS
  -            = "org.jahia.services.search.lucene.LuceneSearchHandlerImpl";
  +            = "org.jahia.services.search.lucene.fs.LuceneSearchHandlerImpl";
   
       private static SearchManager searchManager;
   
  
  
  
  Index: AbstractLuceneSearchHandler.java
  ====================================================================
  package org.jahia.services.search.lucene;
  
  import org.jahia.services.search.*;
  import org.jahia.services.search.analyzer.StandardAnalyzer;
  import org.apache.lucene.search.*;
  import org.apache.lucene.analysis.Analyzer;
  import org.apache.lucene.index.IndexReader;
  import org.apache.lucene.queryParser.QueryParser;
  import org.apache.lucene.document.Document;
  import org.apache.lucene.document.Field;
  
  import java.util.*;
  import java.io.File;
  import java.io.IOException;
  
  
  /**
   * Created by IntelliJ IDEA.
   * User: hollis
   * Date: 15 f�vr. 2005
   * Time: 18:47:47
   * To change this template use File | Settings | File Templates.
   */
  public abstract class AbstractLuceneSearchHandler extends SearchHandlerImpl {
  
      private static org.apache.log4j.Logger logger =
              org.apache.log4j.Logger.getLogger 
(AbstractLuceneSearchHandler.class);
  
      private SearchIndexer indexer = null;
  
      /** The Lucene analyzer * */
      private Analyzer analyzer;
  
      private Properties config = new Properties();
  
      public AbstractLuceneSearchHandler(){
          super();
      }
  
      public AbstractLuceneSearchHandler(Properties config){
          super(config);
      }
  
      public AbstractLuceneSearchHandler(SearchManager searchManager, 
Properties config){
          super(searchManager, config);
      }
  
      /**
       * This method should be called, once the config and searchManager are 
set to allow
       * internal initialisation.
       *
       * @throws Exception
       */
      public void init() throws Exception{
          if ( this.getAnalyzer() == null ){
              String[] stopWorld = {};
              this.setAnalyzer(new StandardAnalyzer (stopWorld));
          }
      }
  
      public Analyzer getAnalyzer() {
          return analyzer;
      }
  
      public void setAnalyzer(Analyzer analyzer) {
          this.analyzer = analyzer;
      }
  
      public Properties getConfig() {
          return config;
      }
  
      public void setConfig(Properties config) {
          this.config = config;
      }
  
      public SearchResult search(String query){
          SearchResult result = new SearchResultImpl();
          search(query, result);
          return result;
      }
  
      public void search(String query, SearchResult collector){
          SearchResult result = null;
          IndexReader reader = null;
          try {
              reader = this.getIndexReader();
              IndexSearcher searcher = new IndexSearcher(reader);
              Query q = QueryParser.parse(query,
                      IndexableDocument.DEFAULT_FULLTEXT_SEARCH_FIELD,
                      this.analyzer);
              Hits hits = searcher.search (q);
              result = getSearchResult(hits);
              collector.results().addAll(result.results());
          } catch ( Throwable t ){
              logger.debug("Exception occured when performing search search", 
t);
          } finally {
              this.closeIndexReader(reader);
          }
      }
  
      public SearchIndexer getIndexer(){
          return this.indexer;
      }
  
      public void setIndexer(SearchIndexer indexer){
          this.indexer = indexer;
      }
  
      public Searchable getSearchable(){
          IndexSearcher searcher = null;
          IndexReader reader = null;
          try {
              reader = this.getIndexReader();
              searcher = new IndexSearcher(reader);
              return searcher;
          } catch ( Throwable t ){
              logger.debug("Exception occured when creating searchable", t);
          } finally {
          }
          return null;
      }
  
      
//--------------------------------------------------------------------------
      /**
       * 
       * @return
       * @throws Exception
       */
      protected abstract IndexReader getIndexReader () throws Exception;
  
      
//--------------------------------------------------------------------------
      /**
       * Close a IndexReader
       *
       * @param reader the index reader
       */
      protected abstract void closeIndexReader (IndexReader reader);
  
      /**
       *
       * @param hits
       * @return
       * @throws Exception
       */
      private SearchResult getSearchResult(Hits hits) throws Exception {
         SearchResultImpl searchResult = new SearchResultImpl();
         if ( hits == null || hits.length()==0 ){
             return searchResult;
         }
         int size = hits.length();
         for ( int i=0; i<size; i++ ){
             Document doc = hits.doc(i);
             SearchHitImpl searchHit = new SearchHitImpl(doc);
             searchHit.setScore(hits.score(i));
             Enumeration fields = doc.fields();
             Field field = null;
             String name = null;
             List list = null;
             Hashtable fieldsMap = new Hashtable();
             while ( fields.hasMoreElements() ){
                 list = new ArrayList();
                 field = (Field)fields.nextElement();
                 name = field.name();
                 String[] values = doc.getValues(name);
                 String val = null;
                 for ( int j=0; j<values.length; j++ ){
                     val = values[j];
                     list.add(new FieldValue(val));
                 }
                 fieldsMap.put(name,list);
             }
             searchHit.setFields(fieldsMap);
             searchResult.add(searchHit);
         }
         return searchResult;
      }
  
  }
  
  
  
  Index: AbstractLuceneSearchIndexer.java
  ====================================================================
  package org.jahia.services.search.lucene;
  
  import org.jahia.services.search.*;
  import org.jahia.services.search.analyzer.StandardAnalyzer;
  import org.apache.lucene.analysis.Analyzer;
  import org.apache.lucene.index.IndexWriter;
  import org.apache.lucene.index.IndexReader;
  import org.apache.lucene.index.Term;
  import org.apache.lucene.document.Document;
  import org.apache.lucene.document.Field;
  import org.apache.lucene.store.RAMDirectory;
  import org.apache.lucene.store.Directory;
  import org.apache.log4j.Logger;
  import org.apache.commons.lang.StringUtils;
  
  import java.util.*;
  import java.io.File;
  import java.io.IOException;
  
  /**
   * Created by IntelliJ IDEA.
   * User: hollis
   * Date: 15 f�vr. 2005
   * Time: 13:05:57
   * To change this template use File | Settings | File Templates.
   */
  public abstract class AbstractLuceneSearchIndexer implements SearchIndexer , 
Runnable {
  
      private static Logger logger =
              Logger.getLogger (AbstractLuceneSearchIndexer.class);
  
      /** The Lucene analyzer * */
      private Analyzer analyzer;
  
      private byte[] lock = new byte[0];
  
      private Properties config = new Properties();
  
      // list of all removed/added fields to add/remove from the index in 
background
      private Vector indexOrders = new Vector(); // les ordres de add/remove
  
      private Thread backgroundIndexingThread;
  
      private boolean indexingThreadActivated = true;
  
      private boolean localIndexing = true;
  
      private SearchHandler searchHandler;
  
      protected Directory indexDirectory;
  
      /** For write **/
      private IndexReader cachedIndexReaderForWrite;
  
      /** For write **/
      private IndexWriter cachedWriter;
  
      public AbstractLuceneSearchIndexer(){
      }
  
      public AbstractLuceneSearchIndexer( boolean localIndexing,
                                          Analyzer analyzer,
                                          Properties config){
          this.localIndexing = localIndexing;
          this.analyzer = analyzer;
          if ( analyzer == null ){
              String[] stopWorld = {};
              this.analyzer = new StandardAnalyzer (stopWorld);
          }
          this.setConfig(config);
      }
  
      public void start() throws Exception {
  
          if ( !IndexReader.indexExists(this.getIndexDirectory()) ){
              getIndexWriter (this.analyzer, true);
          }
  
          // now let's remove any stale lock files if there were some.
          removeStaleLockFiles ();
  
          backgroundIndexingThread = new Thread(this,"LuceneSearchIndexer 
Background Thread");
          int priority = Thread.NORM_PRIORITY;
          String prop = 
this.getConfig().getProperty("org.apache.lucene.backgroundIndexing.priority");
          if ( prop != null){
              try {
                  priority = Integer.parseInt(prop);
              } catch ( Throwable t ){
              }
          }
          backgroundIndexingThread.setPriority(priority);
          backgroundIndexingThread.setDaemon(true);
          backgroundIndexingThread.start(); // start background thread
      }
  
      public boolean isLocalIndexing() {
          return localIndexing;
      }
  
      public void setLocalIndexing(boolean localIndexing) {
          this.localIndexing = localIndexing;
      }
  
      public Directory getIndexDirectory() {
          return indexDirectory;
      }
  
      public void setIndexDirectory(Directory indexDirectory) {
          this.indexDirectory = indexDirectory;
      }
  
      public Analyzer getAnalyzer() {
          return analyzer;
      }
  
      public void setAnalyzer(Analyzer analyzer) {
          this.analyzer = analyzer;
      }
      public Properties getConfig() {
          return config;
      }
  
      public void setConfig(Properties config) {
          this.config = config;
          if ( this.config == null ){
              this.config = new Properties();
          }
      }
      
      public void addDocument(IndexableDocument document){
          if ( document == null ){
              return;
          }
          if ( this.localIndexing ){
               addToIndexOrder(document);
          }
          synchronized(lock){
              lock.notifyAll();
          }
          SearchEvent ev = new SearchEvent(this,document);
          this.getSearchHandler().notify(ev,"addDocument");
      }
  
      public void removeDocument(RemovableDocument document){
          if ( document == null ){
              return;
          }
          if ( this.localIndexing ){
               addToIndexOrder(document);
          }
          synchronized(lock){
              lock.notifyAll();
          }
          SearchEvent ev = new SearchEvent(this,document);
          this.getSearchHandler().notify(ev,"removeDocument");
      }
  
      public void setSearchHandler(SearchHandler searchHandler){
          this.searchHandler = searchHandler;
      }
  
      public SearchHandler getSearchHandler(){
          return this.searchHandler;
      }
  
      /**
       * Background task that handles the remove/add fields to search engine 
from
       * the queue
       */
      public void run () {
  
          RAMDirectory ramDir = null;
          Integer siteId = null;
          try {
              while (indexingThreadActivated) {
  
                  Vector v = new Vector();
                  HashMap toBeAdded = new HashMap();
                  HashMap toBeRemoved = new HashMap();
                  IndexableDocument doc = null;
                  synchronized (this.indexOrders) {
  
                      // 1. separate docs that are going to be added or removed
                      for ( int i=0; i<indexOrders.size(); i++ ){
                          doc = (IndexableDocument)indexOrders.get(i);
                          if ( doc instanceof RemovableDocument ){
                              toBeRemoved.put(doc.getKeyFieldName() + "_" + 
doc.getKey(),new Integer(i));
                          } else {
                              toBeAdded.put(doc.getKeyFieldName() + "_" + 
doc.getKey(),new Integer(i));
                          }
                          v.add(indexOrders.get(i));
                      }
  
                      // 2. remove "to added" docs, if they are going to be 
removed
                      Iterator iterator = toBeRemoved.keySet().iterator();
                      String key = null;
                      Integer addOrder = null;
                      Integer removeOrder = null;
                      while ( iterator.hasNext() ){
                          key = (String)iterator.next();
                          addOrder = (Integer)toBeAdded.get(key);
                          if ( addOrder != null ){
                              removeOrder = (Integer)toBeRemoved.get(key);
                              if ( removeOrder.intValue() > addOrder.intValue() 
){
                                  // it would be great to use weight with 
objects to be removed or added
                                  // ( removing a staging entry of a field is 
not as weight as removing the whole field )
                                  v.setElementAt(null,addOrder.intValue());
                              }
                          }
                      }
  
                      // 3. batch removing Term before adding again
                      int size = v.size();
                      for (int i=0; i<size; i++){
                          IndexableDocument nextObject = 
(IndexableDocument)v.get(i);
                          if ( !(nextObject instanceof RemovableDocument) ){
                              removeDoc(new 
Term(nextObject.getKeyFieldName(),NumberPadding.pad(nextObject.getKey())));
                          }
                      }
  
                      indexOrders = new Vector();
                  }
                  long indexingStartTime = System.currentTimeMillis();
                  int indexOrderCount = v.size ();
                  boolean removing = false;
                  while (v.size() > 0) {
                      IndexableDocument nextObject = null;
  
                      if (v.size() != 0) {
                              nextObject = (IndexableDocument)
                              v.elementAt(0);
                          v.remove(0);
                      }
  
                      // okay now we have the next added/removed field, we 
process it!
                      if (nextObject != null) {
                          if (nextObject instanceof RemovableDocument) {
                              
backgroundRemoveObjectFromSearchEngine(nextObject);
                          } else {
                              backgroundAddObjectToSearchEngine(nextObject);
                          }
                      }
                  }
                  long indexingElapsedTime = System.currentTimeMillis() - 
indexingStartTime;
                  if (logger.isInfoEnabled()) {
                      logger.info(
                          "Finished processing " + indexOrderCount +
                          " indexing orders in " + indexingElapsedTime + "ms.");
                  }
  
                  int size = 0;
                  synchronized (this) {
                      size = indexOrders.size();
                  }
                  if (size == 0) {
                      this.closeIndexReaderForWrite();
                      this.closeIndexWriter();
                      org.jahia.services.database.ConnectionDispenser.
                              terminateConnection();
  
                      synchronized (lock) {
                      try {
                              lock.wait(); // wait for next notify
                          }
                          catch (InterruptedException ie) {
                          }
                      }
                  }
              }
          } catch ( Throwable t) {
              logger.debug("Exception search indexing in background",t);
          } finally {
          }
      }
  
      private void addToIndexOrder(IndexableDocument indObj){
          if ( indObj == null ){
              return;
          }
          synchronized(this.indexOrders){
              IndexableDocument doc = null;
              int size = this.indexOrders.size();
              Vector result = new Vector();
              for ( int i=0; i<size; i++ ){
                  doc = (IndexableDocument)this.indexOrders.get(i);
                  if ( indObj.getKeyFieldName().equals(doc.getKeyFieldName())
                      && indObj.getKey().equals(doc.getKey()) ){
                      if ( !(indObj instanceof RemovableDocument)
                          && !(doc instanceof RemovableDocument) ){
                          // same doc, ignore old doc
                      } else if ( (indObj instanceof RemovableDocument)
                          && (doc instanceof RemovableDocument) ){
                          // same doc, ignore old doc
                      } else {
                          result.add(doc);
                      }
                  } else {
                      result.add(doc);
                  }
              }
              result.add(indObj);
              this.indexOrders = result;
          }
      }
  
      /**
       * index an IndexableDocument
       *
       * @param indObj
       */
      private void index (IndexableDocument indObj) {
  
          if (indObj == null)
              return;
  
          long startTime = System.currentTimeMillis();
  
          Document doc = new Document ();
          Map fields = indObj.getFields ();
          if (fields != null) {
              Iterator iterator = fields.keySet().iterator();
              DocumentField docField = null;
              int count = 0;
              List vals;
              while (iterator.hasNext()) {
                  docField = (DocumentField) fields.get(iterator.next());
                  vals = docField.getValues();
                  Iterator valsIterator = vals.iterator();
                  while ( valsIterator.hasNext() ){
                      FieldValue val = (FieldValue) valsIterator.next();
                      String name = docField.getName();
                      // FIXME : should we call val.getValueAsString(Locale)
                      String strVal = val.getValueAsString();
  
                      // @todo : number padding, we should be done somewhere 
else and customizable
                      strVal = NumberPadding.pad(strVal);
  
                      if ( strVal != null ){
                          strVal = strVal.toLowerCase();
                      }
                      if (docField.isKeyword() ) {
                          doc.add (Field.Keyword(name.toLowerCase(), strVal));
                      } else if ( docField.isText() ) {
                          doc.add (Field.Text(name.toLowerCase(), strVal));
                      } else if ( docField.isUnindexed() ){
                          doc.add (Field.UnIndexed(name.toLowerCase(), strVal));
                      } else if ( docField.isUnstoredText() ){
                          doc.add (Field.UnStored(name.toLowerCase(), strVal));
                      }
                  }
              }
          }
          doc.add (Field.Keyword(indObj.getKeyFieldName ().toLowerCase(),
                  NumberPadding.pad(indObj.getKey ())));
  
          // Fixme : For performance issue, should be done in batch before 
adding again.
          // first remove previous entry
          //Term term = new Term (indObj.getKeyFieldName (), indObj.getKey ());
          //removeDoc (term, reader);
  
          try {
  
              startTime = System.currentTimeMillis();
              // Try to get the site's index if any.
              this.getIndexWriter(this.analyzer,false);
              if (this.cachedWriter == null) {
                  logger.warn ("The index writer is null, abort indexing the 
object");
                  return;
              }
              this.cachedWriter.addDocument(doc);
          } catch (Throwable t) {
              logger.error ("Error while indexing object " + indObj.getKey () + 
":", t);
          } finally {
          }
          if (logger.isInfoEnabled()) {
              logger.debug(
                  "Indexing document : " + indObj.getKey() + " in "
                  + (System.currentTimeMillis() - startTime) + " ms.");
          }
      }
  
      
//--------------------------------------------------------------------------
      /**
       * Add an object into the search engine index in background
       *
       * @param indObj
       */
      private void backgroundAddObjectToSearchEngine (IndexableDocument indObj) 
{
          if (indObj == null)
              return;
          index (indObj);
      }
  
      
//--------------------------------------------------------------------------
      /**
       * Remove an object from search engine in background
       *
       * @param indObj
       */
      private void backgroundRemoveObjectFromSearchEngine (IndexableDocument 
indObj) {
  
          // Create a term with the object key unique identifier.
          Term term = new Term (indObj.getKeyFieldName (),
                  String.valueOf (indObj.getKey ()));
          removeDoc (term);
      }
  
      
//--------------------------------------------------------------------------
      /**
       * Remove all docs containing a given term
       *
       * @param term
       */
      private void removeDoc (Term term) {
  
          if ( term == null ){
              return;
          }
  
          try {
              // Try to get the site's index if any.
              getIndexReaderForWrite();
              if ( this.cachedIndexReaderForWrite == null ){
                  logger.debug("IndexReader is null!! Abort removing Term " + 
term.field() + "=" + term.text());
                  return;
              }
              // Remove all documents containing the term.
              int nbDeleted = this.cachedIndexReaderForWrite.delete (term);
          } catch (Throwable t) {
              logger.error ("Error while removing doc for term " + term.field() 
+ "=" + term.text(), t);
          } finally {
          }
      }
  
      /**
       * Returns the IndexWriter for a given site.
       * Don't forget to close the returned index writer to flush change to the 
index file !
       *
       * @param analyzer the analyzer to use.
       * @param create if true, create a new index and replace existing one.
       *
       * @return IndexWriter writer, the IndexWriter, null on error.
       */
      protected IndexWriter getIndexWriter (Analyzer analyzer,
                                          boolean create) {
          closeIndexReaderForWrite();
          if ( create ) {
              closeIndexWriter();
          }
          if ( this.cachedWriter == null || create ){
              try {
                  if ( create ) {
                      this.cachedWriter = createIndexWriter(analyzer);
                  } else {
                      this.cachedWriter = new 
IndexWriter(this.getIndexDirectory(),
                                              analyzer, false);
                  }
              } catch (Throwable t) {
                  logger.error (
                          "An IO Exception occured  when opening the 
IndexWriter :",
                          t);
              }
          }
          return cachedWriter;
      }
  
      /**
       * Create a new Index writer, overriding the old index
       *
       * @param analyzer
       * @return
       * @throws Exception
       */
      protected abstract IndexWriter createIndexWriter(Analyzer analyzer) 
throws Exception;
  
      /**
       * Returns the IndexReader for write .
       * Don't forget to close the returned index reader to flush change to the 
index file !
       *
       * @return reader, the IndexReader, null if not found.
       */
      protected IndexReader getIndexReaderForWrite() throws IOException {
          this.closeIndexWriter();
          if ( this.cachedIndexReaderForWrite == null ){
              this.cachedIndexReaderForWrite = 
IndexReader.open(this.getIndexDirectory());
          }
          return this.cachedIndexReaderForWrite;
      }
  
      /**
       * Returns the IndexReader for read only ( search ) .
       *
       * @return reader, the IndexReader, null if not found.
       */
      public abstract IndexReader getIndexReaderForRead() throws Exception;
  
      /**
       * Close a IndexWriter
       *
       */
      protected void closeIndexWriter () {
          if (cachedWriter != null) {
              try {
                  cachedWriter.close();
                  doCloseIndexWriter();
              } catch (Throwable t) {
                  logger.error ("Error while closing index writer:", t);
              } finally {
                  cachedWriter = null;
              }
          }
      }
  
  
      /**
       * Close the IndexReader used for write
       *
       */
      protected void closeIndexReaderForWrite () {
          if (cachedIndexReaderForWrite != null) {
              try {
                  cachedIndexReaderForWrite.close ();
                  doCloseIndexReaderForWrite();
              } catch (Throwable t) {
                  logger.error ("Error while closing index reader:", t);
              } finally {
                  cachedIndexReaderForWrite = null;
              }
          }
      }
  
      protected abstract void doCloseIndexWriter();
  
      protected abstract void doCloseIndexReaderForWrite();
  
      /**
       * Removes all *.lock files in the specified directory, going down
       * recursively. Make sure you call this ONLY on lucene managed 
directories.
       *
       */
      protected void removeStaleLockFiles (){
          try {
              if ( IndexReader.isLocked(this.getIndexDirectory()) ){
                  IndexReader.unlock(this.getIndexDirectory());
              }
          } catch ( Throwable t ){
              logger.debug("Exception removing locks",t);
          }
      }
  
  }
  
  
  
  Index: LuceneSearchHandlerImpl.java
  ====================================================================
  package org.jahia.services.search.lucene.fs;
  
  import org.jahia.services.search.*;
  import org.jahia.services.search.lucene.fs.LuceneSearchIndexer;
  import org.jahia.services.search.lucene.AbstractLuceneSearchHandler;
  import org.jahia.services.search.analyzer.StandardAnalyzer;
  import org.apache.lucene.search.*;
  import org.apache.lucene.analysis.Analyzer;
  import org.apache.lucene.index.IndexReader;
  import org.apache.lucene.queryParser.QueryParser;
  import org.apache.lucene.document.Document;
  import org.apache.lucene.document.Field;
  
  import java.util.*;
  import java.io.File;
  import java.io.IOException;
  
  
  /**
   * Created by IntelliJ IDEA.
   * User: hollis
   * Date: 15 f�vr. 2005
   * Time: 18:47:47
   * To change this template use File | Settings | File Templates.
   */
  public class LuceneSearchHandlerImpl extends AbstractLuceneSearchHandler {
  
      private static org.apache.log4j.Logger logger =
              org.apache.log4j.Logger.getLogger (LuceneSearchHandlerImpl.class);
  
      public static final String DEFAULT_INDEX_DIRECTORY = 
System.getProperty("java.io.tmpdir");
  
      private String indexDirectory = "";
  
      public LuceneSearchHandlerImpl(){
          super();
      }
  
      public LuceneSearchHandlerImpl(Properties config){
          super(config);
      }
  
      public LuceneSearchHandlerImpl(SearchManager searchManager, Properties 
config){
          super(searchManager, config);
      }
  
      /**
       * This method should be called, once the config and searchManager are 
set to allow
       * internal initialisation.
       *
       * @throws Exception
       */
      public void init() throws Exception {
          super.init();
          indexDirectory = this.getConfig().getProperty("indexDirectory");
          if ( indexDirectory == null ){
              indexDirectory = DEFAULT_INDEX_DIRECTORY;
          }
          File f = new File(indexDirectory + File.separator + this.getName());
          this.setIndexer(new LuceneSearchIndexer(f,true,this.getAnalyzer(),new 
Properties()));
          this.getIndexer().setSearchHandler(this);
          this.getIndexer().start();
      }
  
      
//--------------------------------------------------------------------------
      /**
       *
       * @return
       * @throws java.io.IOException
       */
      protected IndexReader getIndexReader () throws Exception {
  
          IndexReader reader = null;
          File indexDirFile = new File (this.indexDirectory + File.separator + 
this.getName());
          if (indexDirFile.exists ()) {
              reader = IndexReader.open (this.indexDirectory + File.separator + 
this.getName());
          } else {
              logger.warn (
                      "Cannot read index because directory "
                      + this.indexDirectory
                      + " does not exist, will be created upon first full site 
indexing...");
              return null;
          }
          return reader;
      }
  
      
//--------------------------------------------------------------------------
      /**
       * Close a IndexReader
       *
       * @param reader the index reader
       */
      protected void closeIndexReader (IndexReader reader) {
          if (reader == null)
              return;
  
          try {
              reader.close ();
          } catch (Throwable t) {
              logger.error ("Error while closing index reader:", t);
          }
      }
  
  }
  
  
  
  Index: LuceneSearchIndexer.java
  ====================================================================
  package org.jahia.services.search.lucene.fs;
  
  import org.apache.lucene.analysis.Analyzer;
  import org.apache.lucene.store.FSDirectory;
  import org.apache.lucene.store.Directory;
  import org.apache.lucene.index.IndexReader;
  import org.apache.lucene.index.IndexWriter;
  import org.jahia.services.search.lucene.AbstractLuceneSearchIndexer;
  
  import java.util.*;
  import java.io.File;
  import java.io.IOException;
  
  /**
   * Created by IntelliJ IDEA.
   * User: hollis
   * Date: 15 f�vr. 2005
   * Time: 13:05:57
   * To change this template use File | Settings | File Templates.
   */
  public class LuceneSearchIndexer extends AbstractLuceneSearchIndexer {
  
      private static org.apache.log4j.Logger logger =
              org.apache.log4j.Logger.getLogger (LuceneSearchIndexer.class);
  
      private String indexPath = "";
  
      public LuceneSearchIndexer(){
          super();
      }
  
      public LuceneSearchIndexer(File indexDirectory,
                                 boolean localIndexing,
                                 Analyzer analyzer,
                                 Properties config){
          super(localIndexing,analyzer,config);
  
          if ( indexDirectory != null ) {
              this.indexPath = indexDirectory.getAbsolutePath();
              FSDirectory fsDirectory = null;
              try {
                  fsDirectory = FSDirectory.getDirectory(indexDirectory,false);
                  /*
                  if ( !IndexReader.indexExists(indexDirectory) ){
                      fsDirectory = 
FSDirectory.getDirectory(indexDirectory,true);
                  } else {
                      fsDirectory = 
FSDirectory.getDirectory(indexDirectory,false);
                  }*/
                  this.setIndexDirectory(fsDirectory);
              } catch ( IOException ioe ) {
                  logger.debug("Error opening FSDirectory", ioe);
              }
          }
      }
  
      protected void doCloseIndexWriter(){
          // nothing here
      }
  
      protected void doCloseIndexReaderForWrite(){
          // nothing here
      }
  
      /**
       * Create a new IndexWriter
       *
       * @param analyzer
       * @return
       */
      protected IndexWriter createIndexWriter(Analyzer analyzer) throws 
Exception {
          return new IndexWriter(this.indexPath,analyzer,true);
      }
  
      /**
       * Returns the IndexReader for read only ( search ) .
       *
       * @return reader, the IndexReader, null if not found.
       */
      public IndexReader getIndexReaderForRead() throws Exception {
          return IndexReader.open(this.getIndexDirectory());
      }
  
      /**
       * Removes all *.lock files in the specified directory, going down
       * recursively. Make sure you call this ONLY on lucene managed 
directories.
       *
       */
      protected synchronized void removeStaleLockFiles () {
  
          // With lucene > 1.3,
          // the locks are created in "java.io.tmpdir", not in the search index 
folder
          String tmpDir = System.getProperty("java.io.tmpdir");
          File f = new File (tmpDir);
          if (!f.isDirectory ()) {
              return;
          }
  
          File[] files = f.listFiles();
  
          for (int i = 0; i < files.length; i++) {
              File curFile = files[i];
              if (curFile.isFile() && 
curFile.getName().toLowerCase().startsWith("lucene")
                  && curFile.getName().toLowerCase().endsWith (".lock")) {
                  logger.debug ("Removing stale lock file : [" + 
curFile.toString () + "]");
                  curFile.delete ();
              }
          }
      }
  
  }
  
  
  
  Index: JDBCDirectoryManagerWrapper.java
  ====================================================================
  /*
   * $Id: JDBCDirectoryManagerWrapper.java,v 1.1 2005/04/22 13:11:04 knguyen 
Exp $
   */
  package org.jahia.services.search.lucene.jdbc;
  
  import ppi.jdbc.util.JDBCFile;
  import ppi.jdbc.util.JDBCDirectoryManager;
  
  import java.io.IOException;
  import java.sql.*;
  import java.util.Hashtable;
  import java.util.Iterator;
  import java.util.TreeMap;
  import java.util.WeakHashMap;
  
  import org.jahia.services.database.ConnectionDispenser;
  
  /**
   * @author vito
   * Date: Jun 24, 2003
   * @version $Revision: 1.1 $
   */
  public class JDBCDirectoryManagerWrapper extends JDBCDirectoryManager {
  
      private JDBCDirectoryManager manager;
  
      /**
       * Manages information in the database in the form of blocks. Each block 
is identified with a directoryID
       * and a fileName. This class will work, but not preform very well, if 
the connection used does not support
       * pooling prepared statements.
       *
       * @param directoryID
       * @param tableName
       * @throws SQLException
       */
      public JDBCDirectoryManagerWrapper(String directoryID, 
                                         String tableName) throws SQLException {
  
        super(ConnectionDispenser.getConnection(),directoryID,tableName);
      }
  
      public Connection getConn() {
          return ConnectionDispenser.getConnection();
      }
  
  }
  
  
  Index: LuceneJDBCSearchHandlerImpl.java
  ====================================================================
  package org.jahia.services.search.lucene.jdbc;
  
  import org.jahia.services.search.*;
  import org.jahia.services.search.lucene.AbstractLuceneSearchHandler;
  import org.jahia.services.search.analyzer.StandardAnalyzer;
  import org.jahia.services.database.ConnectionDispenser;
  import org.jahia.registries.ServicesRegistry;
  import org.apache.lucene.search.*;
  import org.apache.lucene.analysis.Analyzer;
  import org.apache.lucene.index.IndexReader;
  import org.apache.lucene.queryParser.QueryParser;
  import org.apache.lucene.document.Document;
  import org.apache.lucene.document.Field;
  import org.apache.lucene.store.Directory;
  
  import java.util.*;
  import java.io.File;
  import java.io.IOException;
  import java.sql.Connection;
  
  import ppi.jdbc.util.JDBCDirectory;
  
  
  /**
   * Created by IntelliJ IDEA.
   * User: hollis
   * Date: 15 f�vr. 2005
   * Time: 18:47:47
   * To change this template use File | Settings | File Templates.
   */
  public class LuceneJDBCSearchHandlerImpl extends AbstractLuceneSearchHandler {
  
      private static org.apache.log4j.Logger logger =
              org.apache.log4j.Logger.getLogger 
(LuceneJDBCSearchHandlerImpl.class);
  
      public LuceneJDBCSearchHandlerImpl(){
          super();
      }
  
      public LuceneJDBCSearchHandlerImpl(Properties config){
          super(config);
      }
  
      public LuceneJDBCSearchHandlerImpl(SearchManager searchManager, 
Properties config){
          super(searchManager, config);
      }
  
      /**
       * This method should be called, once the config and searchManager are 
set to allow
       * internal initialisation.
       *
       * @throws Exception
       */
      public void init() throws Exception {
          super.init();
          this.setIndexer(new LuceneJDBCSearchIndexer("lucene_index_" 
+this.getName(),true,this.getAnalyzer(),new Properties()));
          this.getIndexer().setSearchHandler(this);
          this.getIndexer().start();
      }
  
      
//--------------------------------------------------------------------------
      /**
       *
       * @return
       * @throws java.io.IOException
       */
      protected IndexReader getIndexReader () throws Exception {
          return 
((LuceneJDBCSearchIndexer)this.getIndexer()).getIndexReaderForRead();
      }
  
      
//--------------------------------------------------------------------------
      /**
       * Close a IndexReader
       *
       * @param reader the index reader
       */
      protected void closeIndexReader (IndexReader reader) {
          if (reader == null)
              return;
  
          try {
              reader.close ();
          } catch (Throwable t) {
              logger.error ("Error while closing index reader:", t);
          }
      }
  
  }
  
  
  
  Index: LuceneJDBCSearchIndexer.java
  ====================================================================
  package org.jahia.services.search.lucene.jdbc;
  
  import org.jahia.services.search.*;
  import org.jahia.services.search.lucene.jdbc.JDBCDirectoryManagerWrapper;
  import org.jahia.services.search.lucene.AbstractLuceneSearchIndexer;
  import org.jahia.services.search.analyzer.StandardAnalyzer;
  import org.jahia.services.database.ConnectionDispenser;
  import org.apache.lucene.analysis.Analyzer;
  import org.apache.lucene.index.IndexWriter;
  import org.apache.lucene.index.IndexReader;
  import org.apache.lucene.index.Term;
  import org.apache.lucene.document.Document;
  import org.apache.lucene.document.Field;
  import org.apache.lucene.store.RAMDirectory;
  import org.apache.lucene.store.Directory;
  import org.apache.log4j.Logger;
  import org.apache.commons.lang.StringUtils;
  
  import java.util.*;
  import java.io.File;
  import java.io.IOException;
  import java.sql.Connection;
  
  import ppi.jdbc.util.JDBCDirectory;
  
  /**
   * Created by IntelliJ IDEA.
   * User: hollis
   * Date: 15 f�vr. 2005
   * Time: 13:05:57
   * To change this template use File | Settings | File Templates.
   */
  public class LuceneJDBCSearchIndexer extends AbstractLuceneSearchIndexer {
  
      private static org.apache.log4j.Logger logger =
              org.apache.log4j.Logger.getLogger (LuceneJDBCSearchIndexer.class);
  
      private String directoryId;
  
      public LuceneJDBCSearchIndexer(){
          super();
      }
  
      public LuceneJDBCSearchIndexer( String directoryId,
                                      boolean localIndexing,
                                      Analyzer analyzer,
                                      Properties config){
          super(localIndexing,analyzer,config);
          this.directoryId = directoryId;
      }
  
      public void start() throws Exception {
          JDBCDirectoryManagerWrapper manager =
                  new JDBCDirectoryManagerWrapper(directoryId,
                                                  
JDBCDirectory.INDEX_TABLE_NAME);
          JDBCDirectory directory = new JDBCDirectory(manager,directoryId);
          this.setIndexDirectory(directory);
          super.start();
      }
  
      /**
       * Create a new Index writer, overriding the old index
       *
       * @param analyzer
       * @return
       * @throws Exception
       */
      protected IndexWriter createIndexWriter(Analyzer analyzer) throws 
Exception{
  
          return new IndexWriter(this.getIndexDirectory(),analyzer,true);
      }
  
      protected synchronized void removeStaleLockFiles () {
          //
      }
  
      /**
       * Returns the IndexReader for read only ( search ) .
       *
       * @return reader, the IndexReader, null if not found.
       */
      public IndexReader getIndexReaderForRead() throws Exception {
          JDBCDirectoryManagerWrapper manager =
              new JDBCDirectoryManagerWrapper(directoryId,
                                              JDBCDirectory.INDEX_TABLE_NAME);
          JDBCDirectory directory = new JDBCDirectory(manager,directoryId);
          return IndexReader.open(directory);
      }
  
      protected void doCloseIndexWriter(){
          try {
              this.getIndexDirectory().close();
              // reopen
              JDBCDirectoryManagerWrapper manager =
                      new JDBCDirectoryManagerWrapper(directoryId,
                                                      
JDBCDirectory.INDEX_TABLE_NAME);
              JDBCDirectory directory = new JDBCDirectory(manager,directoryId);
              this.setIndexDirectory(directory);
          } catch ( Throwable t ) {
              logger.debug("Error closing index Writer",t);
          }
      }
  
      protected void doCloseIndexReaderForWrite(){
          try {
              this.getIndexDirectory().close();
              // reopen
              JDBCDirectoryManagerWrapper manager =
                      new JDBCDirectoryManagerWrapper(directoryId,
                                                      
JDBCDirectory.INDEX_TABLE_NAME);
              JDBCDirectory directory = new JDBCDirectory(manager,directoryId);
              this.setIndexDirectory(directory);
          } catch ( Throwable t ) {
              logger.debug("Error closing index Reader",t);
          }
      }
  
  }
  

Reply via email to