mirror of https://github.com/apache/lucene.git
LUCENE-2981: review/remove unused/unsupported contribs
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1126280 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
49fe358760
commit
d1219a5769
16
build.xml
16
build.xml
|
@ -77,14 +77,6 @@
|
||||||
<mkdir dir=".settings"/>
|
<mkdir dir=".settings"/>
|
||||||
<copy file="dev-tools/eclipse/resources.prefs"
|
<copy file="dev-tools/eclipse/resources.prefs"
|
||||||
tofile=".settings/org.eclipse.core.resources.prefs" overwrite="true"/>
|
tofile=".settings/org.eclipse.core.resources.prefs" overwrite="true"/>
|
||||||
<echo>Running Lucene contrib db/bdb-je task 'get-je-jar' ...</echo>
|
|
||||||
<subant target="get-je-jar">
|
|
||||||
<fileset dir="lucene/contrib/db/bdb-je" includes="build.xml" />
|
|
||||||
</subant>
|
|
||||||
<echo>Running Lucene contrib db/bdb task 'get-db-jar' ...</echo>
|
|
||||||
<subant target="get-db-jar">
|
|
||||||
<fileset dir="lucene/contrib/db/bdb" includes="build.xml" />
|
|
||||||
</subant>
|
|
||||||
<echo>
|
<echo>
|
||||||
SUCCESS: You must right-click your project and choose Refresh
|
SUCCESS: You must right-click your project and choose Refresh
|
||||||
Please note, your project must use a Java 6 JRE
|
Please note, your project must use a Java 6 JRE
|
||||||
|
@ -95,14 +87,6 @@
|
||||||
<copy todir=".">
|
<copy todir=".">
|
||||||
<fileset dir="dev-tools/idea"/>
|
<fileset dir="dev-tools/idea"/>
|
||||||
</copy>
|
</copy>
|
||||||
<echo>Running Lucene contrib db/bdb-je task 'get-je-jar' ...</echo>
|
|
||||||
<subant target="get-je-jar">
|
|
||||||
<fileset dir="lucene/contrib/db/bdb-je" includes="build.xml" />
|
|
||||||
</subant>
|
|
||||||
<echo>Running Lucene contrib db/bdb task 'get-db-jar' ...</echo>
|
|
||||||
<subant target="get-db-jar">
|
|
||||||
<fileset dir="lucene/contrib/db/bdb" includes="build.xml" />
|
|
||||||
</subant>
|
|
||||||
<echo>
|
<echo>
|
||||||
To complete IntelliJ IDEA setup, you must manually configure
|
To complete IntelliJ IDEA setup, you must manually configure
|
||||||
Project Structure | Project | Project SDK.
|
Project Structure | Project | Project SDK.
|
||||||
|
|
|
@ -3,21 +3,12 @@
|
||||||
<classpathentry kind="src" path="lucene/src/java"/>
|
<classpathentry kind="src" path="lucene/src/java"/>
|
||||||
<classpathentry kind="src" path="lucene/src/test-framework"/>
|
<classpathentry kind="src" path="lucene/src/test-framework"/>
|
||||||
<classpathentry kind="src" path="lucene/src/test"/>
|
<classpathentry kind="src" path="lucene/src/test"/>
|
||||||
<classpathentry kind="src" path="lucene/contrib/ant/src/java"/>
|
|
||||||
<classpathentry kind="src" path="lucene/contrib/ant/src/resources"/>
|
|
||||||
<classpathentry kind="src" path="lucene/contrib/ant/src/test"/>
|
|
||||||
<classpathentry kind="src" path="lucene/contrib/db/bdb/src/java"/>
|
|
||||||
<classpathentry kind="src" path="lucene/contrib/db/bdb/src/test"/>
|
|
||||||
<classpathentry kind="src" path="lucene/contrib/db/bdb-je/src/java"/>
|
|
||||||
<classpathentry kind="src" path="lucene/contrib/db/bdb-je/src/test"/>
|
|
||||||
<classpathentry kind="src" path="lucene/contrib/demo/src/java"/>
|
<classpathentry kind="src" path="lucene/contrib/demo/src/java"/>
|
||||||
<classpathentry kind="src" path="lucene/contrib/demo/src/test"/>
|
<classpathentry kind="src" path="lucene/contrib/demo/src/test"/>
|
||||||
<classpathentry kind="src" path="lucene/contrib/highlighter/src/java"/>
|
<classpathentry kind="src" path="lucene/contrib/highlighter/src/java"/>
|
||||||
<classpathentry kind="src" path="lucene/contrib/highlighter/src/test"/>
|
<classpathentry kind="src" path="lucene/contrib/highlighter/src/test"/>
|
||||||
<classpathentry kind="src" path="lucene/contrib/instantiated/src/java"/>
|
<classpathentry kind="src" path="lucene/contrib/instantiated/src/java"/>
|
||||||
<classpathentry kind="src" path="lucene/contrib/instantiated/src/test"/>
|
<classpathentry kind="src" path="lucene/contrib/instantiated/src/test"/>
|
||||||
<classpathentry kind="src" path="lucene/contrib/lucli/src/java"/>
|
|
||||||
<classpathentry kind="src" path="lucene/contrib/lucli/src/test"/>
|
|
||||||
<classpathentry kind="src" path="lucene/contrib/memory/src/java"/>
|
<classpathentry kind="src" path="lucene/contrib/memory/src/java"/>
|
||||||
<classpathentry kind="src" path="lucene/contrib/memory/src/test"/>
|
<classpathentry kind="src" path="lucene/contrib/memory/src/test"/>
|
||||||
<classpathentry kind="src" path="lucene/contrib/misc/src/java"/>
|
<classpathentry kind="src" path="lucene/contrib/misc/src/java"/>
|
||||||
|
@ -31,8 +22,6 @@
|
||||||
<classpathentry kind="src" path="lucene/contrib/spatial/src/test"/>
|
<classpathentry kind="src" path="lucene/contrib/spatial/src/test"/>
|
||||||
<classpathentry kind="src" path="lucene/contrib/spellchecker/src/java"/>
|
<classpathentry kind="src" path="lucene/contrib/spellchecker/src/java"/>
|
||||||
<classpathentry kind="src" path="lucene/contrib/spellchecker/src/test"/>
|
<classpathentry kind="src" path="lucene/contrib/spellchecker/src/test"/>
|
||||||
<classpathentry kind="src" path="lucene/contrib/swing/src/java"/>
|
|
||||||
<classpathentry kind="src" path="lucene/contrib/swing/src/test"/>
|
|
||||||
<classpathentry kind="src" path="lucene/contrib/wordnet/src/java"/>
|
<classpathentry kind="src" path="lucene/contrib/wordnet/src/java"/>
|
||||||
<classpathentry kind="src" path="lucene/contrib/wordnet/src/test"/>
|
<classpathentry kind="src" path="lucene/contrib/wordnet/src/test"/>
|
||||||
<classpathentry kind="src" path="lucene/contrib/xml-query-parser/src/java"/>
|
<classpathentry kind="src" path="lucene/contrib/xml-query-parser/src/java"/>
|
||||||
|
@ -84,10 +73,6 @@
|
||||||
<classpathentry kind="lib" path="lucene/lib/ant-1.7.1.jar"/>
|
<classpathentry kind="lib" path="lucene/lib/ant-1.7.1.jar"/>
|
||||||
<classpathentry kind="lib" path="lucene/lib/ant-junit-1.7.1.jar"/>
|
<classpathentry kind="lib" path="lucene/lib/ant-junit-1.7.1.jar"/>
|
||||||
<classpathentry kind="lib" path="lucene/lib/junit-4.7.jar"/>
|
<classpathentry kind="lib" path="lucene/lib/junit-4.7.jar"/>
|
||||||
<classpathentry kind="lib" path="lucene/contrib/ant/lib/jtidy-r938.jar"/>
|
|
||||||
<classpathentry kind="lib" path="lucene/contrib/db/bdb/lib/db-4.7.25.jar"/>
|
|
||||||
<classpathentry kind="lib" path="lucene/contrib/db/bdb-je/lib/je-3.3.93.jar"/>
|
|
||||||
<classpathentry kind="lib" path="lucene/contrib/lucli/lib/jline.jar"/>
|
|
||||||
<classpathentry kind="lib" path="lucene/contrib/queries/lib/jakarta-regexp-1.4.jar"/>
|
<classpathentry kind="lib" path="lucene/contrib/queries/lib/jakarta-regexp-1.4.jar"/>
|
||||||
<classpathentry kind="lib" path="modules/analysis/icu/lib/icu4j-4_6.jar"/>
|
<classpathentry kind="lib" path="modules/analysis/icu/lib/icu4j-4_6.jar"/>
|
||||||
<classpathentry kind="lib" path="modules/analysis/phonetic/lib/commons-codec-1.4.jar"/>
|
<classpathentry kind="lib" path="modules/analysis/phonetic/lib/commons-codec-1.4.jar"/>
|
||||||
|
|
|
@ -220,19 +220,14 @@
|
||||||
<!-- make sure the group list below is updated. -->
|
<!-- make sure the group list below is updated. -->
|
||||||
<!-- Also remember to keep site.xml in sync. -->
|
<!-- Also remember to keep site.xml in sync. -->
|
||||||
|
|
||||||
<packageset dir="contrib/ant/src/java"/>
|
|
||||||
<packageset dir="contrib/db/bdb-je/src/java"/>
|
|
||||||
<packageset dir="contrib/db/bdb/src/java"/>
|
|
||||||
<packageset dir="contrib/demo/src/java"/>
|
<packageset dir="contrib/demo/src/java"/>
|
||||||
<packageset dir="contrib/highlighter/src/java"/>
|
<packageset dir="contrib/highlighter/src/java"/>
|
||||||
<packageset dir="contrib/instantiated/src/java"/>
|
<packageset dir="contrib/instantiated/src/java"/>
|
||||||
<packageset dir="contrib/lucli/src/java"/>
|
|
||||||
<packageset dir="contrib/memory/src/java"/>
|
<packageset dir="contrib/memory/src/java"/>
|
||||||
<packageset dir="contrib/misc/src/java"/>
|
<packageset dir="contrib/misc/src/java"/>
|
||||||
<packageset dir="contrib/queries/src/java"/>
|
<packageset dir="contrib/queries/src/java"/>
|
||||||
<packageset dir="contrib/spatial/src/java"/>
|
<packageset dir="contrib/spatial/src/java"/>
|
||||||
<packageset dir="contrib/spellchecker/src/java"/>
|
<packageset dir="contrib/spellchecker/src/java"/>
|
||||||
<packageset dir="contrib/swing/src/java"/>
|
|
||||||
<packageset dir="contrib/wordnet/src/java"/>
|
<packageset dir="contrib/wordnet/src/java"/>
|
||||||
<packageset dir="contrib/xml-query-parser/src/java"/>
|
<packageset dir="contrib/xml-query-parser/src/java"/>
|
||||||
<packageset dir="contrib/queryparser/src/java"/>
|
<packageset dir="contrib/queryparser/src/java"/>
|
||||||
|
@ -244,20 +239,16 @@
|
||||||
|
|
||||||
<group title="Core" packages="org.apache.*:org.apache.lucene.analysis:org.apache.lucene.analysis.standard*:org.apache.lucene.analysis.tokenattributes*"/>
|
<group title="Core" packages="org.apache.*:org.apache.lucene.analysis:org.apache.lucene.analysis.standard*:org.apache.lucene.analysis.tokenattributes*"/>
|
||||||
|
|
||||||
<group title="contrib: Ant" packages="org.apache.lucene.ant*"/>
|
|
||||||
<group title="contrib: Demo" packages="org.apache.lucene.demo*"/>
|
<group title="contrib: Demo" packages="org.apache.lucene.demo*"/>
|
||||||
<group title="contrib: ICU" packages="org.apache.lucene.collation*"/>
|
<group title="contrib: ICU" packages="org.apache.lucene.collation*"/>
|
||||||
<group title="contrib: DB" packages="org.apache.lucene.store.db*:org.apache.lucene.store.je*:com.sleepycat*"/>
|
|
||||||
<group title="contrib: Highlighter" packages="org.apache.lucene.search.highlight*:org.apache.lucene.search.vectorhighlight*"/>
|
<group title="contrib: Highlighter" packages="org.apache.lucene.search.highlight*:org.apache.lucene.search.vectorhighlight*"/>
|
||||||
<group title="contrib: Instantiated" packages="org.apache.lucene.store.instantiated*"/>
|
<group title="contrib: Instantiated" packages="org.apache.lucene.store.instantiated*"/>
|
||||||
<group title="contrib: Lucli" packages="lucli*"/>
|
|
||||||
<group title="contrib: Memory" packages="org.apache.lucene.index.memory*"/>
|
<group title="contrib: Memory" packages="org.apache.lucene.index.memory*"/>
|
||||||
<group title="contrib: Misc " packages="org.apache.lucene.misc*"/>
|
<group title="contrib: Misc " packages="org.apache.lucene.misc*"/>
|
||||||
<group title="contrib: Queries" packages="org.apache.lucene.search.similar*:org.apache.lucene.search.regex*:org.apache.regexp*"/>
|
<group title="contrib: Queries" packages="org.apache.lucene.search.similar*:org.apache.lucene.search.regex*:org.apache.regexp*"/>
|
||||||
<group title="contrib: Query Parser" packages="org.apache.lucene.queryParser.*"/>
|
<group title="contrib: Query Parser" packages="org.apache.lucene.queryParser.*"/>
|
||||||
<group title="contrib: Spatial" packages="org.apache.lucene.spatial*"/>
|
<group title="contrib: Spatial" packages="org.apache.lucene.spatial*"/>
|
||||||
<group title="contrib: SpellChecker" packages="org.apache.lucene.search.spell*"/>
|
<group title="contrib: SpellChecker" packages="org.apache.lucene.search.spell*"/>
|
||||||
<group title="contrib: Swing" packages="org.apache.lucene.swing*"/>
|
|
||||||
<group title="contrib: WordNet" packages="org.apache.lucene.wordnet*"/>
|
<group title="contrib: WordNet" packages="org.apache.lucene.wordnet*"/>
|
||||||
<group title="contrib: XML Query Parser" packages="org.apache.lucene.xmlparser*"/>
|
<group title="contrib: XML Query Parser" packages="org.apache.lucene.xmlparser*"/>
|
||||||
|
|
||||||
|
|
|
@ -849,15 +849,6 @@
|
||||||
<arg value="-c" />
|
<arg value="-c" />
|
||||||
<arg value="${basedir}/lib" />
|
<arg value="${basedir}/lib" />
|
||||||
<arg value="-c" />
|
<arg value="-c" />
|
||||||
<arg value="${basedir}/contrib/ant/lib" />
|
|
||||||
<!-- BDB libs are downloaded, don't check them -->
|
|
||||||
<!--<arg value="-c" />
|
|
||||||
<arg value="${toplevel.dir}/lucene/contrib/db/bdb/lib" />
|
|
||||||
<arg value="-c" />
|
|
||||||
<arg value="${toplevel.dir}/lucene/contrib/db/bdb-je/lib" />-->
|
|
||||||
<arg value="-c" />
|
|
||||||
<arg value="${basedir}/contrib/lucli/lib" />
|
|
||||||
<arg value="-c" />
|
|
||||||
<arg value="${basedir}/contrib/queries/lib" />
|
<arg value="${basedir}/contrib/queries/lib" />
|
||||||
</java>
|
</java>
|
||||||
</target>
|
</target>
|
||||||
|
|
|
@ -50,6 +50,10 @@ Bug Fixes
|
||||||
|
|
||||||
======================= Lucene 3.x (not yet released) =======================
|
======================= Lucene 3.x (not yet released) =======================
|
||||||
|
|
||||||
|
Changes in backwards compatibility policy
|
||||||
|
|
||||||
|
* LUCENE-2981: Removed the following contribs: ant, db, lucli, swing. (Robert Muir)
|
||||||
|
|
||||||
Changes in runtime behavior
|
Changes in runtime behavior
|
||||||
|
|
||||||
* LUCENE-3086: ItalianAnalyzer now uses ElisionFilter with a set of Italian
|
* LUCENE-3086: ItalianAnalyzer now uses ElisionFilter with a set of Italian
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<project name="ant" default="default">
|
|
||||||
|
|
||||||
<description>
|
|
||||||
Lucene Ant integration
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<path id="additional.dependencies">
|
|
||||||
<!-- TODO: make ${tidy.jar} property -->
|
|
||||||
<fileset dir="lib" includes="jtidy-*.jar"/>
|
|
||||||
</path>
|
|
||||||
|
|
||||||
<pathconvert property="project.classpath"
|
|
||||||
targetos="unix"
|
|
||||||
refid="additional.dependencies"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<property name="javac.includeAntRuntime" value="true"/>
|
|
||||||
|
|
||||||
<import file="../contrib-build.xml"/>
|
|
||||||
|
|
||||||
<module-uptodate name="analysis/common" jarfile="${common.dir}/../modules/analysis/build/common/lucene-analyzers-common-${version}.jar"
|
|
||||||
property="analyzers-common.uptodate" classpath.property="analyzers-common.jar"/>
|
|
||||||
|
|
||||||
<path id="classpath">
|
|
||||||
<pathelement path="${analyzers-common.jar}"/>
|
|
||||||
<path refid="base.classpath"/>
|
|
||||||
</path>
|
|
||||||
|
|
||||||
<target name="compile-core" depends="compile-analyzers-common, common.compile-core" />
|
|
||||||
|
|
||||||
<target name="compile-analyzers-common" unless="analyzers-common.uptodate">
|
|
||||||
<subant target="default">
|
|
||||||
<fileset dir="${common.dir}/../modules/analysis/common" includes="build.xml"/>
|
|
||||||
</subant>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
</project>
|
|
|
@ -1,24 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
<!--
|
|
||||||
To use this example from a source checkout:
|
|
||||||
ant -f example.xml -lib ../../build/contrib/ant/ -lib ../../build/ -lib lib
|
|
||||||
-->
|
|
||||||
<project name="ant-example" default="index">
|
|
||||||
|
|
||||||
<description>
|
|
||||||
Lucene Ant index example
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<property name="index.base.dir" location="build"/>
|
|
||||||
<property name="files.dir" location="src/test"/>
|
|
||||||
|
|
||||||
<target name="index">
|
|
||||||
<mkdir dir="${index.base.dir}"/>
|
|
||||||
|
|
||||||
<index index="${index.base.dir}/index"
|
|
||||||
xmlns="antlib:org.apache.lucene.ant">
|
|
||||||
<fileset dir="${files.dir}"/>
|
|
||||||
</index>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
</project>
|
|
|
@ -1,53 +0,0 @@
|
||||||
/**
|
|
||||||
* Java HTML Tidy - JTidy
|
|
||||||
* HTML parser and pretty printer
|
|
||||||
*
|
|
||||||
* Copyright (c) 1998-2000 World Wide Web Consortium (Massachusetts
|
|
||||||
* Institute of Technology, Institut National de Recherche en
|
|
||||||
* Informatique et en Automatique, Keio University). All Rights
|
|
||||||
* Reserved.
|
|
||||||
*
|
|
||||||
* Contributing Author(s):
|
|
||||||
*
|
|
||||||
* Dave Raggett <dsr@w3.org>
|
|
||||||
* Andy Quick <ac.quick@sympatico.ca> (translation to Java)
|
|
||||||
* Gary L Peskin <garyp@firstech.com> (Java development)
|
|
||||||
* Sami Lempinen <sami@lempinen.net> (release management)
|
|
||||||
* Fabrizio Giustina <fgiust at users.sourceforge.net>
|
|
||||||
*
|
|
||||||
* The contributing author(s) would like to thank all those who
|
|
||||||
* helped with testing, bug fixes, and patience. This wouldn't
|
|
||||||
* have been possible without all of you.
|
|
||||||
*
|
|
||||||
* COPYRIGHT NOTICE:
|
|
||||||
*
|
|
||||||
* This software and documentation is provided "as is," and
|
|
||||||
* the copyright holders and contributing author(s) make no
|
|
||||||
* representations or warranties, express or implied, including
|
|
||||||
* but not limited to, warranties of merchantability or fitness
|
|
||||||
* for any particular purpose or that the use of the software or
|
|
||||||
* documentation will not infringe any third party patents,
|
|
||||||
* copyrights, trademarks or other rights.
|
|
||||||
*
|
|
||||||
* The copyright holders and contributing author(s) will not be
|
|
||||||
* liable for any direct, indirect, special or consequential damages
|
|
||||||
* arising out of any use of the software or documentation, even if
|
|
||||||
* advised of the possibility of such damage.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted to use, copy, modify, and distribute
|
|
||||||
* this source code, or portions hereof, documentation and executables,
|
|
||||||
* for any purpose, without fee, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this source code must not be misrepresented.
|
|
||||||
* 2. Altered versions must be plainly marked as such and must
|
|
||||||
* not be misrepresented as being the original source.
|
|
||||||
* 3. This Copyright notice may not be removed or altered from any
|
|
||||||
* source or altered source distribution.
|
|
||||||
*
|
|
||||||
* The copyright holders and contributing author(s) specifically
|
|
||||||
* permit, without fee, and encourage the use of this source code
|
|
||||||
* as a component for supporting the Hypertext Markup Language in
|
|
||||||
* commercial products. If you use this source code in a product,
|
|
||||||
* acknowledgment is not required but would be appreciated.
|
|
||||||
*
|
|
||||||
*/
|
|
|
@ -1,2 +0,0 @@
|
||||||
AnyObjectId[efde902f3e9b180ee7bed0e849b4be8d6c15aaff] was removed in git history.
|
|
||||||
Apache SVN contains full history.
|
|
|
@ -1,24 +0,0 @@
|
||||||
package org.apache.lucene.ant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.util.Properties;
|
|
||||||
|
|
||||||
public interface ConfigurableDocumentHandler extends DocumentHandler {
|
|
||||||
void configure(Properties props);
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
package org.apache.lucene.ant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 org.apache.lucene.document.Document;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows a class to act as a Lucene document handler
|
|
||||||
*
|
|
||||||
*@since October 27, 2001
|
|
||||||
*/
|
|
||||||
public interface DocumentHandler {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the document attribute of the DocumentHandler object
|
|
||||||
*
|
|
||||||
*@param file Description of Parameter
|
|
||||||
*@return The document value
|
|
||||||
*/
|
|
||||||
Document getDocument(File file)
|
|
||||||
throws DocumentHandlerException;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
package org.apache.lucene.ant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.PrintStream;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
|
|
||||||
|
|
||||||
public class DocumentHandlerException extends Exception {
|
|
||||||
private Throwable cause;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor.
|
|
||||||
*/
|
|
||||||
public DocumentHandlerException() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs with message.
|
|
||||||
*/
|
|
||||||
public DocumentHandlerException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs with chained exception.
|
|
||||||
*/
|
|
||||||
public DocumentHandlerException(Throwable cause) {
|
|
||||||
super(cause.toString());
|
|
||||||
this.cause = cause;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves nested exception.
|
|
||||||
*/
|
|
||||||
public Throwable getException() {
|
|
||||||
return cause;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void printStackTrace() {
|
|
||||||
printStackTrace(System.err);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void printStackTrace(PrintStream ps) {
|
|
||||||
synchronized (ps) {
|
|
||||||
super.printStackTrace(ps);
|
|
||||||
if (cause != null) {
|
|
||||||
ps.println("--- Nested Exception ---");
|
|
||||||
cause.printStackTrace(ps);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void printStackTrace(PrintWriter pw) {
|
|
||||||
synchronized (pw) {
|
|
||||||
super.printStackTrace(pw);
|
|
||||||
if (cause != null) {
|
|
||||||
pw.println("--- Nested Exception ---");
|
|
||||||
cause.printStackTrace(pw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
package org.apache.lucene.ant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 org.apache.lucene.document.Document;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A DocumentHandler implementation to delegate responsibility to
|
|
||||||
* based on a files extension. Currently only .html and .txt
|
|
||||||
* files are handled, other extensions ignored.
|
|
||||||
*
|
|
||||||
*@since October 28, 2001
|
|
||||||
*TODO: Implement dynamic document type lookup
|
|
||||||
*/
|
|
||||||
public class FileExtensionDocumentHandler
|
|
||||||
implements DocumentHandler {
|
|
||||||
/**
|
|
||||||
* Gets the document attribute of the
|
|
||||||
* FileExtensionDocumentHandler object
|
|
||||||
*
|
|
||||||
*@param file Description of
|
|
||||||
* Parameter
|
|
||||||
*@return The document value
|
|
||||||
*@exception DocumentHandlerException Description of
|
|
||||||
* Exception
|
|
||||||
*/
|
|
||||||
public Document getDocument(File file)
|
|
||||||
throws DocumentHandlerException {
|
|
||||||
Document doc = null;
|
|
||||||
|
|
||||||
String name = file.getName();
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (name.endsWith(".txt")) {
|
|
||||||
doc = TextDocument.Document(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name.endsWith(".html")) {
|
|
||||||
doc = HtmlDocument.Document(file);
|
|
||||||
}
|
|
||||||
} catch (java.io.IOException e) {
|
|
||||||
throw new DocumentHandlerException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return doc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,294 +0,0 @@
|
||||||
package org.apache.lucene.ant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 org.apache.lucene.document.Field;
|
|
||||||
import org.w3c.dom.Element;
|
|
||||||
import org.w3c.dom.Node;
|
|
||||||
import org.w3c.dom.NodeList;
|
|
||||||
import org.w3c.dom.Text;
|
|
||||||
import org.w3c.tidy.Tidy;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The <code>HtmlDocument</code> class creates a Lucene {@link
|
|
||||||
* org.apache.lucene.document.Document} from an HTML document. <P>
|
|
||||||
*
|
|
||||||
* It does this by using JTidy package. It can take input input
|
|
||||||
* from {@link java.io.File} or {@link java.io.InputStream}.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class HtmlDocument {
|
|
||||||
private Element rawDoc;
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------
|
|
||||||
// Constructors
|
|
||||||
//-------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs an <code>HtmlDocument</code> from a {@link
|
|
||||||
* java.io.File}.
|
|
||||||
*
|
|
||||||
*@param file the <code>File</code> containing the
|
|
||||||
* HTML to parse
|
|
||||||
*@exception IOException if an I/O exception occurs
|
|
||||||
*/
|
|
||||||
public HtmlDocument(File file) throws IOException {
|
|
||||||
Tidy tidy = new Tidy();
|
|
||||||
tidy.setQuiet(true);
|
|
||||||
tidy.setShowWarnings(false);
|
|
||||||
org.w3c.dom.Document root = null;
|
|
||||||
InputStream is = new FileInputStream(file);
|
|
||||||
try {
|
|
||||||
root = tidy.parseDOM(is, null);
|
|
||||||
} finally {
|
|
||||||
is.close();
|
|
||||||
}
|
|
||||||
rawDoc = root.getDocumentElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs an <code>HtmlDocument</code> from an {@link
|
|
||||||
* java.io.InputStream}.
|
|
||||||
*
|
|
||||||
*@param is the <code>InputStream</code>
|
|
||||||
* containing the HTML
|
|
||||||
*/
|
|
||||||
public HtmlDocument(InputStream is) {
|
|
||||||
Tidy tidy = new Tidy();
|
|
||||||
tidy.setQuiet(true);
|
|
||||||
tidy.setShowWarnings(false);
|
|
||||||
org.w3c.dom.Document root = tidy.parseDOM(is, null);
|
|
||||||
rawDoc = root.getDocumentElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs an <code>HtmlDocument</code> from a
|
|
||||||
* {@link java.io.File}.
|
|
||||||
* @param file the <code>File</code> containing the
|
|
||||||
* HTML to parse
|
|
||||||
* @param tidyConfigFile the <code>String</code>
|
|
||||||
* containing the full path to the Tidy config file
|
|
||||||
* @exception IOException if an I/O exception occurs */
|
|
||||||
public HtmlDocument(File file, String tidyConfigFile) throws IOException {
|
|
||||||
Tidy tidy = new Tidy();
|
|
||||||
tidy.setConfigurationFromFile(tidyConfigFile);
|
|
||||||
tidy.setQuiet(true);
|
|
||||||
tidy.setShowWarnings(false);
|
|
||||||
org.w3c.dom.Document root =
|
|
||||||
tidy.parseDOM(new FileInputStream(file), null);
|
|
||||||
rawDoc = root.getDocumentElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Lucene <code>Document</code> from a
|
|
||||||
* {@link java.io.File}.
|
|
||||||
* @param file
|
|
||||||
* @param tidyConfigFile the full path to the Tidy
|
|
||||||
* config file
|
|
||||||
* @exception IOException */
|
|
||||||
public static org.apache.lucene.document.Document
|
|
||||||
Document(File file, String tidyConfigFile) throws IOException {
|
|
||||||
|
|
||||||
HtmlDocument htmlDoc = new HtmlDocument(file, tidyConfigFile);
|
|
||||||
|
|
||||||
org.apache.lucene.document.Document luceneDoc = new org.apache.lucene.document.Document();
|
|
||||||
|
|
||||||
luceneDoc.add(new Field("title", htmlDoc.getTitle(), Field.Store.YES, Field.Index.ANALYZED));
|
|
||||||
luceneDoc.add(new Field("contents", htmlDoc.getBody(), Field.Store.YES, Field.Index.ANALYZED));
|
|
||||||
|
|
||||||
String contents = null;
|
|
||||||
BufferedReader br =
|
|
||||||
new BufferedReader(new FileReader(file));
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
String line = br.readLine();
|
|
||||||
while (line != null) {
|
|
||||||
sw.write(line);
|
|
||||||
line = br.readLine();
|
|
||||||
}
|
|
||||||
br.close();
|
|
||||||
contents = sw.toString();
|
|
||||||
sw.close();
|
|
||||||
|
|
||||||
luceneDoc.add(new Field("rawcontents", contents, Field.Store.YES, Field.Index.NO));
|
|
||||||
|
|
||||||
return luceneDoc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Lucene <code>Document</code> from an {@link
|
|
||||||
* java.io.InputStream}.
|
|
||||||
*
|
|
||||||
*@param is
|
|
||||||
*/
|
|
||||||
public static org.apache.lucene.document.Document
|
|
||||||
getDocument(InputStream is) {
|
|
||||||
HtmlDocument htmlDoc = new HtmlDocument(is);
|
|
||||||
org.apache.lucene.document.Document luceneDoc =
|
|
||||||
new org.apache.lucene.document.Document();
|
|
||||||
|
|
||||||
luceneDoc.add(new Field("title", htmlDoc.getTitle(), Field.Store.YES, Field.Index.ANALYZED));
|
|
||||||
luceneDoc.add(new Field("contents", htmlDoc.getBody(), Field.Store.YES, Field.Index.ANALYZED));
|
|
||||||
|
|
||||||
return luceneDoc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------
|
|
||||||
// Public methods
|
|
||||||
//-------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Lucene <code>Document</code> from a {@link
|
|
||||||
* java.io.File}.
|
|
||||||
*
|
|
||||||
*@param file
|
|
||||||
*@exception IOException
|
|
||||||
*/
|
|
||||||
public static org.apache.lucene.document.Document
|
|
||||||
Document(File file) throws IOException {
|
|
||||||
HtmlDocument htmlDoc = new HtmlDocument(file);
|
|
||||||
org.apache.lucene.document.Document luceneDoc =
|
|
||||||
new org.apache.lucene.document.Document();
|
|
||||||
|
|
||||||
luceneDoc.add(new Field("title", htmlDoc.getTitle(), Field.Store.YES, Field.Index.ANALYZED));
|
|
||||||
luceneDoc.add(new Field("contents", htmlDoc.getBody(), Field.Store.YES, Field.Index.ANALYZED));
|
|
||||||
|
|
||||||
String contents = null;
|
|
||||||
BufferedReader br =
|
|
||||||
new BufferedReader(new FileReader(file));
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
String line = br.readLine();
|
|
||||||
while (line != null) {
|
|
||||||
sw.write(line);
|
|
||||||
line = br.readLine();
|
|
||||||
}
|
|
||||||
br.close();
|
|
||||||
contents = sw.toString();
|
|
||||||
sw.close();
|
|
||||||
|
|
||||||
luceneDoc.add(new Field("rawcontents", contents, Field.Store.YES, Field.Index.NO));
|
|
||||||
|
|
||||||
return luceneDoc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------
|
|
||||||
// Private methods
|
|
||||||
//-------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs <code>HtmlDocument</code> on the files specified on
|
|
||||||
* the command line.
|
|
||||||
*
|
|
||||||
*@param args Command line arguments
|
|
||||||
*@exception Exception Description of Exception
|
|
||||||
*/
|
|
||||||
public static void main(String args[]) throws Exception {
|
|
||||||
// HtmlDocument doc = new HtmlDocument(new File(args[0]));
|
|
||||||
// System.out.println("Title = " + doc.getTitle());
|
|
||||||
// System.out.println("Body = " + doc.getBody());
|
|
||||||
|
|
||||||
HtmlDocument doc =
|
|
||||||
new HtmlDocument(new FileInputStream(new File(args[0])));
|
|
||||||
System.out.println("Title = " + doc.getTitle());
|
|
||||||
System.out.println("Body = " + doc.getBody());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the title attribute of the <code>HtmlDocument</code>
|
|
||||||
* object.
|
|
||||||
*
|
|
||||||
*@return the title value
|
|
||||||
*/
|
|
||||||
public String getTitle() {
|
|
||||||
if (rawDoc == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = "";
|
|
||||||
|
|
||||||
NodeList nl = rawDoc.getElementsByTagName("title");
|
|
||||||
if (nl.getLength() > 0) {
|
|
||||||
Element titleElement = ((Element) nl.item(0));
|
|
||||||
Text text = (Text) titleElement.getFirstChild();
|
|
||||||
if (text != null) {
|
|
||||||
title = text.getData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the bodyText attribute of the
|
|
||||||
* <code>HtmlDocument</code> object.
|
|
||||||
*
|
|
||||||
*@return the bodyText value
|
|
||||||
*/
|
|
||||||
public String getBody() {
|
|
||||||
if (rawDoc == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String body = "";
|
|
||||||
NodeList nl = rawDoc.getElementsByTagName("body");
|
|
||||||
if (nl.getLength() > 0) {
|
|
||||||
body = getBodyText(nl.item(0));
|
|
||||||
}
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the bodyText attribute of the
|
|
||||||
* <code>HtmlDocument</code> object.
|
|
||||||
*
|
|
||||||
*@param node a DOM Node
|
|
||||||
*@return The bodyText value
|
|
||||||
*/
|
|
||||||
private String getBodyText(Node node) {
|
|
||||||
NodeList nl = node.getChildNodes();
|
|
||||||
StringBuilder buffer = new StringBuilder();
|
|
||||||
for (int i = 0; i < nl.getLength(); i++) {
|
|
||||||
Node child = nl.item(i);
|
|
||||||
switch (child.getNodeType()) {
|
|
||||||
case Node.ELEMENT_NODE:
|
|
||||||
buffer.append(getBodyText(child));
|
|
||||||
buffer.append(" ");
|
|
||||||
break;
|
|
||||||
case Node.TEXT_NODE:
|
|
||||||
buffer.append(((Text) child).getData());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return buffer.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,444 +0,0 @@
|
||||||
package org.apache.lucene.ant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.Vector;
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
|
||||||
import org.apache.lucene.analysis.core.SimpleAnalyzer;
|
|
||||||
import org.apache.lucene.analysis.core.StopAnalyzer;
|
|
||||||
import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
|
|
||||||
import org.apache.lucene.analysis.standard.StandardAnalyzer;
|
|
||||||
import org.apache.lucene.document.DateTools;
|
|
||||||
import org.apache.lucene.document.Document;
|
|
||||||
import org.apache.lucene.document.Field;
|
|
||||||
import org.apache.lucene.index.IndexWriter;
|
|
||||||
import org.apache.lucene.index.IndexWriterConfig;
|
|
||||||
import org.apache.lucene.index.TieredMergePolicy;
|
|
||||||
import org.apache.lucene.index.Term;
|
|
||||||
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
|
|
||||||
import org.apache.lucene.search.IndexSearcher;
|
|
||||||
import org.apache.lucene.search.ScoreDoc;
|
|
||||||
import org.apache.lucene.search.TermQuery;
|
|
||||||
import org.apache.lucene.store.FSDirectory;
|
|
||||||
import org.apache.lucene.util.Version;
|
|
||||||
import org.apache.tools.ant.BuildException;
|
|
||||||
import org.apache.tools.ant.DynamicConfigurator;
|
|
||||||
import org.apache.tools.ant.Project;
|
|
||||||
import org.apache.tools.ant.Task;
|
|
||||||
import org.apache.tools.ant.types.EnumeratedAttribute;
|
|
||||||
import org.apache.tools.ant.types.FileSet;
|
|
||||||
import org.apache.tools.ant.types.Resource;
|
|
||||||
import org.apache.tools.ant.types.ResourceCollection;
|
|
||||||
import org.apache.tools.ant.types.resources.FileResource;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ant task to index files with Lucene
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class IndexTask extends Task {
|
|
||||||
/**
|
|
||||||
* resources
|
|
||||||
*/
|
|
||||||
protected Vector<ResourceCollection> rcs = new Vector<ResourceCollection>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* overwrite index?
|
|
||||||
*/
|
|
||||||
private boolean overwrite = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* index path
|
|
||||||
*/
|
|
||||||
private File indexDir;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* document handler classname
|
|
||||||
*/
|
|
||||||
private String handlerClassName =
|
|
||||||
FileExtensionDocumentHandler.class.getName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* document handler instance
|
|
||||||
*/
|
|
||||||
private DocumentHandler handler;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private String analyzerClassName =
|
|
||||||
StandardAnalyzer.class.getName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* analyzer instance
|
|
||||||
*/
|
|
||||||
private Analyzer analyzer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lucene merge factor
|
|
||||||
*/
|
|
||||||
private int mergeFactor = 20;
|
|
||||||
|
|
||||||
private HandlerConfig handlerConfig;
|
|
||||||
|
|
||||||
private boolean useCompoundIndex = true;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates new instance
|
|
||||||
*/
|
|
||||||
public IndexTask() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies the directory where the index will be stored
|
|
||||||
*/
|
|
||||||
public void setIndex(File indexDir) {
|
|
||||||
this.indexDir = indexDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the mergeFactor attribute of the IndexTask object
|
|
||||||
*
|
|
||||||
*@param mergeFactor The new mergeFactor value
|
|
||||||
*/
|
|
||||||
public void setMergeFactor(int mergeFactor) {
|
|
||||||
this.mergeFactor = mergeFactor;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the overwrite attribute of the IndexTask object
|
|
||||||
*
|
|
||||||
*@param overwrite The new overwrite value
|
|
||||||
*/
|
|
||||||
public void setOverwrite(boolean overwrite) {
|
|
||||||
this.overwrite = overwrite;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If creating a new index and this is set to true, the
|
|
||||||
* index will be created in compound format.
|
|
||||||
*/
|
|
||||||
public void setUseCompoundIndex(boolean useCompoundIndex) {
|
|
||||||
this.useCompoundIndex = useCompoundIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the documentHandler attribute of the IndexTask object
|
|
||||||
*
|
|
||||||
*@param classname The new documentHandler value
|
|
||||||
*/
|
|
||||||
public void setDocumentHandler(String classname) {
|
|
||||||
handlerClassName = classname;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the analyzer based on the builtin Lucene analyzer types.
|
|
||||||
*
|
|
||||||
* TODO: Enforce analyzer and analyzerClassName to be mutually exclusive
|
|
||||||
*/
|
|
||||||
public void setAnalyzer(AnalyzerType type) {
|
|
||||||
analyzerClassName = type.getClassname();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAnalyzerClassName(String classname) {
|
|
||||||
analyzerClassName = classname;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a set of files (nested fileset attribute).
|
|
||||||
*
|
|
||||||
*@param set FileSet to be added
|
|
||||||
*/
|
|
||||||
public void addFileset(FileSet set) {
|
|
||||||
add(set);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a collection of files to copy.
|
|
||||||
* @param res a resource collection to copy.
|
|
||||||
* @since Ant 1.7
|
|
||||||
*/
|
|
||||||
public void add(ResourceCollection res) {
|
|
||||||
rcs.add(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets custom properties for a configurable document handler.
|
|
||||||
*/
|
|
||||||
public void addConfig(HandlerConfig config) throws BuildException {
|
|
||||||
if (handlerConfig != null) {
|
|
||||||
throw new BuildException("Only one config element allowed");
|
|
||||||
}
|
|
||||||
|
|
||||||
handlerConfig = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Analyzer createAnalyzer(String className) throws Exception{
|
|
||||||
final Class<? extends Analyzer> clazz = Class.forName(className).asSubclass(Analyzer.class);
|
|
||||||
try {
|
|
||||||
// first try to use a ctor with version parameter (needed for many new Analyzers that have no default one anymore
|
|
||||||
Constructor<? extends Analyzer> cnstr = clazz.getConstructor(Version.class);
|
|
||||||
return cnstr.newInstance(Version.LUCENE_CURRENT);
|
|
||||||
} catch (NoSuchMethodException nsme) {
|
|
||||||
// otherwise use default ctor
|
|
||||||
return clazz.newInstance();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Begins the indexing
|
|
||||||
*
|
|
||||||
*@exception BuildException If an error occurs indexing the
|
|
||||||
* fileset
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void execute() throws BuildException {
|
|
||||||
|
|
||||||
// construct handler and analyzer dynamically
|
|
||||||
try {
|
|
||||||
handler = Class.forName(handlerClassName).asSubclass(DocumentHandler.class).newInstance();
|
|
||||||
|
|
||||||
analyzer = IndexTask.createAnalyzer(analyzerClassName);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new BuildException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
log("Document handler = " + handler.getClass(), Project.MSG_VERBOSE);
|
|
||||||
log("Analyzer = " + analyzer.getClass(), Project.MSG_VERBOSE);
|
|
||||||
|
|
||||||
if (handler instanceof ConfigurableDocumentHandler) {
|
|
||||||
((ConfigurableDocumentHandler) handler).configure(handlerConfig.getProperties());
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
indexDocs();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new BuildException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Index the fileset.
|
|
||||||
*
|
|
||||||
*@exception IOException if Lucene I/O exception
|
|
||||||
*TODO: refactor!!!!!
|
|
||||||
*/
|
|
||||||
private void indexDocs() throws IOException {
|
|
||||||
Date start = new Date();
|
|
||||||
|
|
||||||
boolean create = overwrite;
|
|
||||||
// If the index directory doesn't exist,
|
|
||||||
// create it and force create mode
|
|
||||||
if (indexDir.mkdirs() && !overwrite) {
|
|
||||||
create = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
FSDirectory dir = FSDirectory.open(indexDir);
|
|
||||||
try {
|
|
||||||
IndexSearcher searcher = null;
|
|
||||||
boolean checkLastModified = false;
|
|
||||||
if (!create) {
|
|
||||||
try {
|
|
||||||
searcher = new IndexSearcher(dir, true);
|
|
||||||
checkLastModified = true;
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
log("IOException: " + ioe.getMessage());
|
|
||||||
// Empty - ignore, which indicates to index all
|
|
||||||
// documents
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log("checkLastModified = " + checkLastModified, Project.MSG_VERBOSE);
|
|
||||||
|
|
||||||
IndexWriterConfig conf = new IndexWriterConfig(
|
|
||||||
Version.LUCENE_CURRENT, analyzer).setOpenMode(
|
|
||||||
create ? OpenMode.CREATE : OpenMode.APPEND);
|
|
||||||
TieredMergePolicy tmp = (TieredMergePolicy) conf.getMergePolicy();
|
|
||||||
tmp.setUseCompoundFile(useCompoundIndex);
|
|
||||||
tmp.setMaxMergeAtOnce(mergeFactor);
|
|
||||||
IndexWriter writer = new IndexWriter(dir, conf);
|
|
||||||
int totalFiles = 0;
|
|
||||||
int totalIndexed = 0;
|
|
||||||
int totalIgnored = 0;
|
|
||||||
try {
|
|
||||||
|
|
||||||
for (int i = 0; i < rcs.size(); i++) {
|
|
||||||
ResourceCollection rc = rcs.elementAt(i);
|
|
||||||
if (rc.isFilesystemOnly()) {
|
|
||||||
Iterator resources = rc.iterator();
|
|
||||||
while (resources.hasNext()) {
|
|
||||||
Resource r = (Resource) resources.next();
|
|
||||||
if (!r.isExists() || !(r instanceof FileResource)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
totalFiles++;
|
|
||||||
|
|
||||||
File file = ((FileResource) r).getFile();
|
|
||||||
|
|
||||||
if (!file.exists() || !file.canRead()) {
|
|
||||||
throw new BuildException("File \"" +
|
|
||||||
file.getAbsolutePath()
|
|
||||||
+ "\" does not exist or is not readable.");
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean indexIt = true;
|
|
||||||
|
|
||||||
if (checkLastModified) {
|
|
||||||
Term pathTerm =
|
|
||||||
new Term("path", file.getPath());
|
|
||||||
TermQuery query =
|
|
||||||
new TermQuery(pathTerm);
|
|
||||||
ScoreDoc[] hits = searcher.search(query, null, 1).scoreDocs;
|
|
||||||
|
|
||||||
// if document is found, compare the
|
|
||||||
// indexed last modified time with the
|
|
||||||
// current file
|
|
||||||
// - don't index if up to date
|
|
||||||
if (hits.length > 0) {
|
|
||||||
Document doc = searcher.doc(hits[0].doc);
|
|
||||||
String indexModified =
|
|
||||||
doc.get("modified").trim();
|
|
||||||
if (indexModified != null) {
|
|
||||||
long lastModified = 0;
|
|
||||||
try {
|
|
||||||
lastModified = DateTools.stringToTime(indexModified);
|
|
||||||
} catch (ParseException e) {
|
|
||||||
// if modified time is not parsable, skip
|
|
||||||
}
|
|
||||||
if (lastModified == file.lastModified()) {
|
|
||||||
// TODO: remove existing document
|
|
||||||
indexIt = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (indexIt) {
|
|
||||||
try {
|
|
||||||
log("Indexing " + file.getPath(),
|
|
||||||
Project.MSG_VERBOSE);
|
|
||||||
Document doc =
|
|
||||||
handler.getDocument(file);
|
|
||||||
|
|
||||||
if (doc == null) {
|
|
||||||
totalIgnored++;
|
|
||||||
} else {
|
|
||||||
// Add the path of the file as a field named "path". Use a Keyword field, so
|
|
||||||
// that the index stores the path, and so that the path is searchable
|
|
||||||
doc.add(new Field("path", file.getPath(), Field.Store.YES, Field.Index.NOT_ANALYZED));
|
|
||||||
|
|
||||||
// Add the last modified date of the file a field named "modified". Use a
|
|
||||||
// Keyword field, so that it's searchable, but so that no attempt is made
|
|
||||||
// to tokenize the field into words.
|
|
||||||
doc.add(new Field("modified", DateTools.timeToString(file.lastModified(), DateTools.Resolution.MILLISECOND), Field.Store.YES, Field.Index.NOT_ANALYZED));
|
|
||||||
|
|
||||||
writer.addDocument(doc);
|
|
||||||
totalIndexed++;
|
|
||||||
}
|
|
||||||
} catch (DocumentHandlerException e) {
|
|
||||||
throw new BuildException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// for j
|
|
||||||
}
|
|
||||||
// if (fs != null)
|
|
||||||
}
|
|
||||||
// for i
|
|
||||||
|
|
||||||
writer.optimize();
|
|
||||||
}
|
|
||||||
//try
|
|
||||||
finally {
|
|
||||||
// always make sure everything gets closed,
|
|
||||||
// no matter how we exit.
|
|
||||||
writer.close();
|
|
||||||
if (searcher != null) {
|
|
||||||
searcher.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Date end = new Date();
|
|
||||||
|
|
||||||
log(totalIndexed + " out of " + totalFiles + " indexed (" +
|
|
||||||
totalIgnored + " ignored) in " + (end.getTime() - start.getTime()) +
|
|
||||||
" milliseconds");
|
|
||||||
} finally {
|
|
||||||
dir.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class HandlerConfig implements DynamicConfigurator {
|
|
||||||
Properties props = new Properties();
|
|
||||||
|
|
||||||
public void setDynamicAttribute(String attributeName, String value) throws BuildException {
|
|
||||||
props.setProperty(attributeName, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object createDynamicElement(String elementName) throws BuildException {
|
|
||||||
throw new BuildException("Sub elements not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Properties getProperties() {
|
|
||||||
return props;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class AnalyzerType extends EnumeratedAttribute {
|
|
||||||
private static Map<String,String> analyzerLookup = new HashMap<String,String>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
analyzerLookup.put("simple", SimpleAnalyzer.class.getName());
|
|
||||||
analyzerLookup.put("standard", StandardAnalyzer.class.getName());
|
|
||||||
analyzerLookup.put("stop", StopAnalyzer.class.getName());
|
|
||||||
analyzerLookup.put("whitespace", WhitespaceAnalyzer.class.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see EnumeratedAttribute#getValues
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String[] getValues() {
|
|
||||||
Set<String> keys = analyzerLookup.keySet();
|
|
||||||
return keys.toArray(new String[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClassname() {
|
|
||||||
return analyzerLookup.get(getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,98 +0,0 @@
|
||||||
package org.apache.lucene.ant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 org.apache.lucene.document.Document;
|
|
||||||
import org.apache.lucene.document.Field;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A utility for making Lucene Documents from a File.
|
|
||||||
*
|
|
||||||
*@since December 6, 2001
|
|
||||||
*TODO: Fix JavaDoc comments here
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class TextDocument {
|
|
||||||
private String contents;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor for the TextDocument object
|
|
||||||
*
|
|
||||||
*@param file Description of Parameter
|
|
||||||
*@exception IOException Description of Exception
|
|
||||||
*/
|
|
||||||
public TextDocument(File file) throws IOException {
|
|
||||||
BufferedReader br =
|
|
||||||
new BufferedReader(new FileReader(file));
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
|
|
||||||
String line = br.readLine();
|
|
||||||
while (line != null) {
|
|
||||||
sw.write(line);
|
|
||||||
line = br.readLine();
|
|
||||||
}
|
|
||||||
br.close();
|
|
||||||
|
|
||||||
contents = sw.toString();
|
|
||||||
sw.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Makes a document for a File. <p>
|
|
||||||
*
|
|
||||||
* The document has a single field:
|
|
||||||
* <ul>
|
|
||||||
* <li> <code>contents</code>--containing the full contents
|
|
||||||
* of the file, as a Text field;
|
|
||||||
*
|
|
||||||
*@param f Description of Parameter
|
|
||||||
*@return Description of the Returned Value
|
|
||||||
*@exception IOException Description of Exception
|
|
||||||
*/
|
|
||||||
public static Document Document(File f) throws IOException {
|
|
||||||
|
|
||||||
TextDocument textDoc = new TextDocument(f);
|
|
||||||
// make a new, empty document
|
|
||||||
Document doc = new Document();
|
|
||||||
|
|
||||||
doc.add(new Field("title", f.getName(), Field.Store.YES, Field.Index.ANALYZED));
|
|
||||||
doc.add(new Field("contents", textDoc.getContents(), Field.Store.YES, Field.Index.ANALYZED));
|
|
||||||
doc.add(new Field("rawcontents", textDoc.getContents(), Field.Store.YES, Field.Index.NO));
|
|
||||||
|
|
||||||
// return the document
|
|
||||||
return doc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*@return The contents value
|
|
||||||
*TODO: finish this method
|
|
||||||
*/
|
|
||||||
public String getContents() {
|
|
||||||
return contents;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
|
||||||
<!--
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
<html><head></head>
|
|
||||||
<body>
|
|
||||||
Ant task to create Lucene indexes.
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,26 +0,0 @@
|
||||||
<!--
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>
|
|
||||||
Apache Lucene Ant task to create Lucene indexes.
|
|
||||||
</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Ant task to create Lucene indexes.
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,21 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
<antlib>
|
|
||||||
<taskdef name="index" classname="org.apache.lucene.ant.IndexTask"/>
|
|
||||||
</antlib>
|
|
|
@ -1,36 +0,0 @@
|
||||||
package org.apache.lucene.ant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URLDecoder;
|
|
||||||
|
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
|
||||||
|
|
||||||
public abstract class DocumentTestCase extends LuceneTestCase
|
|
||||||
{
|
|
||||||
protected File getFile(String filename) throws IOException {
|
|
||||||
String fullname =
|
|
||||||
this.getClass().getResource(filename).getFile();
|
|
||||||
|
|
||||||
File file = new File(URLDecoder.decode(fullname, "UTF-8"));
|
|
||||||
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
package org.apache.lucene.ant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 org.apache.lucene.ant.DocumentTestCase;
|
|
||||||
import org.apache.lucene.ant.HtmlDocument;
|
|
||||||
|
|
||||||
public class HtmlDocumentTest extends DocumentTestCase
|
|
||||||
{
|
|
||||||
HtmlDocument doc;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
doc = new HtmlDocument(getFile("test.html"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testDoc() {
|
|
||||||
assertEquals("Title", "Test Title", doc.getTitle());
|
|
||||||
assertTrue("Body", doc.getBody().startsWith("This is some test"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
doc = null;
|
|
||||||
super.tearDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,95 +0,0 @@
|
||||||
package org.apache.lucene.ant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.File;
|
|
||||||
import java.io.IOException; // javadoc
|
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
|
||||||
import org.apache.lucene.analysis.core.StopAnalyzer;
|
|
||||||
import org.apache.lucene.queryParser.QueryParser;
|
|
||||||
import org.apache.lucene.search.IndexSearcher;
|
|
||||||
import org.apache.lucene.search.Query;
|
|
||||||
import org.apache.lucene.store.Directory;
|
|
||||||
import org.apache.tools.ant.Project;
|
|
||||||
import org.apache.tools.ant.types.FileSet;
|
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test cases for index task
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class IndexTaskTest extends LuceneTestCase {
|
|
||||||
private final static String docHandler =
|
|
||||||
"org.apache.lucene.ant.FileExtensionDocumentHandler";
|
|
||||||
|
|
||||||
private IndexSearcher searcher;
|
|
||||||
private Analyzer analyzer;
|
|
||||||
private Directory dir;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The JUnit setup method
|
|
||||||
*
|
|
||||||
*@exception IOException Description of Exception
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
// slightly hackish way to get the src/test dir
|
|
||||||
String docsDir = getDataFile("test.txt").getParent();
|
|
||||||
File indexDir = TEMP_DIR;
|
|
||||||
Project project = new Project();
|
|
||||||
|
|
||||||
IndexTask task = new IndexTask();
|
|
||||||
FileSet fs = new FileSet();
|
|
||||||
fs.setProject(project);
|
|
||||||
fs.setDir(new File(docsDir));
|
|
||||||
task.addFileset(fs);
|
|
||||||
task.setOverwrite(true);
|
|
||||||
task.setDocumentHandler(docHandler);
|
|
||||||
task.setIndex(indexDir);
|
|
||||||
task.setProject(project);
|
|
||||||
task.execute();
|
|
||||||
|
|
||||||
dir = newFSDirectory(indexDir);
|
|
||||||
searcher = new IndexSearcher(dir, true);
|
|
||||||
analyzer = new StopAnalyzer(TEST_VERSION_CURRENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void testSearch() throws Exception {
|
|
||||||
Query query = new QueryParser(TEST_VERSION_CURRENT, "contents",analyzer).parse("test");
|
|
||||||
|
|
||||||
int numHits = searcher.search(query, null, 1000).totalHits;
|
|
||||||
|
|
||||||
assertEquals("Find document(s)", 2, numHits);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The teardown method for JUnit
|
|
||||||
* TODO: remove indexDir?
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
searcher.close();
|
|
||||||
dir.close();
|
|
||||||
super.tearDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
package org.apache.lucene.ant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 org.apache.lucene.ant.DocumentTestCase;
|
|
||||||
import org.apache.lucene.ant.TextDocument;
|
|
||||||
|
|
||||||
public class TextDocumentTest extends DocumentTestCase
|
|
||||||
{
|
|
||||||
TextDocument doc;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
doc = new TextDocument(getFile("test.txt"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testDoc() {
|
|
||||||
assertEquals("Contents", "Test Contents", doc.getContents());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
doc = null;
|
|
||||||
super.tearDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test Title</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<i>This is <b>some</b>test</i>
|
|
||||||
</body>
|
|
|
@ -1 +0,0 @@
|
||||||
Test Contents
|
|
|
@ -1,50 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
<!--
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
<project name="bdb-je" default="default">
|
|
||||||
|
|
||||||
<description>
|
|
||||||
Lucene Berkeley DB Java Edition integration
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<property name="je.version" value="3.3.93" />
|
|
||||||
|
|
||||||
<path id="je.jar">
|
|
||||||
<pathelement location="lib/je-${je.version}.jar" />
|
|
||||||
</path>
|
|
||||||
|
|
||||||
<available classname="com.sleepycat.je.Database" property="je.jar.exists">
|
|
||||||
<classpath refid="je.jar" />
|
|
||||||
</available>
|
|
||||||
|
|
||||||
<pathconvert property="project.classpath" targetos="unix" refid="je.jar" />
|
|
||||||
|
|
||||||
<property name="build.dir" location="../../../build/contrib/db/bdb-je" />
|
|
||||||
<property name="dist.dir" location="../../../dist/contrib/db/bdb-je" />
|
|
||||||
<property name="maven.dist.dir" location="../../../dist/maven" />
|
|
||||||
|
|
||||||
<import file="../../contrib-build.xml" />
|
|
||||||
|
|
||||||
<target name="get-je-jar" unless="je.jar.exists">
|
|
||||||
<mkdir dir="lib" />
|
|
||||||
<get src="http://download.oracle.com/maven/com/sleepycat/je/${je.version}/je-${je.version}.jar"
|
|
||||||
dest="lib/je-${je.version}.jar" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="check-and-get-je-jar" depends="get-je-jar" />
|
|
||||||
<target name="init" depends="contrib-build.init,check-and-get-je-jar" />
|
|
||||||
</project>
|
|
|
@ -1,2 +0,0 @@
|
||||||
AnyObjectId[9a9ff077cdd36a96e7e0506986edd4e52b90a22f] was removed in git history.
|
|
||||||
Apache SVN contains full history.
|
|
|
@ -1 +0,0 @@
|
||||||
No bdb jars are shipped with lucene. This is a fake license to work around the automated license checking.
|
|
|
@ -1 +0,0 @@
|
||||||
No bdb jars are shipped with lucene. This is a fake license to work around the automated license checking.
|
|
|
@ -1,83 +0,0 @@
|
||||||
package org.apache.lucene.store.je;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 com.sleepycat.je.DatabaseEntry;
|
|
||||||
import com.sleepycat.je.DatabaseException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Port of Andi Vajda's DbDirectory to Java Edition of Berkeley Database
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class Block extends Object {
|
|
||||||
protected DatabaseEntry key, data;
|
|
||||||
|
|
||||||
protected Block(File file) throws IOException {
|
|
||||||
byte[] fileKey = file.getKey();
|
|
||||||
|
|
||||||
key = new DatabaseEntry(new byte[fileKey.length + 8]);
|
|
||||||
data = new DatabaseEntry(new byte[JEIndexOutput.BLOCK_LEN]);
|
|
||||||
|
|
||||||
System.arraycopy(fileKey, 0, key.getData(), 0, fileKey.length);
|
|
||||||
seek(0L);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected byte[] getKey() {
|
|
||||||
return key.getData();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected byte[] getData() {
|
|
||||||
return data.getData();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void seek(long position) throws IOException {
|
|
||||||
byte[] data = key.getData();
|
|
||||||
int index = data.length - 8;
|
|
||||||
|
|
||||||
position >>>= JEIndexOutput.BLOCK_SHIFT;
|
|
||||||
|
|
||||||
data[index + 0] = (byte) (0xff & (position >>> 56));
|
|
||||||
data[index + 1] = (byte) (0xff & (position >>> 48));
|
|
||||||
data[index + 2] = (byte) (0xff & (position >>> 40));
|
|
||||||
data[index + 3] = (byte) (0xff & (position >>> 32));
|
|
||||||
data[index + 4] = (byte) (0xff & (position >>> 24));
|
|
||||||
data[index + 5] = (byte) (0xff & (position >>> 16));
|
|
||||||
data[index + 6] = (byte) (0xff & (position >>> 8));
|
|
||||||
data[index + 7] = (byte) (0xff & (position >>> 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void get(JEDirectory directory) throws IOException {
|
|
||||||
try {
|
|
||||||
// TODO check LockMode
|
|
||||||
directory.blocks.get(directory.txn, key, data, null);
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
throw new IOException(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void put(JEDirectory directory) throws IOException {
|
|
||||||
try {
|
|
||||||
directory.blocks.put(directory.txn, key, data);
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
throw new IOException(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,237 +0,0 @@
|
||||||
package org.apache.lucene.store.je;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import com.sleepycat.je.Cursor;
|
|
||||||
import com.sleepycat.je.Database;
|
|
||||||
import com.sleepycat.je.DatabaseEntry;
|
|
||||||
import com.sleepycat.je.DatabaseException;
|
|
||||||
import com.sleepycat.je.OperationStatus;
|
|
||||||
import com.sleepycat.je.Transaction;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Port of Andi Vajda's DbDirectory to Java Edition of Berkeley Database
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class File extends Object {
|
|
||||||
|
|
||||||
static protected Random random = new Random();
|
|
||||||
|
|
||||||
protected DatabaseEntry key, data;
|
|
||||||
|
|
||||||
protected long length, timeModified;
|
|
||||||
|
|
||||||
protected String name;
|
|
||||||
|
|
||||||
protected byte[] uuid;
|
|
||||||
|
|
||||||
protected File(String name) throws IOException {
|
|
||||||
setName(name);
|
|
||||||
|
|
||||||
data = new DatabaseEntry(new byte[32]);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected File(JEDirectory directory, String name, boolean create)
|
|
||||||
throws IOException {
|
|
||||||
this(name);
|
|
||||||
|
|
||||||
if (!exists(directory)) {
|
|
||||||
if (!create)
|
|
||||||
throw new IOException("File does not exist: " + name);
|
|
||||||
else {
|
|
||||||
DatabaseEntry key = new DatabaseEntry(new byte[24]);
|
|
||||||
DatabaseEntry data = new DatabaseEntry(null);
|
|
||||||
Database blocks = directory.blocks;
|
|
||||||
Transaction txn = directory.txn;
|
|
||||||
|
|
||||||
data.setPartial(true);
|
|
||||||
|
|
||||||
uuid = new byte[16];
|
|
||||||
|
|
||||||
try {
|
|
||||||
do {
|
|
||||||
/* generate a v.4 random-uuid unique to this db */
|
|
||||||
random.nextBytes(uuid);
|
|
||||||
uuid[6] = (byte) ((byte) 0x40 | (uuid[6] & (byte) 0x0f));
|
|
||||||
uuid[8] = (byte) ((byte) 0x80 | (uuid[8] & (byte) 0x3f));
|
|
||||||
System.arraycopy(uuid, 0, key.getData(), 0, 16);
|
|
||||||
// TODO check LockMode
|
|
||||||
} while (blocks.get(txn, key, data, null) != OperationStatus.NOTFOUND);
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
throw new IOException(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (create)
|
|
||||||
length = 0L;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setName(String name) throws IOException {
|
|
||||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream(128);
|
|
||||||
DataOutputStream out = new DataOutputStream(buffer);
|
|
||||||
|
|
||||||
out.writeUTF(name);
|
|
||||||
out.close();
|
|
||||||
|
|
||||||
key = new DatabaseEntry(buffer.toByteArray());
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected byte[] getKey() throws IOException {
|
|
||||||
if (uuid == null)
|
|
||||||
throw new IOException("Uninitialized file");
|
|
||||||
|
|
||||||
return uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected long getLength() {
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected long getTimeModified() {
|
|
||||||
return timeModified;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean exists(JEDirectory directory) throws IOException {
|
|
||||||
Database files = directory.files;
|
|
||||||
Transaction txn = directory.txn;
|
|
||||||
try {
|
|
||||||
// TODO check LockMode
|
|
||||||
if (files.get(txn, key, data, null) == OperationStatus.NOTFOUND)
|
|
||||||
return false;
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
throw new IOException(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] bytes = data.getData();
|
|
||||||
ByteArrayInputStream buffer = new ByteArrayInputStream(bytes);
|
|
||||||
DataInputStream in = new DataInputStream(buffer);
|
|
||||||
|
|
||||||
length = in.readLong();
|
|
||||||
timeModified = in.readLong();
|
|
||||||
in.close();
|
|
||||||
|
|
||||||
uuid = new byte[16];
|
|
||||||
System.arraycopy(bytes, 16, uuid, 0, 16);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void modify(JEDirectory directory, long length, long timeModified)
|
|
||||||
throws IOException {
|
|
||||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream(32);
|
|
||||||
DataOutputStream out = new DataOutputStream(buffer);
|
|
||||||
Database files = directory.files;
|
|
||||||
Transaction txn = directory.txn;
|
|
||||||
|
|
||||||
out.writeLong(length);
|
|
||||||
out.writeLong(timeModified);
|
|
||||||
out.write(getKey());
|
|
||||||
out.close();
|
|
||||||
|
|
||||||
System.arraycopy(buffer.toByteArray(), 0, data.getData(), 0, 32);
|
|
||||||
|
|
||||||
try {
|
|
||||||
files.put(txn, key, data);
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
throw new IOException(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
this.length = length;
|
|
||||||
this.timeModified = timeModified;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void delete(JEDirectory directory) throws IOException {
|
|
||||||
if (!exists(directory))
|
|
||||||
throw new IOException("File does not exist: " + getName());
|
|
||||||
|
|
||||||
Cursor cursor = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
try {
|
|
||||||
byte[] bytes = getKey();
|
|
||||||
int ulen = bytes.length + 8;
|
|
||||||
byte[] cursorBytes = new byte[ulen];
|
|
||||||
DatabaseEntry cursorKey = new DatabaseEntry(cursorBytes);
|
|
||||||
DatabaseEntry cursorData = new DatabaseEntry(null);
|
|
||||||
Database files = directory.files;
|
|
||||||
Database blocks = directory.blocks;
|
|
||||||
Transaction txn = directory.txn;
|
|
||||||
|
|
||||||
System.arraycopy(bytes, 0, cursorBytes, 0, bytes.length);
|
|
||||||
|
|
||||||
cursorData.setPartial(true);
|
|
||||||
|
|
||||||
cursor = blocks.openCursor(txn, null);
|
|
||||||
|
|
||||||
if (cursor.getSearchKey(cursorKey, cursorData, null) != OperationStatus.NOTFOUND) {
|
|
||||||
cursor.delete();
|
|
||||||
advance: while (cursor.getNext(cursorKey, cursorData, null) != OperationStatus.NOTFOUND) {
|
|
||||||
byte[] temp = cursorKey.getData();
|
|
||||||
for (int i = 0; i < bytes.length; i++)
|
|
||||||
if (bytes[i] != temp[i]) {
|
|
||||||
break advance;
|
|
||||||
}
|
|
||||||
cursor.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
files.delete(txn, key);
|
|
||||||
} finally {
|
|
||||||
if (cursor != null)
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
throw new IOException(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void rename(JEDirectory directory, String name)
|
|
||||||
throws IOException {
|
|
||||||
if (!exists(directory))
|
|
||||||
throw new IOException("File does not exist: " + getName());
|
|
||||||
|
|
||||||
File newFile = new File(name);
|
|
||||||
|
|
||||||
if (newFile.exists(directory))
|
|
||||||
newFile.delete(directory);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Database files = directory.files;
|
|
||||||
Transaction txn = directory.txn;
|
|
||||||
|
|
||||||
files.delete(txn, key);
|
|
||||||
setName(name);
|
|
||||||
files.put(txn, key, data);
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
throw new IOException(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,213 +0,0 @@
|
||||||
package org.apache.lucene.store.je;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.ByteArrayInputStream;
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import org.apache.lucene.store.Directory;
|
|
||||||
import org.apache.lucene.store.IndexInput;
|
|
||||||
import org.apache.lucene.store.IndexOutput;
|
|
||||||
import org.apache.lucene.store.Lock;
|
|
||||||
|
|
||||||
import com.sleepycat.je.Cursor;
|
|
||||||
import com.sleepycat.je.Database;
|
|
||||||
import com.sleepycat.je.DatabaseEntry;
|
|
||||||
import com.sleepycat.je.DatabaseException;
|
|
||||||
import com.sleepycat.je.OperationStatus;
|
|
||||||
import com.sleepycat.je.Transaction;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Port of Andi Vajda's DbDirectory to to Java Edition of Berkeley Database
|
|
||||||
*
|
|
||||||
* A JEDirectory is a Berkeley DB JE based implementation of
|
|
||||||
* {@link org.apache.lucene.store.Directory Directory}. It uses two
|
|
||||||
* {@link com.sleepycat.je.Database Db} database handles, one for storing file
|
|
||||||
* records and another for storing file data blocks.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class JEDirectory extends Directory {
|
|
||||||
|
|
||||||
protected Set<JEIndexOutput> openFiles = Collections.synchronizedSet(new HashSet<JEIndexOutput>());
|
|
||||||
|
|
||||||
protected Database files, blocks;
|
|
||||||
|
|
||||||
protected Transaction txn;
|
|
||||||
|
|
||||||
protected int flags;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instantiate a DbDirectory. The same threading rules that apply to
|
|
||||||
* Berkeley DB handles apply to instances of DbDirectory.
|
|
||||||
*
|
|
||||||
* @param txn
|
|
||||||
* a transaction handle that is going to be used for all db
|
|
||||||
* operations done by this instance. This parameter may be
|
|
||||||
* <code>null</code>.
|
|
||||||
* @param files
|
|
||||||
* a db handle to store file records.
|
|
||||||
* @param blocks
|
|
||||||
* a db handle to store file data blocks.
|
|
||||||
* @param flags
|
|
||||||
* flags used for db read operations.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public JEDirectory(Transaction txn, Database files, Database blocks,
|
|
||||||
int flags) {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.txn = txn;
|
|
||||||
this.files = files;
|
|
||||||
this.blocks = blocks;
|
|
||||||
this.flags = flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JEDirectory(Transaction txn, Database files, Database blocks) {
|
|
||||||
this(txn, files, blocks, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flush the currently open files. After they have been flushed it is safe
|
|
||||||
* to commit the transaction without closing this DbDirectory instance
|
|
||||||
* first.
|
|
||||||
*
|
|
||||||
* @see #setTransaction
|
|
||||||
*/
|
|
||||||
public void flush() throws IOException {
|
|
||||||
Iterator<JEIndexOutput> iterator = openFiles.iterator();
|
|
||||||
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
System.out
|
|
||||||
.println(iterator.next().file.getName());
|
|
||||||
// ((IndexOutput) iterator.next()).flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IndexOutput createOutput(String name) throws IOException {
|
|
||||||
return new JEIndexOutput(this, name, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteFile(String name) throws IOException {
|
|
||||||
new File(name).delete(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean fileExists(String name) throws IOException {
|
|
||||||
return new File(name).exists(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long fileLength(String name) throws IOException {
|
|
||||||
File file = new File(name);
|
|
||||||
|
|
||||||
if (file.exists(this))
|
|
||||||
return file.getLength();
|
|
||||||
|
|
||||||
throw new FileNotFoundException(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long fileModified(String name) throws IOException {
|
|
||||||
File file = new File(name);
|
|
||||||
|
|
||||||
if (file.exists(this))
|
|
||||||
return file.getTimeModified();
|
|
||||||
|
|
||||||
throw new IOException("File does not exist: " + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] listAll() throws IOException {
|
|
||||||
Cursor cursor = null;
|
|
||||||
List<String> list = new ArrayList<String>();
|
|
||||||
|
|
||||||
try {
|
|
||||||
try {
|
|
||||||
DatabaseEntry key = new DatabaseEntry(new byte[0]);
|
|
||||||
DatabaseEntry data = new DatabaseEntry(null);
|
|
||||||
|
|
||||||
data.setPartial(true);
|
|
||||||
// TODO see if cursor needs configuration
|
|
||||||
cursor = files.openCursor(txn, null);
|
|
||||||
// TODO see if LockMode should be set
|
|
||||||
if (cursor.getNext(key, data, null) != OperationStatus.NOTFOUND) {
|
|
||||||
ByteArrayInputStream buffer = new ByteArrayInputStream(key
|
|
||||||
.getData());
|
|
||||||
DataInputStream in = new DataInputStream(buffer);
|
|
||||||
String name = in.readUTF();
|
|
||||||
|
|
||||||
in.close();
|
|
||||||
list.add(name);
|
|
||||||
|
|
||||||
while (cursor.getNext(key, data, null) != OperationStatus.NOTFOUND) {
|
|
||||||
buffer = new ByteArrayInputStream(key.getData());
|
|
||||||
in = new DataInputStream(buffer);
|
|
||||||
name = in.readUTF();
|
|
||||||
in.close();
|
|
||||||
|
|
||||||
list.add(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (cursor != null)
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
throw new IOException(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return list.toArray(new String[list.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IndexInput openInput(String name) throws IOException {
|
|
||||||
return new JEIndexInput(this, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sync(Collection<String> names) throws IOException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Lock makeLock(String name) {
|
|
||||||
return new JELock();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Once a transaction handle was committed it is no longer valid. In order
|
|
||||||
* to continue using this JEDirectory instance after a commit, the
|
|
||||||
* transaction handle has to be replaced.
|
|
||||||
*
|
|
||||||
* @param txn
|
|
||||||
* the new transaction handle to use
|
|
||||||
*/
|
|
||||||
public void setTransaction(Transaction txn) {
|
|
||||||
this.txn = txn;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,141 +0,0 @@
|
||||||
package org.apache.lucene.store.je;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 org.apache.lucene.store.IndexInput;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Port of Andi Vajda's DbDirectory to Java Edition of Berkeley Database
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class JEIndexInput extends IndexInput {
|
|
||||||
|
|
||||||
protected long position = 0L, length = 0L;
|
|
||||||
|
|
||||||
protected JEDirectory directory;
|
|
||||||
|
|
||||||
protected Block block;
|
|
||||||
|
|
||||||
protected File file;
|
|
||||||
|
|
||||||
protected JEIndexInput(JEDirectory directory, String name)
|
|
||||||
throws IOException {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.directory = directory;
|
|
||||||
|
|
||||||
this.file = new File(name);
|
|
||||||
if (!file.exists(directory))
|
|
||||||
throw new IOException("File does not exist: " + name);
|
|
||||||
|
|
||||||
length = file.getLength();
|
|
||||||
|
|
||||||
block = new Block(file);
|
|
||||||
block.get(directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object clone() {
|
|
||||||
try {
|
|
||||||
JEIndexInput clone = (JEIndexInput) super.clone();
|
|
||||||
|
|
||||||
clone.block = new Block(file);
|
|
||||||
clone.block.seek(position);
|
|
||||||
clone.block.get(directory);
|
|
||||||
|
|
||||||
return clone;
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long length() {
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte readByte() throws IOException {
|
|
||||||
if (position + 1 > length)
|
|
||||||
throw new IOException(file.getName() + ": Reading past end of file");
|
|
||||||
|
|
||||||
int blockPos = (int) (position++ & JEIndexOutput.BLOCK_MASK);
|
|
||||||
byte b = block.getData()[blockPos];
|
|
||||||
|
|
||||||
if (blockPos + 1 == JEIndexOutput.BLOCK_LEN) {
|
|
||||||
block.seek(position);
|
|
||||||
block.get(directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void readBytes(byte[] b, int offset, int len) throws IOException {
|
|
||||||
if (position + len > length)
|
|
||||||
throw new IOException("Reading past end of file");
|
|
||||||
else {
|
|
||||||
int blockPos = (int) (position & JEIndexOutput.BLOCK_MASK);
|
|
||||||
|
|
||||||
while (blockPos + len >= JEIndexOutput.BLOCK_LEN) {
|
|
||||||
int blockLen = JEIndexOutput.BLOCK_LEN - blockPos;
|
|
||||||
|
|
||||||
System
|
|
||||||
.arraycopy(block.getData(), blockPos, b, offset,
|
|
||||||
blockLen);
|
|
||||||
|
|
||||||
len -= blockLen;
|
|
||||||
offset += blockLen;
|
|
||||||
position += blockLen;
|
|
||||||
|
|
||||||
block.seek(position);
|
|
||||||
block.get(directory);
|
|
||||||
blockPos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len > 0) {
|
|
||||||
System.arraycopy(block.getData(), blockPos, b, offset, len);
|
|
||||||
position += len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void seek(long pos) throws IOException {
|
|
||||||
if (pos > length)
|
|
||||||
throw new IOException("seeking past end of file");
|
|
||||||
|
|
||||||
if ((pos >>> JEIndexOutput.BLOCK_SHIFT) != (position >>> JEIndexOutput.BLOCK_SHIFT)) {
|
|
||||||
block.seek(pos);
|
|
||||||
block.get(directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
position = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getFilePointer() {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,147 +0,0 @@
|
||||||
package org.apache.lucene.store.je;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 org.apache.lucene.store.IndexOutput;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Port of Andi Vajda's DbDirectory to Java Edition of Berkeley Database
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class JEIndexOutput extends IndexOutput {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The size of data blocks, currently 16k (2^14), is determined by this
|
|
||||||
* constant.
|
|
||||||
*/
|
|
||||||
static public final int BLOCK_SHIFT = 14;
|
|
||||||
|
|
||||||
static public final int BLOCK_LEN = 1 << BLOCK_SHIFT;
|
|
||||||
|
|
||||||
static public final int BLOCK_MASK = BLOCK_LEN - 1;
|
|
||||||
|
|
||||||
protected long position = 0L, length = 0L;
|
|
||||||
|
|
||||||
protected JEDirectory directory;
|
|
||||||
|
|
||||||
protected Block block;
|
|
||||||
|
|
||||||
protected File file;
|
|
||||||
|
|
||||||
protected JEIndexOutput(JEDirectory directory, String name, boolean create)
|
|
||||||
throws IOException {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.directory = directory;
|
|
||||||
|
|
||||||
file = new File(directory, name, create);
|
|
||||||
block = new Block(file);
|
|
||||||
length = file.getLength();
|
|
||||||
|
|
||||||
seek(length);
|
|
||||||
block.get(directory);
|
|
||||||
|
|
||||||
directory.openFiles.add(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
flush();
|
|
||||||
file.modify(directory, length, System.currentTimeMillis());
|
|
||||||
|
|
||||||
directory.openFiles.remove(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void flush() throws IOException {
|
|
||||||
if (length > 0)
|
|
||||||
block.put(directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeByte(byte b) throws IOException {
|
|
||||||
int blockPos = (int) (position++ & BLOCK_MASK);
|
|
||||||
|
|
||||||
block.getData()[blockPos] = b;
|
|
||||||
|
|
||||||
if (blockPos + 1 == BLOCK_LEN) {
|
|
||||||
block.put(directory);
|
|
||||||
block.seek(position);
|
|
||||||
block.get(directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (position > length)
|
|
||||||
length = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeBytes(byte[] b, int offset, int len) throws IOException {
|
|
||||||
int blockPos = (int) (position & BLOCK_MASK);
|
|
||||||
|
|
||||||
while (blockPos + len >= BLOCK_LEN) {
|
|
||||||
int blockLen = BLOCK_LEN - blockPos;
|
|
||||||
|
|
||||||
System.arraycopy(b, offset, block.getData(), blockPos, blockLen);
|
|
||||||
block.put(directory);
|
|
||||||
|
|
||||||
len -= blockLen;
|
|
||||||
offset += blockLen;
|
|
||||||
position += blockLen;
|
|
||||||
|
|
||||||
block.seek(position);
|
|
||||||
block.get(directory);
|
|
||||||
blockPos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len > 0) {
|
|
||||||
System.arraycopy(b, offset, block.getData(), blockPos, len);
|
|
||||||
position += len;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (position > length)
|
|
||||||
length = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long length() throws IOException {
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void seek(long pos) throws IOException {
|
|
||||||
if (pos > length)
|
|
||||||
throw new IOException("seeking past end of file");
|
|
||||||
|
|
||||||
if ((pos >>> BLOCK_SHIFT) == (position >>> BLOCK_SHIFT))
|
|
||||||
position = pos;
|
|
||||||
else {
|
|
||||||
block.put(directory);
|
|
||||||
block.seek(pos);
|
|
||||||
block.get(directory);
|
|
||||||
position = pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getFilePointer() {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
package org.apache.lucene.store.je;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 org.apache.lucene.store.Lock;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Port of Andi Vajda's DbDirectory to Java Edition of Berkeley Database
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class JELock extends Lock {
|
|
||||||
|
|
||||||
boolean isLocked = false;
|
|
||||||
|
|
||||||
public JELock()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean obtain()
|
|
||||||
{
|
|
||||||
return (isLocked = true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void release()
|
|
||||||
{
|
|
||||||
isLocked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isLocked()
|
|
||||||
{
|
|
||||||
return isLocked;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
|
||||||
<!--
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
<html>
|
|
||||||
<body>
|
|
||||||
Berkeley DB Java Edition based implementation of {@link org.apache.lucene.store.Directory Directory}.
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,26 +0,0 @@
|
||||||
<!--
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>
|
|
||||||
bdb-je
|
|
||||||
</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
bdb-je
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,636 +0,0 @@
|
||||||
package org.apache.lucene.store.je;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import org.apache.lucene.store.Directory;
|
|
||||||
import org.apache.lucene.store.IndexInput;
|
|
||||||
import org.apache.lucene.store.IndexOutput;
|
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
|
||||||
|
|
||||||
import com.sleepycat.je.Cursor;
|
|
||||||
import com.sleepycat.je.Database;
|
|
||||||
import com.sleepycat.je.DatabaseConfig;
|
|
||||||
import com.sleepycat.je.DatabaseEntry;
|
|
||||||
import com.sleepycat.je.DatabaseException;
|
|
||||||
import com.sleepycat.je.Environment;
|
|
||||||
import com.sleepycat.je.EnvironmentConfig;
|
|
||||||
import com.sleepycat.je.LockMode;
|
|
||||||
import com.sleepycat.je.OperationStatus;
|
|
||||||
import com.sleepycat.je.Transaction;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link JEDirectory}.
|
|
||||||
*
|
|
||||||
* Adapted from Andi Vajda's org.apache.lucene.db.DbStoreTest.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class JEStoreTest extends LuceneTestCase {
|
|
||||||
protected File dbHome = new File(TEMP_DIR,"index");
|
|
||||||
|
|
||||||
protected Environment env;
|
|
||||||
|
|
||||||
protected Database index, blocks;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
|
|
||||||
if (!dbHome.exists())
|
|
||||||
dbHome.mkdir();
|
|
||||||
else {
|
|
||||||
File[] files = dbHome.listFiles();
|
|
||||||
|
|
||||||
for (int i = 0; i < files.length; i++) {
|
|
||||||
String name = files[i].getName();
|
|
||||||
if (name.endsWith("jdb") || name.equals("je.lck"))
|
|
||||||
files[i].delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EnvironmentConfig envConfig = new EnvironmentConfig();
|
|
||||||
DatabaseConfig dbConfig = new DatabaseConfig();
|
|
||||||
|
|
||||||
envConfig.setTransactional(true);
|
|
||||||
envConfig.setAllowCreate(true);
|
|
||||||
dbConfig.setAllowCreate(true);
|
|
||||||
dbConfig.setTransactional(true);
|
|
||||||
|
|
||||||
env = new Environment(dbHome, envConfig);
|
|
||||||
|
|
||||||
Transaction txn = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
txn = env.beginTransaction(null, null);
|
|
||||||
index = env.openDatabase(txn, "__index__", dbConfig);
|
|
||||||
blocks = env.openDatabase(txn, "__blocks__", dbConfig);
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
if (txn != null) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
}
|
|
||||||
index = null;
|
|
||||||
blocks = null;
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
if (txn != null)
|
|
||||||
txn.commit();
|
|
||||||
txn = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
|
|
||||||
if (index != null)
|
|
||||||
index.close();
|
|
||||||
if (blocks != null)
|
|
||||||
blocks.close();
|
|
||||||
if (env != null)
|
|
||||||
env.close();
|
|
||||||
super.tearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testBytes() throws Exception {
|
|
||||||
final int count = 250;
|
|
||||||
final int LENGTH_MASK = 0xffff;
|
|
||||||
|
|
||||||
Random r = random;
|
|
||||||
final long seed = r.nextLong();
|
|
||||||
Random gen = new Random(seed);
|
|
||||||
int totalLength = 0;
|
|
||||||
int duration;
|
|
||||||
Date end;
|
|
||||||
|
|
||||||
Date veryStart = new Date();
|
|
||||||
Date start = new Date();
|
|
||||||
Transaction txn = env.beginTransaction(null, null);
|
|
||||||
Directory store = null;
|
|
||||||
|
|
||||||
if (VERBOSE) System.out.println("Writing files byte by byte");
|
|
||||||
|
|
||||||
try {
|
|
||||||
store = new JEDirectory(txn, index, blocks);
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
String name = i + ".dat";
|
|
||||||
int length = gen.nextInt() & LENGTH_MASK;
|
|
||||||
IndexOutput file = store.createOutput(name);
|
|
||||||
|
|
||||||
totalLength += length;
|
|
||||||
|
|
||||||
for (int j = 0; j < length; j++) {
|
|
||||||
byte b = (byte) (gen.nextInt() & 0x7F);
|
|
||||||
file.writeByte(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
if (txn != null)
|
|
||||||
txn.commit();
|
|
||||||
|
|
||||||
store.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
end = new Date();
|
|
||||||
|
|
||||||
if (VERBOSE) {
|
|
||||||
duration = (int) (end.getTime() - start.getTime());
|
|
||||||
System.out.print(duration);
|
|
||||||
System.out.print(" total milliseconds to create, ");
|
|
||||||
System.out.print(totalLength / duration);
|
|
||||||
System.out.println(" kb/s");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
txn = env.beginTransaction(null, null);
|
|
||||||
store = new JEDirectory(txn, index, blocks);
|
|
||||||
|
|
||||||
gen = new Random(seed);
|
|
||||||
start = new Date();
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
String name = i + ".dat";
|
|
||||||
int length = gen.nextInt() & LENGTH_MASK;
|
|
||||||
IndexInput file = store.openInput(name);
|
|
||||||
|
|
||||||
if (file.length() != length)
|
|
||||||
throw new Exception("length incorrect");
|
|
||||||
|
|
||||||
for (int j = 0; j < length; j++) {
|
|
||||||
byte b = (byte) (gen.nextInt() & 0x7F);
|
|
||||||
|
|
||||||
if (file.readByte() != b)
|
|
||||||
throw new Exception("contents incorrect");
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
throw e;
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
if (txn != null) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
if (txn != null)
|
|
||||||
txn.commit();
|
|
||||||
|
|
||||||
store.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
end = new Date();
|
|
||||||
|
|
||||||
if (VERBOSE) {
|
|
||||||
duration = (int) (end.getTime() - start.getTime());
|
|
||||||
System.out.print(duration);
|
|
||||||
System.out.print(" total milliseconds to read, ");
|
|
||||||
System.out.print(totalLength / duration);
|
|
||||||
System.out.println(" kb/s");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
txn = env.beginTransaction(null, null);
|
|
||||||
store = new JEDirectory(txn, index, blocks);
|
|
||||||
|
|
||||||
gen = new Random(seed);
|
|
||||||
start = new Date();
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
String name = i + ".dat";
|
|
||||||
store.deleteFile(name);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
throw e;
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
if (txn != null) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
if (txn != null)
|
|
||||||
txn.commit();
|
|
||||||
|
|
||||||
store.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
end = new Date();
|
|
||||||
|
|
||||||
if (VERBOSE) {
|
|
||||||
System.out.print(end.getTime() - start.getTime());
|
|
||||||
System.out.println(" total milliseconds to delete");
|
|
||||||
|
|
||||||
System.out.print(end.getTime() - veryStart.getTime());
|
|
||||||
System.out.println(" total milliseconds");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testDelete() throws Exception {
|
|
||||||
final int count = 250;
|
|
||||||
final int LENGTH_MASK = 0xffff;
|
|
||||||
|
|
||||||
Random r = random;
|
|
||||||
final long seed = r.nextLong();
|
|
||||||
Random gen = new Random(seed);
|
|
||||||
int totalLength = 0;
|
|
||||||
int duration;
|
|
||||||
Date end;
|
|
||||||
|
|
||||||
Date veryStart = new Date();
|
|
||||||
Date start = new Date();
|
|
||||||
Transaction txn = env.beginTransaction(null, null);
|
|
||||||
Directory store = null;
|
|
||||||
|
|
||||||
if (VERBOSE) System.out.println("Writing files byte by byte");
|
|
||||||
|
|
||||||
try {
|
|
||||||
store = new JEDirectory(txn, index, blocks);
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
String name = i + ".dat";
|
|
||||||
int length = gen.nextInt() & LENGTH_MASK;
|
|
||||||
IndexOutput file = store.createOutput(name);
|
|
||||||
|
|
||||||
totalLength += length;
|
|
||||||
|
|
||||||
for (int j = 0; j < length; j++) {
|
|
||||||
byte b = (byte) (gen.nextInt() & 0x7F);
|
|
||||||
file.writeByte(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
if (txn != null)
|
|
||||||
txn.commit();
|
|
||||||
|
|
||||||
store.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
end = new Date();
|
|
||||||
|
|
||||||
if (VERBOSE) {
|
|
||||||
duration = (int) (end.getTime() - start.getTime());
|
|
||||||
System.out.print(duration);
|
|
||||||
System.out.print(" total milliseconds to read, ");
|
|
||||||
System.out.print(totalLength / duration);
|
|
||||||
System.out.println(" kb/s");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
txn = env.beginTransaction(null, null);
|
|
||||||
store = new JEDirectory(txn, index, blocks);
|
|
||||||
|
|
||||||
gen = new Random(seed);
|
|
||||||
start = new Date();
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
if (i % 2 == 0) {
|
|
||||||
String name = i + ".dat";
|
|
||||||
store.deleteFile(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
throw e;
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
if (txn != null) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
if (txn != null)
|
|
||||||
txn.commit();
|
|
||||||
|
|
||||||
store.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
end = new Date();
|
|
||||||
|
|
||||||
if (VERBOSE) {
|
|
||||||
System.out.print(end.getTime() - start.getTime());
|
|
||||||
System.out.println(" total milliseconds to delete even files");
|
|
||||||
|
|
||||||
duration = (int) (end.getTime() - start.getTime());
|
|
||||||
System.out.print(duration);
|
|
||||||
System.out.print(" total milliseconds to create, ");
|
|
||||||
System.out.print(totalLength / duration);
|
|
||||||
System.out.println(" kb/s");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
txn = env.beginTransaction(null, null);
|
|
||||||
store = new JEDirectory(txn, index, blocks);
|
|
||||||
|
|
||||||
gen = new Random(seed);
|
|
||||||
start = new Date();
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
int length = gen.nextInt() & LENGTH_MASK;
|
|
||||||
|
|
||||||
if (i % 2 != 0) {
|
|
||||||
String name = i + ".dat";
|
|
||||||
IndexInput file = store.openInput(name);
|
|
||||||
if (file.length() != length)
|
|
||||||
throw new Exception("length incorrect");
|
|
||||||
|
|
||||||
for (int j = 0; j < length; j++) {
|
|
||||||
byte b = (byte) (gen.nextInt() & 0x7F);
|
|
||||||
|
|
||||||
if (file.readByte() != b)
|
|
||||||
throw new Exception("contents incorrect");
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
} else {
|
|
||||||
for (int j = 0; j < length; j++) {
|
|
||||||
gen.nextInt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
throw e;
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
if (txn != null) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
if (txn != null)
|
|
||||||
txn.commit();
|
|
||||||
|
|
||||||
store.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
end = new Date();
|
|
||||||
|
|
||||||
if (VERBOSE) {
|
|
||||||
duration = (int) (end.getTime() - start.getTime());
|
|
||||||
System.out.print(duration);
|
|
||||||
System.out.print(" total milliseconds to read, ");
|
|
||||||
System.out.print(totalLength / duration);
|
|
||||||
System.out.println(" kb/s");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
txn = env.beginTransaction(null, null);
|
|
||||||
store = new JEDirectory(txn, index, blocks);
|
|
||||||
|
|
||||||
gen = new Random(seed);
|
|
||||||
start = new Date();
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
if (i % 2 != 0) {
|
|
||||||
String name = i + ".dat";
|
|
||||||
store.deleteFile(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
throw e;
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
if (txn != null) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
if (txn != null)
|
|
||||||
txn.commit();
|
|
||||||
|
|
||||||
store.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
end = new Date();
|
|
||||||
|
|
||||||
if (VERBOSE) {
|
|
||||||
System.out.print(end.getTime() - start.getTime());
|
|
||||||
System.out.println(" total milliseconds to delete");
|
|
||||||
|
|
||||||
System.out.print(end.getTime() - veryStart.getTime());
|
|
||||||
System.out.println(" total milliseconds");
|
|
||||||
}
|
|
||||||
|
|
||||||
Cursor cursor = null;
|
|
||||||
try {
|
|
||||||
cursor = index.openCursor(null, null);
|
|
||||||
|
|
||||||
DatabaseEntry foundKey = new DatabaseEntry();
|
|
||||||
DatabaseEntry foundData = new DatabaseEntry();
|
|
||||||
|
|
||||||
if (cursor.getNext(foundKey, foundData, LockMode.DEFAULT) == OperationStatus.SUCCESS) {
|
|
||||||
fail("index database is not empty");
|
|
||||||
}
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
if (cursor != null)
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor = null;
|
|
||||||
try {
|
|
||||||
cursor = blocks.openCursor(null, null);
|
|
||||||
|
|
||||||
DatabaseEntry foundKey = new DatabaseEntry();
|
|
||||||
DatabaseEntry foundData = new DatabaseEntry();
|
|
||||||
|
|
||||||
if (cursor.getNext(foundKey, foundData, LockMode.DEFAULT) == OperationStatus.SUCCESS) {
|
|
||||||
fail("blocks database is not empty");
|
|
||||||
}
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
if (cursor != null)
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testArrays() throws Exception {
|
|
||||||
final int count = 250;
|
|
||||||
final int LENGTH_MASK = 0xffff;
|
|
||||||
|
|
||||||
Random r = random;
|
|
||||||
final long seed = r.nextLong();
|
|
||||||
Random gen = new Random(seed);
|
|
||||||
int totalLength = 0;
|
|
||||||
int duration;
|
|
||||||
Date end;
|
|
||||||
|
|
||||||
Date veryStart = new Date();
|
|
||||||
Date start = new Date();
|
|
||||||
Transaction txn = env.beginTransaction(null, null);
|
|
||||||
Directory store = null;
|
|
||||||
|
|
||||||
if (VERBOSE) System.out.println("Writing files as one byte array");
|
|
||||||
|
|
||||||
try {
|
|
||||||
store = new JEDirectory(txn, index, blocks);
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
String name = i + ".dat";
|
|
||||||
int length = gen.nextInt() & LENGTH_MASK;
|
|
||||||
IndexOutput file = store.createOutput(name);
|
|
||||||
byte[] data = new byte[length];
|
|
||||||
|
|
||||||
totalLength += length;
|
|
||||||
gen.nextBytes(data);
|
|
||||||
file.writeBytes(data, length);
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
if (txn != null)
|
|
||||||
txn.commit();
|
|
||||||
|
|
||||||
store.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
end = new Date();
|
|
||||||
|
|
||||||
if (VERBOSE) {
|
|
||||||
duration = (int) (end.getTime() - start.getTime());
|
|
||||||
System.out.print(duration);
|
|
||||||
System.out.print(" total milliseconds to create, ");
|
|
||||||
System.out.print(totalLength / duration);
|
|
||||||
System.out.println(" kb/s");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
txn = env.beginTransaction(null, null);
|
|
||||||
store = new JEDirectory(txn, index, blocks);
|
|
||||||
|
|
||||||
gen = new Random(seed);
|
|
||||||
start = new Date();
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
String name = i + ".dat";
|
|
||||||
int length = gen.nextInt() & LENGTH_MASK;
|
|
||||||
IndexInput file = store.openInput(name);
|
|
||||||
|
|
||||||
if (file.length() != length)
|
|
||||||
throw new Exception("length incorrect");
|
|
||||||
|
|
||||||
byte[] data = new byte[length];
|
|
||||||
byte[] read = new byte[length];
|
|
||||||
gen.nextBytes(data);
|
|
||||||
file.readBytes(read, 0, length);
|
|
||||||
|
|
||||||
if (!Arrays.equals(data, read))
|
|
||||||
throw new Exception("contents incorrect");
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
throw e;
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
if (txn != null) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
if (txn != null)
|
|
||||||
txn.commit();
|
|
||||||
|
|
||||||
store.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
end = new Date();
|
|
||||||
|
|
||||||
if (VERBOSE) {
|
|
||||||
duration = (int) (end.getTime() - start.getTime());
|
|
||||||
System.out.print(duration);
|
|
||||||
System.out.print(" total milliseconds to read, ");
|
|
||||||
System.out.print(totalLength / duration);
|
|
||||||
System.out.println(" kb/s");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
txn = env.beginTransaction(null, null);
|
|
||||||
store = new JEDirectory(txn, index, blocks);
|
|
||||||
|
|
||||||
gen = new Random(seed);
|
|
||||||
start = new Date();
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
String name = i + ".dat";
|
|
||||||
store.deleteFile(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
throw e;
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
if (txn != null) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
if (txn != null)
|
|
||||||
txn.commit();
|
|
||||||
|
|
||||||
store.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
end = new Date();
|
|
||||||
|
|
||||||
if (VERBOSE) {
|
|
||||||
System.out.print(end.getTime() - start.getTime());
|
|
||||||
System.out.println(" total milliseconds to delete");
|
|
||||||
|
|
||||||
System.out.print(end.getTime() - veryStart.getTime());
|
|
||||||
System.out.println(" total milliseconds");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,77 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
<!--
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
<project name="bdb" default="default">
|
|
||||||
|
|
||||||
<description>
|
|
||||||
Lucene Berkeley DB integration
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<property name="db.version" value="4.7.25" />
|
|
||||||
|
|
||||||
<path id="db.jar">
|
|
||||||
<pathelement location="lib/db-${db.version}.jar" />
|
|
||||||
</path>
|
|
||||||
|
|
||||||
<available classname="com.sleepycat.db.internal.Db" property="db.jar.exists">
|
|
||||||
<classpath refid="db.jar" />
|
|
||||||
</available>
|
|
||||||
|
|
||||||
<pathconvert property="project.classpath" targetos="unix" refid="db.jar" />
|
|
||||||
|
|
||||||
<property name="build.dir" location="../../../build/contrib/db/bdb" />
|
|
||||||
<property name="dist.dir" location="../../../dist/contrib/db/bdb" />
|
|
||||||
<property name="maven.dist.dir" location="../../../dist/maven" />
|
|
||||||
|
|
||||||
<import file="../../contrib-build.xml" />
|
|
||||||
|
|
||||||
<target name="get-db-jar" unless="db.jar.exists">
|
|
||||||
<mkdir dir="lib" />
|
|
||||||
<get src="http://downloads.osafoundation.org/db/db-${db.version}.jar"
|
|
||||||
dest="lib/db-${db.version}.jar" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="sanity-load-lib" depends="compile-test">
|
|
||||||
<java classname="org.apache.lucene.store.db.SanityLoadLibrary"
|
|
||||||
classpathref="junit.classpath"
|
|
||||||
fork="true"
|
|
||||||
failonerror="false"
|
|
||||||
logError="false"
|
|
||||||
outputproperty="sanity-load-lib-error"
|
|
||||||
/>
|
|
||||||
<condition property="no-bdb-lib" value="true">
|
|
||||||
<and>
|
|
||||||
<isset property="sanity-load-lib-error"/>
|
|
||||||
<not>
|
|
||||||
<equals arg1="${sanity-load-lib-error}" arg2="" trim="true" />
|
|
||||||
</not>
|
|
||||||
</and>
|
|
||||||
</condition>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="warn-no-lib" if="no-bdb-lib">
|
|
||||||
<echo>Unit Tests Skipped: Could not sanity check Native Library</echo>
|
|
||||||
</target>
|
|
||||||
<target name="test" depends="sanity-load-lib,warn-no-lib"
|
|
||||||
unless="no-bdb-lib">
|
|
||||||
<antcall target="common.test" inheritAll="true" inheritRefs="true" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="check-and-get-db-jar" depends="get-db-jar" />
|
|
||||||
<target name="init" depends="contrib-build.init,check-and-get-db-jar" />
|
|
||||||
|
|
||||||
</project>
|
|
|
@ -1 +0,0 @@
|
||||||
No bdb jars are shipped with lucene. This is a fake license to work around the automated license checking.
|
|
|
@ -1,2 +0,0 @@
|
||||||
AnyObjectId[99baf20bacd712cae91dd6e4e1f46224cafa1a37] was removed in git history.
|
|
||||||
Apache SVN contains full history.
|
|
|
@ -1 +0,0 @@
|
||||||
No bdb jars are shipped with lucene. This is a fake license to work around the automated license checking.
|
|
|
@ -1,50 +0,0 @@
|
||||||
package com.sleepycat.db;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 com.sleepycat.db.internal.Db;
|
|
||||||
import com.sleepycat.db.internal.DbTxn;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class is a hack to workaround the need to rewrite the entire
|
|
||||||
* org.apache.lucene.store.db package after Sleepycat radically changed its
|
|
||||||
* Java API from version 4.2.52 to version 4.3.21.
|
|
||||||
*
|
|
||||||
* The code below extracts the package-accessible internal handle instances
|
|
||||||
* that were the entrypoint objects in the pre-4.3 Java API and that wrap the
|
|
||||||
* actual Berkeley DB C objects via SWIG.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class DbHandleExtractor {
|
|
||||||
|
|
||||||
private DbHandleExtractor()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static public Db getDb(Database database)
|
|
||||||
{
|
|
||||||
return database.db;
|
|
||||||
}
|
|
||||||
|
|
||||||
static public DbTxn getDbTxn(Transaction transaction)
|
|
||||||
{
|
|
||||||
return transaction.txn;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,92 +0,0 @@
|
||||||
package org.apache.lucene.store.db;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 com.sleepycat.db.DatabaseEntry;
|
|
||||||
import com.sleepycat.db.DatabaseException;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class Block extends Object {
|
|
||||||
protected DatabaseEntry key, data;
|
|
||||||
|
|
||||||
protected Block(File file)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
byte[] fileKey = file.getKey();
|
|
||||||
|
|
||||||
key = new DatabaseEntry(new byte[fileKey.length + 8]);
|
|
||||||
key.setUserBuffer(fileKey.length + 8, true);
|
|
||||||
|
|
||||||
data = new DatabaseEntry(new byte[DbIndexOutput.BLOCK_LEN]);
|
|
||||||
data.setUserBuffer(data.getSize(), true);
|
|
||||||
|
|
||||||
System.arraycopy(fileKey, 0, key.getData(), 0, fileKey.length);
|
|
||||||
seek(0L);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected byte[] getKey()
|
|
||||||
{
|
|
||||||
return key.getData();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected byte[] getData()
|
|
||||||
{
|
|
||||||
return data.getData();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void seek(long position)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
byte[] data = key.getData();
|
|
||||||
int index = data.length - 8;
|
|
||||||
|
|
||||||
position >>>= DbIndexOutput.BLOCK_SHIFT;
|
|
||||||
|
|
||||||
data[index + 0] = (byte) (0xff & (position >>> 56));
|
|
||||||
data[index + 1] = (byte) (0xff & (position >>> 48));
|
|
||||||
data[index + 2] = (byte) (0xff & (position >>> 40));
|
|
||||||
data[index + 3] = (byte) (0xff & (position >>> 32));
|
|
||||||
data[index + 4] = (byte) (0xff & (position >>> 24));
|
|
||||||
data[index + 5] = (byte) (0xff & (position >>> 16));
|
|
||||||
data[index + 6] = (byte) (0xff & (position >>> 8));
|
|
||||||
data[index + 7] = (byte) (0xff & (position >>> 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void get(DbDirectory directory)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
directory.blocks.get(directory.txn, key, data, directory.flags);
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
throw new IOException(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void put(DbDirectory directory)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
directory.blocks.put(directory.txn, key, data, 0);
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
throw new IOException(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,246 +0,0 @@
|
||||||
package org.apache.lucene.store.db;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import org.apache.lucene.store.Directory;
|
|
||||||
import org.apache.lucene.store.Lock;
|
|
||||||
import org.apache.lucene.store.IndexOutput;
|
|
||||||
import org.apache.lucene.store.IndexInput;
|
|
||||||
|
|
||||||
import com.sleepycat.db.internal.Db;
|
|
||||||
import com.sleepycat.db.internal.DbConstants;
|
|
||||||
import com.sleepycat.db.DatabaseEntry;
|
|
||||||
import com.sleepycat.db.internal.Dbc;
|
|
||||||
import com.sleepycat.db.internal.DbTxn;
|
|
||||||
import com.sleepycat.db.DatabaseException;
|
|
||||||
|
|
||||||
import com.sleepycat.db.Database;
|
|
||||||
import com.sleepycat.db.Transaction;
|
|
||||||
import com.sleepycat.db.DbHandleExtractor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A DbDirectory is a Berkeley DB 4.3 based implementation of
|
|
||||||
* {@link org.apache.lucene.store.Directory Directory}. It uses two
|
|
||||||
* {@link com.sleepycat.db.internal.Db Db} database handles, one for storing file
|
|
||||||
* records and another for storing file data blocks.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class DbDirectory extends Directory {
|
|
||||||
|
|
||||||
protected Set<DbIndexOutput> openFiles = Collections.synchronizedSet(new HashSet<DbIndexOutput>());
|
|
||||||
protected Db files, blocks;
|
|
||||||
protected DbTxn txn;
|
|
||||||
protected int flags;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instantiate a DbDirectory. The same threading rules that apply to
|
|
||||||
* Berkeley DB handles apply to instances of DbDirectory.
|
|
||||||
*
|
|
||||||
* @param txn a transaction handle that is going to be used for all db
|
|
||||||
* operations done by this instance. This parameter may be
|
|
||||||
* <code>null</code>.
|
|
||||||
* @param files a db handle to store file records.
|
|
||||||
* @param blocks a db handle to store file data blocks.
|
|
||||||
* @param flags flags used for db read operations.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public DbDirectory(DbTxn txn, Db files, Db blocks, int flags)
|
|
||||||
{
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.txn = txn;
|
|
||||||
this.files = files;
|
|
||||||
this.blocks = blocks;
|
|
||||||
this.flags = flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DbDirectory(Transaction txn, Database files, Database blocks,
|
|
||||||
int flags)
|
|
||||||
{
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.txn = txn != null ? DbHandleExtractor.getDbTxn(txn) : null;
|
|
||||||
this.files = DbHandleExtractor.getDb(files);
|
|
||||||
this.blocks = DbHandleExtractor.getDb(blocks);
|
|
||||||
this.flags = flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DbDirectory(Transaction txn, Database files, Database blocks)
|
|
||||||
{
|
|
||||||
this(txn, files, blocks, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close()
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flush the currently open files. After they have been flushed it is
|
|
||||||
* safe to commit the transaction without closing this DbDirectory
|
|
||||||
* instance first.
|
|
||||||
* @see #setTransaction
|
|
||||||
*/
|
|
||||||
public void flush()
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
Iterator<DbIndexOutput> iterator = openFiles.iterator();
|
|
||||||
|
|
||||||
while (iterator.hasNext())
|
|
||||||
iterator.next().flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IndexOutput createOutput(String name)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
return new DbIndexOutput(this, name, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteFile(String name)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
new File(name).delete(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean fileExists(String name)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
return new File(name).exists(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long fileLength(String name) throws IOException {
|
|
||||||
File file = new File(name);
|
|
||||||
|
|
||||||
if (file.exists(this))
|
|
||||||
return file.getLength();
|
|
||||||
|
|
||||||
throw new FileNotFoundException(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long fileModified(String name)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
File file = new File(name);
|
|
||||||
|
|
||||||
if (file.exists(this))
|
|
||||||
return file.getTimeModified();
|
|
||||||
|
|
||||||
throw new IOException("File does not exist: " + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] listAll()
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
Dbc cursor = null;
|
|
||||||
List<String> list = new ArrayList<String>();
|
|
||||||
|
|
||||||
try {
|
|
||||||
try {
|
|
||||||
DatabaseEntry key = new DatabaseEntry(new byte[0]);
|
|
||||||
DatabaseEntry data = new DatabaseEntry((byte[]) null);
|
|
||||||
|
|
||||||
data.setPartial(true);
|
|
||||||
|
|
||||||
cursor = files.cursor(txn, flags);
|
|
||||||
|
|
||||||
if (cursor.get(key, data,
|
|
||||||
DbConstants.DB_SET_RANGE | flags) != DbConstants.DB_NOTFOUND)
|
|
||||||
{
|
|
||||||
ByteArrayInputStream buffer =
|
|
||||||
new ByteArrayInputStream(key.getData());
|
|
||||||
DataInputStream in = new DataInputStream(buffer);
|
|
||||||
String name = in.readUTF();
|
|
||||||
|
|
||||||
in.close();
|
|
||||||
list.add(name);
|
|
||||||
|
|
||||||
while (cursor.get(key, data,
|
|
||||||
DbConstants.DB_NEXT | flags) != DbConstants.DB_NOTFOUND) {
|
|
||||||
buffer = new ByteArrayInputStream(key.getData());
|
|
||||||
in = new DataInputStream(buffer);
|
|
||||||
name = in.readUTF();
|
|
||||||
in.close();
|
|
||||||
|
|
||||||
list.add(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (cursor != null)
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
throw new IOException(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return list.toArray(new String[list.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sync(Collection<String> names) throws IOException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IndexInput openInput(String name)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
return new DbIndexInput(this, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Lock makeLock(String name)
|
|
||||||
{
|
|
||||||
return new DbLock();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Once a transaction handle was committed it is no longer valid. In
|
|
||||||
* order to continue using this DbDirectory instance after a commit, the
|
|
||||||
* transaction handle has to be replaced.
|
|
||||||
* @param txn the new transaction handle to use
|
|
||||||
*/
|
|
||||||
public void setTransaction(Transaction txn)
|
|
||||||
{
|
|
||||||
setTransaction(txn != null ? DbHandleExtractor.getDbTxn(txn) : null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Once a transaction handle was committed it is no longer valid. In
|
|
||||||
* order to continue using this DbDirectory instance after a commit, the
|
|
||||||
* transaction handle has to be replaced.
|
|
||||||
* @param txn the new transaction handle to use
|
|
||||||
*/
|
|
||||||
public void setTransaction(DbTxn txn)
|
|
||||||
{
|
|
||||||
this.txn = txn;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,152 +0,0 @@
|
||||||
package org.apache.lucene.store.db;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 org.apache.lucene.store.IndexInput;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class DbIndexInput extends IndexInput {
|
|
||||||
|
|
||||||
protected long position = 0L, length = 0L;
|
|
||||||
protected DbDirectory directory;
|
|
||||||
protected Block block;
|
|
||||||
protected File file;
|
|
||||||
|
|
||||||
protected DbIndexInput(DbDirectory directory, String name)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.directory = directory;
|
|
||||||
|
|
||||||
this.file = new File(name);
|
|
||||||
if (!file.exists(directory))
|
|
||||||
throw new IOException("File does not exist: " + name);
|
|
||||||
|
|
||||||
length = file.getLength();
|
|
||||||
|
|
||||||
block = new Block(file);
|
|
||||||
block.get(directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object clone()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
DbIndexInput clone = (DbIndexInput) super.clone();
|
|
||||||
|
|
||||||
clone.block = new Block(file);
|
|
||||||
clone.block.seek(position);
|
|
||||||
clone.block.get(directory);
|
|
||||||
|
|
||||||
return clone;
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close()
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long length()
|
|
||||||
{
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte readByte()
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
if (position + 1 > length)
|
|
||||||
throw new IOException("Reading past end of file");
|
|
||||||
|
|
||||||
int blockPos = (int) (position++ & DbIndexOutput.BLOCK_MASK);
|
|
||||||
byte b = block.getData()[blockPos];
|
|
||||||
|
|
||||||
if (blockPos + 1 == DbIndexOutput.BLOCK_LEN)
|
|
||||||
{
|
|
||||||
block.seek(position);
|
|
||||||
block.get(directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void readBytes(byte[] b, int offset, int len)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
if (position + len > length)
|
|
||||||
throw new IOException("Reading past end of file");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int blockPos = (int) (position & DbIndexOutput.BLOCK_MASK);
|
|
||||||
|
|
||||||
while (blockPos + len >= DbIndexOutput.BLOCK_LEN) {
|
|
||||||
int blockLen = DbIndexOutput.BLOCK_LEN - blockPos;
|
|
||||||
|
|
||||||
System.arraycopy(block.getData(), blockPos,
|
|
||||||
b, offset, blockLen);
|
|
||||||
|
|
||||||
len -= blockLen;
|
|
||||||
offset += blockLen;
|
|
||||||
position += blockLen;
|
|
||||||
|
|
||||||
block.seek(position);
|
|
||||||
block.get(directory);
|
|
||||||
blockPos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len > 0)
|
|
||||||
{
|
|
||||||
System.arraycopy(block.getData(), blockPos, b, offset, len);
|
|
||||||
position += len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void seek(long pos)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
if (pos > length)
|
|
||||||
throw new IOException("seeking past end of file");
|
|
||||||
|
|
||||||
if ((pos >>> DbIndexOutput.BLOCK_SHIFT) !=
|
|
||||||
(position >>> DbIndexOutput.BLOCK_SHIFT))
|
|
||||||
{
|
|
||||||
block.seek(pos);
|
|
||||||
block.get(directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
position = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getFilePointer()
|
|
||||||
{
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,156 +0,0 @@
|
||||||
package org.apache.lucene.store.db;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 org.apache.lucene.store.IndexOutput;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class DbIndexOutput extends IndexOutput {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The size of data blocks, currently 16k (2^14), is determined by this
|
|
||||||
* constant.
|
|
||||||
*/
|
|
||||||
static public final int BLOCK_SHIFT = 14;
|
|
||||||
static public final int BLOCK_LEN = 1 << BLOCK_SHIFT;
|
|
||||||
static public final int BLOCK_MASK = BLOCK_LEN - 1;
|
|
||||||
|
|
||||||
protected long position = 0L, length = 0L;
|
|
||||||
protected DbDirectory directory;
|
|
||||||
protected Block block;
|
|
||||||
protected File file;
|
|
||||||
|
|
||||||
protected DbIndexOutput(DbDirectory directory, String name, boolean create)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.directory = directory;
|
|
||||||
|
|
||||||
file = new File(directory, name, create);
|
|
||||||
block = new Block(file);
|
|
||||||
length = file.getLength();
|
|
||||||
|
|
||||||
seek(length);
|
|
||||||
block.get(directory);
|
|
||||||
|
|
||||||
directory.openFiles.add(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close()
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
flush();
|
|
||||||
file.modify(directory, length, System.currentTimeMillis());
|
|
||||||
|
|
||||||
directory.openFiles.remove(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void flush()
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
if (length > 0)
|
|
||||||
block.put(directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeByte(byte b)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
int blockPos = (int) (position++ & BLOCK_MASK);
|
|
||||||
|
|
||||||
block.getData()[blockPos] = b;
|
|
||||||
|
|
||||||
if (blockPos + 1 == BLOCK_LEN)
|
|
||||||
{
|
|
||||||
block.put(directory);
|
|
||||||
block.seek(position);
|
|
||||||
block.get(directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (position > length)
|
|
||||||
length = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeBytes(byte[] b, int offset, int len)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
int blockPos = (int) (position & BLOCK_MASK);
|
|
||||||
|
|
||||||
while (blockPos + len >= BLOCK_LEN) {
|
|
||||||
int blockLen = BLOCK_LEN - blockPos;
|
|
||||||
|
|
||||||
System.arraycopy(b, offset, block.getData(), blockPos, blockLen);
|
|
||||||
block.put(directory);
|
|
||||||
|
|
||||||
len -= blockLen;
|
|
||||||
offset += blockLen;
|
|
||||||
position += blockLen;
|
|
||||||
|
|
||||||
block.seek(position);
|
|
||||||
block.get(directory);
|
|
||||||
blockPos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len > 0)
|
|
||||||
{
|
|
||||||
System.arraycopy(b, offset, block.getData(), blockPos, len);
|
|
||||||
position += len;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (position > length)
|
|
||||||
length = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long length()
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void seek(long pos)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
if (pos > length)
|
|
||||||
throw new IOException("seeking past end of file");
|
|
||||||
|
|
||||||
if ((pos >>> BLOCK_SHIFT) == (position >>> BLOCK_SHIFT))
|
|
||||||
position = pos;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
block.put(directory);
|
|
||||||
block.seek(pos);
|
|
||||||
block.get(directory);
|
|
||||||
position = pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getFilePointer()
|
|
||||||
{
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
package org.apache.lucene.store.db;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 org.apache.lucene.store.Lock;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This implementation of {@link org.apache.lucene.store.Lock Lock} is
|
|
||||||
* trivial as {@link DbDirectory} operations are managed by the Berkeley DB
|
|
||||||
* locking system.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class DbLock extends Lock {
|
|
||||||
|
|
||||||
boolean isLocked = false;
|
|
||||||
|
|
||||||
public DbLock()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean obtain()
|
|
||||||
{
|
|
||||||
return (isLocked = true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void release()
|
|
||||||
{
|
|
||||||
isLocked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isLocked()
|
|
||||||
{
|
|
||||||
return isLocked;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,263 +0,0 @@
|
||||||
package org.apache.lucene.store.db;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.io.ByteArrayOutputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import com.sleepycat.db.DatabaseEntry;
|
|
||||||
import com.sleepycat.db.internal.DbConstants;
|
|
||||||
import com.sleepycat.db.internal.Dbc;
|
|
||||||
import com.sleepycat.db.internal.Db;
|
|
||||||
import com.sleepycat.db.internal.DbTxn;
|
|
||||||
import com.sleepycat.db.DatabaseException;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class File extends Object {
|
|
||||||
|
|
||||||
static protected Random random = new Random();
|
|
||||||
|
|
||||||
protected DatabaseEntry key, data;
|
|
||||||
protected long length, timeModified;
|
|
||||||
protected String name;
|
|
||||||
protected byte[] uuid;
|
|
||||||
|
|
||||||
protected File(String name)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
setName(name);
|
|
||||||
|
|
||||||
data = new DatabaseEntry(new byte[32]);
|
|
||||||
data.setUserBuffer(data.getSize(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected File(DbDirectory directory, String name, boolean create)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
this(name);
|
|
||||||
|
|
||||||
if (!exists(directory))
|
|
||||||
{
|
|
||||||
if (!create)
|
|
||||||
throw new IOException("File does not exist: " + name);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DatabaseEntry key = new DatabaseEntry(new byte[24]);
|
|
||||||
DatabaseEntry data = new DatabaseEntry((byte[]) null);
|
|
||||||
Db blocks = directory.blocks;
|
|
||||||
DbTxn txn = directory.txn;
|
|
||||||
int flags = directory.flags;
|
|
||||||
|
|
||||||
key.setUserBuffer(24, true);
|
|
||||||
data.setPartial(true);
|
|
||||||
|
|
||||||
uuid = new byte[16];
|
|
||||||
|
|
||||||
try {
|
|
||||||
do {
|
|
||||||
/* generate a v.4 random-uuid unique to this db */
|
|
||||||
random.nextBytes(uuid);
|
|
||||||
uuid[6] = (byte) ((byte) 0x40 |
|
|
||||||
(uuid[6] & (byte) 0x0f));
|
|
||||||
uuid[8] = (byte) ((byte) 0x80 |
|
|
||||||
(uuid[8] & (byte) 0x3f));
|
|
||||||
System.arraycopy(uuid, 0, key.getData(), 0, 16);
|
|
||||||
} while (blocks.get(txn, key, data,
|
|
||||||
flags) != DbConstants.DB_NOTFOUND);
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
throw new IOException(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (create)
|
|
||||||
length = 0L;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setName(String name)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream(128);
|
|
||||||
DataOutputStream out = new DataOutputStream(buffer);
|
|
||||||
|
|
||||||
out.writeUTF(name);
|
|
||||||
out.close();
|
|
||||||
|
|
||||||
key = new DatabaseEntry(buffer.toByteArray());
|
|
||||||
key.setUserBuffer(key.getSize(), true);
|
|
||||||
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected byte[] getKey()
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
if (uuid == null)
|
|
||||||
throw new IOException("Uninitialized file");
|
|
||||||
|
|
||||||
return uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected long getLength()
|
|
||||||
{
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected long getTimeModified()
|
|
||||||
{
|
|
||||||
return timeModified;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean exists(DbDirectory directory)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
Db files = directory.files;
|
|
||||||
DbTxn txn = directory.txn;
|
|
||||||
int flags = directory.flags;
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (files.get(txn, key, data, flags) == DbConstants.DB_NOTFOUND)
|
|
||||||
return false;
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
throw new IOException(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] bytes = data.getData();
|
|
||||||
ByteArrayInputStream buffer = new ByteArrayInputStream(bytes);
|
|
||||||
DataInputStream in = new DataInputStream(buffer);
|
|
||||||
|
|
||||||
length = in.readLong();
|
|
||||||
timeModified = in.readLong();
|
|
||||||
in.close();
|
|
||||||
|
|
||||||
uuid = new byte[16];
|
|
||||||
System.arraycopy(bytes, 16, uuid, 0, 16);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void modify(DbDirectory directory, long length, long timeModified)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream(32);
|
|
||||||
DataOutputStream out = new DataOutputStream(buffer);
|
|
||||||
Db files = directory.files;
|
|
||||||
DbTxn txn = directory.txn;
|
|
||||||
|
|
||||||
out.writeLong(length);
|
|
||||||
out.writeLong(timeModified);
|
|
||||||
out.write(getKey());
|
|
||||||
out.close();
|
|
||||||
|
|
||||||
System.arraycopy(buffer.toByteArray(), 0, data.getData(), 0, 32);
|
|
||||||
|
|
||||||
try {
|
|
||||||
files.put(txn, key, data, 0);
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
throw new IOException(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
this.length = length;
|
|
||||||
this.timeModified = timeModified;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void delete(DbDirectory directory)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
if (!exists(directory))
|
|
||||||
throw new IOException("File does not exist: " + getName());
|
|
||||||
|
|
||||||
Dbc cursor = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
try {
|
|
||||||
byte[] bytes = getKey();
|
|
||||||
int ulen = bytes.length + 8;
|
|
||||||
byte[] cursorBytes = new byte[ulen];
|
|
||||||
DatabaseEntry cursorKey = new DatabaseEntry(cursorBytes);
|
|
||||||
DatabaseEntry cursorData = new DatabaseEntry((byte[]) null);
|
|
||||||
Db files = directory.files;
|
|
||||||
Db blocks = directory.blocks;
|
|
||||||
DbTxn txn = directory.txn;
|
|
||||||
int flags = directory.flags;
|
|
||||||
|
|
||||||
System.arraycopy(bytes, 0, cursorBytes, 0, bytes.length);
|
|
||||||
cursorKey.setUserBuffer(ulen, true);
|
|
||||||
cursorData.setPartial(true);
|
|
||||||
|
|
||||||
cursor = blocks.cursor(txn, flags);
|
|
||||||
|
|
||||||
if (cursor.get(cursorKey, cursorData,
|
|
||||||
DbConstants.DB_SET_RANGE | flags) != DbConstants.DB_NOTFOUND)
|
|
||||||
{
|
|
||||||
cursor.del(0);
|
|
||||||
|
|
||||||
outer:
|
|
||||||
while (cursor.get(cursorKey, cursorData,
|
|
||||||
DbConstants.DB_NEXT | flags) != DbConstants.DB_NOTFOUND)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < bytes.length; i++)
|
|
||||||
if (bytes[i] != cursorBytes[i])
|
|
||||||
break outer;
|
|
||||||
|
|
||||||
cursor.del(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
files.del(txn, key, 0);
|
|
||||||
} finally {
|
|
||||||
if (cursor != null)
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
throw new IOException(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void rename(DbDirectory directory, String name)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
if (!exists(directory))
|
|
||||||
throw new IOException("File does not exist: " + getName());
|
|
||||||
|
|
||||||
File newFile = new File(name);
|
|
||||||
|
|
||||||
if (newFile.exists(directory))
|
|
||||||
newFile.delete(directory);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Db files = directory.files;
|
|
||||||
DbTxn txn = directory.txn;
|
|
||||||
|
|
||||||
files.del(txn, key, 0);
|
|
||||||
setName(name);
|
|
||||||
files.put(txn, key, data, 0);
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
throw new IOException(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
|
||||||
<!--
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
<html>
|
|
||||||
<body>
|
|
||||||
Berkeley DB 4.3 based implementation of {@link org.apache.lucene.store.Directory Directory}.
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,26 +0,0 @@
|
||||||
<!--
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>
|
|
||||||
bdb
|
|
||||||
</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
bdb
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,413 +0,0 @@
|
||||||
package org.apache.lucene.store.db;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.util.Date;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import com.sleepycat.db.EnvironmentConfig;
|
|
||||||
import com.sleepycat.db.Environment;
|
|
||||||
import com.sleepycat.db.Transaction;
|
|
||||||
import com.sleepycat.db.Database;
|
|
||||||
import com.sleepycat.db.DatabaseConfig;
|
|
||||||
import com.sleepycat.db.DatabaseType;
|
|
||||||
import com.sleepycat.db.DatabaseException;
|
|
||||||
|
|
||||||
import org.apache.lucene.store.Directory;
|
|
||||||
import org.apache.lucene.store.IndexInput;
|
|
||||||
import org.apache.lucene.store.IndexOutput;
|
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link DbDirectory}.
|
|
||||||
*
|
|
||||||
* Adapted from org.apache.lucene.StoreTest with larger files and random bytes.
|
|
||||||
*/
|
|
||||||
public class DbStoreTest extends LuceneTestCase {
|
|
||||||
protected File dbHome = new File(TEMP_DIR,"index");
|
|
||||||
protected Environment env;
|
|
||||||
protected Database index, blocks;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
if (!dbHome.exists())
|
|
||||||
dbHome.mkdir();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
File[] files = dbHome.listFiles();
|
|
||||||
|
|
||||||
for (int i = 0; i < files.length; i++) {
|
|
||||||
String name = files[i].getName();
|
|
||||||
if (name.startsWith("__") || name.startsWith("log."))
|
|
||||||
files[i].delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EnvironmentConfig envConfig = new EnvironmentConfig();
|
|
||||||
DatabaseConfig dbConfig = new DatabaseConfig();
|
|
||||||
|
|
||||||
envConfig.setTransactional(true);
|
|
||||||
envConfig.setInitializeCache(true);
|
|
||||||
envConfig.setInitializeLocking(true);
|
|
||||||
envConfig.setInitializeLogging(true);
|
|
||||||
envConfig.setAllowCreate(true);
|
|
||||||
envConfig.setThreaded(true);
|
|
||||||
dbConfig.setAllowCreate(true);
|
|
||||||
dbConfig.setType(DatabaseType.BTREE);
|
|
||||||
|
|
||||||
env = new Environment(dbHome, envConfig);
|
|
||||||
|
|
||||||
Transaction txn = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
txn = env.beginTransaction(null, null);
|
|
||||||
index = env.openDatabase(txn, "__index__", null, dbConfig);
|
|
||||||
blocks = env.openDatabase(txn, "__blocks__", null, dbConfig);
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
if (txn != null)
|
|
||||||
{
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
}
|
|
||||||
index = null;
|
|
||||||
blocks = null;
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
if (txn != null)
|
|
||||||
txn.commit();
|
|
||||||
txn = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
if (index != null)
|
|
||||||
index.close();
|
|
||||||
if (blocks != null)
|
|
||||||
blocks.close();
|
|
||||||
if (env != null)
|
|
||||||
env.close();
|
|
||||||
super.tearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testBytes()
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
final int count = 250;
|
|
||||||
final int LENGTH_MASK = 0xffff;
|
|
||||||
|
|
||||||
Random r = random;
|
|
||||||
final long seed = r.nextLong();
|
|
||||||
|
|
||||||
Random gen = new Random(seed);
|
|
||||||
int totalLength = 0;
|
|
||||||
int duration;
|
|
||||||
Date end;
|
|
||||||
|
|
||||||
Date veryStart = new Date();
|
|
||||||
Date start = new Date();
|
|
||||||
Transaction txn = env.beginTransaction(null, null);
|
|
||||||
Directory store = null;
|
|
||||||
|
|
||||||
if (VERBOSE) System.out.println("Writing files byte by byte");
|
|
||||||
|
|
||||||
try {
|
|
||||||
store = new DbDirectory(txn, index, blocks);
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
String name = i + ".dat";
|
|
||||||
int length = gen.nextInt() & LENGTH_MASK;
|
|
||||||
IndexOutput file = store.createOutput(name);
|
|
||||||
|
|
||||||
totalLength += length;
|
|
||||||
|
|
||||||
for (int j = 0; j < length; j++) {
|
|
||||||
byte b = (byte)(gen.nextInt() & 0x7F);
|
|
||||||
file.writeByte(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
if (txn != null)
|
|
||||||
txn.commit();
|
|
||||||
|
|
||||||
store.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
end = new Date();
|
|
||||||
|
|
||||||
if (VERBOSE) {
|
|
||||||
duration = (int) (end.getTime() - start.getTime());
|
|
||||||
System.out.print(duration);
|
|
||||||
System.out.print(" total milliseconds to create, ");
|
|
||||||
System.out.print(totalLength / duration);
|
|
||||||
System.out.println(" kb/s");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
txn = env.beginTransaction(null, null);
|
|
||||||
store = new DbDirectory(txn, index, blocks);
|
|
||||||
|
|
||||||
gen = new Random(seed);
|
|
||||||
start = new Date();
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
String name = i + ".dat";
|
|
||||||
int length = gen.nextInt() & LENGTH_MASK;
|
|
||||||
IndexInput file = store.openInput(name);
|
|
||||||
|
|
||||||
if (file.length() != length)
|
|
||||||
throw new Exception("length incorrect");
|
|
||||||
|
|
||||||
for (int j = 0; j < length; j++) {
|
|
||||||
byte b = (byte)(gen.nextInt() & 0x7F);
|
|
||||||
|
|
||||||
if (file.readByte() != b)
|
|
||||||
throw new Exception("contents incorrect");
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
throw e;
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
if (txn != null)
|
|
||||||
{
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
if (txn != null)
|
|
||||||
txn.commit();
|
|
||||||
|
|
||||||
store.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
end = new Date();
|
|
||||||
|
|
||||||
if (VERBOSE) {
|
|
||||||
duration = (int) (end.getTime() - start.getTime());
|
|
||||||
System.out.print(duration);
|
|
||||||
System.out.print(" total milliseconds to read, ");
|
|
||||||
System.out.print(totalLength / duration);
|
|
||||||
System.out.println(" kb/s");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
txn = env.beginTransaction(null, null);
|
|
||||||
store = new DbDirectory(txn, index, blocks);
|
|
||||||
|
|
||||||
gen = new Random(seed);
|
|
||||||
start = new Date();
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
String name = i + ".dat";
|
|
||||||
store.deleteFile(name);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
throw e;
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
if (txn != null)
|
|
||||||
{
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
if (txn != null)
|
|
||||||
txn.commit();
|
|
||||||
|
|
||||||
store.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
end = new Date();
|
|
||||||
|
|
||||||
if (VERBOSE) {
|
|
||||||
System.out.print(end.getTime() - start.getTime());
|
|
||||||
System.out.println(" total milliseconds to delete");
|
|
||||||
|
|
||||||
System.out.print(end.getTime() - veryStart.getTime());
|
|
||||||
System.out.println(" total milliseconds");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testArrays()
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
final int count = 250;
|
|
||||||
final int LENGTH_MASK = 0xffff;
|
|
||||||
|
|
||||||
Random r = random;
|
|
||||||
final long seed = r.nextLong();
|
|
||||||
|
|
||||||
Random gen = new Random(seed);
|
|
||||||
int totalLength = 0;
|
|
||||||
int duration;
|
|
||||||
Date end;
|
|
||||||
|
|
||||||
Date veryStart = new Date();
|
|
||||||
Date start = new Date();
|
|
||||||
Transaction txn = env.beginTransaction(null, null);
|
|
||||||
Directory store = null;
|
|
||||||
|
|
||||||
if (VERBOSE) System.out.println("Writing files as one byte array");
|
|
||||||
|
|
||||||
try {
|
|
||||||
store = new DbDirectory(txn, index, blocks);
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
String name = i + ".dat";
|
|
||||||
int length = gen.nextInt() & LENGTH_MASK;
|
|
||||||
IndexOutput file = store.createOutput(name);
|
|
||||||
byte[] data = new byte[length];
|
|
||||||
|
|
||||||
totalLength += length;
|
|
||||||
gen.nextBytes(data);
|
|
||||||
file.writeBytes(data, length);
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
if (txn != null)
|
|
||||||
txn.commit();
|
|
||||||
|
|
||||||
store.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
end = new Date();
|
|
||||||
|
|
||||||
if (VERBOSE) {
|
|
||||||
duration = (int) (end.getTime() - start.getTime());
|
|
||||||
System.out.print(duration);
|
|
||||||
System.out.print(" total milliseconds to create, ");
|
|
||||||
System.out.print(totalLength / duration);
|
|
||||||
System.out.println(" kb/s");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
txn = env.beginTransaction(null, null);
|
|
||||||
store = new DbDirectory(txn, index, blocks);
|
|
||||||
|
|
||||||
gen = new Random(seed);
|
|
||||||
start = new Date();
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
String name = i + ".dat";
|
|
||||||
int length = gen.nextInt() & LENGTH_MASK;
|
|
||||||
IndexInput file = store.openInput(name);
|
|
||||||
|
|
||||||
if (file.length() != length)
|
|
||||||
throw new Exception("length incorrect");
|
|
||||||
|
|
||||||
byte[] data = new byte[length];
|
|
||||||
byte[] read = new byte[length];
|
|
||||||
gen.nextBytes(data);
|
|
||||||
file.readBytes(read, 0, length);
|
|
||||||
|
|
||||||
if (!Arrays.equals(data, read))
|
|
||||||
throw new Exception("contents incorrect");
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
throw e;
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
if (txn != null)
|
|
||||||
{
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
if (txn != null)
|
|
||||||
txn.commit();
|
|
||||||
|
|
||||||
store.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
end = new Date();
|
|
||||||
|
|
||||||
if (VERBOSE) {
|
|
||||||
duration = (int) (end.getTime() - start.getTime());
|
|
||||||
System.out.print(duration);
|
|
||||||
System.out.print(" total milliseconds to read, ");
|
|
||||||
System.out.print(totalLength / duration);
|
|
||||||
System.out.println(" kb/s");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
txn = env.beginTransaction(null, null);
|
|
||||||
store = new DbDirectory(txn, index, blocks);
|
|
||||||
|
|
||||||
gen = new Random(seed);
|
|
||||||
start = new Date();
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
String name = i + ".dat";
|
|
||||||
store.deleteFile(name);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
throw e;
|
|
||||||
} catch (DatabaseException e) {
|
|
||||||
if (txn != null)
|
|
||||||
{
|
|
||||||
txn.abort();
|
|
||||||
txn = null;
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
if (txn != null)
|
|
||||||
txn.commit();
|
|
||||||
|
|
||||||
store.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
end = new Date();
|
|
||||||
|
|
||||||
if (VERBOSE) {
|
|
||||||
System.out.print(end.getTime() - start.getTime());
|
|
||||||
System.out.println(" total milliseconds to delete");
|
|
||||||
|
|
||||||
System.out.print(end.getTime() - veryStart.getTime());
|
|
||||||
System.out.println(" total milliseconds");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package org.apache.lucene.store.db;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 com.sleepycat.db.EnvironmentConfig;
|
|
||||||
import com.sleepycat.db.Environment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple sanity testing application to verify that the underlying
|
|
||||||
* native library can be loaded cleanly.
|
|
||||||
*
|
|
||||||
* For use in the build.xml of this contrib, to determine if tests
|
|
||||||
* should be skipped.
|
|
||||||
*/
|
|
||||||
public class SanityLoadLibrary {
|
|
||||||
public static void main(String[] ignored) throws Exception {
|
|
||||||
EnvironmentConfig envConfig = EnvironmentConfig.DEFAULT;
|
|
||||||
envConfig.setAllowCreate(false);
|
|
||||||
new Environment(null, envConfig);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<project name="db" default="default">
|
|
||||||
|
|
||||||
<description>
|
|
||||||
Lucene DB integration
|
|
||||||
- bdb: using the Java interface of C Berkeley DB
|
|
||||||
- bdb-je: using Berkeley DB Java Edition
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<!-- we dont import contrib-build.xml here, as this file only delegates to the real build files -->
|
|
||||||
|
|
||||||
<target name="bdb">
|
|
||||||
<ant dir="bdb" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="bdb-je">
|
|
||||||
<ant dir="bdb-je" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="default" depends="bdb,bdb-je" />
|
|
||||||
|
|
||||||
<target name="clean">
|
|
||||||
<ant dir="bdb" target="clean" />
|
|
||||||
<ant dir="bdb-je" target="clean" />
|
|
||||||
</target>
|
|
||||||
<target name="compile-core">
|
|
||||||
<ant dir="bdb" target="compile-core" />
|
|
||||||
<ant dir="bdb-je" target="compile-core" />
|
|
||||||
</target>
|
|
||||||
<target name="compile-test">
|
|
||||||
<ant dir="bdb" target="compile-test" />
|
|
||||||
<ant dir="bdb-je" target="compile-test" />
|
|
||||||
</target>
|
|
||||||
<target name="test">
|
|
||||||
<ant dir="bdb" target="test" />
|
|
||||||
<ant dir="bdb-je" target="test" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="build-artifacts-and-tests" depends="default,compile-test" />
|
|
||||||
|
|
||||||
<target name="dist-maven" depends="default">
|
|
||||||
<ant dir="bdb" target="dist-maven" />
|
|
||||||
<ant dir="bdb-je" target="dist-maven" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="javadocs">
|
|
||||||
<ant dir="bdb" target="javadocs" />
|
|
||||||
<ant dir="bdb-je" target="javadocs" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="javadocs-index.html">
|
|
||||||
<ant dir="bdb" target="javadocs-index.html" />
|
|
||||||
<ant dir="bdb-je" target="javadocs-index.html" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
</project>
|
|
|
@ -1,24 +0,0 @@
|
||||||
lucli (pronounced Luckily) is the Lucene Command Line Interface.
|
|
||||||
|
|
||||||
INSTALLATION
|
|
||||||
|
|
||||||
Call "ant", then call the run.sh shell script. If it doesn't work right away:
|
|
||||||
Edit JAVA_HOME to point to your java directory.
|
|
||||||
Edit LUCLI to point to where you installed lucli.
|
|
||||||
Edit LUCLI_MEMORY and set it to the maximum amount of memory you want to allocate to lucli
|
|
||||||
You can also replace the Lucene jar file that came with lucli with your own.
|
|
||||||
|
|
||||||
|
|
||||||
ENABLING READLINE
|
|
||||||
|
|
||||||
Readline support should automatically work thanks to JLine, see http://jline.sourceforge.net/
|
|
||||||
|
|
||||||
|
|
||||||
Documentation
|
|
||||||
|
|
||||||
There is none :-). Type help at the command line or read the code.
|
|
||||||
|
|
||||||
Enjoy
|
|
||||||
|
|
||||||
Dror Matalon
|
|
||||||
dror@zapatec.com.
|
|
|
@ -1,71 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<project name="lucli" default="jar">
|
|
||||||
|
|
||||||
<description>
|
|
||||||
Lucene Command Line Interface
|
|
||||||
</description>
|
|
||||||
|
|
||||||
|
|
||||||
<path id="additional.dependencies">
|
|
||||||
<pathelement location="lib/jline.jar"/>
|
|
||||||
</path>
|
|
||||||
|
|
||||||
<pathconvert property="project.classpath"
|
|
||||||
targetos="unix"
|
|
||||||
refid="additional.dependencies"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<import file="../contrib-build.xml"/>
|
|
||||||
|
|
||||||
<module-uptodate name="analysis/common" jarfile="${common.dir}/../modules/analysis/build/common/lucene-analyzers-common-${version}.jar"
|
|
||||||
property="analyzers-common.uptodate" classpath.property="analyzers-common.jar"/>
|
|
||||||
|
|
||||||
<path id="classpath">
|
|
||||||
<pathelement path="${analyzers-common.jar}"/>
|
|
||||||
<path refid="base.classpath"/>
|
|
||||||
</path>
|
|
||||||
|
|
||||||
<target name="compile-core" depends="compile-analyzers-common, common.compile-core" />
|
|
||||||
|
|
||||||
<target name="compile-analyzers-common" unless="analyzers-common.uptodate">
|
|
||||||
<subant target="default">
|
|
||||||
<fileset dir="${common.dir}/../modules/analysis/common" includes="build.xml"/>
|
|
||||||
</subant>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="jar" depends="compile" description="Create JAR">
|
|
||||||
<jarify>
|
|
||||||
<manifest-attributes>
|
|
||||||
<attribute name="Main-Class" value="lucli.Lucli" />
|
|
||||||
<attribute name="Class-Path" value="lib/jline.jar lib/lucene.jar" />
|
|
||||||
</manifest-attributes>
|
|
||||||
</jarify>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="jar-src" depends="init">
|
|
||||||
<jarify basedir="${src.dir}" destfile="${build.dir}/${final.name}-src.jar">
|
|
||||||
<manifest-attributes>
|
|
||||||
<attribute name="Main-Class" value="lucli.Lucli" />
|
|
||||||
<attribute name="Class-Path" value="lib/jline.jar lib/lucene.jar" />
|
|
||||||
</manifest-attributes>
|
|
||||||
</jarify>
|
|
||||||
</target>
|
|
||||||
</project>
|
|
|
@ -1,33 +0,0 @@
|
||||||
Copyright (c) 2002, 2003, 2004, 2005, Marc Prud'hommeaux <mwp1@cornell.edu>
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or
|
|
||||||
without modification, are permitted provided that the following
|
|
||||||
conditions are met:
|
|
||||||
|
|
||||||
Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Neither the name of JLine nor the names of its contributors
|
|
||||||
may be used to endorse or promote products derived from this
|
|
||||||
software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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.
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
JLine (under contrib/lucli/lib/jline.jar) is licensed under the BSD License.
|
|
||||||
See http://jline.sourceforge.net/
|
|
|
@ -1,2 +0,0 @@
|
||||||
AnyObjectId[b841cf167aa3ca6c82f2e40ba2fd8732e829525f] was removed in git history.
|
|
||||||
Apache SVN contains full history.
|
|
|
@ -1,22 +0,0 @@
|
||||||
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
LUCLI=.
|
|
||||||
LUCLI_MEMORY=128M
|
|
||||||
#JAVA_HOME=/home/dror/j2sdk1.4.1_03/
|
|
||||||
CLASSPATH=${CLASSPATH}:$LUCLI/lib/jline.jar:$LUCLI/lib/lucene.jar:$LUCLI/dist/lucli-dev.jar
|
|
||||||
export CLASSPATH
|
|
||||||
$JAVA_HOME/bin/java -Xmx${LUCLI_MEMORY} lucli.Lucli
|
|
|
@ -1,406 +0,0 @@
|
||||||
package lucli;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.io.StringReader;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
import jline.ConsoleReader;
|
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
|
||||||
import org.apache.lucene.analysis.TokenStream;
|
|
||||||
import org.apache.lucene.analysis.standard.StandardAnalyzer;
|
|
||||||
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
|
|
||||||
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
|
|
||||||
import org.apache.lucene.document.Document;
|
|
||||||
import org.apache.lucene.document.Fieldable;
|
|
||||||
import org.apache.lucene.index.IndexReader;
|
|
||||||
import org.apache.lucene.index.IndexReader.AtomicReaderContext;
|
|
||||||
import org.apache.lucene.index.IndexWriter;
|
|
||||||
import org.apache.lucene.index.IndexWriterConfig;
|
|
||||||
import org.apache.lucene.index.Fields;
|
|
||||||
import org.apache.lucene.index.FieldsEnum;
|
|
||||||
import org.apache.lucene.index.TermsEnum;
|
|
||||||
import org.apache.lucene.index.MultiFields;
|
|
||||||
import org.apache.lucene.index.IndexReader.FieldOption;
|
|
||||||
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
|
|
||||||
import org.apache.lucene.queryParser.MultiFieldQueryParser;
|
|
||||||
import org.apache.lucene.queryParser.ParseException;
|
|
||||||
import org.apache.lucene.search.Collector;
|
|
||||||
import org.apache.lucene.search.Explanation;
|
|
||||||
import org.apache.lucene.search.Query;
|
|
||||||
import org.apache.lucene.search.ScoreDoc;
|
|
||||||
import org.apache.lucene.search.Scorer;
|
|
||||||
import org.apache.lucene.search.IndexSearcher;
|
|
||||||
import org.apache.lucene.store.FSDirectory;
|
|
||||||
import org.apache.lucene.util.Version;
|
|
||||||
import org.apache.lucene.util.BytesRef;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Various methods that interact with Lucene and provide info about the
|
|
||||||
* index, search, etc. Parts adapted from Lucene demo.
|
|
||||||
*/
|
|
||||||
class LuceneMethods {
|
|
||||||
|
|
||||||
private int numDocs;
|
|
||||||
private final FSDirectory indexName; //directory of this index
|
|
||||||
private List<String> fields; //Fields as a vector
|
|
||||||
private List<String> indexedFields; //Fields as a vector
|
|
||||||
private String fieldsArray[]; //Fields as an array
|
|
||||||
private IndexSearcher searcher;
|
|
||||||
private Query query; //current query string
|
|
||||||
private String analyzerClassFQN = null; // Analyzer class, if NULL, use default Analyzer
|
|
||||||
|
|
||||||
public LuceneMethods(String index) throws IOException {
|
|
||||||
indexName = FSDirectory.open(new File(index));
|
|
||||||
message("Lucene CLI. Using directory '" + indexName + "'. Type 'help' for instructions.");
|
|
||||||
}
|
|
||||||
|
|
||||||
private Analyzer createAnalyzer() {
|
|
||||||
if (analyzerClassFQN == null) return new StandardAnalyzer(Version.LUCENE_CURRENT);
|
|
||||||
try {
|
|
||||||
return Class.forName(analyzerClassFQN).asSubclass(Analyzer.class).newInstance();
|
|
||||||
} catch (ClassCastException cce) {
|
|
||||||
message("Given class is not an Analyzer: " + analyzerClassFQN);
|
|
||||||
return new StandardAnalyzer(Version.LUCENE_CURRENT);
|
|
||||||
} catch (Exception e) {
|
|
||||||
message("Unable to use Analyzer " + analyzerClassFQN);
|
|
||||||
return new StandardAnalyzer(Version.LUCENE_CURRENT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void info() throws java.io.IOException {
|
|
||||||
IndexReader indexReader = IndexReader.open(indexName, true);
|
|
||||||
|
|
||||||
|
|
||||||
getFieldInfo();
|
|
||||||
numDocs = indexReader.numDocs();
|
|
||||||
message("Index has " + numDocs + " documents ");
|
|
||||||
message("All Fields:" + fields.toString());
|
|
||||||
message("Indexed Fields:" + indexedFields.toString());
|
|
||||||
|
|
||||||
if (IndexWriter.isLocked(indexName)) {
|
|
||||||
message("Index is locked");
|
|
||||||
}
|
|
||||||
//IndexReader.getCurrentVersion(indexName);
|
|
||||||
//System.out.println("Version:" + version);
|
|
||||||
|
|
||||||
indexReader.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void search(String queryString, boolean explain, boolean showTokens, ConsoleReader cr)
|
|
||||||
throws java.io.IOException, org.apache.lucene.queryParser.ParseException {
|
|
||||||
initSearch(queryString);
|
|
||||||
int numHits = computeCount(query);
|
|
||||||
message(numHits + " total matching documents");
|
|
||||||
if (explain) {
|
|
||||||
query = explainQuery(queryString);
|
|
||||||
}
|
|
||||||
|
|
||||||
final int HITS_PER_PAGE = 10;
|
|
||||||
message("--------------------------------------");
|
|
||||||
for (int start = 0; start < numHits; start += HITS_PER_PAGE) {
|
|
||||||
int end = Math.min(numHits, start + HITS_PER_PAGE);
|
|
||||||
ScoreDoc[] hits = search(query, end);
|
|
||||||
for (int ii = start; ii < end; ii++) {
|
|
||||||
Document doc = searcher.doc(hits[ii].doc);
|
|
||||||
message("---------------- " + (ii + 1) + " score:" + hits[ii].score + "---------------------");
|
|
||||||
printHit(doc);
|
|
||||||
if (showTokens) {
|
|
||||||
invertDocument(doc);
|
|
||||||
}
|
|
||||||
if (explain) {
|
|
||||||
Explanation exp = searcher.explain(query, hits[ii].doc);
|
|
||||||
message("Explanation:" + exp.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
message("#################################################");
|
|
||||||
|
|
||||||
if (numHits > end) {
|
|
||||||
// TODO: don't let the input end up in the command line history
|
|
||||||
queryString = cr.readLine("more (y/n) ? ");
|
|
||||||
if (queryString.length() == 0 || queryString.charAt(0) == 'n')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
searcher.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: Allow user to specify what field(s) to display
|
|
||||||
*/
|
|
||||||
private void printHit(Document doc) {
|
|
||||||
for (int ii = 0; ii < fieldsArray.length; ii++) {
|
|
||||||
String currField = fieldsArray[ii];
|
|
||||||
String[] result = doc.getValues(currField);
|
|
||||||
if (result != null) {
|
|
||||||
for (int i = 0; i < result.length; i++) {
|
|
||||||
message(currField + ":" + result[i]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
message(currField + ": <not available>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//another option is to just do message(doc);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void optimize() throws IOException {
|
|
||||||
//open the index writer. False: don't create a new one
|
|
||||||
IndexWriter indexWriter = new IndexWriter(indexName, new IndexWriterConfig(
|
|
||||||
Version.LUCENE_CURRENT, createAnalyzer()).setOpenMode(
|
|
||||||
OpenMode.APPEND));
|
|
||||||
message("Starting to optimize index.");
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
indexWriter.optimize();
|
|
||||||
message("Done optimizing index. Took " + (System.currentTimeMillis() - start) + " msecs");
|
|
||||||
indexWriter.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Query explainQuery(String queryString) throws IOException, ParseException {
|
|
||||||
|
|
||||||
searcher = new IndexSearcher(indexName, true);
|
|
||||||
Analyzer analyzer = createAnalyzer();
|
|
||||||
getFieldInfo();
|
|
||||||
|
|
||||||
int arraySize = indexedFields.size();
|
|
||||||
String indexedArray[] = new String[arraySize];
|
|
||||||
for (int ii = 0; ii < arraySize; ii++) {
|
|
||||||
indexedArray[ii] = indexedFields.get(ii);
|
|
||||||
}
|
|
||||||
MultiFieldQueryParser parser = new MultiFieldQueryParser(Version.LUCENE_CURRENT, indexedArray, analyzer);
|
|
||||||
query = parser.parse(queryString);
|
|
||||||
message("Searching for: " + query.toString());
|
|
||||||
return (query);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: Allow user to specify analyzer
|
|
||||||
*/
|
|
||||||
private void initSearch(String queryString) throws IOException, ParseException {
|
|
||||||
|
|
||||||
searcher = new IndexSearcher(indexName, true);
|
|
||||||
Analyzer analyzer = createAnalyzer();
|
|
||||||
getFieldInfo();
|
|
||||||
|
|
||||||
int arraySize = fields.size();
|
|
||||||
fieldsArray = new String[arraySize];
|
|
||||||
for (int ii = 0; ii < arraySize; ii++) {
|
|
||||||
fieldsArray[ii] = fields.get(ii);
|
|
||||||
}
|
|
||||||
MultiFieldQueryParser parser = new MultiFieldQueryParser(Version.LUCENE_CURRENT, fieldsArray, analyzer);
|
|
||||||
query = parser.parse(queryString);
|
|
||||||
System.out.println("Searching for: " + query.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
final static class CountingCollector extends Collector {
|
|
||||||
public int numHits = 0;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setScorer(Scorer scorer) throws IOException {}
|
|
||||||
@Override
|
|
||||||
public void collect(int doc) throws IOException {
|
|
||||||
numHits++;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setNextReader(AtomicReaderContext context) {}
|
|
||||||
@Override
|
|
||||||
public boolean acceptsDocsOutOfOrder() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int computeCount(Query q) throws IOException {
|
|
||||||
CountingCollector countingCollector = new CountingCollector();
|
|
||||||
|
|
||||||
searcher.search(q, countingCollector);
|
|
||||||
return countingCollector.numHits;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void count(String queryString) throws java.io.IOException, ParseException {
|
|
||||||
initSearch(queryString);
|
|
||||||
message(computeCount(query) + " total documents");
|
|
||||||
searcher.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ScoreDoc[] search(Query q, int numHits) throws IOException {
|
|
||||||
return searcher.search(query, numHits).scoreDocs;
|
|
||||||
}
|
|
||||||
|
|
||||||
static public void message(String s) {
|
|
||||||
System.out.println(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getFieldInfo() throws IOException {
|
|
||||||
IndexReader indexReader = IndexReader.open(indexName, true);
|
|
||||||
fields = new ArrayList<String>();
|
|
||||||
indexedFields = new ArrayList<String>();
|
|
||||||
|
|
||||||
//get the list of all field names
|
|
||||||
for(String field : indexReader.getFieldNames(FieldOption.ALL)) {
|
|
||||||
if (field != null && !field.equals(""))
|
|
||||||
fields.add(field.toString());
|
|
||||||
}
|
|
||||||
//
|
|
||||||
//get the list of indexed field names
|
|
||||||
for(String field : indexReader.getFieldNames(FieldOption.INDEXED)) {
|
|
||||||
if (field != null && !field.equals(""))
|
|
||||||
indexedFields.add(field.toString());
|
|
||||||
}
|
|
||||||
indexReader.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Copied from DocumentWriter
|
|
||||||
// Tokenizes the fields of a document into Postings.
|
|
||||||
private void invertDocument(Document doc)
|
|
||||||
throws IOException {
|
|
||||||
|
|
||||||
Map<String,Integer> tokenMap = new HashMap<String,Integer>();
|
|
||||||
final int maxFieldLength = 10000;
|
|
||||||
|
|
||||||
Analyzer analyzer = createAnalyzer();
|
|
||||||
for (Fieldable field : doc.getFields()) {
|
|
||||||
String fieldName = field.name();
|
|
||||||
if (field.isIndexed()) {
|
|
||||||
if (field.isTokenized()) { // un-tokenized field
|
|
||||||
Reader reader; // find or make Reader
|
|
||||||
if (field.readerValue() != null)
|
|
||||||
reader = field.readerValue();
|
|
||||||
else if (field.stringValue() != null)
|
|
||||||
reader = new StringReader(field.stringValue());
|
|
||||||
else
|
|
||||||
throw new IllegalArgumentException
|
|
||||||
("field must have either String or Reader value");
|
|
||||||
|
|
||||||
int position = 0;
|
|
||||||
// Tokenize field and add to postingTable
|
|
||||||
TokenStream stream = analyzer.reusableTokenStream(fieldName, reader);
|
|
||||||
CharTermAttribute termAtt = stream.addAttribute(CharTermAttribute.class);
|
|
||||||
PositionIncrementAttribute posIncrAtt = stream.addAttribute(PositionIncrementAttribute.class);
|
|
||||||
|
|
||||||
try {
|
|
||||||
stream.reset();
|
|
||||||
while (stream.incrementToken()) {
|
|
||||||
position += (posIncrAtt.getPositionIncrement() - 1);
|
|
||||||
position++;
|
|
||||||
String name = termAtt.toString();
|
|
||||||
Integer Count = tokenMap.get(name);
|
|
||||||
if (Count == null) { // not in there yet
|
|
||||||
tokenMap.put(name, Integer.valueOf(1)); //first one
|
|
||||||
} else {
|
|
||||||
int count = Count.intValue();
|
|
||||||
tokenMap.put(name, Integer.valueOf(count + 1));
|
|
||||||
}
|
|
||||||
if (position > maxFieldLength) break;
|
|
||||||
}
|
|
||||||
stream.end();
|
|
||||||
} finally {
|
|
||||||
stream.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Map.Entry<String,Integer>[] sortedHash = getSortedMapEntries(tokenMap);
|
|
||||||
for (int ii = 0; ii < sortedHash.length && ii < 10; ii++) {
|
|
||||||
Map.Entry<String,Integer> currentEntry = sortedHash[ii];
|
|
||||||
message((ii + 1) + ":" + currentEntry.getKey() + " " + currentEntry.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Provides a list of the top terms of the index.
|
|
||||||
*
|
|
||||||
* @param field - the name of the command or null for all of them.
|
|
||||||
*/
|
|
||||||
public void terms(String field) throws IOException {
|
|
||||||
TreeMap<String,Integer> termMap = new TreeMap<String,Integer>();
|
|
||||||
IndexReader indexReader = IndexReader.open(indexName, true);
|
|
||||||
Fields fields = MultiFields.getFields(indexReader);
|
|
||||||
if (fields != null) {
|
|
||||||
FieldsEnum fieldsEnum = fields.iterator();
|
|
||||||
String curField;
|
|
||||||
while((curField = fieldsEnum.next()) != null) {
|
|
||||||
TermsEnum terms = fieldsEnum.terms();
|
|
||||||
BytesRef text;
|
|
||||||
while ((text = terms.next()) != null) {
|
|
||||||
//message(term.field() + ":" + term.text() + " freq:" + terms.docFreq());
|
|
||||||
//if we're either not looking by field or we're matching the specific field
|
|
||||||
if ((field == null) || field.equals(curField)) {
|
|
||||||
termMap.put(curField + ":" + text.utf8ToString(), Integer.valueOf((terms.docFreq())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator<String> termIterator = termMap.keySet().iterator();
|
|
||||||
for (int ii = 0; termIterator.hasNext() && ii < 100; ii++) {
|
|
||||||
String termDetails = termIterator.next();
|
|
||||||
Integer termFreq = termMap.get(termDetails);
|
|
||||||
message(termDetails + ": " + termFreq);
|
|
||||||
}
|
|
||||||
indexReader.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sort Map values
|
|
||||||
* @param m the map we're sorting
|
|
||||||
* from http://developer.java.sun.com/developer/qow/archive/170/index.jsp
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static <K,V extends Comparable<V>> Map.Entry<K,V>[]
|
|
||||||
getSortedMapEntries(Map<K,V> m) {
|
|
||||||
Set<Map.Entry<K, V>> set = m.entrySet();
|
|
||||||
Map.Entry<K,V>[] entries =
|
|
||||||
set.toArray(new Map.Entry[set.size()]);
|
|
||||||
Arrays.sort(entries, new Comparator<Map.Entry<K,V>>() {
|
|
||||||
public int compare(Map.Entry<K,V> o1, Map.Entry<K,V> o2) {
|
|
||||||
V v1 = o1.getValue();
|
|
||||||
V v2 = o2.getValue();
|
|
||||||
return v2.compareTo(v1); //descending order
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void analyzer(String word) {
|
|
||||||
if ("current".equals(word)) {
|
|
||||||
String current = analyzerClassFQN == null ? "StandardAnalyzer" : analyzerClassFQN;
|
|
||||||
message("The currently used Analyzer class is: " + current);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
analyzerClassFQN = word;
|
|
||||||
message("Switched to Analyzer class " + analyzerClassFQN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,321 +0,0 @@
|
||||||
package lucli;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.StringTokenizer;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
import jline.ArgumentCompletor;
|
|
||||||
import jline.Completor;
|
|
||||||
import jline.ConsoleReader;
|
|
||||||
import jline.FileNameCompletor;
|
|
||||||
import jline.History;
|
|
||||||
import jline.SimpleCompletor;
|
|
||||||
|
|
||||||
import org.apache.lucene.queryParser.ParseException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main class for lucli: the Lucene Command Line Interface.
|
|
||||||
* This class handles mostly the actual CLI part, command names, help, etc.
|
|
||||||
*/
|
|
||||||
public class Lucli {
|
|
||||||
|
|
||||||
final static String DEFAULT_INDEX = "index"; //directory "index" under the current directory
|
|
||||||
final static String HISTORYFILE = ".lucli"; //history file in user's home directory
|
|
||||||
public final static int MAX_TERMS = 100; //Maximum number of terms we're going to show
|
|
||||||
|
|
||||||
// List of commands
|
|
||||||
// To add another command, add it in here, in the list of addcomand(), and in the switch statement
|
|
||||||
final static int NOCOMMAND = -2;
|
|
||||||
final static int UNKOWN = -1;
|
|
||||||
final static int INFO = 0;
|
|
||||||
final static int SEARCH = 1;
|
|
||||||
final static int OPTIMIZE = 2;
|
|
||||||
final static int QUIT = 3;
|
|
||||||
final static int HELP = 4;
|
|
||||||
final static int COUNT = 5;
|
|
||||||
final static int TERMS = 6;
|
|
||||||
final static int INDEX = 7;
|
|
||||||
final static int TOKENS = 8;
|
|
||||||
final static int EXPLAIN = 9;
|
|
||||||
final static int ANALYZER = 10;
|
|
||||||
|
|
||||||
String historyFile;
|
|
||||||
TreeMap<String,Command> commandMap = new TreeMap<String,Command>();
|
|
||||||
LuceneMethods luceneMethods; //current cli class we're using
|
|
||||||
boolean enableReadline; //false: use plain java. True: shared library readline
|
|
||||||
|
|
||||||
/**
|
|
||||||
Main entry point. The first argument can be a filename with an
|
|
||||||
application initialization file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public Lucli(String[] args) throws IOException {
|
|
||||||
String line;
|
|
||||||
|
|
||||||
historyFile = System.getProperty("user.home") + File.separator + HISTORYFILE;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize the list of commands
|
|
||||||
*/
|
|
||||||
addCommand("info", INFO, "Display info about the current Lucene index. Example: info");
|
|
||||||
addCommand("search", SEARCH, "Search the current index. Example: search foo", 1);
|
|
||||||
addCommand("count", COUNT, "Return the number of hits for a search. Example: count foo", 1);
|
|
||||||
addCommand("optimize", OPTIMIZE, "Optimize the current index");
|
|
||||||
addCommand("quit", QUIT, "Quit/exit the program");
|
|
||||||
addCommand("help", HELP, "Display help about commands");
|
|
||||||
addCommand("terms", TERMS, "Show the first " + MAX_TERMS + " terms in this index. Supply a field name to only show terms in a specific field. Example: terms");
|
|
||||||
addCommand("index", INDEX, "Choose a different lucene index. Example index my_index", 1);
|
|
||||||
addCommand("tokens", TOKENS, "Does a search and shows the top 10 tokens for each document. Verbose! Example: tokens foo", 1);
|
|
||||||
addCommand("explain", EXPLAIN, "Explanation that describes how the document scored against query. Example: explain foo", 1);
|
|
||||||
addCommand("analyzer", ANALYZER, "Specifies the Analyzer class to be used. Example: analyzer org.apache.lucene.analysis.SimpleAnalyzer", 1);
|
|
||||||
|
|
||||||
//parse command line arguments
|
|
||||||
parseArgs(args);
|
|
||||||
|
|
||||||
ConsoleReader cr = new ConsoleReader();
|
|
||||||
//Readline.readHistoryFile(fullPath);
|
|
||||||
cr.setHistory(new History(new File(historyFile)));
|
|
||||||
|
|
||||||
// set completer with list of words
|
|
||||||
Completor[] comp = new Completor[]{
|
|
||||||
new SimpleCompletor(getCommandsAsArray()),
|
|
||||||
new FileNameCompletor()
|
|
||||||
};
|
|
||||||
cr.addCompletor (new ArgumentCompletor(comp));
|
|
||||||
|
|
||||||
// main input loop
|
|
||||||
luceneMethods = new LuceneMethods(DEFAULT_INDEX);
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
line = cr.readLine("lucli> ");
|
|
||||||
if (line != null) {
|
|
||||||
handleCommand(line, cr);
|
|
||||||
}
|
|
||||||
} catch (java.io.EOFException eof) {
|
|
||||||
System.out.println("");//new line
|
|
||||||
exit();
|
|
||||||
} catch (UnsupportedEncodingException enc) {
|
|
||||||
enc.printStackTrace(System.err);
|
|
||||||
} catch (ParseException pe) {
|
|
||||||
pe.printStackTrace(System.err);
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
ioe.printStackTrace(System.err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String[] getCommandsAsArray() {
|
|
||||||
Set<String> commandSet = commandMap.keySet();
|
|
||||||
String[] commands = new String[commandMap.size()];
|
|
||||||
int i = 0;
|
|
||||||
for (Iterator<String> iter = commandSet.iterator(); iter.hasNext();) {
|
|
||||||
String cmd = iter.next();
|
|
||||||
commands[i++] = cmd;
|
|
||||||
}
|
|
||||||
return commands;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
|
||||||
new Lucli(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void handleCommand(String line, ConsoleReader cr) throws IOException, ParseException {
|
|
||||||
String [] words = tokenizeCommand(line);
|
|
||||||
if (words.length == 0)
|
|
||||||
return; //white space
|
|
||||||
String query = "";
|
|
||||||
if (line.trim().startsWith("#")) // # = comment
|
|
||||||
return;
|
|
||||||
//Command name and number of arguments
|
|
||||||
switch (getCommandId(words[0], words.length - 1)) {
|
|
||||||
case INFO:
|
|
||||||
luceneMethods.info();
|
|
||||||
break;
|
|
||||||
case SEARCH:
|
|
||||||
for (int ii = 1; ii < words.length; ii++) {
|
|
||||||
query += words[ii] + " ";
|
|
||||||
}
|
|
||||||
luceneMethods.search(query, false, false, cr);
|
|
||||||
break;
|
|
||||||
case COUNT:
|
|
||||||
for (int ii = 1; ii < words.length; ii++) {
|
|
||||||
query += words[ii] + " ";
|
|
||||||
}
|
|
||||||
luceneMethods.count(query);
|
|
||||||
break;
|
|
||||||
case QUIT:
|
|
||||||
exit();
|
|
||||||
break;
|
|
||||||
case TERMS:
|
|
||||||
if(words.length > 1)
|
|
||||||
luceneMethods.terms(words[1]);
|
|
||||||
else
|
|
||||||
luceneMethods.terms(null);
|
|
||||||
break;
|
|
||||||
case INDEX:
|
|
||||||
LuceneMethods newLm = new LuceneMethods(words[1]);
|
|
||||||
try {
|
|
||||||
newLm.info(); //will fail if can't open the index
|
|
||||||
luceneMethods = newLm; //OK, so we'll use the new one
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
//problem we'll keep using the old one
|
|
||||||
error(ioe.toString());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPTIMIZE:
|
|
||||||
luceneMethods.optimize();
|
|
||||||
break;
|
|
||||||
case TOKENS:
|
|
||||||
for (int ii = 1; ii < words.length; ii++) {
|
|
||||||
query += words[ii] + " ";
|
|
||||||
}
|
|
||||||
luceneMethods.search(query, false, true, cr);
|
|
||||||
break;
|
|
||||||
case EXPLAIN:
|
|
||||||
for (int ii = 1; ii < words.length; ii++) {
|
|
||||||
query += words[ii] + " ";
|
|
||||||
}
|
|
||||||
luceneMethods.search(query, true, false, cr);
|
|
||||||
break;
|
|
||||||
case ANALYZER:
|
|
||||||
luceneMethods.analyzer(words[1]);
|
|
||||||
break;
|
|
||||||
case HELP:
|
|
||||||
help();
|
|
||||||
break;
|
|
||||||
case NOCOMMAND: //do nothing
|
|
||||||
break;
|
|
||||||
case UNKOWN:
|
|
||||||
System.out.println("Unknown command: " + words[0] + ". Type help to get a list of commands.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String [] tokenizeCommand(String line) {
|
|
||||||
StringTokenizer tokenizer = new StringTokenizer(line, " \t");
|
|
||||||
int size = tokenizer.countTokens();
|
|
||||||
String [] tokens = new String[size];
|
|
||||||
for (int ii = 0; tokenizer.hasMoreTokens(); ii++) {
|
|
||||||
tokens[ii] = tokenizer.nextToken();
|
|
||||||
}
|
|
||||||
return tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void exit() {
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a command to the list of commands for the interpreter for a
|
|
||||||
* command that doesn't take any parameters.
|
|
||||||
* @param name - the name of the command
|
|
||||||
* @param id - the unique id of the command
|
|
||||||
* @param help - the help message for this command
|
|
||||||
*/
|
|
||||||
private void addCommand(String name, int id, String help) {
|
|
||||||
addCommand(name, id, help, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a command to the list of commands for the interpreter.
|
|
||||||
* @param name - the name of the command
|
|
||||||
* @param id - the unique id of the command
|
|
||||||
* @param help - the help message for this command
|
|
||||||
* @param params - the minimum number of required params if any
|
|
||||||
*/
|
|
||||||
private void addCommand(String name, int id, String help, int params) {
|
|
||||||
Command command = new Command(name, id, help, params);
|
|
||||||
commandMap.put(name, command);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getCommandId(String name, int params) {
|
|
||||||
name = name.toLowerCase(); //treat uppercase and lower case commands the same
|
|
||||||
Command command = commandMap.get(name);
|
|
||||||
if (command == null) {
|
|
||||||
return(UNKOWN);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(command.params > params) {
|
|
||||||
error(command.name + " needs at least " + command.params + " arguments.");
|
|
||||||
return (NOCOMMAND);
|
|
||||||
}
|
|
||||||
return (command.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void help() {
|
|
||||||
Iterator<String> commands = commandMap.keySet().iterator();
|
|
||||||
while (commands.hasNext()) {
|
|
||||||
Command command = commandMap.get(commands.next());
|
|
||||||
System.out.println("\t" + command.name + ": " + command.help);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void error(String message) {
|
|
||||||
System.err.println("Error:" + message);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void message(String text) {
|
|
||||||
System.out.println(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Parse command line arguments (currently none)
|
|
||||||
*/
|
|
||||||
private void parseArgs(String[] args) {
|
|
||||||
if (args.length > 0) {
|
|
||||||
usage();
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void usage() {
|
|
||||||
message("Usage: lucli.Lucli");
|
|
||||||
message("(currently, no parameters are supported)");
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Command {
|
|
||||||
String name;
|
|
||||||
int id;
|
|
||||||
String help;
|
|
||||||
int params;
|
|
||||||
|
|
||||||
Command(String name, int id, String help, int params) {
|
|
||||||
this.name = name;
|
|
||||||
this.id = id;
|
|
||||||
this.help = help;
|
|
||||||
this.params = params;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints out a usage message for this command.
|
|
||||||
*/
|
|
||||||
public String commandUsage() {
|
|
||||||
return (name + ":" + help + ". Command takes " + params + " params");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
|
||||||
<!--
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
<html><head></head>
|
|
||||||
<body>
|
|
||||||
Lucene Command Line Interface
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,26 +0,0 @@
|
||||||
<!--
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>
|
|
||||||
lucli
|
|
||||||
</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
lucli
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,57 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<project name="swing" default="default">
|
|
||||||
|
|
||||||
<description>
|
|
||||||
Swing Models
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<import file="../contrib-build.xml"/>
|
|
||||||
|
|
||||||
<module-uptodate name="analysis/common" jarfile="${common.dir}/../modules/analysis/build/common/lucene-analyzers-common-${version}.jar"
|
|
||||||
property="analyzers-common.uptodate" classpath.property="analyzers-common.jar"/>
|
|
||||||
|
|
||||||
<path id="classpath">
|
|
||||||
<pathelement path="${analyzers-common.jar}"/>
|
|
||||||
<path refid="base.classpath"/>
|
|
||||||
</path>
|
|
||||||
|
|
||||||
<target name="compile-core" depends="compile-analyzers-common, common.compile-core" />
|
|
||||||
|
|
||||||
<target name="compile-analyzers-common" unless="analyzers-common.uptodate">
|
|
||||||
<subant target="default">
|
|
||||||
<fileset dir="${common.dir}/../modules/analysis/common" includes="build.xml"/>
|
|
||||||
</subant>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="list-demo" depends="compile">
|
|
||||||
<java classname="org.apache.lucene.swing.models.ListSearcherSimulator"
|
|
||||||
fork="yes" spawn="yes"
|
|
||||||
classpathref="test.classpath"
|
|
||||||
/>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="table-demo" depends="compile">
|
|
||||||
<java classname="org.apache.lucene.swing.models.TableSearcherSimulator"
|
|
||||||
fork="yes" spawn="yes"
|
|
||||||
classpathref="test.classpath"
|
|
||||||
/>
|
|
||||||
</target>
|
|
||||||
</project>
|
|
|
@ -1,97 +0,0 @@
|
||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Lucene Powered Swing Data Models</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1><strong> Lucene Powered Swing Data Models </strong></h1>
|
|
||||||
<p><strong>by Jonathan Simon </strong></p>
|
|
||||||
<p> </p>
|
|
||||||
<p><strong>What it is.</strong></p>
|
|
||||||
<p>This package contains classes that help you easily integrate Lucene based searching
|
|
||||||
into your Swing components. Currently there are classes to index and search
|
|
||||||
JTables and JLists. This is done using model decorators rather than custom models
|
|
||||||
to make it easier to search current models as well as new ones. </p>
|
|
||||||
<p><em>These models do not actually contain any data</em>. Rather, the ListModel
|
|
||||||
decorator (ListSearcher) and the TableModel decorator (TableSearcher) take a
|
|
||||||
model in the constructor and delegate all calls to it (after a little alteration,
|
|
||||||
but we'll get to that). That said, these are not full fledged models themselves.
|
|
||||||
You still have to have another model to decorate with the searching models.
|
|
||||||
If you are adding searching to a pre-existing model, you can use your pre-existing
|
|
||||||
model directly. Otherwise, you can implement a model from scratch or use a pre-existing
|
|
||||||
one to get started. </p>
|
|
||||||
<p><strong>What it isn't. </strong></p>
|
|
||||||
<p>A complete component: These are just models. They are not complete components
|
|
||||||
with search fields and buttons laid out like a searchable interface. You still
|
|
||||||
have to build that since the UI changes drastically between applciations.</p>
|
|
||||||
<p>A complete model: There are just model decorators. You can't just set the model
|
|
||||||
of a JList or JTable to one of these models, and you can't add data directly
|
|
||||||
to these models. </p>
|
|
||||||
<p>A front end for a lucene index: In other words, you can't use these classes
|
|
||||||
to point a JTable directly to a Lucene index. Although that's interesting in
|
|
||||||
its own right, this is not that. </p>
|
|
||||||
<p><strong>Usage: </strong></p>
|
|
||||||
<p>Coding to both models nearly identical. They both take the model to decorate
|
|
||||||
at construction time. Here is the code from the demo to decorate a JTable model
|
|
||||||
with the TableSearcher and set it as the table model. </p>
|
|
||||||
<pre><code>//make a new JTable
|
|
||||||
JTable table = new JTable();
|
|
||||||
//make my base model, the model with the data
|
|
||||||
BaseTableModel tableModel = new BaseTableModel(DataStore.getRestaurants());
|
|
||||||
//decorate the tableModel with the TableSearcher
|
|
||||||
TableSearcher searchTableModel = new TableSearcher(tableModel);
|
|
||||||
//set the TableModel in the table to the TableSearcher
|
|
||||||
table.setModel(searchTableModel);
|
|
||||||
</code></pre>
|
|
||||||
<p>Initially, you won't notice a difference. This is because there is no active
|
|
||||||
search which displays all data from the underlying model. You search by calling
|
|
||||||
the <code>search</code>() method passing a search string. This filters the data
|
|
||||||
set down without changing the underlying data model -- one of the main reasons
|
|
||||||
for decorating in the first place. Any valid Lucene search string should work
|
|
||||||
(see notes for more info on this). You'll probaby have some code somewhere like
|
|
||||||
this in your app to connect a text field and search button to the model. </p>
|
|
||||||
<pre><code>//create components
|
|
||||||
final JTextField searchField = new JTextField();
|
|
||||||
JButton searchButton = new JButton("Go");
|
|
||||||
|
|
||||||
//make an action listener
|
|
||||||
ActionListener searchListener = new ActionListener() {
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
searchTableModel.search(searchField.getText().trim().toLowerCase());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//register listeners
|
|
||||||
searchButton.addActionListener(searchListener);
|
|
||||||
searchField.addActionListener(searchListener);</code></pre>
|
|
||||||
<p>You also might want to have a clear search button, working the same way. But
|
|
||||||
to keep things simple, if you search will a <code>null </code>String or an empty
|
|
||||||
String, the search clears and you will once again see all of your data. </p>
|
|
||||||
<p><strong>Demo notes:</strong> </p>
|
|
||||||
<p>The list demo does real time searching. In other words, as you type, searches
|
|
||||||
run and the result set updates. The table demo has a search button, and only
|
|
||||||
searches when the button is clicked. They both work, I just implemented them
|
|
||||||
this way to show the different UI metaphors and that they both work.</p>
|
|
||||||
<p><strong>Implementation notes: </strong></p>
|
|
||||||
<p>This code started as a proof of concept so it's not a <em>fully</em> featured
|
|
||||||
model. Don't get me wrong, it <em>fully</em> works, but it could use some improvement
|
|
||||||
that it will hopefully get over time. I just wanted to get it out there and
|
|
||||||
get people using it. I'm also trying to keep everything as simple as possible.
|
|
||||||
Here are some of the issues. </p>
|
|
||||||
<ul>
|
|
||||||
<li>You can't change the model after the Searcher is constructed. </li>
|
|
||||||
<li>The search model decorators <em>do</em> update when the decorated model
|
|
||||||
is updated, but not in a very efficient way. The whole search model is reindexed
|
|
||||||
when anything changes. This is a definite scaling issue. </li>
|
|
||||||
<li>The indexing and searching logic needs to be generally more configurable
|
|
||||||
to allow custom tailoring of searched and indexing. </li>
|
|
||||||
<li>The TableSearcher uses column names to index column values. This could be
|
|
||||||
an issue with multiple word column names. </li>
|
|
||||||
<li>The ListSearcher uses MultiFieldQueryParser even though its not really indexing
|
|
||||||
multiple fields. </li>
|
|
||||||
</ul>
|
|
||||||
<p> </p>
|
|
||||||
<p> </p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,311 +0,0 @@
|
||||||
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.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import javax.swing.AbstractListModel;
|
|
||||||
import javax.swing.ListModel;
|
|
||||||
import javax.swing.event.ListDataEvent;
|
|
||||||
import javax.swing.event.ListDataListener;
|
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
|
||||||
import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
|
|
||||||
import org.apache.lucene.document.Document;
|
|
||||||
import org.apache.lucene.document.Field;
|
|
||||||
import org.apache.lucene.document.Fieldable;
|
|
||||||
import org.apache.lucene.index.IndexReader;
|
|
||||||
import org.apache.lucene.index.IndexWriter;
|
|
||||||
import org.apache.lucene.index.IndexWriterConfig;
|
|
||||||
import org.apache.lucene.index.IndexReader.AtomicReaderContext;
|
|
||||||
import org.apache.lucene.queryParser.MultiFieldQueryParser;
|
|
||||||
import org.apache.lucene.search.Collector;
|
|
||||||
import org.apache.lucene.search.IndexSearcher;
|
|
||||||
import org.apache.lucene.search.Query;
|
|
||||||
import org.apache.lucene.search.ScoreDoc;
|
|
||||||
import org.apache.lucene.search.Scorer;
|
|
||||||
import org.apache.lucene.store.RAMDirectory;
|
|
||||||
import org.apache.lucene.util.Version;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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<Integer> rowToModelIndex = new ArrayList<Integer>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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(Version.LUCENE_CURRENT);
|
|
||||||
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, new IndexWriterConfig(Version.LUCENE_CURRENT, analyzer));
|
|
||||||
|
|
||||||
// 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 retrieve 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, true);
|
|
||||||
|
|
||||||
//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(Version.LUCENE_CURRENT, fields, analyzer);
|
|
||||||
Query query =parser.parse(searchString);
|
|
||||||
//reset this list model with the new results
|
|
||||||
resetSearchResults(is, query);
|
|
||||||
} catch (Exception e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
//notify all listeners that the list has been changed
|
|
||||||
fireContentsChanged(this, 0, getSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
final static class CountingCollector extends Collector {
|
|
||||||
public int numHits = 0;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setScorer(Scorer scorer) throws IOException {}
|
|
||||||
@Override
|
|
||||||
public void collect(int doc) throws IOException {
|
|
||||||
numHits++;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setNextReader(AtomicReaderContext context) {}
|
|
||||||
@Override
|
|
||||||
public boolean acceptsDocsOutOfOrder() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param hits The new result set to set this list to.
|
|
||||||
*/
|
|
||||||
private void resetSearchResults(IndexSearcher searcher, Query query) {
|
|
||||||
try {
|
|
||||||
//clear our index mapping this list model rows to
|
|
||||||
//the decorated inner list model
|
|
||||||
rowToModelIndex.clear();
|
|
||||||
|
|
||||||
CountingCollector countingCollector = new CountingCollector();
|
|
||||||
searcher.search(query, countingCollector);
|
|
||||||
ScoreDoc[] hits = searcher.search(query, countingCollector.numHits).scoreDocs;
|
|
||||||
|
|
||||||
//iterate through the hits
|
|
||||||
//get the row number stored at the index
|
|
||||||
//that number is the row number of the decorated
|
|
||||||
//table model row that we are mapping to
|
|
||||||
for (int t=0; t<hits.length; t++){
|
|
||||||
Document document = searcher.doc(hits[t].doc);
|
|
||||||
Fieldable field = document.getField(ROW_NUMBER);
|
|
||||||
rowToModelIndex.add(Integer.valueOf(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(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getModelRow(int row){
|
|
||||||
return rowToModelIndex.get(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,362 +0,0 @@
|
||||||
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 javax.swing.event.TableModelEvent;
|
|
||||||
import javax.swing.event.TableModelListener;
|
|
||||||
import javax.swing.table.AbstractTableModel;
|
|
||||||
import javax.swing.table.TableModel;
|
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
|
||||||
import org.apache.lucene.analysis.core.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.index.IndexWriterConfig;
|
|
||||||
import org.apache.lucene.queryParser.MultiFieldQueryParser;
|
|
||||||
import org.apache.lucene.search.IndexSearcher;
|
|
||||||
import org.apache.lucene.search.Query;
|
|
||||||
import org.apache.lucene.search.ScoreDoc;
|
|
||||||
import org.apache.lucene.store.RAMDirectory;
|
|
||||||
import org.apache.lucene.swing.models.ListSearcher.CountingCollector;
|
|
||||||
import org.apache.lucene.util.Version;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 functionality 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<Integer> rowToModelIndex = new ArrayList<Integer>();
|
|
||||||
|
|
||||||
|
|
||||||
//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(Version.LUCENE_CURRENT);
|
|
||||||
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, new IndexWriterConfig(
|
|
||||||
Version.LUCENE_CURRENT, analyzer));
|
|
||||||
|
|
||||||
// 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 retrieve 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, true);
|
|
||||||
|
|
||||||
//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(Version.LUCENE_CURRENT, fields, analyzer);
|
|
||||||
Query query = parser.parse(searchString);
|
|
||||||
//reset this table model with the new results
|
|
||||||
resetSearchResults(is, query);
|
|
||||||
} 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(IndexSearcher searcher, Query query) {
|
|
||||||
try {
|
|
||||||
//clear our index mapping this table model rows to
|
|
||||||
//the decorated inner table model
|
|
||||||
rowToModelIndex.clear();
|
|
||||||
|
|
||||||
CountingCollector countingCollector = new CountingCollector();
|
|
||||||
searcher.search(query, countingCollector);
|
|
||||||
ScoreDoc[] hits = searcher.search(query, countingCollector.numHits).scoreDocs;
|
|
||||||
|
|
||||||
//iterate through the hits
|
|
||||||
//get the row number stored at the index
|
|
||||||
//that number is the row number of the decorated
|
|
||||||
//table model row that we are mapping to
|
|
||||||
for (int t=0; t<hits.length; t++){
|
|
||||||
Document document = searcher.doc(hits[t].doc);
|
|
||||||
Fieldable field = document.getField(ROW_NUMBER);
|
|
||||||
rowToModelIndex.add(Integer.valueOf(field.stringValue()));
|
|
||||||
}
|
|
||||||
} catch (Exception e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getModelRow(int row){
|
|
||||||
return rowToModelIndex.get(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableModel interface methods
|
|
||||||
public int getRowCount() {
|
|
||||||
return (tableModel == null) ? 0 : rowToModelIndex.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getColumnCount() {
|
|
||||||
return (tableModel == null) ? 0 : tableModel.getColumnCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getColumnName(int column) {
|
|
||||||
return tableModel.getColumnName(column);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<?> getColumnClass(int column) {
|
|
||||||
return tableModel.getColumnClass(column);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
|
||||||
<!--
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
<html>
|
|
||||||
<body>
|
|
||||||
Decorators for JTable TableModel and JList ListModel encapsulating Lucene indexing and searching functionality.
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,23 +0,0 @@
|
||||||
<!--
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Apache Lucene Swing Component Models</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,55 +0,0 @@
|
||||||
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<Object> data = new ArrayList<Object>();
|
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,104 +0,0 @@
|
||||||
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<String> columnNames = new ArrayList<String>();
|
|
||||||
private List<Object> rows = new ArrayList<Object>();
|
|
||||||
|
|
||||||
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 = 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
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 "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
|
||||||
//no op
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getColumnName(int columnIndex) {
|
|
||||||
return columnNames.get(columnIndex).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,202 +0,0 @@
|
||||||
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.Collection;
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
|
|
||||||
public class DataStore {
|
|
||||||
|
|
||||||
private static final String ITALIAN_CATEGORY = "Italian";
|
|
||||||
private static final String CUBAN_CATEGORY = "Cuban";
|
|
||||||
private static final String STEAK_CATEGORY = "Steak";
|
|
||||||
private static int id = 0;
|
|
||||||
|
|
||||||
static Collection<RestaurantInfo> restaurants = new ArrayList<RestaurantInfo>();
|
|
||||||
static RestaurantInfo pinos = new RestaurantInfo();
|
|
||||||
static RestaurantInfo canolis = new RestaurantInfo();
|
|
||||||
static RestaurantInfo picadillo = new RestaurantInfo();
|
|
||||||
static RestaurantInfo versailles = new RestaurantInfo();
|
|
||||||
static RestaurantInfo laCaretta = new RestaurantInfo();
|
|
||||||
static RestaurantInfo laCaretta2 = new RestaurantInfo();
|
|
||||||
static RestaurantInfo laCaretta3 = new RestaurantInfo();
|
|
||||||
static RestaurantInfo ranchaLuna = new RestaurantInfo();
|
|
||||||
static RestaurantInfo leMerais = new RestaurantInfo();
|
|
||||||
static RestaurantInfo chris = new RestaurantInfo();
|
|
||||||
static RestaurantInfo outback = new RestaurantInfo();
|
|
||||||
static RestaurantInfo outback2 = new RestaurantInfo();
|
|
||||||
static RestaurantInfo outback3 = new RestaurantInfo();
|
|
||||||
static RestaurantInfo outback4 = new RestaurantInfo();
|
|
||||||
|
|
||||||
|
|
||||||
public static Iterator<RestaurantInfo> getRestaurants(){
|
|
||||||
return restaurants.iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
static {
|
|
||||||
pinos.setId(getNextId());
|
|
||||||
pinos.setType(ITALIAN_CATEGORY);
|
|
||||||
pinos.setName("Pino's");
|
|
||||||
pinos.setPhone("(305) 111-2222");
|
|
||||||
pinos.setStreet("12115 105th Street ");
|
|
||||||
pinos.setCity("Miami");
|
|
||||||
pinos.setState("FL");
|
|
||||||
pinos.setZip("33176");
|
|
||||||
restaurants.add(pinos);
|
|
||||||
|
|
||||||
canolis.setId(getNextId());
|
|
||||||
canolis.setType(ITALIAN_CATEGORY);
|
|
||||||
canolis.setName("Canoli's");
|
|
||||||
canolis.setPhone("(305) 234-5543");
|
|
||||||
canolis.setStreet("12123 85th Street ");
|
|
||||||
canolis.setCity("Miami");
|
|
||||||
canolis.setState("FL");
|
|
||||||
canolis.setZip("33176");
|
|
||||||
restaurants.add(canolis);
|
|
||||||
|
|
||||||
picadillo.setId(getNextId());
|
|
||||||
picadillo.setType(CUBAN_CATEGORY);
|
|
||||||
picadillo.setName("Picadillo");
|
|
||||||
picadillo.setPhone("(305) 746-7865");
|
|
||||||
picadillo.setStreet("109 12th Street ");
|
|
||||||
picadillo.setCity("Miami");
|
|
||||||
picadillo.setState("FL");
|
|
||||||
picadillo.setZip("33176");
|
|
||||||
restaurants.add(picadillo);
|
|
||||||
|
|
||||||
versailles.setId(getNextId());
|
|
||||||
versailles.setType(CUBAN_CATEGORY);
|
|
||||||
versailles.setName("Cafe Versailles");
|
|
||||||
versailles.setPhone("(305) 201-5438");
|
|
||||||
versailles.setStreet("312 8th Street ");
|
|
||||||
versailles.setCity("Miami");
|
|
||||||
versailles.setState("FL");
|
|
||||||
versailles.setZip("33176");
|
|
||||||
restaurants.add(versailles);
|
|
||||||
|
|
||||||
laCaretta.setId(getNextId());
|
|
||||||
laCaretta.setType(CUBAN_CATEGORY);
|
|
||||||
laCaretta.setName("La Carretta");
|
|
||||||
laCaretta.setPhone("(305) 342-9876");
|
|
||||||
laCaretta.setStreet("348 8th Street ");
|
|
||||||
laCaretta.setCity("Miami");
|
|
||||||
laCaretta.setState("FL");
|
|
||||||
laCaretta.setZip("33176");
|
|
||||||
restaurants.add(laCaretta);
|
|
||||||
|
|
||||||
laCaretta2.setId(getNextId());
|
|
||||||
laCaretta2.setType(CUBAN_CATEGORY);
|
|
||||||
laCaretta2.setName("La Carretta");
|
|
||||||
laCaretta2.setPhone("(305) 556-9876");
|
|
||||||
laCaretta2.setStreet("31224 23rd Street ");
|
|
||||||
laCaretta2.setCity("Miami");
|
|
||||||
laCaretta2.setState("FL");
|
|
||||||
laCaretta2.setZip("33176");
|
|
||||||
restaurants.add(laCaretta2);
|
|
||||||
|
|
||||||
laCaretta3.setId(getNextId());
|
|
||||||
laCaretta3.setType(CUBAN_CATEGORY);
|
|
||||||
laCaretta3.setName("La Carretta");
|
|
||||||
laCaretta3.setPhone("(305) 682-9876");
|
|
||||||
laCaretta3.setStreet("23543 107th Street ");
|
|
||||||
laCaretta3.setCity("Miami");
|
|
||||||
laCaretta3.setState("FL");
|
|
||||||
laCaretta3.setZip("33176");
|
|
||||||
restaurants.add(laCaretta3);
|
|
||||||
|
|
||||||
ranchaLuna.setId(getNextId());
|
|
||||||
ranchaLuna.setType(CUBAN_CATEGORY);
|
|
||||||
ranchaLuna.setName("Rancha Luna");
|
|
||||||
ranchaLuna.setPhone("(305) 777-4384");
|
|
||||||
ranchaLuna.setStreet("110 23rd Street ");
|
|
||||||
ranchaLuna.setCity("Miami");
|
|
||||||
ranchaLuna.setState("FL");
|
|
||||||
ranchaLuna.setZip("33176");
|
|
||||||
restaurants.add(ranchaLuna);
|
|
||||||
|
|
||||||
leMerais.setId(getNextId());
|
|
||||||
leMerais.setType(STEAK_CATEGORY);
|
|
||||||
leMerais.setName("Le Merais");
|
|
||||||
leMerais.setPhone("(212) 654-9187");
|
|
||||||
leMerais.setStreet("11 West 46th Street");
|
|
||||||
leMerais.setCity("New York");
|
|
||||||
leMerais.setState("NY");
|
|
||||||
leMerais.setZip("10018");
|
|
||||||
restaurants.add(leMerais);
|
|
||||||
|
|
||||||
chris.setId(getNextId());
|
|
||||||
chris.setType(STEAK_CATEGORY);
|
|
||||||
chris.setName("Ruth's Chris Seakhouse");
|
|
||||||
chris.setPhone("(305) 354-8885");
|
|
||||||
chris.setStreet("12365 203rd Street ");
|
|
||||||
chris.setCity("Miami");
|
|
||||||
chris.setState("FL");
|
|
||||||
chris.setZip("33176");
|
|
||||||
restaurants.add(chris);
|
|
||||||
|
|
||||||
outback.setId(getNextId());
|
|
||||||
outback.setType(STEAK_CATEGORY);
|
|
||||||
outback.setName("Outback");
|
|
||||||
outback.setPhone("(305) 244-7623");
|
|
||||||
outback.setStreet("348 136th Street ");
|
|
||||||
outback.setCity("Miami");
|
|
||||||
outback.setState("FL");
|
|
||||||
outback.setZip("33176");
|
|
||||||
restaurants.add(outback);
|
|
||||||
|
|
||||||
outback2.setId(getNextId());
|
|
||||||
outback2.setType(STEAK_CATEGORY);
|
|
||||||
outback2.setName("Outback");
|
|
||||||
outback2.setPhone("(305) 533-6522");
|
|
||||||
outback2.setStreet("21 207th Street ");
|
|
||||||
outback2.setCity("Miami");
|
|
||||||
outback2.setState("FL");
|
|
||||||
outback2.setZip("33176");
|
|
||||||
restaurants.add(outback2);
|
|
||||||
|
|
||||||
outback3.setId(getNextId());
|
|
||||||
outback3.setType(STEAK_CATEGORY);
|
|
||||||
outback3.setName("Outback");
|
|
||||||
outback3.setPhone("(305) 244-7623");
|
|
||||||
outback3.setStreet("10117 107th Street ");
|
|
||||||
outback3.setCity("Miami");
|
|
||||||
outback3.setState("FL");
|
|
||||||
outback3.setZip("33176");
|
|
||||||
restaurants.add(outback3);
|
|
||||||
|
|
||||||
outback4.setId(getNextId());
|
|
||||||
outback4.setType(STEAK_CATEGORY);
|
|
||||||
outback4.setName("Outback");
|
|
||||||
outback4.setPhone("(954) 221-3312");
|
|
||||||
outback4.setStreet("10 11th Street ");
|
|
||||||
outback4.setCity("Aventura");
|
|
||||||
outback4.setState("FL");
|
|
||||||
outback4.setZip("32154");
|
|
||||||
restaurants.add(outback4);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getNextId(){
|
|
||||||
id++;
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,88 +0,0 @@
|
||||||
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.awt.BorderLayout;
|
|
||||||
|
|
||||||
import javax.swing.JFrame;
|
|
||||||
import javax.swing.JLabel;
|
|
||||||
import javax.swing.JList;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.JScrollPane;
|
|
||||||
import javax.swing.JTextField;
|
|
||||||
import javax.swing.event.DocumentEvent;
|
|
||||||
import javax.swing.event.DocumentListener;
|
|
||||||
|
|
||||||
|
|
||||||
public class ListSearcherSimulator {
|
|
||||||
|
|
||||||
public ListSearcherSimulator() {
|
|
||||||
JFrame frame = new JFrame();
|
|
||||||
frame.setBounds(200,200, 400,250);
|
|
||||||
|
|
||||||
JList list = new JList();
|
|
||||||
JScrollPane scrollPane = new JScrollPane(list);
|
|
||||||
|
|
||||||
final BaseListModel listModel = new BaseListModel(DataStore.getRestaurants());
|
|
||||||
final ListSearcher listSearcher = new ListSearcher(listModel);
|
|
||||||
|
|
||||||
list.setModel(listSearcher);
|
|
||||||
|
|
||||||
final JTextField searchField = new JTextField();
|
|
||||||
searchField.getDocument().addDocumentListener(
|
|
||||||
new DocumentListener(){
|
|
||||||
public void changedUpdate(DocumentEvent e) {
|
|
||||||
listSearcher.search(searchField.getText().trim().toLowerCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void insertUpdate(DocumentEvent e) {
|
|
||||||
listSearcher.search(searchField.getText().trim().toLowerCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeUpdate(DocumentEvent e) {
|
|
||||||
listSearcher.search(searchField.getText().trim().toLowerCase());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
frame.getContentPane().setLayout(new BorderLayout());
|
|
||||||
frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
|
|
||||||
|
|
||||||
JPanel searchPanel = new JPanel();
|
|
||||||
searchPanel.setLayout(new BorderLayout(10,10));
|
|
||||||
searchPanel.add(searchField, BorderLayout.CENTER);
|
|
||||||
searchPanel.add(new JLabel("Search: "), BorderLayout.WEST);
|
|
||||||
|
|
||||||
JPanel topPanel = new JPanel(new BorderLayout());
|
|
||||||
topPanel.add(searchPanel, BorderLayout.CENTER);
|
|
||||||
topPanel.add(new JPanel(), BorderLayout.EAST);
|
|
||||||
topPanel.add(new JPanel(), BorderLayout.WEST);
|
|
||||||
topPanel.add(new JPanel(), BorderLayout.NORTH);
|
|
||||||
topPanel.add(new JPanel(), BorderLayout.SOUTH);
|
|
||||||
|
|
||||||
frame.getContentPane().add(topPanel, BorderLayout.NORTH);
|
|
||||||
|
|
||||||
frame.setTitle("Lucene powered table searching");
|
|
||||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
||||||
frame.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
new ListSearcherSimulator();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,101 +0,0 @@
|
||||||
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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
public class RestaurantInfo {
|
|
||||||
private int id;
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
private String type;
|
|
||||||
|
|
||||||
private String phone;
|
|
||||||
private String street;
|
|
||||||
private String city;
|
|
||||||
private String state;
|
|
||||||
private String zip;
|
|
||||||
|
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(int id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPhone() {
|
|
||||||
return phone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPhone(String phone) {
|
|
||||||
this.phone = phone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStreet() {
|
|
||||||
return street;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStreet(String street) {
|
|
||||||
this.street = street;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCity() {
|
|
||||||
return city;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCity(String city) {
|
|
||||||
this.city = city;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getState() {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setState(String state) {
|
|
||||||
this.state = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getZip() {
|
|
||||||
return zip;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setZip(String zip) {
|
|
||||||
this.zip = zip;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setType(String type) {
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return getName() + " - " + getPhone();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,81 +0,0 @@
|
||||||
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 javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
|
|
||||||
|
|
||||||
public class TableSearcherSimulator {
|
|
||||||
|
|
||||||
public TableSearcherSimulator() {
|
|
||||||
JFrame frame = new JFrame();
|
|
||||||
frame.setBounds(200,200, 400,250);
|
|
||||||
|
|
||||||
JTable table = new JTable();
|
|
||||||
final BaseTableModel tableModel = new BaseTableModel(DataStore.getRestaurants());
|
|
||||||
final TableSearcher searchTableModel = new TableSearcher(tableModel);
|
|
||||||
|
|
||||||
table.setModel(searchTableModel);
|
|
||||||
JScrollPane scrollPane = new JScrollPane(table);
|
|
||||||
|
|
||||||
final JTextField searchField = new JTextField();
|
|
||||||
JButton searchButton = new JButton("Go");
|
|
||||||
|
|
||||||
ActionListener searchListener = new ActionListener() {
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
searchTableModel.search(searchField.getText().trim().toLowerCase());
|
|
||||||
searchField.requestFocus();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
searchButton.addActionListener(searchListener);
|
|
||||||
searchField.addActionListener(searchListener);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
frame.getContentPane().setLayout(new BorderLayout());
|
|
||||||
frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
|
|
||||||
|
|
||||||
JPanel searchPanel = new JPanel();
|
|
||||||
searchPanel.setLayout(new BorderLayout(10,10));
|
|
||||||
searchPanel.add(searchField, BorderLayout.CENTER);
|
|
||||||
searchPanel.add(searchButton, BorderLayout.EAST);
|
|
||||||
|
|
||||||
JPanel topPanel = new JPanel(new BorderLayout());
|
|
||||||
topPanel.add(searchPanel, BorderLayout.CENTER);
|
|
||||||
topPanel.add(new JPanel(), BorderLayout.EAST);
|
|
||||||
topPanel.add(new JPanel(), BorderLayout.WEST);
|
|
||||||
topPanel.add(new JPanel(), BorderLayout.NORTH);
|
|
||||||
topPanel.add(new JPanel(), BorderLayout.SOUTH);
|
|
||||||
|
|
||||||
frame.getContentPane().add(topPanel, BorderLayout.NORTH);
|
|
||||||
|
|
||||||
frame.setTitle("Lucene powered table searching");
|
|
||||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
||||||
frame.show();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
new TableSearcherSimulator();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
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.List;
|
|
||||||
|
|
||||||
import javax.swing.ListModel;
|
|
||||||
|
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
**/
|
|
||||||
public class TestBasicList extends LuceneTestCase {
|
|
||||||
private ListModel baseListModel;
|
|
||||||
private ListSearcher listSearcher;
|
|
||||||
private List<RestaurantInfo> list;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
list = new ArrayList<RestaurantInfo>();
|
|
||||||
list.add(DataStore.canolis);
|
|
||||||
list.add(DataStore.chris);
|
|
||||||
|
|
||||||
baseListModel = new BaseListModel(list.iterator());
|
|
||||||
listSearcher = new ListSearcher(baseListModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testRows(){
|
|
||||||
assertEquals(list.size(), listSearcher.getSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testValueAt(){
|
|
||||||
assertEquals(baseListModel.getElementAt(0), listSearcher.getElementAt(0));
|
|
||||||
assertNotSame(baseListModel.getElementAt(1), listSearcher.getElementAt(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
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.List;
|
|
||||||
|
|
||||||
import javax.swing.table.TableModel;
|
|
||||||
|
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
|
||||||
|
|
||||||
|
|
||||||
public class TestBasicTable extends LuceneTestCase {
|
|
||||||
private TableModel baseTableModel;
|
|
||||||
private TableSearcher tableSearcher;
|
|
||||||
private List<RestaurantInfo> list;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
list = new ArrayList<RestaurantInfo>();
|
|
||||||
list.add(DataStore.canolis);
|
|
||||||
list.add(DataStore.chris);
|
|
||||||
|
|
||||||
baseTableModel = new BaseTableModel(list.iterator());
|
|
||||||
tableSearcher = new TableSearcher(baseTableModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testColumns(){
|
|
||||||
|
|
||||||
assertEquals(baseTableModel.getColumnCount(), tableSearcher.getColumnCount());
|
|
||||||
assertEquals(baseTableModel.getColumnName(0), tableSearcher.getColumnName(0));
|
|
||||||
assertNotSame(baseTableModel.getColumnName(0), tableSearcher.getColumnName(1));
|
|
||||||
assertEquals(baseTableModel.getColumnClass(0), tableSearcher.getColumnClass(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testRows(){
|
|
||||||
assertEquals(list.size(), tableSearcher.getRowCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testValueAt(){
|
|
||||||
assertEquals(baseTableModel.getValueAt(0,0), tableSearcher.getValueAt(0,0));
|
|
||||||
assertEquals(baseTableModel.getValueAt(0,3), tableSearcher.getValueAt(0,3));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
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 javax.swing.ListModel;
|
|
||||||
|
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class TestSearchingList extends LuceneTestCase {
|
|
||||||
private ListModel baseListModel;
|
|
||||||
private ListSearcher listSearcher;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
baseListModel = new BaseListModel(DataStore.getRestaurants());
|
|
||||||
listSearcher = new ListSearcher(baseListModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSearch(){
|
|
||||||
//make sure data is there
|
|
||||||
assertEquals(baseListModel.getSize(), listSearcher.getSize());
|
|
||||||
//search for pino's
|
|
||||||
listSearcher.search("pino's");
|
|
||||||
assertEquals(1, listSearcher.getSize());
|
|
||||||
//clear search and check that
|
|
||||||
listSearcher.search(null);
|
|
||||||
assertEquals(baseListModel.getSize(), listSearcher.getSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
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 javax.swing.table.TableModel;
|
|
||||||
|
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
|
||||||
|
|
||||||
public class TestSearchingTable extends LuceneTestCase {
|
|
||||||
private TableModel baseTableModel;
|
|
||||||
private TableSearcher tableSearcher;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
baseTableModel = new BaseTableModel(DataStore.getRestaurants());
|
|
||||||
tableSearcher = new TableSearcher(baseTableModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSearch(){
|
|
||||||
//make sure data is there
|
|
||||||
assertEquals(baseTableModel.getRowCount(), tableSearcher.getRowCount());
|
|
||||||
//search for pino's
|
|
||||||
tableSearcher.search("pino's");
|
|
||||||
assertEquals(1, tableSearcher.getRowCount());
|
|
||||||
//clear search and check that
|
|
||||||
tableSearcher.search(null);
|
|
||||||
assertEquals(baseTableModel.getRowCount(), tableSearcher.getRowCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
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.util.LuceneTestCase;
|
|
||||||
|
|
||||||
|
|
||||||
public class TestUpdatingList extends LuceneTestCase {
|
|
||||||
private BaseListModel baseListModel;
|
|
||||||
private ListSearcher listSearcher;
|
|
||||||
|
|
||||||
RestaurantInfo infoToAdd1, infoToAdd2;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
baseListModel = new BaseListModel(DataStore.getRestaurants());
|
|
||||||
listSearcher = new ListSearcher(baseListModel);
|
|
||||||
|
|
||||||
infoToAdd1 = new RestaurantInfo();
|
|
||||||
infoToAdd1.setName("Pino's");
|
|
||||||
|
|
||||||
infoToAdd2 = new RestaurantInfo();
|
|
||||||
infoToAdd2.setName("Pino's");
|
|
||||||
infoToAdd2.setType("Italian");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAddWithoutSearch(){
|
|
||||||
assertEquals(baseListModel.getSize(), listSearcher.getSize());
|
|
||||||
int count = listSearcher.getSize();
|
|
||||||
baseListModel.addRow(infoToAdd1);
|
|
||||||
count++;
|
|
||||||
assertEquals(count, listSearcher.getSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testRemoveWithoutSearch(){
|
|
||||||
assertEquals(baseListModel.getSize(), listSearcher.getSize());
|
|
||||||
baseListModel.addRow(infoToAdd1);
|
|
||||||
int count = listSearcher.getSize();
|
|
||||||
baseListModel.removeRow(infoToAdd1);
|
|
||||||
count--;
|
|
||||||
assertEquals(count, listSearcher.getSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAddWithSearch(){
|
|
||||||
assertEquals(baseListModel.getSize(), listSearcher.getSize());
|
|
||||||
listSearcher.search("pino's");
|
|
||||||
int count = listSearcher.getSize();
|
|
||||||
baseListModel.addRow(infoToAdd2);
|
|
||||||
count++;
|
|
||||||
assertEquals(count, listSearcher.getSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testRemoveWithSearch(){
|
|
||||||
assertEquals(baseListModel.getSize(), listSearcher.getSize());
|
|
||||||
baseListModel.addRow(infoToAdd1);
|
|
||||||
listSearcher.search("pino's");
|
|
||||||
int count = listSearcher.getSize();
|
|
||||||
baseListModel.removeRow(infoToAdd1);
|
|
||||||
count--;
|
|
||||||
assertEquals(count, listSearcher.getSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
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.util.LuceneTestCase;
|
|
||||||
|
|
||||||
|
|
||||||
public class TestUpdatingTable extends LuceneTestCase {
|
|
||||||
private BaseTableModel baseTableModel;
|
|
||||||
private TableSearcher tableSearcher;
|
|
||||||
|
|
||||||
RestaurantInfo infoToAdd1, infoToAdd2;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
baseTableModel = new BaseTableModel(DataStore.getRestaurants());
|
|
||||||
tableSearcher = new TableSearcher(baseTableModel);
|
|
||||||
|
|
||||||
infoToAdd1 = new RestaurantInfo();
|
|
||||||
infoToAdd1.setName("Pino's");
|
|
||||||
infoToAdd1.setType("Italian");
|
|
||||||
|
|
||||||
infoToAdd2 = new RestaurantInfo();
|
|
||||||
infoToAdd2.setName("Pino's");
|
|
||||||
infoToAdd2.setType("Italian");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAddWithoutSearch(){
|
|
||||||
assertEquals(baseTableModel.getRowCount(), tableSearcher.getRowCount());
|
|
||||||
int count = tableSearcher.getRowCount();
|
|
||||||
baseTableModel.addRow(infoToAdd1);
|
|
||||||
count++;
|
|
||||||
assertEquals(count, tableSearcher.getRowCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testRemoveWithoutSearch(){
|
|
||||||
assertEquals(baseTableModel.getRowCount(), tableSearcher.getRowCount());
|
|
||||||
int count = tableSearcher.getRowCount();
|
|
||||||
baseTableModel.addRow(infoToAdd1);
|
|
||||||
baseTableModel.removeRow(infoToAdd1);
|
|
||||||
assertEquals(count, tableSearcher.getRowCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAddWithSearch(){
|
|
||||||
assertEquals(baseTableModel.getRowCount(), tableSearcher.getRowCount());
|
|
||||||
tableSearcher.search("pino's");
|
|
||||||
int count = tableSearcher.getRowCount();
|
|
||||||
baseTableModel.addRow(infoToAdd2);
|
|
||||||
count++;
|
|
||||||
assertEquals(count, tableSearcher.getRowCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testRemoveWithSearch(){
|
|
||||||
assertEquals(baseTableModel.getRowCount(), tableSearcher.getRowCount());
|
|
||||||
baseTableModel.addRow(infoToAdd1);
|
|
||||||
tableSearcher.search("pino's");
|
|
||||||
int count = tableSearcher.getRowCount();
|
|
||||||
baseTableModel.removeRow(infoToAdd1);
|
|
||||||
count--;
|
|
||||||
assertEquals(count, tableSearcher.getRowCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -50,11 +50,6 @@
|
||||||
<a href="http://svn.apache.org/repos/asf/lucene/dev/trunk/lucene/contrib/">http://svn.apache.org/repos/asf/lucene/dev/trunk/lucene/contrib/</a>.
|
<a href="http://svn.apache.org/repos/asf/lucene/dev/trunk/lucene/contrib/">http://svn.apache.org/repos/asf/lucene/dev/trunk/lucene/contrib/</a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<section id="ant"><title>ant</title>
|
|
||||||
<p>Ant task to create Lucene indexes.</p>
|
|
||||||
<p>See <a href="../api/contrib-ant/index.html">ant javadoc</a></p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="benchmark"><title>benchmark</title>
|
<section id="benchmark"><title>benchmark</title>
|
||||||
<p>The benchmark contribution contains tools for benchmarking Lucene using standard, freely available corpora.</p>
|
<p>The benchmark contribution contains tools for benchmarking Lucene using standard, freely available corpora.</p>
|
||||||
<p>See <a href="../api/contrib-benchmark/index.html">benchmark javadoc</a></p>
|
<p>See <a href="../api/contrib-benchmark/index.html">benchmark javadoc</a></p>
|
||||||
|
@ -66,11 +61,6 @@
|
||||||
<p>See <a href="../api/contrib-demo/index.html">demo javadoc</a></p>
|
<p>See <a href="../api/contrib-demo/index.html">demo javadoc</a></p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="db"><title>db</title>
|
|
||||||
<p>Provides integration with Berkley DB.</p>
|
|
||||||
<p>See <a href="../api/contrib-db/index.html">db javadoc</a></p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="highlighter"><title>highlighter</title>
|
<section id="highlighter"><title>highlighter</title>
|
||||||
<p>A set of classes for highlighting matching terms in search results.</p>
|
<p>A set of classes for highlighting matching terms in search results.</p>
|
||||||
<p>See <a href="../api/contrib-highlighter/index.html">highlighter javadoc</a></p>
|
<p>See <a href="../api/contrib-highlighter/index.html">highlighter javadoc</a></p>
|
||||||
|
@ -81,11 +71,6 @@
|
||||||
<p>See <a href="../api/contrib-instantiated/index.html">instantiated javadoc</a></p>
|
<p>See <a href="../api/contrib-instantiated/index.html">instantiated javadoc</a></p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="lucli"><title>lucli</title>
|
|
||||||
<p>An application that allows Lucene index manipulation from the command-line.</p>
|
|
||||||
<p>See <a href="../api/contrib-lucli/index.html">lucli javadoc</a></p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="memory"><title>memory</title>
|
<section id="memory"><title>memory</title>
|
||||||
<p>High-performance single-document main memory index.</p>
|
<p>High-performance single-document main memory index.</p>
|
||||||
<p>See <a href="../api/contrib-memory/index.html">memory javadoc</a></p>
|
<p>See <a href="../api/contrib-memory/index.html">memory javadoc</a></p>
|
||||||
|
@ -121,11 +106,6 @@
|
||||||
<p>See <a href="../api/contrib-spellchecker/index.html">spellchecker javadoc</a></p>
|
<p>See <a href="../api/contrib-spellchecker/index.html">spellchecker javadoc</a></p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="swing"><title>swing</title>
|
|
||||||
<p>Swing components designed to integrate with Lucene.</p>
|
|
||||||
<p>See <a href="../api/contrib-swing/index.html">swing javadoc</a></p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="wordnet"><title>wordnet</title>
|
<section id="wordnet"><title>wordnet</title>
|
||||||
<p>Tools to help utilize wordnet synonyms with Lucene</p>
|
<p>Tools to help utilize wordnet synonyms with Lucene</p>
|
||||||
<p>See <a href="../api/contrib-wordnet/index.html">wordnet javadoc</a></p>
|
<p>See <a href="../api/contrib-wordnet/index.html">wordnet javadoc</a></p>
|
||||||
|
|
|
@ -52,14 +52,10 @@ See http://forrest.apache.org/docs/linking.html for more info
|
||||||
<javadoc-core label="Core" href="ext:javadocs-core"/>
|
<javadoc-core label="Core" href="ext:javadocs-core"/>
|
||||||
<javadoc-test-framework label="Test Framework" href="ext:javadocs-test-framework"/>
|
<javadoc-test-framework label="Test Framework" href="ext:javadocs-test-framework"/>
|
||||||
<javadoc-contrib label="Contrib">
|
<javadoc-contrib label="Contrib">
|
||||||
<javadoc-contrib-ant label="Ant" href="ext:javadocs-contrib-ant"/>
|
|
||||||
<javadoc-contrib-bdb label="Bdb" href="ext:javadocs-contrib-bdb"/>
|
|
||||||
<javadoc-contrib-bdb-je label="Bdb-je" href="ext:javadocs-contrib-bdb-je"/>
|
|
||||||
<javadoc-contrib-benchmark label="Benchmark" href="ext:javadocs-contrib-benchmark"/>
|
<javadoc-contrib-benchmark label="Benchmark" href="ext:javadocs-contrib-benchmark"/>
|
||||||
<javadoc-contrib-demo label="Demo" href="ext:javadocs-contrib-demo"/>
|
<javadoc-contrib-demo label="Demo" href="ext:javadocs-contrib-demo"/>
|
||||||
<javadoc-contrib-highlighter label="Highlighter" href="ext:javadocs-contrib-highlighter"/>
|
<javadoc-contrib-highlighter label="Highlighter" href="ext:javadocs-contrib-highlighter"/>
|
||||||
<javadoc-contrib-instantiated label="Instantiated" href="ext:javadocs-contrib-instantiated"/>
|
<javadoc-contrib-instantiated label="Instantiated" href="ext:javadocs-contrib-instantiated"/>
|
||||||
<javadoc-contrib-lucli label="Lucli" href="ext:javadocs-contrib-lucli"/>
|
|
||||||
<javadoc-contrib-memory label="Memory" href="ext:javadocs-contrib-memory"/>
|
<javadoc-contrib-memory label="Memory" href="ext:javadocs-contrib-memory"/>
|
||||||
<javadoc-contrib-misc label="Miscellaneous" href="ext:javadocs-contrib-misc"/>
|
<javadoc-contrib-misc label="Miscellaneous" href="ext:javadocs-contrib-misc"/>
|
||||||
<javadoc-contrib-queries label="Queries" href="ext:javadocs-contrib-queries"/>
|
<javadoc-contrib-queries label="Queries" href="ext:javadocs-contrib-queries"/>
|
||||||
|
@ -70,7 +66,6 @@ See http://forrest.apache.org/docs/linking.html for more info
|
||||||
<javadoc-contrib-remote label="Remote" href="ext:javadocs-contrib-remote"/>
|
<javadoc-contrib-remote label="Remote" href="ext:javadocs-contrib-remote"/>
|
||||||
<javadoc-contrib-spatial label="Spatial" href="ext:javadocs-contrib-spatial"/>
|
<javadoc-contrib-spatial label="Spatial" href="ext:javadocs-contrib-spatial"/>
|
||||||
<javadoc-contrib-spellchecker label="Spellchecker" href="ext:javadocs-contrib-spellchecker"/>
|
<javadoc-contrib-spellchecker label="Spellchecker" href="ext:javadocs-contrib-spellchecker"/>
|
||||||
<javadoc-contrib-swing label="Swing" href="ext:javadocs-contrib-swing"/>
|
|
||||||
<javadoc-contrib-wordnet label="Wordnet" href="ext:javadocs-contrib-wordnet"/>
|
<javadoc-contrib-wordnet label="Wordnet" href="ext:javadocs-contrib-wordnet"/>
|
||||||
<javadoc-contrib-xml-query-parser label="XML Query Parser" href="ext:javadocs-contrib-xml-query-parser"/>
|
<javadoc-contrib-xml-query-parser label="XML Query Parser" href="ext:javadocs-contrib-xml-query-parser"/>
|
||||||
</javadoc-contrib>
|
</javadoc-contrib>
|
||||||
|
@ -100,14 +95,10 @@ See http://forrest.apache.org/docs/linking.html for more info
|
||||||
<javadocs-all href="api/all/index.html"/>
|
<javadocs-all href="api/all/index.html"/>
|
||||||
<javadocs-core href="api/core/index.html"/>
|
<javadocs-core href="api/core/index.html"/>
|
||||||
<javadocs-test-framework href="api/test-framework/index.html"/>
|
<javadocs-test-framework href="api/test-framework/index.html"/>
|
||||||
<javadocs-contrib-ant href="api/contrib-ant/index.html"/>
|
|
||||||
<javadocs-contrib-bdb href="api/contrib-bdb/index.html"/>
|
|
||||||
<javadocs-contrib-bdb-je href="api/contrib-bdb-je/index.html"/>
|
|
||||||
<javadocs-contrib-benchmark href="api/contrib-benchmark/index.html"/>
|
<javadocs-contrib-benchmark href="api/contrib-benchmark/index.html"/>
|
||||||
<javadocs-contrib-demo href="api/contrib-demo/index.html"/>
|
<javadocs-contrib-demo href="api/contrib-demo/index.html"/>
|
||||||
<javadocs-contrib-highlighter href="api/contrib-highlighter/index.html"/>
|
<javadocs-contrib-highlighter href="api/contrib-highlighter/index.html"/>
|
||||||
<javadocs-contrib-instantiated href="api/contrib-instantiated/index.html"/>
|
<javadocs-contrib-instantiated href="api/contrib-instantiated/index.html"/>
|
||||||
<javadocs-contrib-lucli href="api/contrib-lucli/index.html"/>
|
|
||||||
<javadocs-contrib-memory href="api/contrib-memory/index.html"/>
|
<javadocs-contrib-memory href="api/contrib-memory/index.html"/>
|
||||||
<javadocs-contrib-misc href="api/contrib-misc/index.html"/>
|
<javadocs-contrib-misc href="api/contrib-misc/index.html"/>
|
||||||
<javadocs-contrib-queries href="api/contrib-queries/index.html"/>
|
<javadocs-contrib-queries href="api/contrib-queries/index.html"/>
|
||||||
|
@ -115,7 +106,6 @@ See http://forrest.apache.org/docs/linking.html for more info
|
||||||
<javadocs-contrib-remote href="api/contrib-remote/index.html"/>
|
<javadocs-contrib-remote href="api/contrib-remote/index.html"/>
|
||||||
<javadocs-contrib-spatial href="api/contrib-spatial/index.html"/>
|
<javadocs-contrib-spatial href="api/contrib-spatial/index.html"/>
|
||||||
<javadocs-contrib-spellchecker href="api/contrib-spellchecker/index.html"/>
|
<javadocs-contrib-spellchecker href="api/contrib-spellchecker/index.html"/>
|
||||||
<javadocs-contrib-swing href="api/contrib-swing/index.html"/>
|
|
||||||
<javadocs-contrib-wordnet href="api/contrib-wordnet/index.html"/>
|
<javadocs-contrib-wordnet href="api/contrib-wordnet/index.html"/>
|
||||||
<javadocs-contrib-xml-query-parser href="api/contrib-xml-query-parser/index.html"/>
|
<javadocs-contrib-xml-query-parser href="api/contrib-xml-query-parser/index.html"/>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue