From 28eb95821f4ee980d31f6fce0488b855397159ba Mon Sep 17 00:00:00 2001 From: Doug Cutting Date: Wed, 17 Jul 2002 21:54:38 +0000 Subject: [PATCH] Added support for remote searching via RMI. git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@149814 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 5 + .../org/apache/lucene/document/Document.java | 4 +- .../org/apache/lucene/document/Field.java | 2 +- src/java/org/apache/lucene/search/Filter.java | 2 +- .../lucene/search/RemoteSearchableImpl.java | 120 ++++++++++++++++++ .../org/apache/lucene/search/ScoreDoc.java | 2 +- .../org/apache/lucene/search/Searchable.java | 15 +-- .../org/apache/lucene/search/TopDocs.java | 2 +- .../lucene/search/TestRemoteSearchable.java | 116 +++++++++++++++++ 9 files changed, 254 insertions(+), 14 deletions(-) create mode 100644 src/java/org/apache/lucene/search/RemoteSearchableImpl.java create mode 100644 src/test/org/apache/lucene/search/TestRemoteSearchable.java diff --git a/build.xml b/build.xml index e2135df059e..e77fd25fc22 100644 --- a/build.xml +++ b/build.xml @@ -111,6 +111,11 @@ debug="${debug}"> + + + + diff --git a/src/java/org/apache/lucene/document/Document.java b/src/java/org/apache/lucene/document/Document.java index dc908fe2e27..1f4f5095029 100644 --- a/src/java/org/apache/lucene/document/Document.java +++ b/src/java/org/apache/lucene/document/Document.java @@ -64,7 +64,7 @@ import java.util.Enumeration; * stored fields which uniquely identify it. * */ -public final class Document { +public final class Document implements java.io.Serializable { DocumentFieldList fieldList = null; /** Constructs a new document with no fields. */ @@ -118,7 +118,7 @@ public final class Document { } -final class DocumentFieldList { +final class DocumentFieldList implements java.io.Serializable { DocumentFieldList(Field f, DocumentFieldList n) { field = f; next = n; diff --git a/src/java/org/apache/lucene/document/Field.java b/src/java/org/apache/lucene/document/Field.java index 99535f8a3a6..ebb8f9d1dfb 100644 --- a/src/java/org/apache/lucene/document/Field.java +++ b/src/java/org/apache/lucene/document/Field.java @@ -65,7 +65,7 @@ import java.util.Date; index, so that they may be returned with hits on the document. */ -public final class Field { +public final class Field implements java.io.Serializable { private String name = "body"; private String stringValue = null; private Reader readerValue = null; diff --git a/src/java/org/apache/lucene/search/Filter.java b/src/java/org/apache/lucene/search/Filter.java index 2881ecaef2f..b0ee7340dd1 100644 --- a/src/java/org/apache/lucene/search/Filter.java +++ b/src/java/org/apache/lucene/search/Filter.java @@ -60,7 +60,7 @@ import org.apache.lucene.index.IndexReader; /** Abstract base class providing a mechanism to restrict searches to a subset of an index. */ -abstract public class Filter { +abstract public class Filter implements java.io.Serializable { /** Returns a BitSet with true for documents which should be permitted in search results, and false for those that should not. */ abstract public BitSet bits(IndexReader reader) throws IOException; diff --git a/src/java/org/apache/lucene/search/RemoteSearchableImpl.java b/src/java/org/apache/lucene/search/RemoteSearchableImpl.java new file mode 100644 index 00000000000..e6095797604 --- /dev/null +++ b/src/java/org/apache/lucene/search/RemoteSearchableImpl.java @@ -0,0 +1,120 @@ +package org.apache.lucene.search; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache Lucene" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache Lucene", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.IOException; +import org.apache.lucene.document.Document; +import org.apache.lucene.index.Term; +import org.apache.lucene.index.IndexReader; + +import java.rmi.Naming; +import java.rmi.RemoteException; +import java.rmi.RMISecurityManager; +import java.rmi.server.UnicastRemoteObject; + +/** A remote searchable implementation. */ +public class RemoteSearchableImpl + extends UnicastRemoteObject + implements Searchable { + + private Searchable local; + + /** Constructs and exports a remote searcher. */ + public RemoteSearchableImpl(Searchable local) throws RemoteException { + super(); + this.local = local; + } + + public void search(Query query, Filter filter, HitCollector results) + throws IOException { + local.search(query, filter, results); + } + + public void close() throws IOException { + local.close(); + } + + public int docFreq(Term term) throws IOException { + return local.docFreq(term); + } + + public int maxDoc() throws IOException { + return local.maxDoc(); + } + + public TopDocs search(Query query, Filter filter, int n) throws IOException { + return local.search(query, filter, n); + } + + public Document doc(int i) throws IOException { + return local.doc(i); + } + + /** Exports a searcher for the index in args[0] named + * "//localhost/Searchable". */ + public static void main(String args[]) throws Exception { + // create and install a security manager + if (System.getSecurityManager() == null) { + System.setSecurityManager(new RMISecurityManager()); + } + + Searchable local = new IndexSearcher(args[0]); + RemoteSearchableImpl impl = new RemoteSearchableImpl(local); + + // bind the implementation to "Searchable" + Naming.rebind("//localhost/Searchable", impl); + } + +} diff --git a/src/java/org/apache/lucene/search/ScoreDoc.java b/src/java/org/apache/lucene/search/ScoreDoc.java index a3087998f2f..3b6747f0499 100644 --- a/src/java/org/apache/lucene/search/ScoreDoc.java +++ b/src/java/org/apache/lucene/search/ScoreDoc.java @@ -56,7 +56,7 @@ package org.apache.lucene.search; /** Expert: Returned by low-level search implementations. * @see TopDocs */ -public class ScoreDoc { +public class ScoreDoc implements java.io.Serializable { /** Expert: The score of this document for the query. */ public float score; diff --git a/src/java/org/apache/lucene/search/Searchable.java b/src/java/org/apache/lucene/search/Searchable.java index 442cdffbe5f..2a732644267 100644 --- a/src/java/org/apache/lucene/search/Searchable.java +++ b/src/java/org/apache/lucene/search/Searchable.java @@ -60,7 +60,7 @@ import org.apache.lucene.index.Term; import org.apache.lucene.index.IndexReader; /** The interface for search implementations. */ -public interface Searchable { +public interface Searchable extends java.rmi.Remote { /** Lower-level search API. * *

{@link HitCollector#collect(int,float)} is called for every non-zero @@ -75,23 +75,23 @@ public interface Searchable { * @param filter if non-null, a bitset used to eliminate some documents * @param results to receive hits */ - public abstract void search(Query query, Filter filter, HitCollector results) + void search(Query query, Filter filter, HitCollector results) throws IOException; /** Frees resources associated with this Searcher. */ - public abstract void close() throws IOException; + void close() throws IOException; /** Expert: Returns the number of documents containing term. * Called by search code to compute term weights. * @see IndexReader#docFreq(Term). */ - public abstract int docFreq(Term term) throws IOException; + int docFreq(Term term) throws IOException; /** Expert: Returns one greater than the largest possible document number. * Called by search code to compute term weights. * @see IndexReader#maxDoc(). */ - public abstract int maxDoc() throws IOException; + int maxDoc() throws IOException; /** Expert: Low-level search implementation. Finds the top n * hits for query, applying filter if non-null. @@ -101,12 +101,11 @@ public interface Searchable { *

Applications should usually call {@link Searcher#search(Query)} or * {@link Searcher#search(Query,Filter)} instead. */ - public abstract TopDocs search(Query query, Filter filter, int n) - throws IOException; + TopDocs search(Query query, Filter filter, int n) throws IOException; /** Expert: Returns the stored fields of document i. * Called by {@link HitCollector} implementations. * @see IndexReader#document(int). */ - public abstract Document doc(int i) throws IOException; + Document doc(int i) throws IOException; } diff --git a/src/java/org/apache/lucene/search/TopDocs.java b/src/java/org/apache/lucene/search/TopDocs.java index 9cf732666cd..336d698a6fc 100644 --- a/src/java/org/apache/lucene/search/TopDocs.java +++ b/src/java/org/apache/lucene/search/TopDocs.java @@ -56,7 +56,7 @@ package org.apache.lucene.search; /** Expert: Returned by low-level search implementations. * @see Searcher#search(Query,Filter,int) */ -public class TopDocs { +public class TopDocs implements java.io.Serializable { /** Expert: The total number of hits for the query. * @see Hits#length() */ diff --git a/src/test/org/apache/lucene/search/TestRemoteSearchable.java b/src/test/org/apache/lucene/search/TestRemoteSearchable.java new file mode 100644 index 00000000000..9a302e7e170 --- /dev/null +++ b/src/test/org/apache/lucene/search/TestRemoteSearchable.java @@ -0,0 +1,116 @@ +package org.apache.lucene.search; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache Lucene" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache Lucene", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.rmi.Naming; +import java.rmi.RemoteException; +import java.rmi.registry.LocateRegistry; + +import junit.framework.TestCase; + +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.MultiSearcher; +import org.apache.lucene.index.Term; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.store.RAMDirectory; +import org.apache.lucene.analysis.SimpleAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; + +public class TestRemoteSearchable extends TestCase { + public TestRemoteSearchable(String name) { + super(name); + } + + public static void startServer() throws Exception { + // construct an index + RAMDirectory indexStore = new RAMDirectory(); + IndexWriter writer = new IndexWriter(indexStore,new SimpleAnalyzer(),true); + Document doc = new Document(); + doc.add(Field.Text("test", "test")); + writer.addDocument(doc); + writer.optimize(); + writer.close(); + + // publish it + LocateRegistry.createRegistry(1099); + Searchable local = new IndexSearcher(indexStore); + RemoteSearchableImpl impl = new RemoteSearchableImpl(local); + Naming.rebind("//localhost/Searchable", impl); + } + + public static void search() throws Exception { + // try to search the published index + Searchable remote = (Searchable)Naming.lookup("//localhost/Searchable"); + Searchable[] searchables = {remote}; + Searcher searcher = new MultiSearcher(searchables); + Query query = new TermQuery(new Term("test", "test")); + Hits result = searcher.search(query); + + assertEquals(1, result.length()); + assertEquals("test", result.doc(0).get("test")); + } + + public void testRemoteSearch() throws Exception { + startServer(); + search(); + } + + public static void main(String[] args) throws Exception { + startServer(); + search(); + System.exit(0); + } +}