[exo-jcr-commits] exo-jcr SVN: r348 - in jcr/trunk/component/core: src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/spell and 1 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Thu Oct 22 05:45:53 EDT 2009


Author: sergiykarpenko
Date: 2009-10-22 05:45:53 -0400 (Thu, 22 Oct 2009)
New Revision: 348

Modified:
   jcr/trunk/component/core/known-issues.txt
   jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/spell/LuceneSpellChecker.java
   jcr/trunk/component/core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/spell/SpellCheckerTest.java
Log:
EXOJCR-192: SpellChecker accuracy increased to 0.55f. Fails fixed

Modified: jcr/trunk/component/core/known-issues.txt
===================================================================
--- jcr/trunk/component/core/known-issues.txt	2009-10-21 16:18:15 UTC (rev 347)
+++ jcr/trunk/component/core/known-issues.txt	2009-10-22 09:45:53 UTC (rev 348)
@@ -1,6 +1,3 @@
 
 // https://jira.jboss.org/jira/browse/EXOJCR-193 
 org.exoplatform.services.jcr.impl.core.query.TestSimilarity.java
-
-//https://jira.jboss.org/jira/browse/EXOJCR-192
-org.exoplatform.services.jcr.api.core.query.lucene.spell.SpellCheckerTest.java
\ No newline at end of file

Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/spell/LuceneSpellChecker.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/spell/LuceneSpellChecker.java	2009-10-21 16:18:15 UTC (rev 347)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/spell/LuceneSpellChecker.java	2009-10-22 09:45:53 UTC (rev 348)
@@ -47,390 +47,442 @@
  * <code>LuceneSpellChecker</code> implements a spell checker based on the terms
  * present in a lucene index.
  */
