You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-commits@lucene.apache.org by yo...@apache.org on 2008/11/11 03:35:52 UTC
svn commit: r712922 [5/9] - in /lucene/java/trunk:
contrib/analyzers/src/java/org/apache/lucene/analysis/el/
contrib/analyzers/src/java/org/apache/lucene/analysis/fr/
contrib/analyzers/src/java/org/apache/lucene/analysis/miscellaneous/
contrib/analyzer...
Modified: lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/search/FuzzyLikeThisQueryTest.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/search/FuzzyLikeThisQueryTest.java?rev=712922&r1=712921&r2=712922&view=diff
==============================================================================
--- lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/search/FuzzyLikeThisQueryTest.java (original)
+++ lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/search/FuzzyLikeThisQueryTest.java Mon Nov 10 18:35:46 2008
@@ -1,114 +1,114 @@
-package org.apache.lucene.search;
-
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.io.IOException;
-import java.util.HashSet;
-
-import junit.framework.TestCase;
-
-import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.analysis.WhitespaceAnalyzer;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.index.IndexWriter;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.index.IndexWriter.MaxFieldLength;
-import org.apache.lucene.store.RAMDirectory;
-
-public class FuzzyLikeThisQueryTest extends TestCase
-{
- private RAMDirectory directory;
- private IndexSearcher searcher;
- private Analyzer analyzer=new WhitespaceAnalyzer();
-
- protected void setUp() throws Exception
- {
- directory = new RAMDirectory();
- IndexWriter writer = new IndexWriter(directory, analyzer,true, MaxFieldLength.UNLIMITED);
-
- //Add series of docs with misspelt names
- addDoc(writer, "jonathon smythe","1");
- addDoc(writer, "jonathan smith","2");
- addDoc(writer, "johnathon smyth","3");
- addDoc(writer, "johnny smith","4" );
- addDoc(writer, "jonny smith","5" );
- addDoc(writer, "johnathon smythe","6");
-
- writer.close();
- searcher=new IndexSearcher(directory);
- }
-
- private void addDoc(IndexWriter writer, String name, String id) throws IOException
- {
- Document doc=new Document();
- doc.add(new Field("name",name,Field.Store.YES,Field.Index.ANALYZED));
- doc.add(new Field("id",id,Field.Store.YES,Field.Index.ANALYZED));
- writer.addDocument(doc);
- }
-
-
- //Tests that idf ranking is not favouring rare mis-spellings over a strong edit-distance match
- public void testClosestEditDistanceMatchComesFirst() throws Throwable
- {
- FuzzyLikeThisQuery flt=new FuzzyLikeThisQuery(10,analyzer);
- flt.addTerms("smith", "name", 0.3f, 1);
- Query q=flt.rewrite(searcher.getIndexReader());
- HashSet queryTerms=new HashSet();
- q.extractTerms(queryTerms);
- assertTrue("Should have variant smythe",queryTerms.contains(new Term("name","smythe")));
- assertTrue("Should have variant smith",queryTerms.contains(new Term("name","smith")));
- assertTrue("Should have variant smyth",queryTerms.contains(new Term("name","smyth")));
- TopDocs topDocs = searcher.search(flt, 1);
- ScoreDoc[] sd = topDocs.scoreDocs;
- assertTrue("score docs must match 1 doc", (sd!=null)&&(sd.length>0));
- Document doc=searcher.doc(sd[0].doc);
- assertEquals("Should match most similar not most rare variant", "2",doc.get("id"));
- }
- //Test multiple input words are having variants produced
- public void testMultiWord() throws Throwable
- {
- FuzzyLikeThisQuery flt=new FuzzyLikeThisQuery(10,analyzer);
- flt.addTerms("jonathin smoth", "name", 0.3f, 1);
- Query q=flt.rewrite(searcher.getIndexReader());
- HashSet queryTerms=new HashSet();
- q.extractTerms(queryTerms);
- assertTrue("Should have variant jonathan",queryTerms.contains(new Term("name","jonathan")));
- assertTrue("Should have variant smith",queryTerms.contains(new Term("name","smith")));
- TopDocs topDocs = searcher.search(flt, 1);
- ScoreDoc[] sd = topDocs.scoreDocs;
- assertTrue("score docs must match 1 doc", (sd!=null)&&(sd.length>0));
- Document doc=searcher.doc(sd[0].doc);
- assertEquals("Should match most similar when using 2 words", "2",doc.get("id"));
- }
- //Test bug found when first query word does not match anything
- public void testNoMatchFirstWordBug() throws Throwable
- {
- FuzzyLikeThisQuery flt=new FuzzyLikeThisQuery(10,analyzer);
- flt.addTerms("fernando smith", "name", 0.3f, 1);
- Query q=flt.rewrite(searcher.getIndexReader());
- HashSet queryTerms=new HashSet();
- q.extractTerms(queryTerms);
- assertTrue("Should have variant smith",queryTerms.contains(new Term("name","smith")));
- TopDocs topDocs = searcher.search(flt, 1);
- ScoreDoc[] sd = topDocs.scoreDocs;
- assertTrue("score docs must match 1 doc", (sd!=null)&&(sd.length>0));
- Document doc=searcher.doc(sd[0].doc);
- assertEquals("Should match most similar when using 2 words", "2",doc.get("id"));
- }
-}
+package org.apache.lucene.search;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.util.HashSet;
+
+import junit.framework.TestCase;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.WhitespaceAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.index.IndexWriter.MaxFieldLength;
+import org.apache.lucene.store.RAMDirectory;
+
+public class FuzzyLikeThisQueryTest extends TestCase
+{
+ private RAMDirectory directory;
+ private IndexSearcher searcher;
+ private Analyzer analyzer=new WhitespaceAnalyzer();
+
+ protected void setUp() throws Exception
+ {
+ directory = new RAMDirectory();
+ IndexWriter writer = new IndexWriter(directory, analyzer,true, MaxFieldLength.UNLIMITED);
+
+ //Add series of docs with misspelt names
+ addDoc(writer, "jonathon smythe","1");
+ addDoc(writer, "jonathan smith","2");
+ addDoc(writer, "johnathon smyth","3");
+ addDoc(writer, "johnny smith","4" );
+ addDoc(writer, "jonny smith","5" );
+ addDoc(writer, "johnathon smythe","6");
+
+ writer.close();
+ searcher=new IndexSearcher(directory);
+ }
+
+ private void addDoc(IndexWriter writer, String name, String id) throws IOException
+ {
+ Document doc=new Document();
+ doc.add(new Field("name",name,Field.Store.YES,Field.Index.ANALYZED));
+ doc.add(new Field("id",id,Field.Store.YES,Field.Index.ANALYZED));
+ writer.addDocument(doc);
+ }
+
+
+ //Tests that idf ranking is not favouring rare mis-spellings over a strong edit-distance match
+ public void testClosestEditDistanceMatchComesFirst() throws Throwable
+ {
+ FuzzyLikeThisQuery flt=new FuzzyLikeThisQuery(10,analyzer);
+ flt.addTerms("smith", "name", 0.3f, 1);
+ Query q=flt.rewrite(searcher.getIndexReader());
+ HashSet queryTerms=new HashSet();
+ q.extractTerms(queryTerms);
+ assertTrue("Should have variant smythe",queryTerms.contains(new Term("name","smythe")));
+ assertTrue("Should have variant smith",queryTerms.contains(new Term("name","smith")));
+ assertTrue("Should have variant smyth",queryTerms.contains(new Term("name","smyth")));
+ TopDocs topDocs = searcher.search(flt, 1);
+ ScoreDoc[] sd = topDocs.scoreDocs;
+ assertTrue("score docs must match 1 doc", (sd!=null)&&(sd.length>0));
+ Document doc=searcher.doc(sd[0].doc);
+ assertEquals("Should match most similar not most rare variant", "2",doc.get("id"));
+ }
+ //Test multiple input words are having variants produced
+ public void testMultiWord() throws Throwable
+ {
+ FuzzyLikeThisQuery flt=new FuzzyLikeThisQuery(10,analyzer);
+ flt.addTerms("jonathin smoth", "name", 0.3f, 1);
+ Query q=flt.rewrite(searcher.getIndexReader());
+ HashSet queryTerms=new HashSet();
+ q.extractTerms(queryTerms);
+ assertTrue("Should have variant jonathan",queryTerms.contains(new Term("name","jonathan")));
+ assertTrue("Should have variant smith",queryTerms.contains(new Term("name","smith")));
+ TopDocs topDocs = searcher.search(flt, 1);
+ ScoreDoc[] sd = topDocs.scoreDocs;
+ assertTrue("score docs must match 1 doc", (sd!=null)&&(sd.length>0));
+ Document doc=searcher.doc(sd[0].doc);
+ assertEquals("Should match most similar when using 2 words", "2",doc.get("id"));
+ }
+ //Test bug found when first query word does not match anything
+ public void testNoMatchFirstWordBug() throws Throwable
+ {
+ FuzzyLikeThisQuery flt=new FuzzyLikeThisQuery(10,analyzer);
+ flt.addTerms("fernando smith", "name", 0.3f, 1);
+ Query q=flt.rewrite(searcher.getIndexReader());
+ HashSet queryTerms=new HashSet();
+ q.extractTerms(queryTerms);
+ assertTrue("Should have variant smith",queryTerms.contains(new Term("name","smith")));
+ TopDocs topDocs = searcher.search(flt, 1);
+ ScoreDoc[] sd = topDocs.scoreDocs;
+ assertTrue("score docs must match 1 doc", (sd!=null)&&(sd.length>0));
+ Document doc=searcher.doc(sd[0].doc);
+ assertEquals("Should match most similar when using 2 words", "2",doc.get("id"));
+ }
+}
Propchange: lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/search/FuzzyLikeThisQueryTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/regex/src/java/org/apache/lucene/search/regex/JakartaRegexpCapabilities.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/regex/src/java/org/apache/lucene/search/regex/JavaUtilRegexCapabilities.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/regex/src/java/org/apache/lucene/search/regex/RegexCapabilities.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/regex/src/java/org/apache/lucene/search/regex/RegexQuery.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/regex/src/java/org/apache/lucene/search/regex/RegexQueryCapable.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/regex/src/java/org/apache/lucene/search/regex/RegexTermEnum.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/regex/src/java/org/apache/lucene/search/regex/SpanRegexQuery.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/regex/src/java/org/apache/regexp/RegexpTunnel.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/regex/src/test/org/apache/lucene/search/regex/TestRegexQuery.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/regex/src/test/org/apache/lucene/search/regex/TestSpanRegexQuery.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/Among.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/SnowballProgram.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/TestApp.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/ext/DanishStemmer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/ext/DutchStemmer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/ext/EnglishStemmer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/ext/FinnishStemmer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/ext/FrenchStemmer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/ext/German2Stemmer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/ext/GermanStemmer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/ext/HungarianStemmer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/ext/ItalianStemmer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/ext/KpStemmer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/ext/LovinsStemmer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/ext/NorwegianStemmer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/ext/PorterStemmer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/ext/PortugueseStemmer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/ext/RomanianStemmer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/ext/RussianStemmer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/ext/SpanishStemmer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/ext/SwedishStemmer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/snowball/src/java/org/tartarus/snowball/ext/TurkishStemmer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/spellchecker/src/java/org/apache/lucene/search/spell/JaroWinklerDistance.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/spellchecker/src/java/org/apache/lucene/search/spell/StringDistance.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/spellchecker/src/test/org/apache/lucene/search/spell/TestJaroWinklerDistance.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/spellchecker/src/test/org/apache/lucene/search/spell/TestLevenshteinDistance.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/spellchecker/src/test/org/apache/lucene/search/spell/TestLuceneDictionary.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/spellchecker/src/test/org/apache/lucene/search/spell/TestPlainTextDictionary.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/parser/CharStream.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/parser/FastCharStream.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/parser/ParseException.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/parser/QueryParser.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/parser/QueryParserConstants.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/parser/QueryParserTokenManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/parser/Token.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/parser/TokenMgrError.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/AndQuery.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/BasicQueryFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/ComposedQuery.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/DistanceQuery.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/DistanceSubQuery.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/FieldsQuery.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/NotQuery.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/OrQuery.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SimpleTerm.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SpanNearClauseFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndBooleanQuery.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndPrefixQuery.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndQuery.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndTermQuery.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/SrndTruncQuery.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/java/org/apache/lucene/queryParser/surround/query/TooManyBasicQueries.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/BooleanQueryTst.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/ExceptionQueryTst.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/SingleFieldTestDb.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/Test01Exceptions.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/Test02Boolean.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/java/trunk/contrib/surround/src/test/org/apache/lucene/queryParser/surround/query/Test03Distance.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/ListSearcher.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/ListSearcher.java?rev=712922&r1=712921&r2=712922&view=diff
==============================================================================
--- lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/ListSearcher.java (original)
+++ lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/ListSearcher.java Mon Nov 10 18:35:46 2008
@@ -1,280 +1,280 @@
-package org.apache.lucene.swing.models;
-
-/**
- * Copyright 2005 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import org.apache.lucene.store.RAMDirectory;
-import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.analysis.WhitespaceAnalyzer;
-import org.apache.lucene.index.IndexWriter;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.Fieldable;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.Hits;
-import org.apache.lucene.queryParser.MultiFieldQueryParser;
-
-import javax.swing.*;
-import javax.swing.event.ListDataListener;
-import javax.swing.event.ListDataEvent;
-import java.util.ArrayList;
-
-/**
- * See table searcher explanation.
- *
- */
-public class ListSearcher extends AbstractListModel {
- private ListModel listModel;
-
- /**
- * The reference links between the decorated ListModel
- * and this list model based on search criteria
- */
- private ArrayList rowToModelIndex = new ArrayList();
-
- /**
- * In memory lucene index
- */
- private RAMDirectory directory;
-
- /**
- * Cached lucene analyzer
- */
- private Analyzer analyzer;
-
- /**
- * Links between this list model and the decorated list model
- * are maintained through links based on row number. This is a
- * key constant to denote "row number" for indexing
- */
- private static final String ROW_NUMBER = "ROW_NUMBER";
-
- /**
- * Since we only have one field, unlike lists with multiple
- * fields -- we are just using a constant to denote field name.
- * This is most likely unnecessary and should be removed at
- * a later date
- */
- private static final String FIELD_NAME = "FIELD_NAME";
-
- /**
- * Cache the current search String. Also used internally to
- * key whether there is an active search running or not. i.e. if
- * searchString is null, there is no active search.
- */
- private String searchString = null;
- private ListDataListener listModelListener;
-
- public ListSearcher(ListModel newModel) {
- analyzer = new WhitespaceAnalyzer();
- setListModel(newModel);
- listModelListener = new ListModelHandler();
- newModel.addListDataListener(listModelListener);
- clearSearchingState();
- }
-
- private void setListModel(ListModel newModel) {
- //remove listeners if there...
- if (newModel != null) {
- newModel.removeListDataListener(listModelListener);
- }
-
- listModel = newModel;
- if (listModel != null) {
- listModel.addListDataListener(listModelListener);
- }
-
- //recalculate the links between this list model and
- //the inner list model since the decorated model just changed
- reindex();
-
- // let all listeners know the list has changed
- fireContentsChanged(this, 0, getSize());
- }
-
- private void reindex() {
- try {
- // recreate the RAMDirectory
- directory = new RAMDirectory();
- IndexWriter writer = new IndexWriter(directory, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);
-
- // iterate through all rows
- for (int row=0; row < listModel.getSize(); row++){
-
- //for each row make a new document
- Document document = new Document();
- //add the row number of this row in the decorated list model
- //this will allow us to retrive the results later
- //and map this list model's row to a row in the decorated
- //list model
- document.add(new Field(ROW_NUMBER, "" + row, Field.Store.YES, Field.Index.ANALYZED));
- //add the string representation of the row to the index
- document.add(new Field(FIELD_NAME, String.valueOf(listModel.getElementAt(row)).toLowerCase(), Field.Store.YES, Field.Index.ANALYZED));
- writer.addDocument(document);
- }
- writer.optimize();
- writer.close();
- } catch (Exception e){
- e.printStackTrace();
- }
- }
-
- /**
- * Run a new search.
- *
- * @param searchString Any valid lucene search string
- */
- public void search(String searchString){
-
- //if search string is null or empty, clear the search == search all
- if (searchString == null || searchString.equals("")){
- clearSearchingState();
- fireContentsChanged(this, 0, getSize());
- return;
- }
-
-
- try {
- //cache search String
- this.searchString = searchString;
-
- //make a new index searcher with the in memory (RAM) index.
- IndexSearcher is = new IndexSearcher(directory);
-
- //make an array of fields - one for each column
- String[] fields = {FIELD_NAME};
-
- //build a query based on the fields, searchString and cached analyzer
- //NOTE: This is an area for improvement since the MultiFieldQueryParser
- // has some weirdness.
- MultiFieldQueryParser parser = new MultiFieldQueryParser(fields, analyzer);
- Query query =parser.parse(searchString);
- //run the search
- Hits hits = is.search(query);
- //reset this list model with the new results
- resetSearchResults(hits);
- } catch (Exception e){
- e.printStackTrace();
- }
-
- //notify all listeners that the list has been changed
- fireContentsChanged(this, 0, getSize());
- }
-
- /**
- *
- * @param hits The new result set to set this list to.
- */
- private void resetSearchResults(Hits hits) {
- try {
- //clear our index mapping this list model rows to
- //the decorated inner list model
- rowToModelIndex.clear();
- //iterate through the hits
- //get the row number stored at the index
- //that number is the row number of the decorated
- //tabble model row that we are mapping to
- for (int t=0; t<hits.length(); t++){
- Document document = hits.doc(t);
- Fieldable field = document.getField(ROW_NUMBER);
- rowToModelIndex.add(new Integer(field.stringValue()));
- }
- } catch (Exception e){
- e.printStackTrace();
- }
- }
-
- /**
- * @return The current lucene analyzer
- */
- public Analyzer getAnalyzer() {
- return analyzer;
- }
-
- /**
- * @param analyzer The new analyzer to use
- */
- public void setAnalyzer(Analyzer analyzer) {
- this.analyzer = analyzer;
- //reindex from the model with the new analyzer
- reindex();
-
- //rerun the search if there is an active search
- if (isSearching()){
- search(searchString);
- }
- }
-
- private boolean isSearching() {
- return searchString != null;
- }
-
- private void clearSearchingState() {
- searchString = null;
- rowToModelIndex.clear();
- for (int t=0; t<listModel.getSize(); t++){
- rowToModelIndex.add(new Integer(t));
- }
- }
-
- private int getModelRow(int row){
- return ((Integer) rowToModelIndex.get(row)).intValue();
- }
-
- public int getSize() {
- return (listModel == null) ? 0 : rowToModelIndex.size();
- }
-
- public Object getElementAt(int index) {
- return listModel.getElementAt(getModelRow(index));
- }
-
-
- class ListModelHandler implements ListDataListener {
-
- public void contentsChanged(ListDataEvent e) {
- somethingChanged();
- }
-
- public void intervalAdded(ListDataEvent e) {
- somethingChanged();
- }
-
- public void intervalRemoved(ListDataEvent e) {
- somethingChanged();
- }
-
- private void somethingChanged(){
- // If we're not searching, just pass the event along.
- if (!isSearching()) {
- clearSearchingState();
- reindex();
- fireContentsChanged(ListSearcher.this, 0, getSize());
- return;
- }
-
- // Something has happened to the data that may have invalidated the search.
- reindex();
- search(searchString);
- fireContentsChanged(ListSearcher.this, 0, getSize());
- return;
- }
-
- }
-
-
-}
+package org.apache.lucene.swing.models;
+
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.WhitespaceAnalyzer;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.Fieldable;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Hits;
+import org.apache.lucene.queryParser.MultiFieldQueryParser;
+
+import javax.swing.*;
+import javax.swing.event.ListDataListener;
+import javax.swing.event.ListDataEvent;
+import java.util.ArrayList;
+
+/**
+ * See table searcher explanation.
+ *
+ */
+public class ListSearcher extends AbstractListModel {
+ private ListModel listModel;
+
+ /**
+ * The reference links between the decorated ListModel
+ * and this list model based on search criteria
+ */
+ private ArrayList rowToModelIndex = new ArrayList();
+
+ /**
+ * In memory lucene index
+ */
+ private RAMDirectory directory;
+
+ /**
+ * Cached lucene analyzer
+ */
+ private Analyzer analyzer;
+
+ /**
+ * Links between this list model and the decorated list model
+ * are maintained through links based on row number. This is a
+ * key constant to denote "row number" for indexing
+ */
+ private static final String ROW_NUMBER = "ROW_NUMBER";
+
+ /**
+ * Since we only have one field, unlike lists with multiple
+ * fields -- we are just using a constant to denote field name.
+ * This is most likely unnecessary and should be removed at
+ * a later date
+ */
+ private static final String FIELD_NAME = "FIELD_NAME";
+
+ /**
+ * Cache the current search String. Also used internally to
+ * key whether there is an active search running or not. i.e. if
+ * searchString is null, there is no active search.
+ */
+ private String searchString = null;
+ private ListDataListener listModelListener;
+
+ public ListSearcher(ListModel newModel) {
+ analyzer = new WhitespaceAnalyzer();
+ setListModel(newModel);
+ listModelListener = new ListModelHandler();
+ newModel.addListDataListener(listModelListener);
+ clearSearchingState();
+ }
+
+ private void setListModel(ListModel newModel) {
+ //remove listeners if there...
+ if (newModel != null) {
+ newModel.removeListDataListener(listModelListener);
+ }
+
+ listModel = newModel;
+ if (listModel != null) {
+ listModel.addListDataListener(listModelListener);
+ }
+
+ //recalculate the links between this list model and
+ //the inner list model since the decorated model just changed
+ reindex();
+
+ // let all listeners know the list has changed
+ fireContentsChanged(this, 0, getSize());
+ }
+
+ private void reindex() {
+ try {
+ // recreate the RAMDirectory
+ directory = new RAMDirectory();
+ IndexWriter writer = new IndexWriter(directory, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);
+
+ // iterate through all rows
+ for (int row=0; row < listModel.getSize(); row++){
+
+ //for each row make a new document
+ Document document = new Document();
+ //add the row number of this row in the decorated list model
+ //this will allow us to retrive the results later
+ //and map this list model's row to a row in the decorated
+ //list model
+ document.add(new Field(ROW_NUMBER, "" + row, Field.Store.YES, Field.Index.ANALYZED));
+ //add the string representation of the row to the index
+ document.add(new Field(FIELD_NAME, String.valueOf(listModel.getElementAt(row)).toLowerCase(), Field.Store.YES, Field.Index.ANALYZED));
+ writer.addDocument(document);
+ }
+ writer.optimize();
+ writer.close();
+ } catch (Exception e){
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Run a new search.
+ *
+ * @param searchString Any valid lucene search string
+ */
+ public void search(String searchString){
+
+ //if search string is null or empty, clear the search == search all
+ if (searchString == null || searchString.equals("")){
+ clearSearchingState();
+ fireContentsChanged(this, 0, getSize());
+ return;
+ }
+
+
+ try {
+ //cache search String
+ this.searchString = searchString;
+
+ //make a new index searcher with the in memory (RAM) index.
+ IndexSearcher is = new IndexSearcher(directory);
+
+ //make an array of fields - one for each column
+ String[] fields = {FIELD_NAME};
+
+ //build a query based on the fields, searchString and cached analyzer
+ //NOTE: This is an area for improvement since the MultiFieldQueryParser
+ // has some weirdness.
+ MultiFieldQueryParser parser = new MultiFieldQueryParser(fields, analyzer);
+ Query query =parser.parse(searchString);
+ //run the search
+ Hits hits = is.search(query);
+ //reset this list model with the new results
+ resetSearchResults(hits);
+ } catch (Exception e){
+ e.printStackTrace();
+ }
+
+ //notify all listeners that the list has been changed
+ fireContentsChanged(this, 0, getSize());
+ }
+
+ /**
+ *
+ * @param hits The new result set to set this list to.
+ */
+ private void resetSearchResults(Hits hits) {
+ try {
+ //clear our index mapping this list model rows to
+ //the decorated inner list model
+ rowToModelIndex.clear();
+ //iterate through the hits
+ //get the row number stored at the index
+ //that number is the row number of the decorated
+ //tabble model row that we are mapping to
+ for (int t=0; t<hits.length(); t++){
+ Document document = hits.doc(t);
+ Fieldable field = document.getField(ROW_NUMBER);
+ rowToModelIndex.add(new Integer(field.stringValue()));
+ }
+ } catch (Exception e){
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * @return The current lucene analyzer
+ */
+ public Analyzer getAnalyzer() {
+ return analyzer;
+ }
+
+ /**
+ * @param analyzer The new analyzer to use
+ */
+ public void setAnalyzer(Analyzer analyzer) {
+ this.analyzer = analyzer;
+ //reindex from the model with the new analyzer
+ reindex();
+
+ //rerun the search if there is an active search
+ if (isSearching()){
+ search(searchString);
+ }
+ }
+
+ private boolean isSearching() {
+ return searchString != null;
+ }
+
+ private void clearSearchingState() {
+ searchString = null;
+ rowToModelIndex.clear();
+ for (int t=0; t<listModel.getSize(); t++){
+ rowToModelIndex.add(new Integer(t));
+ }
+ }
+
+ private int getModelRow(int row){
+ return ((Integer) rowToModelIndex.get(row)).intValue();
+ }
+
+ public int getSize() {
+ return (listModel == null) ? 0 : rowToModelIndex.size();
+ }
+
+ public Object getElementAt(int index) {
+ return listModel.getElementAt(getModelRow(index));
+ }
+
+
+ class ListModelHandler implements ListDataListener {
+
+ public void contentsChanged(ListDataEvent e) {
+ somethingChanged();
+ }
+
+ public void intervalAdded(ListDataEvent e) {
+ somethingChanged();
+ }
+
+ public void intervalRemoved(ListDataEvent e) {
+ somethingChanged();
+ }
+
+ private void somethingChanged(){
+ // If we're not searching, just pass the event along.
+ if (!isSearching()) {
+ clearSearchingState();
+ reindex();
+ fireContentsChanged(ListSearcher.this, 0, getSize());
+ return;
+ }
+
+ // Something has happened to the data that may have invalidated the search.
+ reindex();
+ search(searchString);
+ fireContentsChanged(ListSearcher.this, 0, getSize());
+ return;
+ }
+
+ }
+
+
+}
Propchange: lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/ListSearcher.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/TableSearcher.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/TableSearcher.java?rev=712922&r1=712921&r2=712922&view=diff
==============================================================================
--- lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/TableSearcher.java (original)
+++ lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/TableSearcher.java Mon Nov 10 18:35:46 2008
@@ -1,351 +1,351 @@
-package org.apache.lucene.swing.models;
-
-/**
- * Copyright 2005 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.analysis.WhitespaceAnalyzer;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.Fieldable;
-import org.apache.lucene.index.IndexWriter;
-import org.apache.lucene.queryParser.MultiFieldQueryParser;
-import org.apache.lucene.search.Hits;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.store.RAMDirectory;
-
-import javax.swing.event.TableModelEvent;
-import javax.swing.event.TableModelListener;
-import javax.swing.table.AbstractTableModel;
-import javax.swing.table.TableModel;
-import java.util.ArrayList;
-
-
-/**
- * This is a TableModel that encapsulates Lucene
- * search logic within a TableModel implementation.
- * It is implemented as a TableModel decorator,
- * similar to the TableSorter demo from Sun that decorates
- * a TableModel and provides sorting functionality. The benefit
- * of this architecture is that you can decorate any TableModel
- * implementation with this searching table model -- making it
- * easy to add searching functionaliy to existing JTables -- or
- * making new search capable table lucene.
- *
- * <p>This decorator works by holding a reference to a decorated ot inner
- * TableModel. All data is stored within that table model, not this
- * table model. Rather, this table model simply manages links to
- * data in the inner table model according to the search. All methods on
- * TableSearcher forward to the inner table model with subtle filtering
- * or alteration according to the search criteria.
- *
- * <p>Using the table model:
- *
- * Pass the TableModel you want to decorate in at the constructor. When
- * the TableModel initializes, it displays all search results. Call
- * the search method with any valid Lucene search String and the data
- * will be filtered by the search string. Users can always clear the search
- * at any time by searching with an empty string. Additionally, you can
- * add a button calling the clearSearch() method.
- *
- */
-public class TableSearcher extends AbstractTableModel {
-
- /**
- * The inner table model we are decorating
- */
- protected TableModel tableModel;
-
- /**
- * This listener is used to register this class as a listener to
- * the decorated table model for update events
- */
- private TableModelListener tableModelListener;
-
- /**
- * these keeps reference to the decorated table model for data
- * only rows that match the search criteria are linked
- */
- private ArrayList rowToModelIndex = new ArrayList();
-
-
- //Lucene stuff.
-
- /**
- * In memory lucene index
- */
- private RAMDirectory directory;
-
- /**
- * Cached lucene analyzer
- */
- private Analyzer analyzer;
-
- /**
- * Links between this table model and the decorated table model
- * are maintained through links based on row number. This is a
- * key constant to denote "row number" for indexing
- */
- private static final String ROW_NUMBER = "ROW_NUMBER";
-
- /**
- * Cache the current search String. Also used internally to
- * key whether there is an active search running or not. i.e. if
- * searchString is null, there is no active search.
- */
- private String searchString = null;
-
- /**
- * @param tableModel The table model to decorate
- */
- public TableSearcher(TableModel tableModel) {
- analyzer = new WhitespaceAnalyzer();
- tableModelListener = new TableModelHandler();
- setTableModel(tableModel);
- tableModel.addTableModelListener(tableModelListener);
- clearSearchingState();
- }
-
- /**
- *
- * @return The inner table model this table model is decorating
- */
- public TableModel getTableModel() {
- return tableModel;
- }
-
- /**
- * Set the table model used by this table model
- * @param tableModel The new table model to decorate
- */
- public void setTableModel(TableModel tableModel) {
-
- //remove listeners if there...
- if (this.tableModel != null) {
- this.tableModel.removeTableModelListener(tableModelListener);
- }
-
- this.tableModel = tableModel;
- if (this.tableModel != null) {
- this.tableModel.addTableModelListener(tableModelListener);
- }
-
- //recalculate the links between this table model and
- //the inner table model since the decorated model just changed
- reindex();
-
- // let all listeners know the table has changed
- fireTableStructureChanged();
- }
-
-
- /**
- * Reset the search results and links to the decorated (inner) table
- * model from this table model.
- */
- private void reindex() {
- try {
- // recreate the RAMDirectory
- directory = new RAMDirectory();
- IndexWriter writer = new IndexWriter(directory, analyzer, true);
-
- // iterate through all rows
- for (int row=0; row < tableModel.getRowCount(); row++){
-
- //for each row make a new document
- Document document = new Document();
- //add the row number of this row in the decorated table model
- //this will allow us to retrive the results later
- //and map this table model's row to a row in the decorated
- //table model
- document.add(new Field(ROW_NUMBER, "" + row, Field.Store.YES, Field.Index.ANALYZED));
- //iterate through all columns
- //index the value keyed by the column name
- //NOTE: there could be a problem with using column names with spaces
- for (int column=0; column < tableModel.getColumnCount(); column++){
- String columnName = tableModel.getColumnName(column);
- String columnValue = String.valueOf(tableModel.getValueAt(row, column)).toLowerCase();
- document.add(new Field(columnName, columnValue, Field.Store.YES, Field.Index.ANALYZED));
- }
- writer.addDocument(document);
- }
- writer.optimize();
- writer.close();
- } catch (Exception e){
- e.printStackTrace();
- }
- }
-
- /**
- * @return The current lucene analyzer
- */
- public Analyzer getAnalyzer() {
- return analyzer;
- }
-
- /**
- * @param analyzer The new analyzer to use
- */
- public void setAnalyzer(Analyzer analyzer) {
- this.analyzer = analyzer;
- //reindex from the model with the new analyzer
- reindex();
-
- //rerun the search if there is an active search
- if (isSearching()){
- search(searchString);
- }
- }
-
- /**
- * Run a new search.
- *
- * @param searchString Any valid lucene search string
- */
- public void search(String searchString){
-
- //if search string is null or empty, clear the search == search all
- if (searchString == null || searchString.equals("")){
- clearSearchingState();
- fireTableDataChanged();
- return;
- }
-
-
- try {
- //cache search String
- this.searchString = searchString;
-
- //make a new index searcher with the in memory (RAM) index.
- IndexSearcher is = new IndexSearcher(directory);
-
- //make an array of fields - one for each column
- String[] fields = new String[tableModel.getColumnCount()];
- for (int t=0; t<tableModel.getColumnCount(); t++){
- fields[t]=tableModel.getColumnName(t);
- }
-
- //build a query based on the fields, searchString and cached analyzer
- //NOTE: This is an area for improvement since the MultiFieldQueryParser
- // has some weirdness.
- MultiFieldQueryParser parser = new MultiFieldQueryParser(fields, analyzer);
- Query query = parser.parse(searchString);
- //run the search
- Hits hits = is.search(query);
- //reset this table model with the new results
- resetSearchResults(hits);
- } catch (Exception e){
- e.printStackTrace();
- }
-
- //notify all listeners that the table has been changed
- fireTableStructureChanged();
- }
-
- /**
- *
- * @param hits The new result set to set this table to.
- */
- private void resetSearchResults(Hits hits) {
- try {
- //clear our index mapping this table model rows to
- //the decorated inner table model
- rowToModelIndex.clear();
- //iterate through the hits
- //get the row number stored at the index
- //that number is the row number of the decorated
- //tabble model row that we are mapping to
- for (int t=0; t<hits.length(); t++){
- Document document = hits.doc(t);
- Fieldable field = document.getField(ROW_NUMBER);
- rowToModelIndex.add(new Integer(field.stringValue()));
- }
- } catch (Exception e){
- e.printStackTrace();
- }
- }
-
- private int getModelRow(int row){
- return ((Integer) rowToModelIndex.get(row)).intValue();
- }
-
- /**
- * Clear the currently active search
- * Resets the complete dataset of the decorated
- * table model.
- */
- private void clearSearchingState(){
- searchString = null;
- rowToModelIndex.clear();
- for (int t=0; t<tableModel.getRowCount(); t++){
- rowToModelIndex.add(new Integer(t));
- }
- }
-
- // TableModel interface methods
- public int getRowCount() {
- return (tableModel == null) ? 0 : rowToModelIndex.size();
- }
-
- public int getColumnCount() {
- return (tableModel == null) ? 0 : tableModel.getColumnCount();
- }
-
- public String getColumnName(int column) {
- return tableModel.getColumnName(column);
- }
-
- public Class getColumnClass(int column) {
- return tableModel.getColumnClass(column);
- }
-
- public boolean isCellEditable(int row, int column) {
- return tableModel.isCellEditable(getModelRow(row), column);
- }
-
- public Object getValueAt(int row, int column) {
- return tableModel.getValueAt(getModelRow(row), column);
- }
-
- public void setValueAt(Object aValue, int row, int column) {
- tableModel.setValueAt(aValue, getModelRow(row), column);
- }
-
- private boolean isSearching() {
- return searchString != null;
- }
-
- private class TableModelHandler implements TableModelListener {
- public void tableChanged(TableModelEvent e) {
- // If we're not searching, just pass the event along.
- if (!isSearching()) {
- clearSearchingState();
- reindex();
- fireTableChanged(e);
- return;
- }
-
- // Something has happened to the data that may have invalidated the search.
- reindex();
- search(searchString);
- fireTableDataChanged();
- return;
- }
-
- }
-
-}
+package org.apache.lucene.swing.models;
+
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.WhitespaceAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.Fieldable;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.queryParser.MultiFieldQueryParser;
+import org.apache.lucene.search.Hits;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.store.RAMDirectory;
+
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.TableModel;
+import java.util.ArrayList;
+
+
+/**
+ * This is a TableModel that encapsulates Lucene
+ * search logic within a TableModel implementation.
+ * It is implemented as a TableModel decorator,
+ * similar to the TableSorter demo from Sun that decorates
+ * a TableModel and provides sorting functionality. The benefit
+ * of this architecture is that you can decorate any TableModel
+ * implementation with this searching table model -- making it
+ * easy to add searching functionaliy to existing JTables -- or
+ * making new search capable table lucene.
+ *
+ * <p>This decorator works by holding a reference to a decorated ot inner
+ * TableModel. All data is stored within that table model, not this
+ * table model. Rather, this table model simply manages links to
+ * data in the inner table model according to the search. All methods on
+ * TableSearcher forward to the inner table model with subtle filtering
+ * or alteration according to the search criteria.
+ *
+ * <p>Using the table model:
+ *
+ * Pass the TableModel you want to decorate in at the constructor. When
+ * the TableModel initializes, it displays all search results. Call
+ * the search method with any valid Lucene search String and the data
+ * will be filtered by the search string. Users can always clear the search
+ * at any time by searching with an empty string. Additionally, you can
+ * add a button calling the clearSearch() method.
+ *
+ */
+public class TableSearcher extends AbstractTableModel {
+
+ /**
+ * The inner table model we are decorating
+ */
+ protected TableModel tableModel;
+
+ /**
+ * This listener is used to register this class as a listener to
+ * the decorated table model for update events
+ */
+ private TableModelListener tableModelListener;
+
+ /**
+ * these keeps reference to the decorated table model for data
+ * only rows that match the search criteria are linked
+ */
+ private ArrayList rowToModelIndex = new ArrayList();
+
+
+ //Lucene stuff.
+
+ /**
+ * In memory lucene index
+ */
+ private RAMDirectory directory;
+
+ /**
+ * Cached lucene analyzer
+ */
+ private Analyzer analyzer;
+
+ /**
+ * Links between this table model and the decorated table model
+ * are maintained through links based on row number. This is a
+ * key constant to denote "row number" for indexing
+ */
+ private static final String ROW_NUMBER = "ROW_NUMBER";
+
+ /**
+ * Cache the current search String. Also used internally to
+ * key whether there is an active search running or not. i.e. if
+ * searchString is null, there is no active search.
+ */
+ private String searchString = null;
+
+ /**
+ * @param tableModel The table model to decorate
+ */
+ public TableSearcher(TableModel tableModel) {
+ analyzer = new WhitespaceAnalyzer();
+ tableModelListener = new TableModelHandler();
+ setTableModel(tableModel);
+ tableModel.addTableModelListener(tableModelListener);
+ clearSearchingState();
+ }
+
+ /**
+ *
+ * @return The inner table model this table model is decorating
+ */
+ public TableModel getTableModel() {
+ return tableModel;
+ }
+
+ /**
+ * Set the table model used by this table model
+ * @param tableModel The new table model to decorate
+ */
+ public void setTableModel(TableModel tableModel) {
+
+ //remove listeners if there...
+ if (this.tableModel != null) {
+ this.tableModel.removeTableModelListener(tableModelListener);
+ }
+
+ this.tableModel = tableModel;
+ if (this.tableModel != null) {
+ this.tableModel.addTableModelListener(tableModelListener);
+ }
+
+ //recalculate the links between this table model and
+ //the inner table model since the decorated model just changed
+ reindex();
+
+ // let all listeners know the table has changed
+ fireTableStructureChanged();
+ }
+
+
+ /**
+ * Reset the search results and links to the decorated (inner) table
+ * model from this table model.
+ */
+ private void reindex() {
+ try {
+ // recreate the RAMDirectory
+ directory = new RAMDirectory();
+ IndexWriter writer = new IndexWriter(directory, analyzer, true);
+
+ // iterate through all rows
+ for (int row=0; row < tableModel.getRowCount(); row++){
+
+ //for each row make a new document
+ Document document = new Document();
+ //add the row number of this row in the decorated table model
+ //this will allow us to retrive the results later
+ //and map this table model's row to a row in the decorated
+ //table model
+ document.add(new Field(ROW_NUMBER, "" + row, Field.Store.YES, Field.Index.ANALYZED));
+ //iterate through all columns
+ //index the value keyed by the column name
+ //NOTE: there could be a problem with using column names with spaces
+ for (int column=0; column < tableModel.getColumnCount(); column++){
+ String columnName = tableModel.getColumnName(column);
+ String columnValue = String.valueOf(tableModel.getValueAt(row, column)).toLowerCase();
+ document.add(new Field(columnName, columnValue, Field.Store.YES, Field.Index.ANALYZED));
+ }
+ writer.addDocument(document);
+ }
+ writer.optimize();
+ writer.close();
+ } catch (Exception e){
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * @return The current lucene analyzer
+ */
+ public Analyzer getAnalyzer() {
+ return analyzer;
+ }
+
+ /**
+ * @param analyzer The new analyzer to use
+ */
+ public void setAnalyzer(Analyzer analyzer) {
+ this.analyzer = analyzer;
+ //reindex from the model with the new analyzer
+ reindex();
+
+ //rerun the search if there is an active search
+ if (isSearching()){
+ search(searchString);
+ }
+ }
+
+ /**
+ * Run a new search.
+ *
+ * @param searchString Any valid lucene search string
+ */
+ public void search(String searchString){
+
+ //if search string is null or empty, clear the search == search all
+ if (searchString == null || searchString.equals("")){
+ clearSearchingState();
+ fireTableDataChanged();
+ return;
+ }
+
+
+ try {
+ //cache search String
+ this.searchString = searchString;
+
+ //make a new index searcher with the in memory (RAM) index.
+ IndexSearcher is = new IndexSearcher(directory);
+
+ //make an array of fields - one for each column
+ String[] fields = new String[tableModel.getColumnCount()];
+ for (int t=0; t<tableModel.getColumnCount(); t++){
+ fields[t]=tableModel.getColumnName(t);
+ }
+
+ //build a query based on the fields, searchString and cached analyzer
+ //NOTE: This is an area for improvement since the MultiFieldQueryParser
+ // has some weirdness.
+ MultiFieldQueryParser parser = new MultiFieldQueryParser(fields, analyzer);
+ Query query = parser.parse(searchString);
+ //run the search
+ Hits hits = is.search(query);
+ //reset this table model with the new results
+ resetSearchResults(hits);
+ } catch (Exception e){
+ e.printStackTrace();
+ }
+
+ //notify all listeners that the table has been changed
+ fireTableStructureChanged();
+ }
+
+ /**
+ *
+ * @param hits The new result set to set this table to.
+ */
+ private void resetSearchResults(Hits hits) {
+ try {
+ //clear our index mapping this table model rows to
+ //the decorated inner table model
+ rowToModelIndex.clear();
+ //iterate through the hits
+ //get the row number stored at the index
+ //that number is the row number of the decorated
+ //tabble model row that we are mapping to
+ for (int t=0; t<hits.length(); t++){
+ Document document = hits.doc(t);
+ Fieldable field = document.getField(ROW_NUMBER);
+ rowToModelIndex.add(new Integer(field.stringValue()));
+ }
+ } catch (Exception e){
+ e.printStackTrace();
+ }
+ }
+
+ private int getModelRow(int row){
+ return ((Integer) rowToModelIndex.get(row)).intValue();
+ }
+
+ /**
+ * Clear the currently active search
+ * Resets the complete dataset of the decorated
+ * table model.
+ */
+ private void clearSearchingState(){
+ searchString = null;
+ rowToModelIndex.clear();
+ for (int t=0; t<tableModel.getRowCount(); t++){
+ rowToModelIndex.add(new Integer(t));
+ }
+ }
+
+ // TableModel interface methods
+ public int getRowCount() {
+ return (tableModel == null) ? 0 : rowToModelIndex.size();
+ }
+
+ public int getColumnCount() {
+ return (tableModel == null) ? 0 : tableModel.getColumnCount();
+ }
+
+ public String getColumnName(int column) {
+ return tableModel.getColumnName(column);
+ }
+
+ public Class getColumnClass(int column) {
+ return tableModel.getColumnClass(column);
+ }
+
+ public boolean isCellEditable(int row, int column) {
+ return tableModel.isCellEditable(getModelRow(row), column);
+ }
+
+ public Object getValueAt(int row, int column) {
+ return tableModel.getValueAt(getModelRow(row), column);
+ }
+
+ public void setValueAt(Object aValue, int row, int column) {
+ tableModel.setValueAt(aValue, getModelRow(row), column);
+ }
+
+ private boolean isSearching() {
+ return searchString != null;
+ }
+
+ private class TableModelHandler implements TableModelListener {
+ public void tableChanged(TableModelEvent e) {
+ // If we're not searching, just pass the event along.
+ if (!isSearching()) {
+ clearSearchingState();
+ reindex();
+ fireTableChanged(e);
+ return;
+ }
+
+ // Something has happened to the data that may have invalidated the search.
+ reindex();
+ search(searchString);
+ fireTableDataChanged();
+ return;
+ }
+
+ }
+
+}
Propchange: lucene/java/trunk/contrib/swing/src/java/org/apache/lucene/swing/models/TableSearcher.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/BaseListModel.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/BaseListModel.java?rev=712922&r1=712921&r2=712922&view=diff
==============================================================================
--- lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/BaseListModel.java (original)
+++ lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/BaseListModel.java Mon Nov 10 18:35:46 2008
@@ -1,55 +1,55 @@
-package org.apache.lucene.swing.models;
-
-/**
- * Copyright 2005 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.swing.AbstractListModel;
-
-
-public class BaseListModel extends AbstractListModel {
- private List data = new ArrayList();
-
- public BaseListModel(Iterator iterator) {
- while (iterator.hasNext()) {
- data.add(iterator.next());
- }
- }
-
- public int getSize() {
- return data.size();
- }
-
- public Object getElementAt(int index) {
- return data.get(index);
- }
-
- public void addRow(Object toAdd) {
- data.add(toAdd);
- fireContentsChanged(this, 0, getSize());
- }
-
- public void removeRow(Object toRemove) {
- data.remove(toRemove);
- fireContentsChanged(this, 0, getSize());
- }
-
-
-
-}
+package org.apache.lucene.swing.models;
+
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.swing.AbstractListModel;
+
+
+public class BaseListModel extends AbstractListModel {
+ private List data = new ArrayList();
+
+ public BaseListModel(Iterator iterator) {
+ while (iterator.hasNext()) {
+ data.add(iterator.next());
+ }
+ }
+
+ public int getSize() {
+ return data.size();
+ }
+
+ public Object getElementAt(int index) {
+ return data.get(index);
+ }
+
+ public void addRow(Object toAdd) {
+ data.add(toAdd);
+ fireContentsChanged(this, 0, getSize());
+ }
+
+ public void removeRow(Object toRemove) {
+ data.remove(toRemove);
+ fireContentsChanged(this, 0, getSize());
+ }
+
+
+
+}
Propchange: lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/BaseListModel.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/BaseTableModel.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/BaseTableModel.java?rev=712922&r1=712921&r2=712922&view=diff
==============================================================================
--- lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/BaseTableModel.java (original)
+++ lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/BaseTableModel.java Mon Nov 10 18:35:46 2008
@@ -1,100 +1,100 @@
-package org.apache.lucene.swing.models;
-
-/**
- * Copyright 2005 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.swing.table.AbstractTableModel;
-
-
-public class BaseTableModel extends AbstractTableModel {
- private List columnNames = new ArrayList();
- private List rows = new ArrayList();
-
- public BaseTableModel(Iterator data) {
- columnNames.add("Name");
- columnNames.add("Type");
- columnNames.add("Phone");
- columnNames.add("Street");
- columnNames.add("City");
- columnNames.add("State");
- columnNames.add("Zip");
-
- while (data.hasNext()) {
- Object nextRow = (Object) data.next();
- rows.add(nextRow);
- }
- }
-
- public int getColumnCount() {
- return columnNames.size();
- }
-
- public int getRowCount() {
- return rows.size();
- }
-
- public void addRow(RestaurantInfo info){
- rows.add(info);
- fireTableDataChanged();
- }
-
- public void removeRow(RestaurantInfo info){
- rows.remove(info);
- fireTableDataChanged();
- }
-
- public boolean isCellEditable(int rowIndex, int columnIndex) {
- return false;
- }
-
- public Class getColumnClass(int columnIndex) {
- return String.class;
- }
-
- public Object getValueAt(int rowIndex, int columnIndex) {
- RestaurantInfo restaurantInfo = (RestaurantInfo) rows.get(rowIndex);
- if (columnIndex == 0){ // name
- return restaurantInfo.getName();
- } else if (columnIndex == 1){ // category
- return restaurantInfo.getType();
- } else if (columnIndex == 2){ // phone
- return restaurantInfo.getPhone();
- } else if (columnIndex == 3){ // street
- return restaurantInfo.getStreet();
- } else if (columnIndex == 4){ // city
- return restaurantInfo.getCity();
- } else if (columnIndex == 5){ // state
- return restaurantInfo.getState();
- } else if (columnIndex == 6){ // zip
- return restaurantInfo.getZip();
- } else {
- return "";
- }
- }
-
- public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
- //no op
- }
-
- public String getColumnName(int columnIndex) {
- return columnNames.get(columnIndex).toString();
- }
-
-}
+package org.apache.lucene.swing.models;
+
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.swing.table.AbstractTableModel;
+
+
+public class BaseTableModel extends AbstractTableModel {
+ private List columnNames = new ArrayList();
+ private List rows = new ArrayList();
+
+ public BaseTableModel(Iterator data) {
+ columnNames.add("Name");
+ columnNames.add("Type");
+ columnNames.add("Phone");
+ columnNames.add("Street");
+ columnNames.add("City");
+ columnNames.add("State");
+ columnNames.add("Zip");
+
+ while (data.hasNext()) {
+ Object nextRow = (Object) data.next();
+ rows.add(nextRow);
+ }
+ }
+
+ public int getColumnCount() {
+ return columnNames.size();
+ }
+
+ public int getRowCount() {
+ return rows.size();
+ }
+
+ public void addRow(RestaurantInfo info){
+ rows.add(info);
+ fireTableDataChanged();
+ }
+
+ public void removeRow(RestaurantInfo info){
+ rows.remove(info);
+ fireTableDataChanged();
+ }
+
+ public boolean isCellEditable(int rowIndex, int columnIndex) {
+ return false;
+ }
+
+ public Class getColumnClass(int columnIndex) {
+ return String.class;
+ }
+
+ public Object getValueAt(int rowIndex, int columnIndex) {
+ RestaurantInfo restaurantInfo = (RestaurantInfo) rows.get(rowIndex);
+ if (columnIndex == 0){ // name
+ return restaurantInfo.getName();
+ } else if (columnIndex == 1){ // category
+ return restaurantInfo.getType();
+ } else if (columnIndex == 2){ // phone
+ return restaurantInfo.getPhone();
+ } else if (columnIndex == 3){ // street
+ return restaurantInfo.getStreet();
+ } else if (columnIndex == 4){ // city
+ return restaurantInfo.getCity();
+ } else if (columnIndex == 5){ // state
+ return restaurantInfo.getState();
+ } else if (columnIndex == 6){ // zip
+ return restaurantInfo.getZip();
+ } else {
+ return "";
+ }
+ }
+
+ public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+ //no op
+ }
+
+ public String getColumnName(int columnIndex) {
+ return columnNames.get(columnIndex).toString();
+ }
+
+}
Propchange: lucene/java/trunk/contrib/swing/src/test/org/apache/lucene/swing/models/BaseTableModel.java
------------------------------------------------------------------------------
svn:eol-style = native