-public class LuceneSpellChecker implements
-	org.exoplatform.services.jcr.impl.core.query.lucene.SpellChecker {
+public class LuceneSpellChecker implements org.exoplatform.services.jcr.impl.core.query.lucene.SpellChecker
+{
 
-    /**
-     * Logger instance for this class.
-     */
-    private static final Log log = ExoLogger
-	    .getLogger(LuceneSpellChecker.class);
+   /**
+    * Logger instance for this class.
+    */
+   private static final Log log = ExoLogger.getLogger(LuceneSpellChecker.class);
 
-    public static final class FiveSecondsRefreshInterval extends
-	    LuceneSpellChecker {
-	public FiveSecondsRefreshInterval() {
-	    super(5 * 1000);
-	}
-    }
+   public static final class FiveSecondsRefreshInterval extends LuceneSpellChecker
+   {
+      public FiveSecondsRefreshInterval()
+      {
+         super(5 * 1000);
+      }
+   }
 
-    public static final class OneMinuteRefreshInterval extends
-	    LuceneSpellChecker {
-	public OneMinuteRefreshInterval() {
-	    super(60 * 1000);
-	}
-    }
+   public static final class OneMinuteRefreshInterval extends LuceneSpellChecker
+   {
+      public OneMinuteRefreshInterval()
+      {
+         super(60 * 1000);
+      }
+   }
 
-    public static final class FiveMinutesRefreshInterval extends
-	    LuceneSpellChecker {
-	public FiveMinutesRefreshInterval() {
-	    super(5 * 60 * 1000);
-	}
-    }
+   public static final class FiveMinutesRefreshInterval extends LuceneSpellChecker
+   {
+      public FiveMinutesRefreshInterval()
+      {
+         super(5 * 60 * 1000);
+      }
+   }
 
-    public static final class ThirtyMinutesRefreshInterval extends
-	    LuceneSpellChecker {
-	public ThirtyMinutesRefreshInterval() {
-	    super(30 * 60 * 1000);
-	}
-    }
+   public static final class ThirtyMinutesRefreshInterval extends LuceneSpellChecker
+   {
+      public ThirtyMinutesRefreshInterval()
+      {
+         super(30 * 60 * 1000);
+      }
+   }
 
-    public static final class OneHourRefreshInterval extends LuceneSpellChecker {
-	public OneHourRefreshInterval() {
-	    super(60 * 60 * 1000);
-	}
-    }
+   public static final class OneHourRefreshInterval extends LuceneSpellChecker
+   {
+      public OneHourRefreshInterval()
+      {
+         super(60 * 60 * 1000);
+      }
+   }
 
-    public static final class SixHoursRefreshInterval extends
-	    LuceneSpellChecker {
-	public SixHoursRefreshInterval() {
-	    super(6 * 60 * 60 * 1000);
-	}
-    }
+   public static final class SixHoursRefreshInterval extends LuceneSpellChecker
+   {
+      public SixHoursRefreshInterval()
+      {
+         super(6 * 60 * 60 * 1000);
+      }
+   }
 
-    public static final class TwelveHoursRefreshInterval extends
-	    LuceneSpellChecker {
-	public TwelveHoursRefreshInterval() {
-	    super(12 * 60 * 60 * 1000);
-	}
-    }
+   public static final class TwelveHoursRefreshInterval extends LuceneSpellChecker
+   {
+      public TwelveHoursRefreshInterval()
+      {
+         super(12 * 60 * 60 * 1000);
+      }
+   }
 
-    public static final class OneDayRefreshInterval extends LuceneSpellChecker {
-	public OneDayRefreshInterval() {
-	    super(24 * 60 * 60 * 1000);
-	}
-    }
+   public static final class OneDayRefreshInterval extends LuceneSpellChecker
+   {
+      public OneDayRefreshInterval()
+      {
+         super(24 * 60 * 60 * 1000);
+      }
+   }
 
-    /**
-     * The internal spell checker.
-     */
-    private InternalSpellChecker spellChecker;
+   /**
+    * The internal spell checker.
+    */
+   private InternalSpellChecker spellChecker;
 
-    /**
-     * The refresh interval.
-     */
-    private final long refreshInterval;
+   /**
+    * The refresh interval.
+    */
+   private final long refreshInterval;
 
-    /**
-     * Spell checker with a default refresh interval of one hour.
-     */
-    public LuceneSpellChecker() {
-	this(60 * 60 * 1000); // default refresh interval: one hour
-    }
+   /**
+    * Spell checker with a default refresh interval of one hour.
+    */
+   public LuceneSpellChecker()
+   {
+      this(60 * 60 * 1000); // default refresh interval: one hour
+   }
 
-    protected LuceneSpellChecker(long refreshInterval) {
-	this.refreshInterval = refreshInterval;
-    }
+   protected LuceneSpellChecker(long refreshInterval)
+   {
+      this.refreshInterval = refreshInterval;
+   }
 
-    /**
-     * Initializes this spell checker.
-     * 
-     * @param handler
-     *            the query handler that created this spell checker.
-     * @throws IOException
-     *             if <code>handler</code> is not of type {@link SearchIndex}.
-     */
-    public void init(QueryHandler handler) throws IOException {
-	if (handler instanceof SearchIndex) {
-	    this.spellChecker = new InternalSpellChecker((SearchIndex) handler);
-	} else {
-	    throw new IOException("LuceneSpellChecker only works with "
-		    + SearchIndex.class.getName());
-	}
-    }
+   /**
+    * Initializes this spell checker.
+    * 
+    * @param handler
+    *            the query handler that created this spell checker.
+    * @throws IOException
+    *             if <code>handler</code> is not of type {@link SearchIndex}.
+    */
+   public void init(QueryHandler handler) throws IOException
+   {
+      if (handler instanceof SearchIndex)
+      {
+         this.spellChecker = new InternalSpellChecker((SearchIndex)handler);
+      }
+      else
+      {
+         throw new IOException("LuceneSpellChecker only works with " + SearchIndex.class.getName());
+      }
+   }
 
-    /**
-     * {@inheritDoc}
-     * 
-     * @throws RepositoryException
-     */
-    public String check(QueryRootNode aqt) throws IOException,
-	    RepositoryException {
-	String stmt = getFulltextStatement(aqt);
-	if (stmt == null) {
-	    // no spellcheck operation in query
-	    return null;
-	}
-	return spellChecker.suggest(stmt);
-    }
+   /**
+    * {@inheritDoc}
+    * 
+    * @throws RepositoryException
+    */
+   public String check(QueryRootNode aqt) throws IOException, RepositoryException
+   {
+      String stmt = getFulltextStatement(aqt);
+      if (stmt == null)
+      {
+         // no spellcheck operation in query
+         return null;
+      }
+      return spellChecker.suggest(stmt);
+   }
 
-    public void close() {
-	spellChecker.close();
-    }
+   public void close()
+   {
+      spellChecker.close();
+   }
 
-    // ------------------------------< internal
-    // >--------------------------------
+   // ------------------------------< internal
+   // >--------------------------------
 
-    /**
-     * Returns the fulltext statement of a spellcheck relation query node or
-     * <code>null</code> if none exists in the abstract query tree.
-     * 
-     * @param aqt
-     *            the abstract query tree.
-     * @return the fulltext statement or <code>null</code>.
-     * @throws RepositoryException
-     */
-    private String getFulltextStatement(QueryRootNode aqt)
-	    throws RepositoryException {
-	final String[] stmt = new String[1];
-	aqt.accept(new TraversingQueryNodeVisitor() {
-	    public Object visit(RelationQueryNode node, Object o)
-		    throws RepositoryException {
-		if (stmt[0] == null
-			&& node.getOperation() == RelationQueryNode.OPERATION_SPELLCHECK) {
-		    stmt[0] = node.getStringValue();
-		}
-		return super.visit(node, o);
-	    }
-	}, null);
-	return stmt[0];
-    }
+   /**
+    * Returns the fulltext statement of a spellcheck relation query node or
+    * <code>null</code> if none exists in the abstract query tree.
+    * 
+    * @param aqt
+    *            the abstract query tree.
+    * @return the fulltext statement or <code>null</code>.
+    * @throws RepositoryException
+    */
+   private String getFulltextStatement(QueryRootNode aqt) throws RepositoryException
+   {
+      final String[] stmt = new String[1];
+      aqt.accept(new TraversingQueryNodeVisitor()
+      {
+         public Object visit(RelationQueryNode node, Object o) throws RepositoryException
+         {
+            if (stmt[0] == null && node.getOperation() == RelationQueryNode.OPERATION_SPELLCHECK)
+            {
+               stmt[0] = node.getStringValue();
+            }
+            return super.visit(node, o);
+         }
+      }, null);
+      return stmt[0];
+   }
 
-    private final class InternalSpellChecker {
+   private final class InternalSpellChecker
+   {
 
-	/**
-	 * Timestamp when the last refresh was done.
-	 */
-	private long lastRefresh;
+      /**
+       * Timestamp when the last refresh was done.
+       */
+      private long lastRefresh;
 
-	/**
-	 * Set to true while a refresh is done in a separate thread.
-	 */
-	private boolean refreshing = false;
+      /**
+       * Set to true while a refresh is done in a separate thread.
+       */
+      private boolean refreshing = false;
 
-	/**
-	 * The query handler associated with this spell checker.
-	 */
-	private final SearchIndex handler;
+      /**
+       * The query handler associated with this spell checker.
+       */
+      private final SearchIndex handler;
 
-	/**
-	 * The directory where the spell index is stored.
-	 */
-	private final Directory spellIndexDirectory;
+      /**
+       * The directory where the spell index is stored.
+       */
+      private final Directory spellIndexDirectory;
 
-	/**
-	 * The underlying spell checker.
-	 */
-	private SpellChecker spellChecker;
+      /**
+       * The underlying spell checker.
+       */
+      private SpellChecker spellChecker;
 
-	/**
-	 * Creates a new internal spell checker.
-	 * 
-	 * @param handler
-	 *            the associated query handler.
-	 */
-	InternalSpellChecker(SearchIndex handler) throws IOException {
-	    this.handler = handler;
-	    String path = handler.getContext().getIndexDirectory()
-		    + File.separatorChar + "spellchecker";
-	    this.spellIndexDirectory = FSDirectory.getDirectory(path,
-		    new NativeFSLockFactory(path));
-	    if (IndexReader.indexExists(spellIndexDirectory)) {
-		this.lastRefresh = System.currentTimeMillis();
-	    }
-	    this.spellChecker = new SpellChecker(spellIndexDirectory);
-	    refreshSpellChecker();
-	}
+      /**
+       * Creates a new internal spell checker.
+       * 
+       * @param handler
+       *            the associated query handler.
+       */
+      InternalSpellChecker(SearchIndex handler) throws IOException
+      {
+         this.handler = handler;
+         String path = handler.getContext().getIndexDirectory() + File.separatorChar + "spellchecker";
+         this.spellIndexDirectory = FSDirectory.getDirectory(path, new NativeFSLockFactory(path));
+         if (IndexReader.indexExists(spellIndexDirectory))
+         {
+            this.lastRefresh = System.currentTimeMillis();
+         }
+         this.spellChecker = new SpellChecker(spellIndexDirectory);
+         this.spellChecker.setAccuracy(0.55f);
+         refreshSpellChecker();
+      }
 
-	/**
-	 * Checks a fulltext query statement and suggests a spell checked
-	 * version of the statement. If the spell checker thinks the spelling is
-	 * correct <code>null</code> is returned.
-	 * 
-	 * @param statement
-	 *            the fulltext query statement.
-	 * @return a suggestion or <code>null</code>.
-	 */
-	String suggest(String statement) throws IOException {
-	    // tokenize the statement (field name doesn't matter actually...)
-	    List<String> words = new ArrayList<String>();
-	    List<Token> tokens = new ArrayList<Token>();
-	    tokenize(statement, words, tokens);
+      /**
+       * Checks a fulltext query statement and suggests a spell checked
+       * version of the statement. If the spell checker thinks the spelling is
+       * correct <code>null</code> is returned.
+       * 
+       * @param statement
+       *            the fulltext query statement.
+       * @return a suggestion or <code>null</code>.
+       */
+      String suggest(String statement) throws IOException
+      {
+         // tokenize the statement (field name doesn't matter actually...)
+         List<String> words = new ArrayList<String>();
+         List<Token> tokens = new ArrayList<Token>();
+         tokenize(statement, words, tokens);
 
-	    String[] suggestions = check(words
-		    .toArray(new String[words.size()]));
-	    if (suggestions != null) {
-		// replace words in statement in reverse order because length
-		// of statement will change
-		StringBuffer sb = new StringBuffer(statement);
-		for (int i = suggestions.length - 1; i >= 0; i--) {
-		    Token t = tokens.get(i);
-		    // only replace if word acutally changed
-		    if (!t.termText().equalsIgnoreCase(suggestions[i])) {
-			sb.replace(t.startOffset(), t.endOffset(),
-				suggestions[i]);
-		    }
-		}
-		return sb.toString();
-	    } else {
-		return null;
-	    }
-	}
+         String[] suggestions = check(words.toArray(new String[words.size()]));
+         if (suggestions != null)
+         {
+            // replace words in statement in reverse order because length
+            // of statement will change
+            StringBuffer sb = new StringBuffer(statement);
+            for (int i = suggestions.length - 1; i >= 0; i--)
+            {
+               Token t = tokens.get(i);
+               // only replace if word acutally changed
+               if (!t.termText().equalsIgnoreCase(suggestions[i]))
+               {
+                  sb.replace(t.startOffset(), t.endOffset(), suggestions[i]);
+               }
+            }
+            return sb.toString();
+         }
+         else
+         {
+            return null;
+         }
+      }
 
-	void close() {
-	    try {
-		spellIndexDirectory.close();
-	    } catch (IOException e) {
-		// ignore
-	    }
-	    // urgh, the lucene spell checker cannot be closed explicitly.
-	    // finalize will close the reader...
-	    spellChecker = null;
-	}
+      void close()
+      {
+         try
+         {
+            spellIndexDirectory.close();
+         }
+         catch (IOException e)
+         {
+            // ignore
+         }
+         // urgh, the lucene spell checker cannot be closed explicitly.
+         // finalize will close the reader...
+         spellChecker = null;
+      }
 
-	/**
-	 * Tokenizes the statement into words and tokens.
-	 * 
-	 * @param statement
-	 *            the fulltext query statement.
-	 * @param words
-	 *            this list will be filled with the original words extracted
-	 *            from the statement.
-	 * @param tokens
-	 *            this list will be filled with the tokens parsed from the
-	 *            statement.
-	 * @throws IOException
-	 *             if an error occurs while parsing the statement.
-	 */
-	private void tokenize(String statement, List<String> words,
-		List<Token> tokens) throws IOException {
-	    TokenStream ts = handler.getTextAnalyzer().tokenStream(
-		    FieldNames.FULLTEXT, new StringReader(statement));
-	    try {
-		Token t;
-		while ((t = ts.next()) != null) {
-		    String origWord = statement.substring(t.startOffset(), t
-			    .endOffset());
-		    if (t.getPositionIncrement() > 0) {
-			words.add(t.termText());
-			tokens.add(t);
-		    } else {
-			// very simple implementation: use termText with length
-			// closer to original word
-			Token current = tokens.get(tokens.size() - 1);
-			if (Math.abs(origWord.length()
-				- current.termText().length()) > Math
-				.abs(origWord.length() - t.termText().length())) {
-			    // replace current token and word
-			    words.set(words.size() - 1, t.termText());
-			    tokens.set(tokens.size() - 1, t);
-			}
-		    }
-		}
-	    } finally {
-		ts.close();
-	    }
-	}
+      /**
+       * Tokenizes the statement into words and tokens.
+       * 
+       * @param statement
+       *            the fulltext query statement.
+       * @param words
+       *            this list will be filled with the original words extracted
+       *            from the statement.
+       * @param tokens
+       *            this list will be filled with the tokens parsed from the
+       *            statement.
+       * @throws IOException
+       *             if an error occurs while parsing the statement.
+       */
+      private void tokenize(String statement, List<String> words, List<Token> tokens) throws IOException
+      {
+         TokenStream ts = handler.getTextAnalyzer().tokenStream(FieldNames.FULLTEXT, new StringReader(statement));
+         try
+         {
+            Token t;
+            while ((t = ts.next()) != null)
+            {
+               String origWord = statement.substring(t.startOffset(), t.endOffset());
+               if (t.getPositionIncrement() > 0)
+               {
+                  words.add(t.termText());
+                  tokens.add(t);
+               }
+               else
+               {
+                  // very simple implementation: use termText with length
+                  // closer to original word
+                  Token current = tokens.get(tokens.size() - 1);
+                  if (Math.abs(origWord.length() - current.termText().length()) > Math.abs(origWord.length()
+                     - t.termText().length()))
+                  {
+                     // replace current token and word
+                     words.set(words.size() - 1, t.termText());
+                     tokens.set(tokens.size() - 1, t);
+                  }
+               }
+            }
+         }
+         finally
+         {
+            ts.close();
+         }
+      }
 
-	/**
-	 * Checks the spelling of the passed <code>words</code> and returns a
-	 * suggestion.
-	 * 
-	 * @param words
-	 *            the words to check.
-	 * @return a suggestion of correctly spelled <code>words</code> or
-	 *         <code>null</code> if this spell checker thinks
-	 *         <code>words</code> are spelled correctly.
-	 * @throws IOException
-	 *             if an error occurs while spell checking.
-	 */
-	private String[] check(String words[]) throws IOException {
-	    refreshSpellChecker();
-	    boolean hasSuggestion = false;
-	    IndexReader reader = handler.getIndexReader();
-	    try {
-		for (int retries = 0; retries < 100; retries++) {
-		    try {
-			String[] suggestion = new String[words.length];
-			for (int i = 0; i < words.length; i++) {
-			    String[] similar = spellChecker.suggestSimilar(
-				    words[i], 5, reader, FieldNames.FULLTEXT,
-				    true);
-			    if (similar.length > 0) {
-				suggestion[i] = similar[0];
-				hasSuggestion = true;
-			    } else {
-				suggestion[i] = words[i];
-			    }
-			}
-			if (hasSuggestion) {
-			    log.debug("Successful after "
-				    + new Integer(retries) + " retries");
-			    return suggestion;
-			} else {
-			    return null;
-			}
-		    } catch (AlreadyClosedException e) {
-			// it may happen that the index reader inside the
-			// spell checker is closed while searching for
-			// suggestions. this is actually a design flaw in the
-			// lucene spell checker, but for now we simply retry
-		    }
-		}
-		// unsuccessful after retries
-		return null;
-	    } finally {
-		reader.close();
-	    }
-	}
+      /**
+       * Checks the spelling of the passed <code>words</code> and returns a
+       * suggestion.
+       * 
+       * @param words
+       *            the words to check.
+       * @return a suggestion of correctly spelled <code>words</code> or
+       *         <code>null</code> if this spell checker thinks
+       *         <code>words</code> are spelled correctly.
+       * @throws IOException
+       *             if an error occurs while spell checking.
+       */
+      private String[] check(String words[]) throws IOException
+      {
+         refreshSpellChecker();
+         boolean hasSuggestion = false;
+         IndexReader reader = handler.getIndexReader();
+         try
+         {
+            for (int retries = 0; retries < 100; retries++)
+            {
+               try
+               {
+                  String[] suggestion = new String[words.length];
+                  for (int i = 0; i < words.length; i++)
+                  {
+                     String[] similar = spellChecker.suggestSimilar(words[i], 5, reader, FieldNames.FULLTEXT, true);
+                     if (similar.length > 0)
+                     {
+                        suggestion[i] = similar[0];
+                        hasSuggestion = true;
+                     }
+                     else
+                     {
+                        suggestion[i] = words[i];
+                     }
+                  }
+                  if (hasSuggestion)
+                  {
+                     log.debug("Successful after " + new Integer(retries) + " retries");
+                     return suggestion;
+                  }
+                  else
+                  {
+                     return null;
+                  }
+               }
+               catch (AlreadyClosedException e)
+               {
+                  // it may happen that the index reader inside the
+                  // spell checker is closed while searching for
+                  // suggestions. this is actually a design flaw in the
+                  // lucene spell checker, but for now we simply retry
+               }
+            }
+            // unsuccessful after retries
+            return null;
+         }
+         finally
+         {
+            reader.close();
+         }
+      }
 
-	/**
-	 * Refreshes the underlying spell checker in a background thread.
-	 * Synchronization is done on this <code>LuceneSpellChecker</code>
-	 * instance. While the refresh takes place {@link #refreshing} is set to
-	 * <code>true</code>.
-	 */
-	private void refreshSpellChecker() {
-	    if (lastRefresh + refreshInterval < System.currentTimeMillis()) {
-		synchronized (this) {
-		    if (refreshing) {
-			return;
-		    } else {
-			refreshing = true;
-			Runnable refresh = new Runnable() {
-			    public void run() {
-				try {
-				    IndexReader reader = handler
-					    .getIndexReader();
-				    try {
-					long time = System.currentTimeMillis();
-					Dictionary dict = new LuceneDictionary(
-						reader, FieldNames.FULLTEXT);
-					log
-						.debug("Starting spell checker index refresh");
-					spellChecker.indexDictionary(dict);
-					time = System.currentTimeMillis()
-						- time;
-					time = time / 1000;
-					log
-						.info("Spell checker index refreshed in: "
-							+ new Long(time)
-							+ " s.");
-				    } finally {
-					reader.close();
-					synchronized (InternalSpellChecker.this) {
-					    refreshing = false;
-					}
-				    }
-				} catch (IOException e) {
-				    // ignore
-				}
-			    }
-			};
-			new Thread(refresh, "SpellChecker Refresh").start();
-			lastRefresh = System.currentTimeMillis();
-		    }
-		}
-	    }
-	}
-    }
+      /**
+       * Refreshes the underlying spell checker in a background thread.
+       * Synchronization is done on this <code>LuceneSpellChecker</code>
+       * instance. While the refresh takes place {@link #refreshing} is set to
+       * <code>true</code>.
+       */
+      private void refreshSpellChecker()
+      {
+         if (lastRefresh + refreshInterval < System.currentTimeMillis())
+         {
+            synchronized (this)
+            {
+               if (refreshing)
+               {
+                  return;
+               }
+               else
+               {
+                  refreshing = true;
+                  Runnable refresh = new Runnable()
+                  {
+                     public void run()
+                     {
+                        try
+                        {
+                           IndexReader reader = handler.getIndexReader();
+                           try
+                           {
+                              long time = System.currentTimeMillis();
+                              Dictionary dict = new LuceneDictionary(reader, FieldNames.FULLTEXT);
+                              log.debug("Starting spell checker index refresh");
+                              spellChecker.indexDictionary(dict);
+                              time = System.currentTimeMillis() - time;
+                              time = time / 1000;
+                              log.info("Spell checker index refreshed in: " + new Long(time) + " s.");
+                           }
+                           finally
+                           {
+                              reader.close();
+                              synchronized (InternalSpellChecker.this)
+                              {
+                                 refreshing = false;
+                              }
+                           }
+                        }
+                        catch (IOException e)
+                        {
+                           // ignore
+                        }
+                     }
+                  };
+                  new Thread(refresh, "SpellChecker Refresh").start();
+                  lastRefresh = System.currentTimeMillis();
+               }
+            }
+         }
+      }
+   }
 }

Modified: jcr/trunk/component/core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/spell/SpellCheckerTest.java
===================================================================
--- jcr/trunk/component/core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/spell/SpellCheckerTest.java	2009-10-21 16:18:15 UTC (rev 347)
+++ jcr/trunk/component/core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/spell/SpellCheckerTest.java	2009-10-22 09:45:53 UTC (rev 348)
@@ -59,7 +59,8 @@
    public void testSpellCheckerComplexQuery() throws RepositoryException
    {
       String text = "the quick brown fox jumps over the lazy dog";
-      testRootNode.setProperty("prop", text);
+      Node n = testRootNode.addNode("testNode");
+      n.setProperty("prop", text);
       superuser.save();
       // wait a couple of seconds, refresh interval in test config is 5 seconds
       try
@@ -80,7 +81,7 @@
    public void testSpellCheckerComplexQuery2() throws RepositoryException
    {
 
-      String text = "the quick brown fox jumps over the lazy dog";
+      String text = "the quick brown fox jumps over the lazy dog and something else";
 
       Node doc = testRootNode.addNode("file", "nt:file");//.setProperty("prop", text);
       NodeImpl cont = (NodeImpl)doc.addNode("jcr:content", "nt:resource");



More information about the exo-jcr-commits mailing list